From 131257cef1b2677dff8b3acc7ec8490568097af9 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 14 Feb 2020 08:31:31 +0100 Subject: [PATCH 001/255] GCodeProcessor basic framework --- src/libslic3r/CMakeLists.txt | 2 + src/libslic3r/GCode.cpp | 8 ++ src/libslic3r/GCode.hpp | 12 ++ src/libslic3r/GCode/GCodeProcessor.cpp | 177 +++++++++++++++++++++++++ src/libslic3r/GCode/GCodeProcessor.hpp | 87 ++++++++++++ src/libslic3r/Technologies.hpp | 11 ++ 6 files changed, 297 insertions(+) create mode 100644 src/libslic3r/GCode/GCodeProcessor.cpp create mode 100644 src/libslic3r/GCode/GCodeProcessor.hpp 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_ From 3b6d334d7bb0331e372cde14c69e153810fc0cbe Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 2 Mar 2020 15:13:23 +0100 Subject: [PATCH 002/255] ENABLE_GCODE_VIEWER - Basic framework for new gcode viewer --- src/PrusaSlicer.cpp | 4 +++ src/libslic3r/GCode.cpp | 34 +++++++++++++++++---- src/libslic3r/GCode.hpp | 10 +++--- src/libslic3r/GCode/GCodeProcessor.cpp | 30 ++++++++++-------- src/libslic3r/GCode/GCodeProcessor.hpp | 32 +++++++++++++------ src/libslic3r/Print.cpp | 12 +++++--- src/libslic3r/Print.hpp | 9 ++++-- src/libslic3r/Technologies.hpp | 2 -- src/slic3r/GUI/BackgroundSlicingProcess.cpp | 22 +++++++++++-- src/slic3r/GUI/BackgroundSlicingProcess.hpp | 6 ++++ src/slic3r/GUI/GLCanvas3D.cpp | 6 ++++ src/slic3r/GUI/GLCanvas3D.hpp | 7 +++++ src/slic3r/GUI/GUI_Preview.cpp | 12 ++++++++ src/slic3r/GUI/GUI_Preview.hpp | 15 +++++++-- src/slic3r/GUI/Plater.cpp | 10 ++++++ tests/fff_print/test_data.cpp | 6 +++- tests/fff_print/test_model.cpp | 4 +++ 17 files changed, 173 insertions(+), 48 deletions(-) diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp index 048aea8869..4557caa7c9 100644 --- a/src/PrusaSlicer.cpp +++ b/src/PrusaSlicer.cpp @@ -443,7 +443,11 @@ int CLI::run(int argc, char **argv) print->process(); if (printer_technology == ptFFF) { // The outfile is processed by a PlaceholderParser. +#if ENABLE_GCODE_VIEWER + outfile = fff_print.export_gcode(outfile, nullptr, nullptr); +#else outfile = fff_print.export_gcode(outfile, nullptr); +#endif // ENABLE_GCODE_VIEWER outfile_final = fff_print.print_statistics().finalize_output_path(outfile); } else { outfile = sla_print.output_filepath(outfile); diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 6717e961d1..701ca43778 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -698,11 +698,13 @@ std::vector>> GCode::collec return layers_to_print; } -#if ENABLE_THUMBNAIL_GENERATOR +#if ENABLE_GCODE_VIEWER +void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_data, GCodeProcessor::Result* result, ThumbnailsGeneratorCallback thumbnail_cb) +#elif ENABLE_THUMBNAIL_GENERATOR void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_data, ThumbnailsGeneratorCallback thumbnail_cb) #else void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_data) -#endif // ENABLE_THUMBNAIL_GENERATOR +#endif // ENABLE_GCODE_VIEWER { PROFILE_CLEAR(); @@ -761,13 +763,11 @@ 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); + if (result != nullptr) + *result = std::move(m_processor.extract_result()); #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(); @@ -905,6 +905,25 @@ namespace DoExport { analyzer.set_gcode_flavor(config.gcode_flavor); } +#if ENABLE_GCODE_VIEWER + static void init_gcode_processor(const PrintConfig& config, GCodeProcessor& processor) + { + processor.reset(); + processor.apply_config(config); + + // send extruder offset data to processor + unsigned int num_extruders = static_cast(config.nozzle_diameter.values.size()); + GCodeProcessor::ExtruderOffsetsMap extruder_offsets; + for (unsigned int id = 0; id < num_extruders; ++id) + { + Vec2d offset = config.extruder_offset.get_at(id); + if (!offset.isApprox(Vec2d::Zero())) + extruder_offsets[id] = offset; + } + processor.set_extruder_offsets(extruder_offsets); + } +#endif // ENABLE_GCODE_VIEWER + static double autospeed_volumetric_limit(const Print &print) { // get the minimum cross-section used in the print @@ -1142,6 +1161,9 @@ void GCode::_do_export(Print& print, FILE* file) // modifies the following: m_normal_time_estimator, m_silent_time_estimator, m_silent_time_estimator_enabled); DoExport::init_gcode_analyzer(print.config(), m_analyzer); +#if ENABLE_GCODE_VIEWER + DoExport::init_gcode_processor(print.config(), m_processor); +#endif // ENABLE_GCODE_VIEWER // resets analyzer's tracking data m_last_mm3_per_mm = GCodeAnalyzer::Default_mm3_per_mm; diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index e3da956c20..4b66d15218 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -14,11 +14,9 @@ #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" @@ -171,11 +169,13 @@ public: // throws std::runtime_exception on error, // throws CanceledException through print->throw_if_canceled(). -#if ENABLE_THUMBNAIL_GENERATOR +#if ENABLE_GCODE_VIEWER + void do_export(Print* print, const char* path, GCodePreviewData* preview_data = nullptr, GCodeProcessor::Result* result = nullptr, ThumbnailsGeneratorCallback thumbnail_cb = nullptr); +#elif ENABLE_THUMBNAIL_GENERATOR void do_export(Print* print, const char* path, GCodePreviewData* preview_data = nullptr, ThumbnailsGeneratorCallback thumbnail_cb = nullptr); #else void do_export(Print *print, const char *path, GCodePreviewData *preview_data = nullptr); -#endif // ENABLE_THUMBNAIL_GENERATOR +#endif // ENABLE_GCODE_VIEWER // Exported for the helper classes (OozePrevention, Wipe) and for the Perl binding for unit tests. const Vec2d& origin() const { return m_origin; } @@ -388,12 +388,10 @@ 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()); } diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 08066ee57e..493321a6e7 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -8,30 +8,26 @@ 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)); + std::fill(m_start_position.begin(), m_start_position.end(), 0.0f); + std::fill(m_end_position.begin(), m_end_position.end(), 0.0f); + std::fill(m_origin.begin(), m_origin.end(), 0.0f); m_feedrate = 0.0f; + m_extruder_id = 0; - m_moves.clear(); + m_result.reset(); } void GCodeProcessor::process_file(const std::string& filename) { - MoveStep start_step {}; - m_moves.emplace_back(start_step); + MoveVertex start_vertex {}; + m_result.moves.emplace_back(start_vertex); m_parser.parse_file(filename, [this](GCodeReader& reader, const GCodeReader::GCodeLine& line) { process_gcode_line(line); }); int a = 0; } @@ -149,9 +145,17 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) else if ((delta_pos[X] != 0.0f) || (delta_pos[Y] != 0.0f) || (delta_pos[Z] != 0.0f)) move_type = EMoveType::Travel; + // correct position by extruder offset + Vec3d extruder_offset = Vec3d::Zero(); + auto it = m_extruder_offsets.find(m_extruder_id); + if (it != m_extruder_offsets.end()) + extruder_offset = Vec3d(it->second(0), it->second(1), 0.0); - MoveStep move_step { m_end_position, m_feedrate, move_type }; - m_moves.emplace_back(move_step); + MoveVertex vertex; + vertex.position = Vec3d(m_end_position[0], m_end_position[1], m_end_position[2]) + extruder_offset; + vertex.feedrate = m_feedrate; + vertex.type = move_type; + m_result.moves.emplace_back(vertex); /* std::cout << "start: "; diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 0a3dae0327..7fa1733b78 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -33,15 +33,24 @@ namespace Slic3r { Num_Types }; - struct MoveStep + struct MoveVertex { - AxisCoords position; // mm - float feedrate; // mm/s - EMoveType type; + Vec3d position{ Vec3d::Zero() }; // mm + float feedrate{ 0.0f }; // mm/s + // type of the move terminating at this vertex + EMoveType type{ EMoveType::Noop }; }; - using MoveStepsList = std::vector; + public: + typedef std::map ExtruderOffsetsMap; + struct Result + { + std::vector moves; + void reset() { moves = std::vector(); } + }; + + private: GCodeReader m_parser; EUnits m_units; @@ -53,17 +62,22 @@ namespace Slic3r { AxisCoords m_origin; // mm float m_feedrate; // mm/s + unsigned int m_extruder_id; + ExtruderOffsetsMap m_extruder_offsets; - MoveStepsList m_moves; - + Result m_result; public: GCodeProcessor() { reset(); } - void apply_config(const PrintConfig& config); - + void apply_config(const PrintConfig& config) { m_parser.apply_config(config); } void reset(); + void set_extruder_offsets(const ExtruderOffsetsMap& extruder_offsets) { m_extruder_offsets = extruder_offsets; } + + const Result& get_result() const { return m_result; } + Result&& extract_result() { return std::move(m_result); } + // Process the gcode contained in the file with the given filename // Return false if any error occourred void process_file(const std::string& filename); diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index d5a1fa178d..d342c9056d 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1619,11 +1619,13 @@ void Print::process() // The export_gcode may die for various reasons (fails to process output_filename_format, // write error into the G-code, cannot execute post-processing scripts). // It is up to the caller to show an error message. -#if ENABLE_THUMBNAIL_GENERATOR +#if ENABLE_GCODE_VIEWER +std::string Print::export_gcode(const std::string& path_template, GCodePreviewData* preview_data, GCodeProcessor::Result* result, ThumbnailsGeneratorCallback thumbnail_cb) +#elif ENABLE_THUMBNAIL_GENERATOR std::string Print::export_gcode(const std::string& path_template, GCodePreviewData* preview_data, ThumbnailsGeneratorCallback thumbnail_cb) #else std::string Print::export_gcode(const std::string &path_template, GCodePreviewData *preview_data) -#endif // ENABLE_THUMBNAIL_GENERATOR +#endif // ENABLE_GCODE_VIEWER { // output everything to a G-code file // The following call may die if the output_filename_format template substitution fails. @@ -1640,11 +1642,13 @@ std::string Print::export_gcode(const std::string &path_template, GCodePreviewDa // The following line may die for multiple reasons. GCode gcode; -#if ENABLE_THUMBNAIL_GENERATOR +#if ENABLE_GCODE_VIEWER + gcode.do_export(this, path.c_str(), preview_data, result, thumbnail_cb); +#elif ENABLE_THUMBNAIL_GENERATOR gcode.do_export(this, path.c_str(), preview_data, thumbnail_cb); #else gcode.do_export(this, path.c_str(), preview_data); -#endif // ENABLE_THUMBNAIL_GENERATOR +#endif // ENABLE_GCODE_VIEWER return path.c_str(); } diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 7b326472e4..ef55482224 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -14,6 +14,9 @@ #if ENABLE_THUMBNAIL_GENERATOR #include "GCode/ThumbnailData.hpp" #endif // ENABLE_THUMBNAIL_GENERATOR +#if ENABLE_GCODE_VIEWER +#include "GCode/GCodeProcessor.hpp" +#endif // ENABLE_GCODE_VIEWER #include "libslic3r.h" @@ -364,11 +367,13 @@ public: void process() override; // Exports G-code into a file name based on the path_template, returns the file path of the generated G-code file. // If preview_data is not null, the preview_data is filled in for the G-code visualization (not used by the command line Slic3r). -#if ENABLE_THUMBNAIL_GENERATOR +#if ENABLE_GCODE_VIEWER + std::string export_gcode(const std::string& path_template, GCodePreviewData* preview_data, GCodeProcessor::Result* result, ThumbnailsGeneratorCallback thumbnail_cb = nullptr); +#elif ENABLE_THUMBNAIL_GENERATOR std::string export_gcode(const std::string& path_template, GCodePreviewData* preview_data, ThumbnailsGeneratorCallback thumbnail_cb = nullptr); #else std::string export_gcode(const std::string &path_template, GCodePreviewData *preview_data); -#endif // ENABLE_THUMBNAIL_GENERATOR +#endif // ENABLE_GCODE_VIEWER // methods for handling state bool is_step_done(PrintStep step) const { return Inherited::is_step_done(step); } diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index e5a2f3faee..4cebe98b1c 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -48,7 +48,6 @@ #define ENABLE_2_2_0_BETA1 1 -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ //================== // 2.3.0.alpha1 techs //================== @@ -56,7 +55,6 @@ // Enable G-Code viewer #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // _technologies_h_ diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 548a19f776..126a77ae74 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -89,11 +89,13 @@ void BackgroundSlicingProcess::process_fff() assert(m_print == m_fff_print); m_print->process(); wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, new wxCommandEvent(m_event_slicing_completed_id)); -#if ENABLE_THUMBNAIL_GENERATOR - m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data, m_thumbnail_cb); +#if ENABLE_GCODE_VIEWER + m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data, m_gcode_result, m_thumbnail_cb); +#elif ENABLE_THUMBNAIL_GENERATOR + m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data, m_thumbnail_cb); #else m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data); -#endif // ENABLE_THUMBNAIL_GENERATOR +#endif // ENABLE_GCODE_VIEWER if (this->set_step_started(bspsGCodeFinalize)) { if (! m_export_path.empty()) { @@ -377,6 +379,19 @@ Print::ApplyStatus BackgroundSlicingProcess::apply(const Model &model, const Dyn assert(m_print != nullptr); assert(config.opt_enum("printer_technology") == m_print->technology()); Print::ApplyStatus invalidated = m_print->apply(model, config); +#if ENABLE_GCODE_VIEWER + if ((invalidated & PrintBase::APPLY_STATUS_INVALIDATED) != 0 && m_print->technology() == ptFFF && + !this->m_fff_print->is_step_done(psGCodeExport)) + { + // Some FFF status was invalidated, and the G-code was not exported yet. + // Let the G-code preview UI know that the final G-code preview is not valid. + // In addition, this early memory deallocation reduces memory footprint. + if (m_gcode_preview_data != nullptr) + m_gcode_preview_data->reset(); + else if (m_gcode_result != nullptr) + m_gcode_result->reset(); + } +#else if ((invalidated & PrintBase::APPLY_STATUS_INVALIDATED) != 0 && m_print->technology() == ptFFF && m_gcode_preview_data != nullptr && ! this->m_fff_print->is_step_done(psGCodeExport)) { // Some FFF status was invalidated, and the G-code was not exported yet. @@ -384,6 +399,7 @@ Print::ApplyStatus BackgroundSlicingProcess::apply(const Model &model, const Dyn // In addition, this early memory deallocation reduces memory footprint. m_gcode_preview_data->reset(); } +#endif // ENABLE_GCODE_VIEWER return invalidated; } diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.hpp b/src/slic3r/GUI/BackgroundSlicingProcess.hpp index c8ece38f09..5b6f09d270 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.hpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.hpp @@ -52,6 +52,9 @@ public: #if ENABLE_THUMBNAIL_GENERATOR void set_thumbnail_cb(ThumbnailsGeneratorCallback cb) { m_thumbnail_cb = cb; } #endif // ENABLE_THUMBNAIL_GENERATOR +#if ENABLE_GCODE_VIEWER + void set_gcode_result(GCodeProcessor::Result* result) { m_gcode_result = result; } +#endif // ENABLE_GCODE_VIEWER // The following wxCommandEvent will be sent to the UI thread / Plater window, when the slicing is finished // and the background processing will transition into G-code export. @@ -159,6 +162,9 @@ private: // Callback function, used to write thumbnails into gcode. ThumbnailsGeneratorCallback m_thumbnail_cb = nullptr; #endif // ENABLE_THUMBNAIL_GENERATOR +#if ENABLE_GCODE_VIEWER + GCodeProcessor::Result* m_gcode_result = nullptr; +#endif // ENABLE_GCODE_VIEWER // Temporary G-code, there is one defined for the BackgroundSlicingProcess, differentiated from the other processes by a process ID. std::string m_temp_output_path; // Output path provided by the user. The output path may be set even if the slicing is running, diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index b5319a2f18..b96b8b47f1 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2480,6 +2480,12 @@ static void load_gcode_retractions(const GCodePreviewData::Retraction& retractio volume->indexed_vertex_array.finalize_geometry(gl_initialized); } +#if ENABLE_GCODE_VIEWER +void GLCanvas3D::load_gcode_preview_2(const GCodeProcessor::Result& gcode_result) +{ +} +#endif // ENABLE_GCODE_VIEWER + void GLCanvas3D::load_gcode_preview(const GCodePreviewData& preview_data, const std::vector& str_tool_colors) { const Print *print = this->fff_print(); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 9ae1278800..0dc2b26dd1 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -13,6 +13,9 @@ #include "Gizmos/GLGizmosManager.hpp" #include "GUI_ObjectLayers.hpp" #include "MeshUtils.hpp" +#if ENABLE_GCODE_VIEWER +#include "libslic3r/GCode/GCodeProcessor.hpp" +#endif // ENABLE_GCODE_VIEWER #include @@ -577,6 +580,10 @@ public: void reload_scene(bool refresh_immediately, bool force_full_scene_refresh = false); +#if ENABLE_GCODE_VIEWER + void load_gcode_preview_2(const GCodeProcessor::Result& gcode_result); +#endif // ENABLE_GCODE_VIEWER + void load_gcode_preview(const GCodePreviewData& preview_data, const std::vector& str_tool_colors); void load_sla_preview(); void load_preview(const std::vector& str_tool_colors, const std::vector& color_print_values); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 5afdb3bb43..d0493adfc6 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -163,9 +163,15 @@ void View3D::render() m_canvas->set_as_dirty(); } +#if ENABLE_GCODE_VIEWER Preview::Preview( wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config, + BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, GCodeProcessor::Result* gcode_result, std::function schedule_background_process_func) +#else +Preview::Preview( + wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function schedule_background_process_func) +#endif // ENABLE_GCODE_VIEWER : m_canvas_widget(nullptr) , m_canvas(nullptr) , m_double_slider_sizer(nullptr) @@ -181,6 +187,9 @@ Preview::Preview( , m_config(config) , m_process(process) , m_gcode_preview_data(gcode_preview_data) +#if ENABLE_GCODE_VIEWER + , m_gcode_result(gcode_result) +#endif // ENABLE_GCODE_VIEWER , m_number_extruders(1) , m_preferred_color_mode("feature") , m_loaded(false) @@ -860,6 +869,9 @@ void Preview::load_print_as_fff(bool keep_z_range) if (gcode_preview_data_valid) { // Load the real G-code preview. m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); +#if ENABLE_GCODE_VIEWER + m_canvas->load_gcode_preview_2(*m_gcode_result); +#endif // ENABLE_GCODE_VIEWER m_loaded = true; } else { // Load the initial preview based on slices, not the final G-code. diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index cc8f153251..f0e7abfeca 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -6,6 +6,9 @@ #include #include "libslic3r/Model.hpp" +#if ENABLE_GCODE_VIEWER +#include "libslic3r/GCode/GCodeProcessor.hpp" +#endif // ENABLE_GCODE_VIEWER class wxNotebook; class wxGLCanvas; @@ -90,6 +93,9 @@ class Preview : public wxPanel DynamicPrintConfig* m_config; BackgroundSlicingProcess* m_process; GCodePreviewData* m_gcode_preview_data; +#if ENABLE_GCODE_VIEWER + GCodeProcessor::Result* m_gcode_result; +#endif // ENABLE_GCODE_VIEWER #ifdef __linux__ // We are getting mysterious crashes on Linux in gtk due to OpenGL context activation GH #1874 #1955. @@ -109,8 +115,13 @@ class Preview : public wxPanel DoubleSlider::Control* m_slider {nullptr}; public: - Preview(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config, - BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function schedule_background_process = [](){}); +#if ENABLE_GCODE_VIEWER + Preview(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config, + BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, GCodeProcessor::Result* gcode_result, std::function schedule_background_process = []() {}); +#else + Preview(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config, + BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function schedule_background_process = []() {}); +#endif // ENABLE_GCODE_VIEWER virtual ~Preview(); wxGLCanvas* get_wxglcanvas() { return m_canvas_widget; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 3171818875..3886d5f359 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1440,6 +1440,9 @@ struct Plater::priv Slic3r::Model model; PrinterTechnology printer_technology = ptFFF; Slic3r::GCodePreviewData gcode_preview_data; +#if ENABLE_GCODE_VIEWER + Slic3r::GCodeProcessor::Result gcode_result; +#endif // ENABLE_GCODE_VIEWER // GUI elements wxSizer* panel_sizer{ nullptr }; @@ -1990,6 +1993,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) background_process.set_fff_print(&fff_print); background_process.set_sla_print(&sla_print); background_process.set_gcode_preview_data(&gcode_preview_data); +#if ENABLE_GCODE_VIEWER + background_process.set_gcode_result(&gcode_result); +#endif // ENABLE_GCODE_VIEWER #if ENABLE_THUMBNAIL_GENERATOR background_process.set_thumbnail_cb([this](ThumbnailsList& thumbnails, const Vec2ds& sizes, bool printable_only, bool parts_only, bool show_bed, bool transparent_background) { @@ -2015,7 +2021,11 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) this->q->Bind(EVT_SLICING_UPDATE, &priv::on_slicing_update, this); view3D = new View3D(q, bed, camera, view_toolbar, &model, config, &background_process); +#if ENABLE_GCODE_VIEWER + preview = new Preview(q, bed, camera, view_toolbar, &model, config, &background_process, &gcode_preview_data, &gcode_result, [this]() { schedule_background_process(); }); +#else preview = new Preview(q, bed, camera, view_toolbar, &model, config, &background_process, &gcode_preview_data, [this](){ schedule_background_process(); }); +#endif // ENABLE_GCODE_VIEWER panels.push_back(view3D); panels.push_back(preview); diff --git a/tests/fff_print/test_data.cpp b/tests/fff_print/test_data.cpp index b3c16f4b01..50b3383254 100644 --- a/tests/fff_print/test_data.cpp +++ b/tests/fff_print/test_data.cpp @@ -244,8 +244,12 @@ std::string gcode(Print & print) boost::filesystem::path temp = boost::filesystem::unique_path(); print.set_status_silent(); print.process(); +#if ENABLE_GCODE_VIEWER + print.export_gcode(temp.string(), nullptr, nullptr); +#else print.export_gcode(temp.string(), nullptr); - std::ifstream t(temp.string()); +#endif // ENABLE_GCODE_VIEWER + std::ifstream t(temp.string()); std::string str((std::istreambuf_iterator(t)), std::istreambuf_iterator()); boost::nowide::remove(temp.string().c_str()); return str; diff --git a/tests/fff_print/test_model.cpp b/tests/fff_print/test_model.cpp index 3378a83638..3d3b54ef02 100644 --- a/tests/fff_print/test_model.cpp +++ b/tests/fff_print/test_model.cpp @@ -50,7 +50,11 @@ SCENARIO("Model construction", "[Model]") { print.apply(model, config); print.process(); boost::filesystem::path temp = boost::filesystem::unique_path(); +#if ENABLE_GCODE_VIEWER + print.export_gcode(temp.string(), nullptr, nullptr); +#else print.export_gcode(temp.string(), nullptr); +#endif // ENABLE_GCODE_VIEWER REQUIRE(boost::filesystem::exists(temp)); REQUIRE(boost::filesystem::is_regular_file(temp)); REQUIRE(boost::filesystem::file_size(temp) > 0); From 35e963a566e9199d0010891312bbb3667d45ebe9 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 30 Mar 2020 09:01:50 +0200 Subject: [PATCH 003/255] Small refactoring --- src/libslic3r/GCode.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 6a3a0bee24..28fa2ca28f 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -906,13 +906,13 @@ namespace DoExport { processor.apply_config(config); // send extruder offset data to processor - unsigned int num_extruders = static_cast(config.nozzle_diameter.values.size()); GCodeProcessor::ExtruderOffsetsMap extruder_offsets; - for (unsigned int id = 0; id < num_extruders; ++id) + const size_t num_extruders = config.nozzle_diameter.values.size(); + for (size_t id = 0; id < num_extruders; ++id) { - Vec2d offset = config.extruder_offset.get_at(id); + const Vec2d& offset = config.extruder_offset.get_at(id); if (!offset.isApprox(Vec2d::Zero())) - extruder_offsets[id] = offset; + extruder_offsets[static_cast(id)] = offset; } processor.set_extruder_offsets(extruder_offsets); } From 956f7a4593887237f68150eb9da855d50a030e5f Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 2 Apr 2020 12:03:18 +0200 Subject: [PATCH 004/255] GCodeProcessor additions: process G90 lines process G91 lines process G92 lines process M82 lines process M83 lines process T lines process extrusion role/width/height comment tags debug output --- src/libslic3r/GCode.cpp | 43 +++-- src/libslic3r/GCode/Analyzer.cpp | 29 ++- src/libslic3r/GCode/Analyzer.hpp | 12 ++ src/libslic3r/GCode/GCodeProcessor.cpp | 251 +++++++++++++++++++------ src/libslic3r/GCode/GCodeProcessor.hpp | 66 +++++-- src/libslic3r/GCode/WipeTower.cpp | 15 ++ src/libslic3r/Technologies.hpp | 7 +- src/slic3r/GUI/GLCanvas3D.cpp | 10 + 8 files changed, 349 insertions(+), 84 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 28fa2ca28f..3ea365b3cc 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -780,6 +780,10 @@ void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_ // starts analyzer calculations if (m_enable_analyzer) { +#if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT + m_analyzer.close_debug_output_file(); +#endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT + BOOST_LOG_TRIVIAL(debug) << "Preparing G-code preview data" << log_memory_info(); m_analyzer.calc_gcode_preview_data(*preview_data, [print]() { print->throw_if_canceled(); }); m_analyzer.reset(); @@ -897,24 +901,17 @@ namespace DoExport { // tell analyzer about the gcode flavor analyzer.set_gcode_flavor(config.gcode_flavor); - } + +#if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT + analyzer.open_debug_output_file(); +#endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT + } #if ENABLE_GCODE_VIEWER static void init_gcode_processor(const PrintConfig& config, GCodeProcessor& processor) { processor.reset(); processor.apply_config(config); - - // send extruder offset data to processor - GCodeProcessor::ExtruderOffsetsMap extruder_offsets; - const size_t num_extruders = config.nozzle_diameter.values.size(); - for (size_t id = 0; id < num_extruders; ++id) - { - const Vec2d& offset = config.extruder_offset.get_at(id); - if (!offset.isApprox(Vec2d::Zero())) - extruder_offsets[static_cast(id)] = offset; - } - processor.set_extruder_offsets(extruder_offsets); } #endif // ENABLE_GCODE_VIEWER @@ -1340,6 +1337,11 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu // adds tag for analyzer _write_format(file, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), erCustom); +#if ENABLE_GCODE_VIEWER + // adds tag for processor + _write_format(file, ";%s%d\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), erCustom); +#endif // ENABLE_GCODE_VIEWER + // Write the custom start G-code _writeln(file, start_gcode); @@ -1493,6 +1495,11 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu // adds tag for analyzer _write_format(file, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), erCustom); +#if ENABLE_GCODE_VIEWER + // adds tag for processor + _write_format(file, ";%s%d\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), erCustom); +#endif // ENABLE_GCODE_VIEWER + // Process filament-specific gcode in extruder order. { DynamicConfig config; @@ -3112,6 +3119,10 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, { m_last_analyzer_extrusion_role = path.role(); sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), int(m_last_analyzer_extrusion_role)); +#if ENABLE_GCODE_VIEWER + gcode += buf; + sprintf(buf, ";%s%d\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), int(m_last_analyzer_extrusion_role)); +#endif // ENABLE_GCODE_VIEWER gcode += buf; } @@ -3127,6 +3138,10 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, m_last_width = path.width; sprintf(buf, ";%s%f\n", GCodeAnalyzer::Width_Tag.c_str(), m_last_width); gcode += buf; +#if ENABLE_GCODE_VIEWER + sprintf(buf, ";%s%f\n", GCodeProcessor::Width_Tag.c_str(), m_last_width); + gcode += buf; +#endif // ENABLE_GCODE_VIEWER } if (last_was_wipe_tower || (m_last_height != path.height)) @@ -3134,6 +3149,10 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, m_last_height = path.height; sprintf(buf, ";%s%f\n", GCodeAnalyzer::Height_Tag.c_str(), m_last_height); gcode += buf; +#if ENABLE_GCODE_VIEWER + sprintf(buf, ";%s%f\n", GCodeProcessor::Height_Tag.c_str(), m_last_height); + gcode += buf; +#endif // ENABLE_GCODE_VIEWER } } diff --git a/src/libslic3r/GCode/Analyzer.cpp b/src/libslic3r/GCode/Analyzer.cpp index 442d5ec839..8a2ba7804b 100644 --- a/src/libslic3r/GCode/Analyzer.cpp +++ b/src/libslic3r/GCode/Analyzer.cpp @@ -174,6 +174,19 @@ bool GCodeAnalyzer::is_valid_extrusion_role(ExtrusionRole role) return ((erPerimeter <= role) && (role < erMixed)); } +#if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT +void GCodeAnalyzer::open_debug_output_file() +{ + boost::filesystem::path path("d:/analyzer.output"); + m_debug_output.open(path.string()); +} + +void GCodeAnalyzer::close_debug_output_file() +{ + m_debug_output.close(); +} +#endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT + void GCodeAnalyzer::_process_gcode_line(GCodeReader&, const GCodeReader::GCodeLine& line) { // processes 'special' comments contained in line @@ -350,7 +363,7 @@ void GCodeAnalyzer::_processG1(const GCodeReader::GCodeLine& line) if (delta_pos[E] < 0.0f) { if ((delta_pos[X] != 0.0f) || (delta_pos[Y] != 0.0f) || (delta_pos[Z] != 0.0f)) - type = GCodeMove::Move; + type = GCodeMove::Move; else type = GCodeMove::Retract; } @@ -922,6 +935,20 @@ void GCodeAnalyzer::_store_move(GCodeAnalyzer::GCodeMove::EType type) Vec3d start_position = _get_start_position() + extruder_offset; Vec3d end_position = _get_end_position() + extruder_offset; it->second.emplace_back(type, _get_extrusion_role(), extruder_id, _get_mm3_per_mm(), _get_width(), _get_height(), _get_feedrate(), start_position, end_position, _get_delta_extrusion(), _get_fan_speed(), _get_cp_color_id()); + +#if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT + if (m_debug_output.good()) + { + m_debug_output << std::to_string((int)type); + m_debug_output << ", " << std::to_string((int)_get_extrusion_role()); + m_debug_output << ", " << Slic3r::to_string(_get_end_position()); + m_debug_output << ", " << std::to_string(extruder_id); + m_debug_output << ", " << std::to_string(_get_feedrate()); + m_debug_output << ", " << std::to_string(_get_width()); + m_debug_output << ", " << std::to_string(_get_height()); + m_debug_output << "\n"; + } +#endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT } bool GCodeAnalyzer::_is_valid_extrusion_role(int value) const diff --git a/src/libslic3r/GCode/Analyzer.hpp b/src/libslic3r/GCode/Analyzer.hpp index cd5654a745..fb5ef3b4c1 100644 --- a/src/libslic3r/GCode/Analyzer.hpp +++ b/src/libslic3r/GCode/Analyzer.hpp @@ -8,6 +8,10 @@ #include "../Point.hpp" #include "../GCodeReader.hpp" +#if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT +#include +#endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT + namespace Slic3r { class GCodePreviewData; @@ -147,6 +151,14 @@ public: static bool is_valid_extrusion_role(ExtrusionRole role); +#if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT +private: + boost::nowide::ofstream m_debug_output; +public: + void open_debug_output_file(); + void close_debug_output_file(); +#endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT + private: // Processes the given gcode line void _process_gcode_line(GCodeReader& reader, const GCodeReader::GCodeLine& line); diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 493321a6e7..ffb4e17146 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -6,19 +6,47 @@ static const float INCHES_TO_MM = 25.4f; static const float MMMIN_TO_MMSEC = 1.0f / 60.0f; +static bool is_valid_extrusion_role(int value) +{ + return ((int)Slic3r::erNone <= value) && (value <= (int)Slic3r::erMixed); +} + namespace Slic3r { +const std::string GCodeProcessor::Extrusion_Role_Tag = "_PROCESSOR_EXTRUSION_ROLE:"; +const std::string GCodeProcessor::Width_Tag = "_PROCESSOR_WIDTH:"; +const std::string GCodeProcessor::Height_Tag = "_PROCESSOR_HEIGHT:"; + +void GCodeProcessor::apply_config(const PrintConfig& config) +{ + m_parser.apply_config(config); + + size_t extruders_count = config.nozzle_diameter.values.size(); + if (m_extruder_offsets.size() != extruders_count) + m_extruder_offsets.resize(extruders_count); + + for (size_t id = 0; id < extruders_count; ++id) + { + Vec2f offset = config.extruder_offset.get_at(id).cast(); + m_extruder_offsets[id] = Vec3f(offset(0), offset(1), 0.0f); + } +} + void GCodeProcessor::reset() { m_units = EUnits::Millimeters; m_global_positioning_type = EPositioningType::Absolute; m_e_local_positioning_type = EPositioningType::Absolute; - + m_extruder_offsets = std::vector(1, Vec3f::Zero()); + std::fill(m_start_position.begin(), m_start_position.end(), 0.0f); std::fill(m_end_position.begin(), m_end_position.end(), 0.0f); std::fill(m_origin.begin(), m_origin.end(), 0.0f); m_feedrate = 0.0f; + m_width = 0.0f; + m_height = 0.0f; + m_extrusion_role = erNone; m_extruder_id = 0; m_result.reset(); @@ -26,10 +54,8 @@ void GCodeProcessor::reset() void GCodeProcessor::process_file(const std::string& filename) { - MoveVertex start_vertex {}; - m_result.moves.emplace_back(start_vertex); + m_result.moves.emplace_back(MoveVertex()); 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) @@ -42,8 +68,6 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) m_start_position = m_end_position; std::string cmd = line.cmd(); - std::string comment = line.comment(); - if (cmd.length() > 1) { // process command lines @@ -54,7 +78,13 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) switch (::atoi(&cmd[1])) { // Move - case 1: { process_G1(line); } + case 1: { process_G1(line); break; } + // Set to Absolute Positioning + case 90: { processG90(line); break; } + // Set to Relative Positioning + case 91: { processG91(line); break; } + // Set Position + case 92: { processG92(line); break; } default: { break; } } break; @@ -63,6 +93,10 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) { switch (::atoi(&cmd[1])) { + // Set extruder to absolute mode + case 82: { processM82(line); break; } + // Set extruder to relative mode + case 83: { processM83(line); break; } default: { break; } } break; @@ -74,20 +108,52 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) default: { break; } } } - else if (comment.length() > 1) + else { - // process tags embedded into comments - process_comment(line); + std::string comment = line.comment(); + if (comment.length() > 1) + // process tags embedded into comments + process_tags(comment); } } -void GCodeProcessor::process_comment(const GCodeReader::GCodeLine& line) +void GCodeProcessor::process_tags(const std::string& comment) { + // extrusion role tag + size_t pos = comment.find(Extrusion_Role_Tag); + if (pos != comment.npos) + { + int role = std::stoi(comment.substr(pos + Extrusion_Role_Tag.length())); + if (is_valid_extrusion_role(role)) + m_extrusion_role = static_cast(role); + else + { + // todo: show some error ? + } + + return; + } + + // width tag + pos = comment.find(Width_Tag); + if (pos != comment.npos) + { + m_width = std::stof(comment.substr(pos + Width_Tag.length())); + return; + } + + // height tag + pos = comment.find(Height_Tag); + if (pos != comment.npos) + { + m_height = std::stof(comment.substr(pos + Height_Tag.length())); + return; + } } void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) { - auto axis_absolute_position = [this](Axis axis, const GCodeReader::GCodeLine& lineG1) + auto absolute_position = [this](Axis axis, const GCodeReader::GCodeLine& lineG1) { bool is_relative = (m_global_positioning_type == EPositioningType::Relative); if (axis == E) @@ -103,10 +169,36 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) return m_start_position[axis]; }; + auto move_type = [this](const AxisCoords& delta_pos) { + EMoveType 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) + type = EMoveType::Travel; + else + 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) + type = EMoveType::Unretract; + else if ((delta_pos[X] != 0.0f) || (delta_pos[Y] != 0.0f)) + type = EMoveType::Extrude; + } + else if (delta_pos[X] != 0.0f || delta_pos[Y] != 0.0f || delta_pos[Z] != 0.0f) + type = EMoveType::Travel; + + if (type == EMoveType::Extrude && (m_width == 0.0f || m_height == 0.0f || !is_valid_extrusion_role(m_extrusion_role))) + type = EMoveType::Travel; + + return type; + }; + // updates axes positions from line for (unsigned char a = X; a <= E; ++a) { - m_end_position[a] = axis_absolute_position((Axis)a, line); + m_end_position[a] = absolute_position((Axis)a, line); } // updates feedrate from line, if present @@ -124,56 +216,109 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) // no displacement, return if (max_abs_delta == 0.0f) - return; // <<<<<<<<<<<<<<<<< is this correct for time estimate ? + return; - // detect move type - EMoveType move_type = EMoveType::Noop; - if (delta_pos[E] < 0.0f) + // store g1 move + store_move_vertex(move_type(delta_pos)); +} + +void GCodeProcessor::processG90(const GCodeReader::GCodeLine& line) +{ + m_global_positioning_type = EPositioningType::Absolute; +} + +void GCodeProcessor::processG91(const GCodeReader::GCodeLine& line) +{ + m_global_positioning_type = EPositioningType::Relative; +} + +void GCodeProcessor::processG92(const GCodeReader::GCodeLine& line) +{ + float lengthsScaleFactor = (m_units == EUnits::Inches) ? INCHES_TO_MM : 1.0f; + bool anyFound = false; + + if (line.has_x()) { - 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; + m_origin[X] = m_end_position[X] - line.x() * lengthsScaleFactor; + anyFound = true; } - else if (delta_pos[E] > 0.0f) + + if (line.has_y()) { - 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; + m_origin[Y] = m_end_position[Y] - line.y() * lengthsScaleFactor; + anyFound = true; } - else if ((delta_pos[X] != 0.0f) || (delta_pos[Y] != 0.0f) || (delta_pos[Z] != 0.0f)) - move_type = EMoveType::Travel; - // correct position by extruder offset - Vec3d extruder_offset = Vec3d::Zero(); - auto it = m_extruder_offsets.find(m_extruder_id); - if (it != m_extruder_offsets.end()) - extruder_offset = Vec3d(it->second(0), it->second(1), 0.0); + if (line.has_z()) + { + m_origin[Z] = m_end_position[Z] - line.z() * lengthsScaleFactor; + anyFound = true; + } + if (line.has_e()) + { + // extruder coordinate can grow to the point where its float representation does not allow for proper addition with small increments, + // we set the value taken from the G92 line as the new current position for it + m_end_position[E] = line.e() * lengthsScaleFactor; + anyFound = true; + } + + if (!anyFound && !line.has_unknown_axis()) + { + // The G92 may be called for axes that PrusaSlicer does not recognize, for example see GH issue #3510, + // where G92 A0 B0 is called although the extruder axis is till E. + for (unsigned char a = X; a <= E; ++a) + { + m_origin[a] = m_end_position[a]; + } + } +} + +void GCodeProcessor::processM82(const GCodeReader::GCodeLine& line) +{ + m_e_local_positioning_type = EPositioningType::Absolute; +} + +void GCodeProcessor::processM83(const GCodeReader::GCodeLine& line) +{ + m_e_local_positioning_type = EPositioningType::Relative; +} + +void GCodeProcessor::processT(const GCodeReader::GCodeLine& line) +{ + const std::string& cmd = line.cmd(); + if (cmd.length() > 1) + { + unsigned int id = (unsigned int)std::stoi(cmd.substr(1)); + if (m_extruder_id != id) + { + unsigned int extruders_count = (unsigned int)m_extruder_offsets.size(); + if (id >= extruders_count) + BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid toolchange, maybe from a custom gcode."; + else + { + m_extruder_id = id; +// if (_get_cp_color_id() != INT_MAX) <<<<<<<<<<<<<<<<<<< TODO +// _set_cp_color_id(m_extruder_color[id]); + } + + // store tool change move + store_move_vertex(EMoveType::Tool_change); + } + } +} + +void GCodeProcessor::store_move_vertex(EMoveType type) +{ MoveVertex vertex; - vertex.position = Vec3d(m_end_position[0], m_end_position[1], m_end_position[2]) + extruder_offset; + vertex.type = type; + vertex.extrusion_role = m_extrusion_role; + vertex.position = Vec3f(m_end_position[0], m_end_position[1], m_end_position[2]) + m_extruder_offsets[m_extruder_id]; vertex.feedrate = m_feedrate; - vertex.type = move_type; + vertex.width = m_width; + vertex.height = m_height; + vertex.extruder_id = m_extruder_id; m_result.moves.emplace_back(vertex); - -/* - 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 */ diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 7fa1733b78..537617485f 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -3,11 +3,19 @@ #if ENABLE_GCODE_VIEWER #include "../GCodeReader.hpp" +#include "../Point.hpp" +#include "../ExtrusionEntity.hpp" namespace Slic3r { class GCodeProcessor { + public: + static const std::string Extrusion_Role_Tag; + static const std::string Width_Tag; + static const std::string Height_Tag; + + private: using AxisCoords = std::array; enum class EUnits : unsigned char @@ -33,16 +41,29 @@ namespace Slic3r { Num_Types }; + public: struct MoveVertex { - Vec3d position{ Vec3d::Zero() }; // mm - float feedrate{ 0.0f }; // mm/s - // type of the move terminating at this vertex EMoveType type{ EMoveType::Noop }; - }; + ExtrusionRole extrusion_role{ erNone }; + Vec3f position{ Vec3f::Zero() }; // mm + float feedrate{ 0.0f }; // mm/s + float width{ 0.0f }; // mm + float height{ 0.0f }; // mm + unsigned int extruder_id{ 0 }; - public: - typedef std::map ExtruderOffsetsMap; + std::string to_string() const + { + std::string str = std::to_string((int)type); + str += ", " + std::to_string((int)extrusion_role); + str += ", " + Slic3r::to_string((Vec3d)position.cast()); + str += ", " + std::to_string(extruder_id); + str += ", " + std::to_string(feedrate); + str += ", " + std::to_string(width); + str += ", " + std::to_string(height); + return str; + } + }; struct Result { @@ -56,25 +77,26 @@ namespace Slic3r { EUnits m_units; EPositioningType m_global_positioning_type; EPositioningType m_e_local_positioning_type; + std::vector m_extruder_offsets; AxisCoords m_start_position; // mm AxisCoords m_end_position; // mm AxisCoords m_origin; // mm float m_feedrate; // mm/s + float m_width; // mm + float m_height; // mm + ExtrusionRole m_extrusion_role; unsigned int m_extruder_id; - ExtruderOffsetsMap m_extruder_offsets; Result m_result; public: GCodeProcessor() { reset(); } - void apply_config(const PrintConfig& config) { m_parser.apply_config(config); } + void apply_config(const PrintConfig& config); void reset(); - void set_extruder_offsets(const ExtruderOffsetsMap& extruder_offsets) { m_extruder_offsets = extruder_offsets; } - const Result& get_result() const { return m_result; } Result&& extract_result() { return std::move(m_result); } @@ -86,11 +108,31 @@ namespace Slic3r { void process_gcode_line(const GCodeReader::GCodeLine& line); // Process tags embedded into comments - void process_comment(const GCodeReader::GCodeLine& line); + void process_tags(const std::string& comment); // Move void process_G1(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); + + void store_move_vertex(EMoveType type); + }; } /* namespace Slic3r */ diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index d31adbd8fc..339012d0b4 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -22,6 +22,9 @@ TODO LIST #include #include "Analyzer.hpp" +#if ENABLE_GCODE_VIEWER +#include "GCodeProcessor.hpp" +#endif // ENABLE_GCODE_VIEWER #include "BoundingBox.hpp" #if defined(__linux) || defined(__GNUC__ ) @@ -55,7 +58,15 @@ public: char buf[64]; sprintf(buf, ";%s%f\n", GCodeAnalyzer::Height_Tag.c_str(), m_layer_height); // don't rely on GCodeAnalyzer knowing the layer height - it knows nothing at priming m_gcode += buf; +#if ENABLE_GCODE_VIEWER + sprintf(buf, ";%s%f\n", GCodeProcessor::Height_Tag.c_str(), m_layer_height); // don't rely on GCodeAnalyzer knowing the layer height - it knows nothing at priming + m_gcode += buf; +#endif // ENABLE_GCODE_VIEWER sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), erWipeTower); +#if ENABLE_GCODE_VIEWER + m_gcode += buf; + sprintf(buf, ";%s%d\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), erWipeTower); +#endif // ENABLE_GCODE_VIEWER m_gcode += buf; change_analyzer_line_width(line_width); } @@ -65,6 +76,10 @@ public: char buf[64]; sprintf(buf, ";%s%f\n", GCodeAnalyzer::Width_Tag.c_str(), line_width); m_gcode += buf; +#if ENABLE_GCODE_VIEWER + sprintf(buf, ";%s%f\n", GCodeProcessor::Width_Tag.c_str(), line_width); + m_gcode += buf; +#endif // ENABLE_GCODE_VIEWER return *this; } diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 44c10fa548..85ce8a2cb2 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -60,14 +60,9 @@ // Moves GLCanvas3DManager from being a static member of _3DScene to be a normal member of GUI_App #define ENABLE_NON_STATIC_CANVAS_MANAGER (1 && ENABLE_2_3_0_ALPHA1) - -//================== -// 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) +#define ENABLE_GCODE_VIEWER_DEBUG_OUTPUT (1 && ENABLE_GCODE_VIEWER) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index d8b102cee5..de85929ea1 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2772,6 +2772,16 @@ static void load_gcode_retractions(const GCodePreviewData::Retraction& retractio #if ENABLE_GCODE_VIEWER void GLCanvas3D::load_gcode_preview_2(const GCodeProcessor::Result& gcode_result) { +#if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT + boost::filesystem::path path("d:/processor.output"); + boost::nowide::ofstream out; + out.open(path.string()); + for (const GCodeProcessor::MoveVertex& v : gcode_result.moves) + { + out << v.to_string() << "\n"; + } + out.close(); +#endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT } #endif // ENABLE_GCODE_VIEWER From ece4f10bf75475057b71a94087cc2db531ca87ce Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 2 Apr 2020 12:30:54 +0200 Subject: [PATCH 005/255] Updated Print.xsp --- xs/xsp/Print.xsp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xs/xsp/Print.xsp b/xs/xsp/Print.xsp index 0952513ca3..160fd3e60c 100644 --- a/xs/xsp/Print.xsp +++ b/xs/xsp/Print.xsp @@ -164,7 +164,7 @@ _constant() void export_gcode(char *path_template) %code%{ try { - THIS->export_gcode(path_template, nullptr); + THIS->export_gcode(path_template, nullptr, nullptr); } catch (std::exception& e) { croak("%s\n", e.what()); } From d0ce17656f34219a764dc5c926394096f7946231 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 2 Apr 2020 13:19:42 +0200 Subject: [PATCH 006/255] Added missing includes --- src/libslic3r/GCode/Analyzer.cpp | 3 +++ src/libslic3r/GCode/GCodeProcessor.hpp | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/libslic3r/GCode/Analyzer.cpp b/src/libslic3r/GCode/Analyzer.cpp index a2a809ca3f..885c5e9e87 100644 --- a/src/libslic3r/GCode/Analyzer.cpp +++ b/src/libslic3r/GCode/Analyzer.cpp @@ -8,6 +8,9 @@ #include "Print.hpp" #include +#if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT +#include +#endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT #include "Analyzer.hpp" #include "PreviewData.hpp" diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 537617485f..0fa8187fd3 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -6,6 +6,8 @@ #include "../Point.hpp" #include "../ExtrusionEntity.hpp" +#include + namespace Slic3r { class GCodeProcessor From f05de150c58608ff6f59c06cab0e022b08b66795 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 2 Apr 2020 15:52:42 +0200 Subject: [PATCH 007/255] Added another missing include --- src/libslic3r/GCode/Analyzer.cpp | 29 ++++++++++++++++---------- src/libslic3r/GCode/Analyzer.hpp | 7 ------- src/libslic3r/GCode/GCodeProcessor.cpp | 2 ++ 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/libslic3r/GCode/Analyzer.cpp b/src/libslic3r/GCode/Analyzer.cpp index 885c5e9e87..b283d70a9b 100644 --- a/src/libslic3r/GCode/Analyzer.cpp +++ b/src/libslic3r/GCode/Analyzer.cpp @@ -15,6 +15,13 @@ #include "Analyzer.hpp" #include "PreviewData.hpp" +#if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT +#include + +// don't worry, this is just temporary +static boost::nowide::ofstream g_debug_output; +#endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT + static const std::string AXIS_STR = "XYZE"; static const float MMMIN_TO_MMSEC = 1.0f / 60.0f; static const float INCHES_TO_MM = 25.4f; @@ -181,12 +188,12 @@ bool GCodeAnalyzer::is_valid_extrusion_role(ExtrusionRole role) void GCodeAnalyzer::open_debug_output_file() { boost::filesystem::path path("d:/analyzer.output"); - m_debug_output.open(path.string()); + g_debug_output.open(path.string()); } void GCodeAnalyzer::close_debug_output_file() { - m_debug_output.close(); + g_debug_output.close(); } #endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT @@ -940,16 +947,16 @@ void GCodeAnalyzer::_store_move(GCodeAnalyzer::GCodeMove::EType type) it->second.emplace_back(type, _get_extrusion_role(), extruder_id, _get_mm3_per_mm(), _get_width(), _get_height(), _get_feedrate(), start_position, end_position, _get_delta_extrusion(), _get_fan_speed(), _get_cp_color_id()); #if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT - if (m_debug_output.good()) + if (g_debug_output.good()) { - m_debug_output << std::to_string((int)type); - m_debug_output << ", " << std::to_string((int)_get_extrusion_role()); - m_debug_output << ", " << Slic3r::to_string((Vec3d)_get_end_position().cast()); - m_debug_output << ", " << std::to_string(extruder_id); - m_debug_output << ", " << std::to_string(_get_feedrate()); - m_debug_output << ", " << std::to_string(_get_width()); - m_debug_output << ", " << std::to_string(_get_height()); - m_debug_output << "\n"; + g_debug_output << std::to_string((int)type); + g_debug_output << ", " << std::to_string((int)_get_extrusion_role()); + g_debug_output << ", " << Slic3r::to_string((Vec3d)_get_end_position().cast()); + g_debug_output << ", " << std::to_string(extruder_id); + g_debug_output << ", " << std::to_string(_get_feedrate()); + g_debug_output << ", " << std::to_string(_get_width()); + g_debug_output << ", " << std::to_string(_get_height()); + g_debug_output << "\n"; } #endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT } diff --git a/src/libslic3r/GCode/Analyzer.hpp b/src/libslic3r/GCode/Analyzer.hpp index 5e5a017357..9d16ab4944 100644 --- a/src/libslic3r/GCode/Analyzer.hpp +++ b/src/libslic3r/GCode/Analyzer.hpp @@ -8,10 +8,6 @@ #include "../Point.hpp" #include "../GCodeReader.hpp" -#if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT -#include -#endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT - namespace Slic3r { class GCodePreviewData; @@ -152,9 +148,6 @@ public: static bool is_valid_extrusion_role(ExtrusionRole role); #if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT -private: - boost::nowide::ofstream m_debug_output; -public: void open_debug_output_file(); void close_debug_output_file(); #endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index ffb4e17146..01ac11c172 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -1,6 +1,8 @@ #include "../libslic3r.h" #include "GCodeProcessor.hpp" +#include + #if ENABLE_GCODE_VIEWER static const float INCHES_TO_MM = 25.4f; From 824e4360584550f74b9a953879afa042f67b34fe Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 2 Apr 2020 16:07:54 +0200 Subject: [PATCH 008/255] Hopefully last missing include --- src/slic3r/GUI/GLCanvas3D.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 2236e8fab8..85ea44ef14 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -59,6 +59,10 @@ #include #include +#if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT +#include +#endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT + #include #include #include From dce1f24ad81c481ba0c4e8c2bf3a39820e08aaf3 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 3 Apr 2020 10:15:46 +0200 Subject: [PATCH 009/255] GCodeProcessor additions: process G10 lines process G11 lines process G22 lines process G23 lines process M106 lines process M107 lines process mm3_per_mm comment tag --- src/libslic3r/GCode.cpp | 4 + src/libslic3r/GCode/Analyzer.cpp | 2 + src/libslic3r/GCode/GCodeProcessor.cpp | 162 +++++++++++++++++++------ src/libslic3r/GCode/GCodeProcessor.hpp | 44 +++++-- src/libslic3r/GCode/WipeTower.cpp | 4 + 5 files changed, 171 insertions(+), 45 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 3ea365b3cc..720b9a1fa7 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -3131,6 +3131,10 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, m_last_mm3_per_mm = path.mm3_per_mm; sprintf(buf, ";%s%f\n", GCodeAnalyzer::Mm3_Per_Mm_Tag.c_str(), m_last_mm3_per_mm); gcode += buf; +#if ENABLE_GCODE_VIEWER + sprintf(buf, ";%s%f\n", GCodeProcessor::Mm3_Per_Mm_Tag.c_str(), m_last_mm3_per_mm); + gcode += buf; +#endif // ENABLE_GCODE_VIEWER } if (last_was_wipe_tower || (m_last_width != path.width)) diff --git a/src/libslic3r/GCode/Analyzer.cpp b/src/libslic3r/GCode/Analyzer.cpp index b283d70a9b..c7b67647f1 100644 --- a/src/libslic3r/GCode/Analyzer.cpp +++ b/src/libslic3r/GCode/Analyzer.cpp @@ -956,6 +956,8 @@ void GCodeAnalyzer::_store_move(GCodeAnalyzer::GCodeMove::EType type) g_debug_output << ", " << std::to_string(_get_feedrate()); g_debug_output << ", " << std::to_string(_get_width()); g_debug_output << ", " << std::to_string(_get_height()); + g_debug_output << ", " << std::to_string(_get_mm3_per_mm()); + g_debug_output << ", " << std::to_string(_get_fan_speed()); g_debug_output << "\n"; } #endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 01ac11c172..0f42c6796e 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -18,6 +18,7 @@ namespace Slic3r { const std::string GCodeProcessor::Extrusion_Role_Tag = "_PROCESSOR_EXTRUSION_ROLE:"; const std::string GCodeProcessor::Width_Tag = "_PROCESSOR_WIDTH:"; const std::string GCodeProcessor::Height_Tag = "_PROCESSOR_HEIGHT:"; +const std::string GCodeProcessor::Mm3_Per_Mm_Tag = "_PROCESSOR_MM3_PER_MM:"; void GCodeProcessor::apply_config(const PrintConfig& config) { @@ -48,6 +49,9 @@ void GCodeProcessor::reset() m_feedrate = 0.0f; m_width = 0.0f; m_height = 0.0f; + m_mm3_per_mm = 0.0f; + m_fan_speed = 0.0f; + m_extrusion_role = erNone; m_extruder_id = 0; @@ -79,14 +83,14 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) { switch (::atoi(&cmd[1])) { - // Move - case 1: { process_G1(line); break; } - // Set to Absolute Positioning - case 90: { processG90(line); break; } - // Set to Relative Positioning - case 91: { processG91(line); break; } - // Set Position - case 92: { processG92(line); break; } + case 1: { process_G1(line); break; } // Move + case 10: { process_G10(line); break; } // Retract + case 11: { process_G11(line); break; } // Unretract + case 22: { process_G22(line); break; } // Firmware controlled retract + case 23: { process_G23(line); break; } // Firmware controlled unretract + case 90: { process_G90(line); break; } // Set to Absolute Positioning + case 91: { process_G91(line); break; } // Set to Relative Positioning + case 92: { process_G92(line); break; } // Set Position default: { break; } } break; @@ -95,16 +99,17 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) { switch (::atoi(&cmd[1])) { - // Set extruder to absolute mode - case 82: { processM82(line); break; } - // Set extruder to relative mode - case 83: { processM83(line); break; } + case 82: { process_M82(line); break; } // Set extruder to absolute mode + case 83: { process_M83(line); break; } // Set extruder to relative mode + case 106: { process_M106(line); break; } // Set fan speed + case 107: { process_M107(line); break; } // Disable fan default: { break; } } break; } case 'T': { + process_T(line); // Select Tool break; } default: { break; } @@ -125,12 +130,19 @@ void GCodeProcessor::process_tags(const std::string& comment) size_t pos = comment.find(Extrusion_Role_Tag); if (pos != comment.npos) { - int role = std::stoi(comment.substr(pos + Extrusion_Role_Tag.length())); - if (is_valid_extrusion_role(role)) - m_extrusion_role = static_cast(role); - else + try { - // todo: show some error ? + int role = std::stoi(comment.substr(pos + Extrusion_Role_Tag.length())); + if (is_valid_extrusion_role(role)) + m_extrusion_role = static_cast(role); + else + { + // todo: show some error ? + } + } + catch (...) + { + BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Extrusion Role (" << comment << ")."; } return; @@ -140,7 +152,14 @@ void GCodeProcessor::process_tags(const std::string& comment) pos = comment.find(Width_Tag); if (pos != comment.npos) { - m_width = std::stof(comment.substr(pos + Width_Tag.length())); + try + { + m_width = std::stof(comment.substr(pos + Width_Tag.length())); + } + catch (...) + { + BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ")."; + } return; } @@ -148,7 +167,29 @@ void GCodeProcessor::process_tags(const std::string& comment) pos = comment.find(Height_Tag); if (pos != comment.npos) { - m_height = std::stof(comment.substr(pos + Height_Tag.length())); + try + { + m_height = std::stof(comment.substr(pos + Height_Tag.length())); + } + catch (...) + { + BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ")."; + } + return; + } + + // mm3 per mm tag + pos = comment.find(Mm3_Per_Mm_Tag); + if (pos != comment.npos) + { + try + { + m_mm3_per_mm = std::stof(comment.substr(pos + Mm3_Per_Mm_Tag.length())); + } + catch (...) + { + BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Mm3_Per_Mm (" << comment << ")."; + } return; } } @@ -224,17 +265,41 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) store_move_vertex(move_type(delta_pos)); } -void GCodeProcessor::processG90(const GCodeReader::GCodeLine& line) +void GCodeProcessor::process_G10(const GCodeReader::GCodeLine& line) +{ + // stores retract move + store_move_vertex(EMoveType::Retract); +} + +void GCodeProcessor::process_G11(const GCodeReader::GCodeLine& line) +{ + // stores unretract move + store_move_vertex(EMoveType::Unretract); +} + +void GCodeProcessor::process_G22(const GCodeReader::GCodeLine& line) +{ + // stores retract move + store_move_vertex(EMoveType::Retract); +} + +void GCodeProcessor::process_G23(const GCodeReader::GCodeLine& line) +{ + // stores unretract move + store_move_vertex(EMoveType::Unretract); +} + +void GCodeProcessor::process_G90(const GCodeReader::GCodeLine& line) { m_global_positioning_type = EPositioningType::Absolute; } -void GCodeProcessor::processG91(const GCodeReader::GCodeLine& line) +void GCodeProcessor::process_G91(const GCodeReader::GCodeLine& line) { m_global_positioning_type = EPositioningType::Relative; } -void GCodeProcessor::processG92(const GCodeReader::GCodeLine& line) +void GCodeProcessor::process_G92(const GCodeReader::GCodeLine& line) { float lengthsScaleFactor = (m_units == EUnits::Inches) ? INCHES_TO_MM : 1.0f; bool anyFound = false; @@ -276,36 +341,61 @@ void GCodeProcessor::processG92(const GCodeReader::GCodeLine& line) } } -void GCodeProcessor::processM82(const GCodeReader::GCodeLine& line) +void GCodeProcessor::process_M82(const GCodeReader::GCodeLine& line) { m_e_local_positioning_type = EPositioningType::Absolute; } -void GCodeProcessor::processM83(const GCodeReader::GCodeLine& line) +void GCodeProcessor::process_M83(const GCodeReader::GCodeLine& line) { m_e_local_positioning_type = EPositioningType::Relative; } -void GCodeProcessor::processT(const GCodeReader::GCodeLine& line) +void GCodeProcessor::process_M106(const GCodeReader::GCodeLine& line) +{ + if (!line.has('P')) + { + // The absence of P means the print cooling fan, so ignore anything else. + float new_fan_speed; + if (line.has_value('S', new_fan_speed)) + m_fan_speed = (100.0f / 255.0f) * new_fan_speed; + else + m_fan_speed = 100.0f; + } +} + +void GCodeProcessor::process_M107(const GCodeReader::GCodeLine& line) +{ + m_fan_speed = 0.0f; +} + +void GCodeProcessor::process_T(const GCodeReader::GCodeLine& line) { const std::string& cmd = line.cmd(); if (cmd.length() > 1) { - unsigned int id = (unsigned int)std::stoi(cmd.substr(1)); - if (m_extruder_id != id) + try { - unsigned int extruders_count = (unsigned int)m_extruder_offsets.size(); - if (id >= extruders_count) - BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid toolchange, maybe from a custom gcode."; - else + unsigned int id = (unsigned int)std::stoi(cmd.substr(1)); + if (m_extruder_id != id) { - m_extruder_id = id; + unsigned int extruders_count = (unsigned int)m_extruder_offsets.size(); + if (id >= extruders_count) + BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid toolchange, maybe from a custom gcode."; + else + { + m_extruder_id = id; // if (_get_cp_color_id() != INT_MAX) <<<<<<<<<<<<<<<<<<< TODO // _set_cp_color_id(m_extruder_color[id]); - } + } - // store tool change move - store_move_vertex(EMoveType::Tool_change); + // store tool change move + store_move_vertex(EMoveType::Tool_change); + } + } + catch (...) + { + BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid toolchange (" << cmd << ")."; } } } @@ -319,6 +409,8 @@ void GCodeProcessor::store_move_vertex(EMoveType type) vertex.feedrate = m_feedrate; vertex.width = m_width; vertex.height = m_height; + vertex.mm3_per_mm = m_mm3_per_mm; + vertex.fan_speed = m_fan_speed; vertex.extruder_id = m_extruder_id; m_result.moves.emplace_back(vertex); } diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 0fa8187fd3..66036728dd 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -16,6 +16,7 @@ namespace Slic3r { static const std::string Extrusion_Role_Tag; static const std::string Width_Tag; static const std::string Height_Tag; + static const std::string Mm3_Per_Mm_Tag; private: using AxisCoords = std::array; @@ -52,6 +53,8 @@ namespace Slic3r { float feedrate{ 0.0f }; // mm/s float width{ 0.0f }; // mm float height{ 0.0f }; // mm + float mm3_per_mm{ 0.0f }; + float fan_speed{ 0.0f }; // percentage unsigned int extruder_id{ 0 }; std::string to_string() const @@ -63,6 +66,8 @@ namespace Slic3r { str += ", " + std::to_string(feedrate); str += ", " + std::to_string(width); str += ", " + std::to_string(height); + str += ", " + std::to_string(mm3_per_mm); + str += ", " + std::to_string(fan_speed); return str; } }; @@ -85,9 +90,11 @@ namespace Slic3r { AxisCoords m_end_position; // mm AxisCoords m_origin; // mm - float m_feedrate; // mm/s - float m_width; // mm - float m_height; // mm + float m_feedrate; // mm/s + float m_width; // mm + float m_height; // mm + float m_mm3_per_mm; + float m_fan_speed; // percentage ExtrusionRole m_extrusion_role; unsigned int m_extruder_id; @@ -103,7 +110,6 @@ namespace Slic3r { Result&& extract_result() { return std::move(m_result); } // 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: @@ -115,23 +121,41 @@ namespace Slic3r { // Move void process_G1(const GCodeReader::GCodeLine& line); + // Retract + void process_G10(const GCodeReader::GCodeLine& line); + + // Unretract + void process_G11(const GCodeReader::GCodeLine& line); + + // Firmware controlled Retract + void process_G22(const GCodeReader::GCodeLine& line); + + // Firmware controlled Unretract + void process_G23(const GCodeReader::GCodeLine& line); + // Set to Absolute Positioning - void processG90(const GCodeReader::GCodeLine& line); + void process_G90(const GCodeReader::GCodeLine& line); // Set to Relative Positioning - void processG91(const GCodeReader::GCodeLine& line); + void process_G91(const GCodeReader::GCodeLine& line); // Set Position - void processG92(const GCodeReader::GCodeLine& line); + void process_G92(const GCodeReader::GCodeLine& line); // Set extruder to absolute mode - void processM82(const GCodeReader::GCodeLine& line); + void process_M82(const GCodeReader::GCodeLine& line); // Set extruder to relative mode - void processM83(const GCodeReader::GCodeLine& line); + void process_M83(const GCodeReader::GCodeLine& line); + + // Set fan speed + void process_M106(const GCodeReader::GCodeLine& line); + + // Disable fan + void process_M107(const GCodeReader::GCodeLine& line); // Processes T line (Select Tool) - void processT(const GCodeReader::GCodeLine& line); + void process_T(const GCodeReader::GCodeLine& line); void store_move_vertex(EMoveType type); }; diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index 339012d0b4..d5d060f773 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -90,6 +90,10 @@ public: char buf[64]; sprintf(buf, ";%s%f\n", GCodeAnalyzer::Mm3_Per_Mm_Tag.c_str(), mm3_per_mm); m_gcode += buf; +#if ENABLE_GCODE_VIEWER + sprintf(buf, ";%s%f\n", GCodeProcessor::Mm3_Per_Mm_Tag.c_str(), mm3_per_mm); + m_gcode += buf; +#endif // ENABLE_GCODE_VIEWER return *this; } From 1caac17b0237c36d36b9e5043a36a75422001b6c Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 6 Apr 2020 08:55:48 +0200 Subject: [PATCH 010/255] GCodeProcessor additions: process M108 lines process M132 lines process M135 lines process M401 lines process M402 lines --- src/libslic3r/GCode/Analyzer.cpp | 2 +- src/libslic3r/GCode/GCodeProcessor.cpp | 117 ++++++++++++++++++++++++- src/libslic3r/GCode/GCodeProcessor.hpp | 24 +++++ 3 files changed, 138 insertions(+), 5 deletions(-) diff --git a/src/libslic3r/GCode/Analyzer.cpp b/src/libslic3r/GCode/Analyzer.cpp index c7b67647f1..5db2ff3dea 100644 --- a/src/libslic3r/GCode/Analyzer.cpp +++ b/src/libslic3r/GCode/Analyzer.cpp @@ -951,7 +951,7 @@ void GCodeAnalyzer::_store_move(GCodeAnalyzer::GCodeMove::EType type) { g_debug_output << std::to_string((int)type); g_debug_output << ", " << std::to_string((int)_get_extrusion_role()); - g_debug_output << ", " << Slic3r::to_string((Vec3d)_get_end_position().cast()); + g_debug_output << ", " << Slic3r::to_string((Vec3d)end_position.cast()); g_debug_output << ", " << std::to_string(extruder_id); g_debug_output << ", " << std::to_string(_get_feedrate()); g_debug_output << ", " << std::to_string(_get_width()); diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 0f42c6796e..bbb5f6046e 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -24,6 +24,8 @@ void GCodeProcessor::apply_config(const PrintConfig& config) { m_parser.apply_config(config); + m_flavor = config.gcode_flavor; + size_t extruders_count = config.nozzle_diameter.values.size(); if (m_extruder_offsets.size() != extruders_count) m_extruder_offsets.resize(extruders_count); @@ -41,10 +43,13 @@ void GCodeProcessor::reset() m_global_positioning_type = EPositioningType::Absolute; m_e_local_positioning_type = EPositioningType::Absolute; m_extruder_offsets = std::vector(1, Vec3f::Zero()); + m_flavor = gcfRepRap; std::fill(m_start_position.begin(), m_start_position.end(), 0.0f); std::fill(m_end_position.begin(), m_end_position.end(), 0.0f); std::fill(m_origin.begin(), m_origin.end(), 0.0f); + std::fill(m_cached_position.position.begin(), m_cached_position.position.end(), FLT_MAX); + m_cached_position.feedrate = FLT_MAX; m_feedrate = 0.0f; m_width = 0.0f; @@ -103,6 +108,11 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) case 83: { process_M83(line); break; } // Set extruder to relative mode case 106: { process_M106(line); break; } // Set fan speed case 107: { process_M107(line); break; } // Disable fan + case 108: { process_M108(line); break; } // Set tool (Sailfish) + case 132: { process_M132(line); break; } // Recall stored home offsets + case 135: { process_M135(line); break; } // Set tool (MakerWare) + case 401: { process_M401(line); break; } // Repetier: Store x, y and z position + case 402: { process_M402(line); break; } // Repetier: Go to stored position default: { break; } } break; @@ -369,14 +379,113 @@ void GCodeProcessor::process_M107(const GCodeReader::GCodeLine& line) m_fan_speed = 0.0f; } +void GCodeProcessor::process_M108(const GCodeReader::GCodeLine& line) +{ + // These M-codes are used by Sailfish to change active tool. + // They have to be processed otherwise toolchanges will be unrecognised + // by the analyzer - see https://github.com/prusa3d/PrusaSlicer/issues/2566 + + if (m_flavor != gcfSailfish) + return; + + std::string cmd = line.raw(); + size_t pos = cmd.find("T"); + if (pos != std::string::npos) + process_T(cmd.substr(pos)); +} + +void GCodeProcessor::process_M132(const GCodeReader::GCodeLine& line) +{ + // This command is used by Makerbot to load the current home position from EEPROM + // see: https://github.com/makerbot/s3g/blob/master/doc/GCodeProtocol.md + // Using this command to reset the axis origin to zero helps in fixing: https://github.com/prusa3d/PrusaSlicer/issues/3082 + + if (line.has_x()) + m_origin[X] = 0.0f; + + if (line.has_y()) + m_origin[Y] = 0.0f; + + if (line.has_z()) + m_origin[Z] = 0.0f; + + if (line.has_e()) + m_origin[E] = 0.0f; +} + +void GCodeProcessor::process_M135(const GCodeReader::GCodeLine& line) +{ + // These M-codes are used by MakerWare to change active tool. + // They have to be processed otherwise toolchanges will be unrecognised + // by the analyzer - see https://github.com/prusa3d/PrusaSlicer/issues/2566 + + if (m_flavor != gcfMakerWare) + return; + + std::string cmd = line.raw(); + size_t pos = cmd.find("T"); + if (pos != std::string::npos) + process_T(cmd.substr(pos)); +} + +void GCodeProcessor::process_M401(const GCodeReader::GCodeLine& line) +{ + if (m_flavor != gcfRepetier) + return; + + for (unsigned char a = 0; a <= 3; ++a) + { + m_cached_position.position[a] = m_start_position[a]; + } + m_cached_position.feedrate = m_feedrate; +} + +void GCodeProcessor::process_M402(const GCodeReader::GCodeLine& line) +{ + if (m_flavor != gcfRepetier) + return; + + // see for reference: + // https://github.com/repetier/Repetier-Firmware/blob/master/src/ArduinoAVR/Repetier/Printer.cpp + // void Printer::GoToMemoryPosition(bool x, bool y, bool z, bool e, float feed) + + bool has_xyz = !(line.has_x() || line.has_y() || line.has_z()); + + float p = FLT_MAX; + for (unsigned char a = X; a <= Z; ++a) + { + if (has_xyz || line.has(a)) + { + p = m_cached_position.position[a]; + if (p != FLT_MAX) + m_start_position[a] = p; + } + } + + p = m_cached_position.position[E]; + if (p != FLT_MAX) + m_start_position[E] = p; + + p = FLT_MAX; + if (!line.has_value(4, p)) + p = m_cached_position.feedrate; + + if (p != FLT_MAX) + m_feedrate = p; +} + void GCodeProcessor::process_T(const GCodeReader::GCodeLine& line) { - const std::string& cmd = line.cmd(); - if (cmd.length() > 1) + process_T(line.cmd()); +} + +void GCodeProcessor::process_T(const std::string& command) +{ + if (command.length() > 1) { try { - unsigned int id = (unsigned int)std::stoi(cmd.substr(1)); + unsigned int id = (unsigned int)std::stoi(command.substr(1)); if (m_extruder_id != id) { unsigned int extruders_count = (unsigned int)m_extruder_offsets.size(); @@ -395,7 +504,7 @@ void GCodeProcessor::process_T(const GCodeReader::GCodeLine& line) } catch (...) { - BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid toolchange (" << cmd << ")."; + BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid toolchange (" << command << ")."; } } } diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 66036728dd..a3cfbdc787 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -44,6 +44,12 @@ namespace Slic3r { Num_Types }; + struct CachedPosition + { + AxisCoords position; // mm + float feedrate; // mm/s + }; + public: struct MoveVertex { @@ -85,10 +91,12 @@ namespace Slic3r { EPositioningType m_global_positioning_type; EPositioningType m_e_local_positioning_type; std::vector m_extruder_offsets; + GCodeFlavor m_flavor; AxisCoords m_start_position; // mm AxisCoords m_end_position; // mm AxisCoords m_origin; // mm + CachedPosition m_cached_position; float m_feedrate; // mm/s float m_width; // mm @@ -154,8 +162,24 @@ namespace Slic3r { // Disable fan void process_M107(const GCodeReader::GCodeLine& line); + // Set tool (Sailfish) + void process_M108(const GCodeReader::GCodeLine& line); + + // Recall stored home offsets + void process_M132(const GCodeReader::GCodeLine& line); + + // Set tool (MakerWare) + void process_M135(const GCodeReader::GCodeLine& line); + + // Repetier: Store x, y and z position + void process_M401(const GCodeReader::GCodeLine& line); + + // Repetier: Go to stored position + void process_M402(const GCodeReader::GCodeLine& line); + // Processes T line (Select Tool) void process_T(const GCodeReader::GCodeLine& line); + void process_T(const std::string& command); void store_move_vertex(EMoveType type); }; From 57dad5dfd2b3d01320ed36d14bdf6a2d93bc5c75 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 6 Apr 2020 11:53:15 +0200 Subject: [PATCH 011/255] GCodeProcessor additions: process color change comment tag process pause print comment tag process custom code comment tag process end pause print or custom code comment tag --- src/libslic3r/GCode.cpp | 26 +++++++- src/libslic3r/GCode/Analyzer.cpp | 13 ++-- src/libslic3r/GCode/GCodeProcessor.cpp | 88 +++++++++++++++++++++++--- src/libslic3r/GCode/GCodeProcessor.hpp | 20 ++++++ 4 files changed, 130 insertions(+), 17 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 720b9a1fa7..ee7be7fea7 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1823,7 +1823,11 @@ namespace ProcessLayer // Color Change or Tool Change as Color Change. // add tag for analyzer gcode += "; " + GCodeAnalyzer::Color_Change_Tag + ",T" + std::to_string(m600_extruder_before_layer) + "\n"; - // add tag for time estimator +#if ENABLE_GCODE_VIEWER + // add tag for processor + gcode += "; " + GCodeProcessor::Color_Change_Tag + ",T" + std::to_string(m600_extruder_before_layer) + "\n"; +#endif // ENABLE_GCODE_VIEWER + // add tag for time estimator gcode += "; " + GCodeTimeEstimator::Color_Change_Tag + "\n"; if (!single_extruder_printer && m600_extruder_before_layer >= 0 && first_extruder_id != (unsigned)m600_extruder_before_layer @@ -1844,7 +1848,11 @@ namespace ProcessLayer { // add tag for analyzer gcode += "; " + GCodeAnalyzer::Pause_Print_Tag + "\n"; - //! FIXME_in_fw show message during print pause +#if ENABLE_GCODE_VIEWER + // add tag for processor + gcode += "; " + GCodeProcessor::Pause_Print_Tag + "\n"; +#endif // ENABLE_GCODE_VIEWER + //! FIXME_in_fw show message during print pause if (!pause_print_msg.empty()) gcode += "M117 " + pause_print_msg + "\n"; // add tag for time estimator @@ -1854,7 +1862,11 @@ namespace ProcessLayer { // add tag for analyzer gcode += "; " + GCodeAnalyzer::Custom_Code_Tag + "\n"; - // add tag for time estimator +#if ENABLE_GCODE_VIEWER + // add tag for processor + gcode += "; " + GCodeProcessor::Custom_Code_Tag + "\n"; +#endif // ENABLE_GCODE_VIEWER + // add tag for time estimator //gcode += "; " + GCodeTimeEstimator::Custom_Code_Tag + "\n"; } gcode += custom_code + "\n"; @@ -2316,6 +2328,14 @@ void GCode::process_layer( else if (gcode.find(GCodeAnalyzer::Custom_Code_Tag) != gcode.npos) gcode += "\n; " + GCodeAnalyzer::End_Pause_Print_Or_Custom_Code_Tag + "\n"; +#if ENABLE_GCODE_VIEWER + // add tag for processor + if (gcode.find(GCodeProcessor::Pause_Print_Tag) != gcode.npos) + gcode += "\n; " + GCodeProcessor::End_Pause_Print_Or_Custom_Code_Tag + "\n"; + else if (gcode.find(GCodeProcessor::Custom_Code_Tag) != gcode.npos) + gcode += "\n; " + GCodeProcessor::End_Pause_Print_Or_Custom_Code_Tag + "\n"; +#endif // ENABLE_GCODE_VIEWER + #ifdef HAS_PRESSURE_EQUALIZER // Apply pressure equalization if enabled; // printf("G-code before filter:\n%s\n", gcode.c_str()); diff --git a/src/libslic3r/GCode/Analyzer.cpp b/src/libslic3r/GCode/Analyzer.cpp index 5db2ff3dea..974176dbd7 100644 --- a/src/libslic3r/GCode/Analyzer.cpp +++ b/src/libslic3r/GCode/Analyzer.cpp @@ -674,7 +674,7 @@ bool GCodeAnalyzer::_process_tags(const GCodeReader::GCodeLine& line) return true; } - // color change tag + // pause print tag pos = comment.find(Pause_Print_Tag); if (pos != comment.npos) { @@ -682,7 +682,7 @@ bool GCodeAnalyzer::_process_tags(const GCodeReader::GCodeLine& line) return true; } - // color change tag + // custom code tag pos = comment.find(Custom_Code_Tag); if (pos != comment.npos) { @@ -690,7 +690,7 @@ bool GCodeAnalyzer::_process_tags(const GCodeReader::GCodeLine& line) return true; } - // color change tag + // end pause print or custom code tag pos = comment.find(End_Pause_Print_Or_Custom_Code_Tag); if (pos != comment.npos) { @@ -949,10 +949,11 @@ void GCodeAnalyzer::_store_move(GCodeAnalyzer::GCodeMove::EType type) #if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT if (g_debug_output.good()) { - g_debug_output << std::to_string((int)type); - g_debug_output << ", " << std::to_string((int)_get_extrusion_role()); - g_debug_output << ", " << Slic3r::to_string((Vec3d)end_position.cast()); + g_debug_output << std::to_string(static_cast(type)); + g_debug_output << ", " << std::to_string(static_cast(_get_extrusion_role())); + g_debug_output << ", " << Slic3r::to_string(static_cast(end_position.cast())); g_debug_output << ", " << std::to_string(extruder_id); + g_debug_output << ", " << std::to_string(_get_cp_color_id()); g_debug_output << ", " << std::to_string(_get_feedrate()); g_debug_output << ", " << std::to_string(_get_width()); g_debug_output << ", " << std::to_string(_get_height()); diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index bbb5f6046e..0a61879d80 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -19,6 +19,22 @@ const std::string GCodeProcessor::Extrusion_Role_Tag = "_PROCESSOR_EXTRUSION_ROL const std::string GCodeProcessor::Width_Tag = "_PROCESSOR_WIDTH:"; const std::string GCodeProcessor::Height_Tag = "_PROCESSOR_HEIGHT:"; const std::string GCodeProcessor::Mm3_Per_Mm_Tag = "_PROCESSOR_MM3_PER_MM:"; +const std::string GCodeProcessor::Color_Change_Tag = "_PROCESSOR_COLOR_CHANGE"; +const std::string GCodeProcessor::Pause_Print_Tag = "_PROCESSOR_PAUSE_PRINT"; +const std::string GCodeProcessor::Custom_Code_Tag = "_PROCESSOR_CUSTOM_CODE"; +const std::string GCodeProcessor::End_Pause_Print_Or_Custom_Code_Tag = "_PROCESSOR_END_PAUSE_PRINT_OR_CUSTOM_CODE"; + +void GCodeProcessor::CachedPosition::reset() +{ + std::fill(position.begin(), position.end(), FLT_MAX); + feedrate = FLT_MAX; +} + +void GCodeProcessor::CpColor::reset() +{ + counter = 0; + current = 0; +} void GCodeProcessor::apply_config(const PrintConfig& config) { @@ -27,14 +43,19 @@ void GCodeProcessor::apply_config(const PrintConfig& config) m_flavor = config.gcode_flavor; size_t extruders_count = config.nozzle_diameter.values.size(); - if (m_extruder_offsets.size() != extruders_count) - m_extruder_offsets.resize(extruders_count); + m_extruder_offsets.resize(extruders_count); for (size_t id = 0; id < extruders_count; ++id) { Vec2f offset = config.extruder_offset.get_at(id).cast(); m_extruder_offsets[id] = Vec3f(offset(0), offset(1), 0.0f); } + + m_extruders_color.resize(extruders_count); + for (size_t id = 0; id < extruders_count; ++id) + { + m_extruders_color[id] = static_cast(id); + } } void GCodeProcessor::reset() @@ -48,8 +69,7 @@ void GCodeProcessor::reset() std::fill(m_start_position.begin(), m_start_position.end(), 0.0f); std::fill(m_end_position.begin(), m_end_position.end(), 0.0f); std::fill(m_origin.begin(), m_origin.end(), 0.0f); - std::fill(m_cached_position.position.begin(), m_cached_position.position.end(), FLT_MAX); - m_cached_position.feedrate = FLT_MAX; + m_cached_position.reset(); m_feedrate = 0.0f; m_width = 0.0f; @@ -59,6 +79,8 @@ void GCodeProcessor::reset() m_extrusion_role = erNone; m_extruder_id = 0; + m_extruders_color = ExtrudersColor(); + m_cp_color.reset(); m_result.reset(); } @@ -202,6 +224,55 @@ void GCodeProcessor::process_tags(const std::string& comment) } return; } + + // color change tag + pos = comment.find(Color_Change_Tag); + if (pos != comment.npos) + { + pos = comment.find_last_of(",T"); + try + { + unsigned int extruder_id = (pos == comment.npos) ? 0 : static_cast(std::stoi(comment.substr(pos + 1, comment.npos))); + + m_extruders_color[extruder_id] = static_cast(m_extruder_offsets.size()) + m_cp_color.counter; // color_change position in list of color for preview + ++m_cp_color.counter; + + if (m_extruder_id == extruder_id) + m_cp_color.current = m_extruders_color[extruder_id]; + } + catch (...) + { + BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Color_Change (" << comment << ")."; + } + + return; + } + + // pause print tag + pos = comment.find(Pause_Print_Tag); + if (pos != comment.npos) + { + m_cp_color.current = INT_MAX; + return; + } + + // custom code tag + pos = comment.find(Custom_Code_Tag); + if (pos != comment.npos) + { + m_cp_color.current = INT_MAX; + return; + } + + // end pause print or custom code tag + pos = comment.find(End_Pause_Print_Or_Custom_Code_Tag); + if (pos != comment.npos) + { + if (m_cp_color.current == INT_MAX) + m_cp_color.current = m_extruders_color[m_extruder_id]; + + return; + } } void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) @@ -485,17 +556,17 @@ void GCodeProcessor::process_T(const std::string& command) { try { - unsigned int id = (unsigned int)std::stoi(command.substr(1)); + unsigned int id = static_cast(std::stoi(command.substr(1))); if (m_extruder_id != id) { - unsigned int extruders_count = (unsigned int)m_extruder_offsets.size(); + unsigned int extruders_count = static_cast(m_extruder_offsets.size()); if (id >= extruders_count) BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid toolchange, maybe from a custom gcode."; else { m_extruder_id = id; -// if (_get_cp_color_id() != INT_MAX) <<<<<<<<<<<<<<<<<<< TODO -// _set_cp_color_id(m_extruder_color[id]); + if (m_cp_color.current != INT_MAX) + m_cp_color.current = m_extruders_color[id]; } // store tool change move @@ -521,6 +592,7 @@ void GCodeProcessor::store_move_vertex(EMoveType type) vertex.mm3_per_mm = m_mm3_per_mm; vertex.fan_speed = m_fan_speed; vertex.extruder_id = m_extruder_id; + vertex.cp_color_id = m_cp_color.current; m_result.moves.emplace_back(vertex); } diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index a3cfbdc787..ce1f695dca 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -7,6 +7,7 @@ #include "../ExtrusionEntity.hpp" #include +#include namespace Slic3r { @@ -17,9 +18,14 @@ namespace Slic3r { static const std::string Width_Tag; static const std::string Height_Tag; static const std::string Mm3_Per_Mm_Tag; + static const std::string Color_Change_Tag; + static const std::string Pause_Print_Tag; + static const std::string Custom_Code_Tag; + static const std::string End_Pause_Print_Or_Custom_Code_Tag; private: using AxisCoords = std::array; + using ExtrudersColor = std::vector; enum class EUnits : unsigned char { @@ -48,6 +54,16 @@ namespace Slic3r { { AxisCoords position; // mm float feedrate; // mm/s + + void reset(); + }; + + struct CpColor + { + unsigned int counter; + unsigned int current; + + void reset(); }; public: @@ -62,6 +78,7 @@ namespace Slic3r { float mm3_per_mm{ 0.0f }; float fan_speed{ 0.0f }; // percentage unsigned int extruder_id{ 0 }; + unsigned int cp_color_id{ 0 }; std::string to_string() const { @@ -69,6 +86,7 @@ namespace Slic3r { str += ", " + std::to_string((int)extrusion_role); str += ", " + Slic3r::to_string((Vec3d)position.cast()); str += ", " + std::to_string(extruder_id); + str += ", " + std::to_string(cp_color_id); str += ", " + std::to_string(feedrate); str += ", " + std::to_string(width); str += ", " + std::to_string(height); @@ -105,6 +123,8 @@ namespace Slic3r { float m_fan_speed; // percentage ExtrusionRole m_extrusion_role; unsigned int m_extruder_id; + ExtrudersColor m_extruders_color; + CpColor m_cp_color; Result m_result; From 2c69d962398c3ceb17ef620270f8c09d504c4202 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 6 Apr 2020 17:24:11 +0200 Subject: [PATCH 012/255] Reduced size of GCodeProcessor::MoveVertex --- src/libslic3r/GCode/GCodeProcessor.cpp | 16 ++++++++-------- src/libslic3r/GCode/GCodeProcessor.hpp | 12 ++++++------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 0a61879d80..7fb06bbda0 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -232,9 +232,9 @@ void GCodeProcessor::process_tags(const std::string& comment) pos = comment.find_last_of(",T"); try { - unsigned int extruder_id = (pos == comment.npos) ? 0 : static_cast(std::stoi(comment.substr(pos + 1, comment.npos))); + unsigned char extruder_id = (pos == comment.npos) ? 0 : static_cast(std::stoi(comment.substr(pos + 1, comment.npos))); - m_extruders_color[extruder_id] = static_cast(m_extruder_offsets.size()) + m_cp_color.counter; // color_change position in list of color for preview + m_extruders_color[extruder_id] = static_cast(m_extruder_offsets.size()) + m_cp_color.counter; // color_change position in list of color for preview ++m_cp_color.counter; if (m_extruder_id == extruder_id) @@ -252,7 +252,7 @@ void GCodeProcessor::process_tags(const std::string& comment) pos = comment.find(Pause_Print_Tag); if (pos != comment.npos) { - m_cp_color.current = INT_MAX; + m_cp_color.current = 255; return; } @@ -260,7 +260,7 @@ void GCodeProcessor::process_tags(const std::string& comment) pos = comment.find(Custom_Code_Tag); if (pos != comment.npos) { - m_cp_color.current = INT_MAX; + m_cp_color.current = 255; return; } @@ -268,7 +268,7 @@ void GCodeProcessor::process_tags(const std::string& comment) pos = comment.find(End_Pause_Print_Or_Custom_Code_Tag); if (pos != comment.npos) { - if (m_cp_color.current == INT_MAX) + if (m_cp_color.current == 255) m_cp_color.current = m_extruders_color[m_extruder_id]; return; @@ -556,16 +556,16 @@ void GCodeProcessor::process_T(const std::string& command) { try { - unsigned int id = static_cast(std::stoi(command.substr(1))); + unsigned char id = static_cast(std::stoi(command.substr(1))); if (m_extruder_id != id) { - unsigned int extruders_count = static_cast(m_extruder_offsets.size()); + unsigned char extruders_count = static_cast(m_extruder_offsets.size()); if (id >= extruders_count) BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid toolchange, maybe from a custom gcode."; else { m_extruder_id = id; - if (m_cp_color.current != INT_MAX) + if (m_cp_color.current != 255) m_cp_color.current = m_extruders_color[id]; } diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index ce1f695dca..54ac546b38 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -25,7 +25,7 @@ namespace Slic3r { private: using AxisCoords = std::array; - using ExtrudersColor = std::vector; + using ExtrudersColor = std::vector; enum class EUnits : unsigned char { @@ -60,8 +60,8 @@ namespace Slic3r { struct CpColor { - unsigned int counter; - unsigned int current; + unsigned char counter; + unsigned char current; void reset(); }; @@ -71,14 +71,14 @@ namespace Slic3r { { EMoveType type{ EMoveType::Noop }; ExtrusionRole extrusion_role{ erNone }; + unsigned char extruder_id{ 0 }; + unsigned char cp_color_id{ 0 }; Vec3f position{ Vec3f::Zero() }; // mm float feedrate{ 0.0f }; // mm/s float width{ 0.0f }; // mm float height{ 0.0f }; // mm float mm3_per_mm{ 0.0f }; float fan_speed{ 0.0f }; // percentage - unsigned int extruder_id{ 0 }; - unsigned int cp_color_id{ 0 }; std::string to_string() const { @@ -122,7 +122,7 @@ namespace Slic3r { float m_mm3_per_mm; float m_fan_speed; // percentage ExtrusionRole m_extrusion_role; - unsigned int m_extruder_id; + unsigned char m_extruder_id; ExtrudersColor m_extruders_color; CpColor m_cp_color; From 22cf0396fcd8b51ef8f0cc0155305538379efb9f Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 6 Apr 2020 17:32:35 +0200 Subject: [PATCH 013/255] Added missing include --- src/libslic3r/GCode/GCodeProcessor.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 7fb06bbda0..f5094553a5 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -3,6 +3,8 @@ #include +#include + #if ENABLE_GCODE_VIEWER static const float INCHES_TO_MM = 25.4f; From c3eb65c4612c6011cda2bdb9a683d3e12af3295a Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 14 Apr 2020 10:02:08 +0200 Subject: [PATCH 014/255] Added class GCodeViewer -> basic render of gcode toolpaths using dedicated shaders --- resources/shaders/extrusions.fs | 45 +++++ resources/shaders/extrusions.vs | 15 ++ resources/shaders/retractions.fs | 45 +++++ resources/shaders/retractions.vs | 15 ++ resources/shaders/toolchanges.fs | 45 +++++ resources/shaders/toolchanges.vs | 15 ++ resources/shaders/travels.fs | 45 +++++ resources/shaders/travels.vs | 15 ++ resources/shaders/unretractions.fs | 45 +++++ resources/shaders/unretractions.vs | 15 ++ src/libslic3r/GCode/GCodeProcessor.cpp | 2 + src/libslic3r/GCode/GCodeProcessor.hpp | 25 +-- src/slic3r/CMakeLists.txt | 2 + src/slic3r/GUI/GCodeViewer.cpp | 242 +++++++++++++++++++++++++ src/slic3r/GUI/GCodeViewer.hpp | 63 +++++++ src/slic3r/GUI/GLCanvas3D.cpp | 20 ++ src/slic3r/GUI/GLCanvas3D.hpp | 8 + src/slic3r/GUI/GUI_Preview.cpp | 3 +- 18 files changed, 652 insertions(+), 13 deletions(-) create mode 100644 resources/shaders/extrusions.fs create mode 100644 resources/shaders/extrusions.vs create mode 100644 resources/shaders/retractions.fs create mode 100644 resources/shaders/retractions.vs create mode 100644 resources/shaders/toolchanges.fs create mode 100644 resources/shaders/toolchanges.vs create mode 100644 resources/shaders/travels.fs create mode 100644 resources/shaders/travels.vs create mode 100644 resources/shaders/unretractions.fs create mode 100644 resources/shaders/unretractions.vs create mode 100644 src/slic3r/GUI/GCodeViewer.cpp create mode 100644 src/slic3r/GUI/GCodeViewer.hpp diff --git a/resources/shaders/extrusions.fs b/resources/shaders/extrusions.fs new file mode 100644 index 0000000000..046dade8a9 --- /dev/null +++ b/resources/shaders/extrusions.fs @@ -0,0 +1,45 @@ +#version 110 + +#define INTENSITY_AMBIENT 0.3 +#define INTENSITY_CORRECTION 0.6 + +// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) +const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); +#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SHININESS 20.0 + +// normalized values for (1./1.43, 0.2/1.43, 1./1.43) +const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0); +#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) + +uniform vec4 uniform_color; + +varying vec3 eye_position; +varying vec3 eye_normal; +//varying float world_normal_z; + +// x = tainted, y = specular; +vec2 intensity; + +void main() +{ + vec3 normal = normalize(eye_normal); + + // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. + // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. + float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0); + + intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); + + // Perform the same lighting calculation for the 2nd light source (no specular applied). + NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + +// // darkens fragments whose normal points downward +// if (world_normal_z < 0.0) +// intensity.x *= (1.0 + world_normal_z * (1.0 - INTENSITY_AMBIENT)); + + gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color.rgb * intensity.x, uniform_color.a); +} diff --git a/resources/shaders/extrusions.vs b/resources/shaders/extrusions.vs new file mode 100644 index 0000000000..d97adbabe0 --- /dev/null +++ b/resources/shaders/extrusions.vs @@ -0,0 +1,15 @@ +#version 110 + +varying vec3 eye_position; +varying vec3 eye_normal; +//// world z component of the normal used to darken the lower side of the toolpaths +//varying float world_normal_z; + +void main() +{ + eye_position = (gl_ModelViewMatrix * gl_Vertex).xyz; + eye_normal = gl_NormalMatrix * vec3(0.0, 0.0, 1.0); +// eye_normal = gl_NormalMatrix * gl_Normal; +// world_normal_z = gl_Normal.z; + gl_Position = ftransform(); +} diff --git a/resources/shaders/retractions.fs b/resources/shaders/retractions.fs new file mode 100644 index 0000000000..046dade8a9 --- /dev/null +++ b/resources/shaders/retractions.fs @@ -0,0 +1,45 @@ +#version 110 + +#define INTENSITY_AMBIENT 0.3 +#define INTENSITY_CORRECTION 0.6 + +// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) +const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); +#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SHININESS 20.0 + +// normalized values for (1./1.43, 0.2/1.43, 1./1.43) +const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0); +#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) + +uniform vec4 uniform_color; + +varying vec3 eye_position; +varying vec3 eye_normal; +//varying float world_normal_z; + +// x = tainted, y = specular; +vec2 intensity; + +void main() +{ + vec3 normal = normalize(eye_normal); + + // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. + // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. + float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0); + + intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); + + // Perform the same lighting calculation for the 2nd light source (no specular applied). + NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + +// // darkens fragments whose normal points downward +// if (world_normal_z < 0.0) +// intensity.x *= (1.0 + world_normal_z * (1.0 - INTENSITY_AMBIENT)); + + gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color.rgb * intensity.x, uniform_color.a); +} diff --git a/resources/shaders/retractions.vs b/resources/shaders/retractions.vs new file mode 100644 index 0000000000..d97adbabe0 --- /dev/null +++ b/resources/shaders/retractions.vs @@ -0,0 +1,15 @@ +#version 110 + +varying vec3 eye_position; +varying vec3 eye_normal; +//// world z component of the normal used to darken the lower side of the toolpaths +//varying float world_normal_z; + +void main() +{ + eye_position = (gl_ModelViewMatrix * gl_Vertex).xyz; + eye_normal = gl_NormalMatrix * vec3(0.0, 0.0, 1.0); +// eye_normal = gl_NormalMatrix * gl_Normal; +// world_normal_z = gl_Normal.z; + gl_Position = ftransform(); +} diff --git a/resources/shaders/toolchanges.fs b/resources/shaders/toolchanges.fs new file mode 100644 index 0000000000..046dade8a9 --- /dev/null +++ b/resources/shaders/toolchanges.fs @@ -0,0 +1,45 @@ +#version 110 + +#define INTENSITY_AMBIENT 0.3 +#define INTENSITY_CORRECTION 0.6 + +// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) +const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); +#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SHININESS 20.0 + +// normalized values for (1./1.43, 0.2/1.43, 1./1.43) +const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0); +#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) + +uniform vec4 uniform_color; + +varying vec3 eye_position; +varying vec3 eye_normal; +//varying float world_normal_z; + +// x = tainted, y = specular; +vec2 intensity; + +void main() +{ + vec3 normal = normalize(eye_normal); + + // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. + // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. + float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0); + + intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); + + // Perform the same lighting calculation for the 2nd light source (no specular applied). + NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + +// // darkens fragments whose normal points downward +// if (world_normal_z < 0.0) +// intensity.x *= (1.0 + world_normal_z * (1.0 - INTENSITY_AMBIENT)); + + gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color.rgb * intensity.x, uniform_color.a); +} diff --git a/resources/shaders/toolchanges.vs b/resources/shaders/toolchanges.vs new file mode 100644 index 0000000000..d97adbabe0 --- /dev/null +++ b/resources/shaders/toolchanges.vs @@ -0,0 +1,15 @@ +#version 110 + +varying vec3 eye_position; +varying vec3 eye_normal; +//// world z component of the normal used to darken the lower side of the toolpaths +//varying float world_normal_z; + +void main() +{ + eye_position = (gl_ModelViewMatrix * gl_Vertex).xyz; + eye_normal = gl_NormalMatrix * vec3(0.0, 0.0, 1.0); +// eye_normal = gl_NormalMatrix * gl_Normal; +// world_normal_z = gl_Normal.z; + gl_Position = ftransform(); +} diff --git a/resources/shaders/travels.fs b/resources/shaders/travels.fs new file mode 100644 index 0000000000..046dade8a9 --- /dev/null +++ b/resources/shaders/travels.fs @@ -0,0 +1,45 @@ +#version 110 + +#define INTENSITY_AMBIENT 0.3 +#define INTENSITY_CORRECTION 0.6 + +// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) +const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); +#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SHININESS 20.0 + +// normalized values for (1./1.43, 0.2/1.43, 1./1.43) +const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0); +#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) + +uniform vec4 uniform_color; + +varying vec3 eye_position; +varying vec3 eye_normal; +//varying float world_normal_z; + +// x = tainted, y = specular; +vec2 intensity; + +void main() +{ + vec3 normal = normalize(eye_normal); + + // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. + // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. + float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0); + + intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); + + // Perform the same lighting calculation for the 2nd light source (no specular applied). + NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + +// // darkens fragments whose normal points downward +// if (world_normal_z < 0.0) +// intensity.x *= (1.0 + world_normal_z * (1.0 - INTENSITY_AMBIENT)); + + gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color.rgb * intensity.x, uniform_color.a); +} diff --git a/resources/shaders/travels.vs b/resources/shaders/travels.vs new file mode 100644 index 0000000000..d97adbabe0 --- /dev/null +++ b/resources/shaders/travels.vs @@ -0,0 +1,15 @@ +#version 110 + +varying vec3 eye_position; +varying vec3 eye_normal; +//// world z component of the normal used to darken the lower side of the toolpaths +//varying float world_normal_z; + +void main() +{ + eye_position = (gl_ModelViewMatrix * gl_Vertex).xyz; + eye_normal = gl_NormalMatrix * vec3(0.0, 0.0, 1.0); +// eye_normal = gl_NormalMatrix * gl_Normal; +// world_normal_z = gl_Normal.z; + gl_Position = ftransform(); +} diff --git a/resources/shaders/unretractions.fs b/resources/shaders/unretractions.fs new file mode 100644 index 0000000000..046dade8a9 --- /dev/null +++ b/resources/shaders/unretractions.fs @@ -0,0 +1,45 @@ +#version 110 + +#define INTENSITY_AMBIENT 0.3 +#define INTENSITY_CORRECTION 0.6 + +// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) +const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); +#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SHININESS 20.0 + +// normalized values for (1./1.43, 0.2/1.43, 1./1.43) +const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0); +#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) + +uniform vec4 uniform_color; + +varying vec3 eye_position; +varying vec3 eye_normal; +//varying float world_normal_z; + +// x = tainted, y = specular; +vec2 intensity; + +void main() +{ + vec3 normal = normalize(eye_normal); + + // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. + // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. + float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0); + + intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); + + // Perform the same lighting calculation for the 2nd light source (no specular applied). + NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + +// // darkens fragments whose normal points downward +// if (world_normal_z < 0.0) +// intensity.x *= (1.0 + world_normal_z * (1.0 - INTENSITY_AMBIENT)); + + gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color.rgb * intensity.x, uniform_color.a); +} diff --git a/resources/shaders/unretractions.vs b/resources/shaders/unretractions.vs new file mode 100644 index 0000000000..d97adbabe0 --- /dev/null +++ b/resources/shaders/unretractions.vs @@ -0,0 +1,15 @@ +#version 110 + +varying vec3 eye_position; +varying vec3 eye_normal; +//// world z component of the normal used to darken the lower side of the toolpaths +//varying float world_normal_z; + +void main() +{ + eye_position = (gl_ModelViewMatrix * gl_Vertex).xyz; + eye_normal = gl_NormalMatrix * vec3(0.0, 0.0, 1.0); +// eye_normal = gl_NormalMatrix * gl_Normal; +// world_normal_z = gl_Normal.z; + gl_Position = ftransform(); +} diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index f5094553a5..c75c240020 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -38,6 +38,8 @@ void GCodeProcessor::CpColor::reset() current = 0; } +unsigned int GCodeProcessor::Result::id = 0; + void GCodeProcessor::apply_config(const PrintConfig& config) { m_parser.apply_config(config); diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 54ac546b38..1f7af9c29d 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -39,17 +39,6 @@ namespace Slic3r { Relative }; - enum class EMoveType : unsigned char - { - Noop, - Retract, - Unretract, - Tool_change, - Travel, - Extrude, - Num_Types - }; - struct CachedPosition { AxisCoords position; // mm @@ -67,6 +56,17 @@ namespace Slic3r { }; public: + enum class EMoveType : unsigned char + { + Noop, + Retract, + Unretract, + Tool_change, + Travel, + Extrude, + Count + }; + struct MoveVertex { EMoveType type{ EMoveType::Noop }; @@ -98,8 +98,9 @@ namespace Slic3r { struct Result { + static unsigned int id; std::vector moves; - void reset() { moves = std::vector(); } + void reset() { ++id; moves = std::vector(); } }; private: diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index c8f7e9f1c9..f5f5f6eb62 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -56,6 +56,8 @@ set(SLIC3R_GUI_SOURCES GUI/GLTexture.cpp GUI/GLToolbar.hpp GUI/GLToolbar.cpp + GUI/GCodeViewer.hpp + GUI/GCodeViewer.cpp GUI/Preferences.cpp GUI/Preferences.hpp GUI/Preset.cpp diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp new file mode 100644 index 0000000000..584ef06c32 --- /dev/null +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -0,0 +1,242 @@ +#include "libslic3r/libslic3r.h" +#include "GCodeViewer.hpp" +#include "3DScene.hpp" + +#if ENABLE_GCODE_VIEWER + +#include +#include + +#include + +namespace Slic3r { +namespace GUI { + +static unsigned char buffer_id(GCodeProcessor::EMoveType type) { + return static_cast(type) - static_cast(GCodeProcessor::EMoveType::Retract); +} + +static GCodeProcessor::EMoveType buffer_type(unsigned char id) { + return static_cast(static_cast(GCodeProcessor::EMoveType::Retract) + id); +} + +void GCodeViewer::generate(const GCodeProcessor::Result& gcode_result) +{ + if (m_last_result_id == gcode_result.id) + return; + + m_last_result_id = gcode_result.id; + + // release gpu memory, if used + reset_buffers(); + + // convert data + size_t vertices_count = gcode_result.moves.size(); + for (size_t i = 0; i < vertices_count; ++i) + { + // skip first vertex + if (i == 0) + continue; + + const GCodeProcessor::MoveVertex& prev = gcode_result.moves[i - 1]; + const GCodeProcessor::MoveVertex& curr = gcode_result.moves[i]; + + Buffer& buffer = m_buffers[buffer_id(curr.type)]; + + switch (curr.type) + { + case GCodeProcessor::EMoveType::Tool_change: + case GCodeProcessor::EMoveType::Retract: + case GCodeProcessor::EMoveType::Unretract: + { + for (int j = 0; j < 3; ++j) + { + buffer.data.insert(buffer.data.end(), curr.position[j]); + } + break; + } + case GCodeProcessor::EMoveType::Extrude: + case GCodeProcessor::EMoveType::Travel: + { + for (int j = 0; j < 3; ++j) + { + buffer.data.insert(buffer.data.end(), prev.position[j]); + } + for (int j = 0; j < 3; ++j) + { + buffer.data.insert(buffer.data.end(), curr.position[j]); + } + break; + } + default: + { + continue; + } + } + } + + // send data to gpu + for (Buffer& buffer : m_buffers) + { + glsafe(::glGenBuffers(1, &buffer.vbo_id)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.vbo_id)); + glsafe(::glBufferData(GL_ARRAY_BUFFER, buffer.data.size() * sizeof(float), buffer.data.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + } +} + +void GCodeViewer::render() const +{ + auto set_color = [](GLint current_program_id, const std::array& color) { + if (current_program_id > 0) + { + GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1; + if (color_id >= 0) + { + glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)color.data())); + return; + } + } + BOOST_LOG_TRIVIAL(error) << "Unable to find uniform_color uniform"; + }; + + unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); + unsigned char end_id = buffer_id(GCodeProcessor::EMoveType::Count); + + glsafe(::glEnable(GL_DEPTH_TEST)); + + for (unsigned char i = begin_id; i < end_id; ++i) + { + const Buffer& buffer = m_buffers[i]; + if (buffer.vbo_id == 0) + continue; + + const Shader& shader = m_shaders[i]; + if (shader.is_initialized()) + { + shader.start_using(); + + GLint current_program_id; + glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id)); + + GCodeProcessor::EMoveType type = buffer_type(i); + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.vbo_id)); + glsafe(::glVertexPointer(3, GL_FLOAT, Buffer::stride(type), (const void*)0)); + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + + switch (type) + { + case GCodeProcessor::EMoveType::Tool_change: + case GCodeProcessor::EMoveType::Retract: + case GCodeProcessor::EMoveType::Unretract: + { + std::array color = { 0.0f, 1.0f, 0.0f, 1.0f }; + set_color(current_program_id, color); + glsafe(::glDrawArrays(GL_POINTS, 0, (GLsizei)buffer.data.size() / Buffer::record_size(type))); + break; + } + case GCodeProcessor::EMoveType::Extrude: + { + std::array color = { 1.0f, 0.0f, 0.0f, 1.0f }; + set_color(current_program_id, color); + glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)buffer.data.size() / Buffer::record_size(type))); + break; + } + case GCodeProcessor::EMoveType::Travel: + { + std::array color = { 1.0f, 1.0f, 0.0f, 1.0f }; + set_color(current_program_id, color); + glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)buffer.data.size() / Buffer::record_size(type))); + break; + } + default: + { + break; + } + } + + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + shader.stop_using(); + } + } +} + +bool GCodeViewer::init_shaders() +{ + unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); + unsigned char end_id = buffer_id(GCodeProcessor::EMoveType::Count); + + for (unsigned char i = begin_id; i < end_id; ++i) + { + Shader& shader = m_shaders[i]; + std::string vertex_shader_src; + std::string fragment_shader_src; + GCodeProcessor::EMoveType type = buffer_type(i); + switch (type) + { + case GCodeProcessor::EMoveType::Tool_change: + { + vertex_shader_src = "toolchanges.vs"; + fragment_shader_src = "toolchanges.fs"; + break; + } + case GCodeProcessor::EMoveType::Retract: + { + vertex_shader_src = "retractions.vs"; + fragment_shader_src = "retractions.fs"; + break; + } + case GCodeProcessor::EMoveType::Unretract: + { + vertex_shader_src = "unretractions.vs"; + fragment_shader_src = "unretractions.fs"; + break; + } + case GCodeProcessor::EMoveType::Extrude: + { + vertex_shader_src = "extrusions.vs"; + fragment_shader_src = "extrusions.fs"; + break; + } + case GCodeProcessor::EMoveType::Travel: + { + vertex_shader_src = "travels.vs"; + fragment_shader_src = "travels.fs"; + break; + } + default: + { + break; + } + } + + if (!shader.init(vertex_shader_src, fragment_shader_src)) + { + BOOST_LOG_TRIVIAL(error) << "Unable to initialize toolpaths shader: please, check that the files " << vertex_shader_src << " and " << fragment_shader_src << " are available"; + return false; + } + } + + return true; +} + +void GCodeViewer::reset_buffers() +{ + for (Buffer& buffer : m_buffers) + { + // release gpu memory + if (buffer.vbo_id > 0) + glsafe(::glDeleteBuffers(1, &buffer.vbo_id)); + + // release cpu memory + buffer.data = std::vector(); + } +} + +} // namespace GUI +} // namespace Slic3r + +#endif // ENABLE_GCODE_VIEWER diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp new file mode 100644 index 0000000000..95250b2034 --- /dev/null +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -0,0 +1,63 @@ +#ifndef slic3r_GCodeViewer_hpp_ +#define slic3r_GCodeViewer_hpp_ + +#if ENABLE_GCODE_VIEWER + +#include "GLShader.hpp" +#include "libslic3r/GCode/GCodeProcessor.hpp" + +#include + +namespace Slic3r { +namespace GUI { + +class GCodeViewer +{ + struct Buffer + { + unsigned int vbo_id{ 0 }; + std::vector data; + + static size_t stride(GCodeProcessor::EMoveType type) + { + return 3 * sizeof(float); + } + + static size_t record_size(GCodeProcessor::EMoveType type) + { + switch (type) + { + case GCodeProcessor::EMoveType::Tool_change: + case GCodeProcessor::EMoveType::Retract: + case GCodeProcessor::EMoveType::Unretract: { return 3; } + case GCodeProcessor::EMoveType::Extrude: + case GCodeProcessor::EMoveType::Travel: { return 6; } + default: { return 0; } + } + } + }; + + std::vector m_buffers{ static_cast(GCodeProcessor::EMoveType::Extrude) }; + std::vector m_shaders{ static_cast(GCodeProcessor::EMoveType::Extrude) }; + unsigned int m_last_result_id{ 0 }; + +public: + GCodeViewer() = default; + ~GCodeViewer() { reset_buffers(); } + + bool init() { return init_shaders(); } + void generate(const GCodeProcessor::Result& gcode_result); + void render() const; + +private: + bool init_shaders(); + void reset_buffers(); +}; + +} // namespace GUI +} // namespace Slic3r + +#endif // ENABLE_GCODE_VIEWER + +#endif // slic3r_GCodeViewer_hpp_ + diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 85ea44ef14..c9c4ab3364 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1678,6 +1678,14 @@ bool GLCanvas3D::init() return false; } +#if ENABLE_GCODE_VIEWER + if (!m_main_toolbar.is_enabled()) + { + if (!m_gcode_viewer.init()) + return false; + } +#endif // ENABLE_GCODE_VIEWER + // on linux the gl context is not valid until the canvas is not shown on screen // we defer the geometry finalization of volumes until the first call to render() m_volumes.finalize_geometry(true); @@ -2109,6 +2117,9 @@ void GLCanvas3D::render() _render_background(); _render_objects(); +#if ENABLE_GCODE_VIEWER + _render_gcode(); +#endif // ENABLE_GCODE_VIEWER _render_sla_slices(); _render_selection(); #if ENABLE_NON_STATIC_CANVAS_MANAGER @@ -2783,6 +2794,8 @@ void GLCanvas3D::load_gcode_preview_2(const GCodeProcessor::Result& gcode_result out << v.to_string() << "\n"; } out.close(); + + m_gcode_viewer.generate(gcode_result); #endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT } #endif // ENABLE_GCODE_VIEWER @@ -5440,6 +5453,13 @@ void GLCanvas3D::_render_objects() const m_camera_clipping_plane = ClippingPlane::ClipsNothing(); } +#if ENABLE_GCODE_VIEWER +void GLCanvas3D::_render_gcode() const +{ + m_gcode_viewer.render(); +} +#endif // ENABLE_GCODE_VIEWER + void GLCanvas3D::_render_selection() const { float scale_factor = 1.0; diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 0c82f058fe..8c6b3c3f0c 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -21,6 +21,7 @@ #endif // !ENABLE_NON_STATIC_CANVAS_MANAGER #if ENABLE_GCODE_VIEWER #include "libslic3r/GCode/GCodeProcessor.hpp" +#include "GCodeViewer.hpp" #endif // ENABLE_GCODE_VIEWER #include @@ -468,6 +469,10 @@ private: bool m_extra_frame_requested; mutable GLVolumeCollection m_volumes; +#if ENABLE_GCODE_VIEWER + GCodeViewer m_gcode_viewer; +#endif // ENABLE_GCODE_VIEWER + Selection m_selection; const DynamicPrintConfig* m_config; Model* m_model; @@ -764,6 +769,9 @@ private: void _render_background() const; void _render_bed(float theta, bool show_axes) const; void _render_objects() const; +#if ENABLE_GCODE_VIEWER + void _render_gcode() const; +#endif // ENABLE_GCODE_VIEWER void _render_selection() const; #if ENABLE_RENDER_SELECTION_CENTER void _render_selection_center() const; diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 9795095626..0171dd597a 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -946,9 +946,10 @@ void Preview::load_print_as_fff(bool keep_z_range) m_canvas->set_selected_extruder(0); if (gcode_preview_data_valid) { // Load the real G-code preview. - m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); #if ENABLE_GCODE_VIEWER m_canvas->load_gcode_preview_2(*m_gcode_result); +#else + m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); #endif // ENABLE_GCODE_VIEWER m_loaded = true; } else { From bc05ab985c278af18590730f7c253caa332c618b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 14 Apr 2020 16:40:08 +0200 Subject: [PATCH 015/255] GCodeViewer -> Toggle visibility of travel paths, retractions and uretractions --- resources/shaders/retractions.vs | 2 + resources/shaders/toolchanges.vs | 2 + resources/shaders/unretractions.vs | 2 + src/slic3r/GUI/GCodeViewer.cpp | 121 ++++++++++++++++++++++------- src/slic3r/GUI/GCodeViewer.hpp | 36 ++++----- src/slic3r/GUI/GLCanvas3D.cpp | 34 ++++++-- src/slic3r/GUI/GLCanvas3D.hpp | 9 +++ src/slic3r/GUI/GUI_Preview.cpp | 20 +++++ 8 files changed, 173 insertions(+), 53 deletions(-) diff --git a/resources/shaders/retractions.vs b/resources/shaders/retractions.vs index d97adbabe0..ba18073356 100644 --- a/resources/shaders/retractions.vs +++ b/resources/shaders/retractions.vs @@ -12,4 +12,6 @@ void main() // eye_normal = gl_NormalMatrix * gl_Normal; // world_normal_z = gl_Normal.z; gl_Position = ftransform(); + + gl_PointSize = 3.0; } diff --git a/resources/shaders/toolchanges.vs b/resources/shaders/toolchanges.vs index d97adbabe0..ba18073356 100644 --- a/resources/shaders/toolchanges.vs +++ b/resources/shaders/toolchanges.vs @@ -12,4 +12,6 @@ void main() // eye_normal = gl_NormalMatrix * gl_Normal; // world_normal_z = gl_Normal.z; gl_Position = ftransform(); + + gl_PointSize = 3.0; } diff --git a/resources/shaders/unretractions.vs b/resources/shaders/unretractions.vs index d97adbabe0..ba18073356 100644 --- a/resources/shaders/unretractions.vs +++ b/resources/shaders/unretractions.vs @@ -12,4 +12,6 @@ void main() // eye_normal = gl_NormalMatrix * gl_Normal; // world_normal_z = gl_Normal.z; gl_Position = ftransform(); + + gl_PointSize = 3.0; } diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 584ef06c32..00567eab6e 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -8,6 +8,8 @@ #include #include +#include +#include namespace Slic3r { namespace GUI { @@ -20,15 +22,27 @@ static GCodeProcessor::EMoveType buffer_type(unsigned char id) { return static_cast(static_cast(GCodeProcessor::EMoveType::Retract) + id); } +void GCodeViewer::Buffer::reset() +{ + // release gpu memory + if (vbo_id > 0) + glsafe(::glDeleteBuffers(1, &vbo_id)); + + // release cpu memory + data = std::vector(); +} + void GCodeViewer::generate(const GCodeProcessor::Result& gcode_result) { if (m_last_result_id == gcode_result.id) return; + auto start_time = std::chrono::high_resolution_clock::now(); + m_last_result_id = gcode_result.id; // release gpu memory, if used - reset_buffers(); + reset(); // convert data size_t vertices_count = gcode_result.moves.size(); @@ -73,16 +87,49 @@ void GCodeViewer::generate(const GCodeProcessor::Result& gcode_result) continue; } } + if (curr.type == GCodeProcessor::EMoveType::Extrude) + m_layers_zs.emplace_back(curr.position[2]); } + std::sort(m_layers_zs.begin(), m_layers_zs.end()); + + // Replace intervals of layers with similar top positions with their average value. + int n = int(m_layers_zs.size()); + int k = 0; + for (int i = 0; i < n;) { + int j = i + 1; + double zmax = m_layers_zs[i] + EPSILON; + for (; j < n && m_layers_zs[j] <= zmax; ++j); + m_layers_zs[k++] = (j > i + 1) ? (0.5 * (m_layers_zs[i] + m_layers_zs[j - 1])) : m_layers_zs[i]; + i = j; + } + if (k < n) + m_layers_zs.erase(m_layers_zs.begin() + k, m_layers_zs.end()); + // send data to gpu for (Buffer& buffer : m_buffers) { - glsafe(::glGenBuffers(1, &buffer.vbo_id)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.vbo_id)); - glsafe(::glBufferData(GL_ARRAY_BUFFER, buffer.data.size() * sizeof(float), buffer.data.data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + if (buffer.data.size() > 0) + { + glsafe(::glGenBuffers(1, &buffer.vbo_id)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.vbo_id)); + glsafe(::glBufferData(GL_ARRAY_BUFFER, buffer.data.size() * sizeof(float), buffer.data.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + } } + + auto end_time = std::chrono::high_resolution_clock::now(); + std::cout << "toolpaths generation time: " << std::chrono::duration_cast(end_time - start_time).count() << "ms \n"; +} + +void GCodeViewer::reset() +{ + for (Buffer& buffer : m_buffers) + { + buffer.reset(); + } + + m_layers_zs = std::vector(); } void GCodeViewer::render() const @@ -111,10 +158,12 @@ void GCodeViewer::render() const if (buffer.vbo_id == 0) continue; - const Shader& shader = m_shaders[i]; - if (shader.is_initialized()) + if (!buffer.visible) + continue; + + if (buffer.shader.is_initialized()) { - shader.start_using(); + buffer.shader.start_using(); GLint current_program_id; glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id)); @@ -122,32 +171,50 @@ void GCodeViewer::render() const GCodeProcessor::EMoveType type = buffer_type(i); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.vbo_id)); - glsafe(::glVertexPointer(3, GL_FLOAT, Buffer::stride(type), (const void*)0)); + glsafe(::glVertexPointer(3, GL_FLOAT, Buffer::vertex_size_bytes(), (const void*)0)); glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); switch (type) { case GCodeProcessor::EMoveType::Tool_change: + { + std::array color = { 1.0f, 1.0f, 1.0f, 1.0f }; + set_color(current_program_id, color); + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glDrawArrays(GL_POINTS, 0, (GLsizei)buffer.data.size() / Buffer::vertex_size())); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + break; + } case GCodeProcessor::EMoveType::Retract: + { + std::array color = { 1.0f, 0.0f, 1.0f, 1.0f }; + set_color(current_program_id, color); + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glDrawArrays(GL_POINTS, 0, (GLsizei)buffer.data.size() / Buffer::vertex_size())); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + break; + } case GCodeProcessor::EMoveType::Unretract: { std::array color = { 0.0f, 1.0f, 0.0f, 1.0f }; set_color(current_program_id, color); - glsafe(::glDrawArrays(GL_POINTS, 0, (GLsizei)buffer.data.size() / Buffer::record_size(type))); + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glDrawArrays(GL_POINTS, 0, (GLsizei)buffer.data.size() / Buffer::vertex_size())); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); break; } case GCodeProcessor::EMoveType::Extrude: { std::array color = { 1.0f, 0.0f, 0.0f, 1.0f }; set_color(current_program_id, color); - glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)buffer.data.size() / Buffer::record_size(type))); + glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)buffer.data.size() / Buffer::vertex_size())); break; } case GCodeProcessor::EMoveType::Travel: { std::array color = { 1.0f, 1.0f, 0.0f, 1.0f }; set_color(current_program_id, color); - glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)buffer.data.size() / Buffer::record_size(type))); + glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)buffer.data.size() / Buffer::vertex_size())); break; } default: @@ -159,11 +226,24 @@ void GCodeViewer::render() const glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - shader.stop_using(); + buffer.shader.stop_using(); } } } +bool GCodeViewer::is_toolpath_visible(GCodeProcessor::EMoveType type) const +{ + size_t id = static_cast(buffer_id(type)); + return (id < m_buffers.size()) ? m_buffers[id].visible : false; +} + +void GCodeViewer::set_toolpath_visible(GCodeProcessor::EMoveType type, bool visible) +{ + size_t id = static_cast(buffer_id(type)); + if (id < m_buffers.size()) + m_buffers[id].visible = visible; +} + bool GCodeViewer::init_shaders() { unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); @@ -171,7 +251,7 @@ bool GCodeViewer::init_shaders() for (unsigned char i = begin_id; i < end_id; ++i) { - Shader& shader = m_shaders[i]; + Shader& shader = m_buffers[i].shader; std::string vertex_shader_src; std::string fragment_shader_src; GCodeProcessor::EMoveType type = buffer_type(i); @@ -223,19 +303,6 @@ bool GCodeViewer::init_shaders() return true; } -void GCodeViewer::reset_buffers() -{ - for (Buffer& buffer : m_buffers) - { - // release gpu memory - if (buffer.vbo_id > 0) - glsafe(::glDeleteBuffers(1, &buffer.vbo_id)); - - // release cpu memory - buffer.data = std::vector(); - } -} - } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 95250b2034..0ed5c337c4 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -16,42 +16,38 @@ class GCodeViewer struct Buffer { unsigned int vbo_id{ 0 }; + Shader shader; std::vector data; + bool visible{ false }; - static size_t stride(GCodeProcessor::EMoveType type) - { - return 3 * sizeof(float); - } + void reset(); - static size_t record_size(GCodeProcessor::EMoveType type) - { - switch (type) - { - case GCodeProcessor::EMoveType::Tool_change: - case GCodeProcessor::EMoveType::Retract: - case GCodeProcessor::EMoveType::Unretract: { return 3; } - case GCodeProcessor::EMoveType::Extrude: - case GCodeProcessor::EMoveType::Travel: { return 6; } - default: { return 0; } - } - } + static size_t vertex_size() { return 3; } + + static size_t vertex_size_bytes() { return vertex_size() * sizeof(float); } }; std::vector m_buffers{ static_cast(GCodeProcessor::EMoveType::Extrude) }; - std::vector m_shaders{ static_cast(GCodeProcessor::EMoveType::Extrude) }; + unsigned int m_last_result_id{ 0 }; + std::vector m_layers_zs; public: GCodeViewer() = default; - ~GCodeViewer() { reset_buffers(); } + ~GCodeViewer() { reset(); } - bool init() { return init_shaders(); } + bool init() { set_toolpath_visible(GCodeProcessor::EMoveType::Extrude, true); return init_shaders(); } void generate(const GCodeProcessor::Result& gcode_result); + void reset(); void render() const; + const std::vector& get_layers_zs() const { return m_layers_zs; }; + + bool is_toolpath_visible(GCodeProcessor::EMoveType type) const; + void set_toolpath_visible(GCodeProcessor::EMoveType type, bool visible); + private: bool init_shaders(); - void reset_buffers(); }; } // namespace GUI diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index c9c4ab3364..66120668c6 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -932,7 +932,11 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_items( const GLCanvas3D std::vector> cp_values; cp_values.reserve(custom_gcode_per_print_z.size()); +#if ENABLE_GCODE_VIEWER + const std::vector& print_zs = canvas.get_layers_zs(); +#else std::vector print_zs = canvas.get_current_print_zs(true); +#endif // ENABLE_GCODE_VIEWER for (auto custom_code : custom_gcode_per_print_z) { if (custom_code.gcode != ColorChangeCode) @@ -2303,10 +2307,23 @@ void GLCanvas3D::ensure_on_bed(unsigned int object_idx) } } + +#if ENABLE_GCODE_VIEWER +const std::vector& GLCanvas3D::get_layers_zs() const +{ + return m_gcode_viewer.get_layers_zs(); +} + +void GLCanvas3D::set_toolpath_visible(GCodeProcessor::EMoveType type, bool visible) +{ + m_gcode_viewer.set_toolpath_visible(type, visible); +} +#else std::vector GLCanvas3D::get_current_print_zs(bool active_only) const { return m_volumes.get_current_print_zs(active_only); } +#endif // ENABLE_GCODE_VIEWER void GLCanvas3D::set_toolpaths_range(double low, double high) { @@ -2786,14 +2803,19 @@ static void load_gcode_retractions(const GCodePreviewData::Retraction& retractio void GLCanvas3D::load_gcode_preview_2(const GCodeProcessor::Result& gcode_result) { #if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT - boost::filesystem::path path("d:/processor.output"); - boost::nowide::ofstream out; - out.open(path.string()); - for (const GCodeProcessor::MoveVertex& v : gcode_result.moves) + static unsigned int last_result_id = 0; + if (last_result_id != gcode_result.id) { - out << v.to_string() << "\n"; + last_result_id = gcode_result.id; + boost::filesystem::path path("d:/processor.output"); + boost::nowide::ofstream out; + out.open(path.string()); + for (const GCodeProcessor::MoveVertex& v : gcode_result.moves) + { + out << v.to_string() << "\n"; + } + out.close(); } - out.close(); m_gcode_viewer.generate(gcode_result); #endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 8c6b3c3f0c..592c85c03f 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -549,6 +549,10 @@ public: void reset_volumes(); int check_volumes_outside_state() const; +#if ENABLE_GCODE_VIEWER + void reset_gcode_toolpaths() { m_gcode_viewer.reset(); } +#endif // ENABLE_GCODE_VIEWER + void toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1); void toggle_model_objects_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1); void update_instance_printable_state_for_object(size_t obj_idx); @@ -635,7 +639,12 @@ public: void delete_selected(); void ensure_on_bed(unsigned int object_idx); +#if ENABLE_GCODE_VIEWER + const std::vector& get_layers_zs() const; + void set_toolpath_visible(GCodeProcessor::EMoveType type, bool visible); +#else std::vector get_current_print_zs(bool active_only) const; +#endif // ENABLE_GCODE_VIEWER void set_toolpaths_range(double low, double high); std::vector load_object(const ModelObject& model_object, int obj_idx, std::vector instance_idxs); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 0171dd597a..2e0c71268c 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -474,6 +474,9 @@ void Preview::reload_print(bool keep_volumes) !keep_volumes) { m_canvas->reset_volumes(); +#if ENABLE_GCODE_VIEWER + m_canvas->reset_gcode_toolpaths(); +#endif // ENABLE_GCODE_VIEWER m_canvas->reset_legend_texture(); m_loaded = false; #ifdef __linux__ @@ -614,21 +617,34 @@ void Preview::on_combochecklist_features(wxCommandEvent& evt) void Preview::on_checkbox_travel(wxCommandEvent& evt) { +#if ENABLE_GCODE_VIEWER + m_canvas->set_toolpath_visible(GCodeProcessor::EMoveType::Travel, m_checkbox_travel->IsChecked()); + refresh_print(); +#else m_gcode_preview_data->travel.is_visible = m_checkbox_travel->IsChecked(); m_gcode_preview_data->ranges.feedrate.set_mode(GCodePreviewData::FeedrateKind::TRAVEL, m_gcode_preview_data->travel.is_visible); // Rather than refresh, reload print so that speed color ranges get recomputed (affected by travel visibility) reload_print(); +#endif // ENABLE_GCODE_VIEWER } void Preview::on_checkbox_retractions(wxCommandEvent& evt) { +#if ENABLE_GCODE_VIEWER + m_canvas->set_toolpath_visible(GCodeProcessor::EMoveType::Retract, m_checkbox_retractions->IsChecked()); +#else m_gcode_preview_data->retraction.is_visible = m_checkbox_retractions->IsChecked(); +#endif // ENABLE_GCODE_VIEWER refresh_print(); } void Preview::on_checkbox_unretractions(wxCommandEvent& evt) { +#if ENABLE_GCODE_VIEWER + m_canvas->set_toolpath_visible(GCodeProcessor::EMoveType::Unretract, m_checkbox_unretractions->IsChecked()); +#else m_gcode_preview_data->unretraction.is_visible = m_checkbox_unretractions->IsChecked(); +#endif // ENABLE_GCODE_VIEWER refresh_print(); } @@ -958,7 +974,11 @@ void Preview::load_print_as_fff(bool keep_z_range) } show_hide_ui_elements(gcode_preview_data_valid ? "full" : "simple"); // recalculates zs and update sliders accordingly +#if ENABLE_GCODE_VIEWER + const std::vector& zs = m_canvas->get_layers_zs(); +#else std::vector zs = m_canvas->get_current_print_zs(true); +#endif // ENABLE_GCODE_VIEWER if (zs.empty()) { // all layers filtered out reset_sliders(true); From cc774dece7fa902d674353cf051cdb1b4abdc2c5 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 15 Apr 2020 14:31:39 +0200 Subject: [PATCH 016/255] GCodeViewer -> Toggle visibility of shells --- resources/shaders/shells.fs | 13 + resources/shaders/shells.vs | 42 ++++ src/slic3r/GUI/GCodeViewer.cpp | 440 ++++++++++++++++++++------------- src/slic3r/GUI/GCodeViewer.hpp | 21 +- src/slic3r/GUI/GLCanvas3D.cpp | 16 +- src/slic3r/GUI/GLCanvas3D.hpp | 7 +- src/slic3r/GUI/GUI_Preview.cpp | 4 + 7 files changed, 363 insertions(+), 180 deletions(-) create mode 100644 resources/shaders/shells.fs create mode 100644 resources/shaders/shells.vs diff --git a/resources/shaders/shells.fs b/resources/shaders/shells.fs new file mode 100644 index 0000000000..0c3388df70 --- /dev/null +++ b/resources/shaders/shells.fs @@ -0,0 +1,13 @@ +#version 110 + +const vec3 ZERO = vec3(0.0, 0.0, 0.0); + +uniform vec4 uniform_color; + +// x = tainted, y = specular; +varying vec2 intensity; + +void main() +{ + gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color.rgb * intensity.x, uniform_color.a); +} diff --git a/resources/shaders/shells.vs b/resources/shaders/shells.vs new file mode 100644 index 0000000000..bb9c144e65 --- /dev/null +++ b/resources/shaders/shells.vs @@ -0,0 +1,42 @@ +#version 110 + +#define INTENSITY_CORRECTION 0.6 + +// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) +const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); +#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SHININESS 20.0 + +// normalized values for (1./1.43, 0.2/1.43, 1./1.43) +const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074); +#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) + +#define INTENSITY_AMBIENT 0.3 + +// x = tainted, y = specular; +varying vec2 intensity; + +void main() +{ + // First transform the normal into camera space and normalize the result. + vec3 normal = normalize(gl_NormalMatrix * gl_Normal); + + // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. + // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. + float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0); + + intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; + intensity.y = 0.0; + + if (NdotL > 0.0) + { + vec3 position = (gl_ModelViewMatrix * gl_Vertex).xyz; + intensity.y += LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); + } + + // Perform the same lighting calculation for the 2nd light source (no specular applied). + intensity.x += max(dot(normal, LIGHT_FRONT_DIR), 0.0) * LIGHT_FRONT_DIFFUSE; + + gl_Position = ftransform(); +} diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 00567eab6e..155c7d765d 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1,8 +1,11 @@ #include "libslic3r/libslic3r.h" #include "GCodeViewer.hpp" -#include "3DScene.hpp" #if ENABLE_GCODE_VIEWER +#include "libslic3r/Print.hpp" +#include "GUI_App.hpp" +#include "PresetBundle.hpp" +#include "Camera.hpp" #include #include @@ -30,96 +33,21 @@ void GCodeViewer::Buffer::reset() // release cpu memory data = std::vector(); + data_size = 0; } -void GCodeViewer::generate(const GCodeProcessor::Result& gcode_result) +void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized) { if (m_last_result_id == gcode_result.id) return; - auto start_time = std::chrono::high_resolution_clock::now(); - m_last_result_id = gcode_result.id; // release gpu memory, if used reset(); - // convert data - size_t vertices_count = gcode_result.moves.size(); - for (size_t i = 0; i < vertices_count; ++i) - { - // skip first vertex - if (i == 0) - continue; - - const GCodeProcessor::MoveVertex& prev = gcode_result.moves[i - 1]; - const GCodeProcessor::MoveVertex& curr = gcode_result.moves[i]; - - Buffer& buffer = m_buffers[buffer_id(curr.type)]; - - switch (curr.type) - { - case GCodeProcessor::EMoveType::Tool_change: - case GCodeProcessor::EMoveType::Retract: - case GCodeProcessor::EMoveType::Unretract: - { - for (int j = 0; j < 3; ++j) - { - buffer.data.insert(buffer.data.end(), curr.position[j]); - } - break; - } - case GCodeProcessor::EMoveType::Extrude: - case GCodeProcessor::EMoveType::Travel: - { - for (int j = 0; j < 3; ++j) - { - buffer.data.insert(buffer.data.end(), prev.position[j]); - } - for (int j = 0; j < 3; ++j) - { - buffer.data.insert(buffer.data.end(), curr.position[j]); - } - break; - } - default: - { - continue; - } - } - if (curr.type == GCodeProcessor::EMoveType::Extrude) - m_layers_zs.emplace_back(curr.position[2]); - } - - std::sort(m_layers_zs.begin(), m_layers_zs.end()); - - // Replace intervals of layers with similar top positions with their average value. - int n = int(m_layers_zs.size()); - int k = 0; - for (int i = 0; i < n;) { - int j = i + 1; - double zmax = m_layers_zs[i] + EPSILON; - for (; j < n && m_layers_zs[j] <= zmax; ++j); - m_layers_zs[k++] = (j > i + 1) ? (0.5 * (m_layers_zs[i] + m_layers_zs[j - 1])) : m_layers_zs[i]; - i = j; - } - if (k < n) - m_layers_zs.erase(m_layers_zs.begin() + k, m_layers_zs.end()); - - // send data to gpu - for (Buffer& buffer : m_buffers) - { - if (buffer.data.size() > 0) - { - glsafe(::glGenBuffers(1, &buffer.vbo_id)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.vbo_id)); - glsafe(::glBufferData(GL_ARRAY_BUFFER, buffer.data.size() * sizeof(float), buffer.data.data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - } - } - - auto end_time = std::chrono::high_resolution_clock::now(); - std::cout << "toolpaths generation time: " << std::chrono::duration_cast(end_time - start_time).count() << "ms \n"; + load_toolpaths(gcode_result); + load_shells(print, initialized); } void GCodeViewer::reset() @@ -129,106 +57,15 @@ void GCodeViewer::reset() buffer.reset(); } + m_shells.volumes.clear(); m_layers_zs = std::vector(); } void GCodeViewer::render() const { - auto set_color = [](GLint current_program_id, const std::array& color) { - if (current_program_id > 0) - { - GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1; - if (color_id >= 0) - { - glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)color.data())); - return; - } - } - BOOST_LOG_TRIVIAL(error) << "Unable to find uniform_color uniform"; - }; - - unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); - unsigned char end_id = buffer_id(GCodeProcessor::EMoveType::Count); - glsafe(::glEnable(GL_DEPTH_TEST)); - - for (unsigned char i = begin_id; i < end_id; ++i) - { - const Buffer& buffer = m_buffers[i]; - if (buffer.vbo_id == 0) - continue; - - if (!buffer.visible) - continue; - - if (buffer.shader.is_initialized()) - { - buffer.shader.start_using(); - - GLint current_program_id; - glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id)); - - GCodeProcessor::EMoveType type = buffer_type(i); - - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.vbo_id)); - glsafe(::glVertexPointer(3, GL_FLOAT, Buffer::vertex_size_bytes(), (const void*)0)); - glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - - switch (type) - { - case GCodeProcessor::EMoveType::Tool_change: - { - std::array color = { 1.0f, 1.0f, 1.0f, 1.0f }; - set_color(current_program_id, color); - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawArrays(GL_POINTS, 0, (GLsizei)buffer.data.size() / Buffer::vertex_size())); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); - break; - } - case GCodeProcessor::EMoveType::Retract: - { - std::array color = { 1.0f, 0.0f, 1.0f, 1.0f }; - set_color(current_program_id, color); - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawArrays(GL_POINTS, 0, (GLsizei)buffer.data.size() / Buffer::vertex_size())); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); - break; - } - case GCodeProcessor::EMoveType::Unretract: - { - std::array color = { 0.0f, 1.0f, 0.0f, 1.0f }; - set_color(current_program_id, color); - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawArrays(GL_POINTS, 0, (GLsizei)buffer.data.size() / Buffer::vertex_size())); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); - break; - } - case GCodeProcessor::EMoveType::Extrude: - { - std::array color = { 1.0f, 0.0f, 0.0f, 1.0f }; - set_color(current_program_id, color); - glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)buffer.data.size() / Buffer::vertex_size())); - break; - } - case GCodeProcessor::EMoveType::Travel: - { - std::array color = { 1.0f, 1.0f, 0.0f, 1.0f }; - set_color(current_program_id, color); - glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)buffer.data.size() / Buffer::vertex_size())); - break; - } - default: - { - break; - } - } - - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); - - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - buffer.shader.stop_using(); - } - } + render_toolpaths(); + render_shells(); } bool GCodeViewer::is_toolpath_visible(GCodeProcessor::EMoveType type) const @@ -300,9 +137,264 @@ bool GCodeViewer::init_shaders() } } + if (!m_shells.shader.init("shells.vs", "shells.fs")) + { + BOOST_LOG_TRIVIAL(error) << "Unable to initialize shells shader: please, check that the files shells.vs and shells.fs are available"; + return false; + } + return true; } +void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) +{ + auto start_time = std::chrono::high_resolution_clock::now(); + + // convert data + size_t vertices_count = gcode_result.moves.size(); + for (size_t i = 0; i < vertices_count; ++i) + { + // skip first vertex + if (i == 0) + continue; + + const GCodeProcessor::MoveVertex& prev = gcode_result.moves[i - 1]; + const GCodeProcessor::MoveVertex& curr = gcode_result.moves[i]; + + Buffer& buffer = m_buffers[buffer_id(curr.type)]; + + switch (curr.type) + { + case GCodeProcessor::EMoveType::Tool_change: + case GCodeProcessor::EMoveType::Retract: + case GCodeProcessor::EMoveType::Unretract: + { + for (int j = 0; j < 3; ++j) + { + buffer.data.insert(buffer.data.end(), curr.position[j]); + } + break; + } + case GCodeProcessor::EMoveType::Extrude: + case GCodeProcessor::EMoveType::Travel: + { + for (int j = 0; j < 3; ++j) + { + buffer.data.insert(buffer.data.end(), prev.position[j]); + } + for (int j = 0; j < 3; ++j) + { + buffer.data.insert(buffer.data.end(), curr.position[j]); + } + break; + } + default: + { + continue; + } + } + + if (curr.type == GCodeProcessor::EMoveType::Extrude) + m_layers_zs.emplace_back(curr.position[2]); + } + + std::sort(m_layers_zs.begin(), m_layers_zs.end()); + + // Replace intervals of layers with similar top positions with their average value. + int n = int(m_layers_zs.size()); + int k = 0; + for (int i = 0; i < n;) { + int j = i + 1; + double zmax = m_layers_zs[i] + EPSILON; + for (; j < n && m_layers_zs[j] <= zmax; ++j); + m_layers_zs[k++] = (j > i + 1) ? (0.5 * (m_layers_zs[i] + m_layers_zs[j - 1])) : m_layers_zs[i]; + i = j; + } + if (k < n) + m_layers_zs.erase(m_layers_zs.begin() + k, m_layers_zs.end()); + + // send data to gpu + for (Buffer& buffer : m_buffers) + { + buffer.data_size = buffer.data.size(); + if (buffer.data_size > 0) + { + glsafe(::glGenBuffers(1, &buffer.vbo_id)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.vbo_id)); + glsafe(::glBufferData(GL_ARRAY_BUFFER, buffer.data_size * sizeof(float), buffer.data.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + buffer.data = std::vector(); + } + } + + auto end_time = std::chrono::high_resolution_clock::now(); + std::cout << "toolpaths generation time: " << std::chrono::duration_cast(end_time - start_time).count() << "ms \n"; +} + +void GCodeViewer::load_shells(const Print& print, bool initialized) +{ + if (print.objects().empty()) + // no shells, return + return; + + // adds objects' volumes + int object_id = 0; + for (const PrintObject* obj : print.objects()) + { + const ModelObject* model_obj = obj->model_object(); + + std::vector instance_ids(model_obj->instances.size()); + for (int i = 0; i < (int)model_obj->instances.size(); ++i) + { + instance_ids[i] = i; + } + + m_shells.volumes.load_object(model_obj, object_id, instance_ids, "object", initialized); + + ++object_id; + } + + if (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptFFF) { + // adds wipe tower's volume + double max_z = print.objects()[0]->model_object()->get_model()->bounding_box().max(2); + const PrintConfig& config = print.config(); + size_t extruders_count = config.nozzle_diameter.size(); + if ((extruders_count > 1) && config.wipe_tower && !config.complete_objects) { + + const DynamicPrintConfig& print_config = wxGetApp().preset_bundle->prints.get_edited_preset().config; + double layer_height = print_config.opt_float("layer_height"); + double first_layer_height = print_config.get_abs_value("first_layer_height", layer_height); + double nozzle_diameter = print.config().nozzle_diameter.values[0]; + float depth = print.wipe_tower_data(extruders_count, first_layer_height, nozzle_diameter).depth; + float brim_width = print.wipe_tower_data(extruders_count, first_layer_height, nozzle_diameter).brim_width; + + m_shells.volumes.load_wipe_tower_preview(1000, config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle, + !print.is_step_done(psWipeTower), brim_width, initialized); + } + } + + for (GLVolume* volume : m_shells.volumes.volumes) + { + volume->zoom_to_volumes = false; + volume->color[3] = 0.25f; + volume->force_native_color = true; + volume->set_render_color(); + } +} + +void GCodeViewer::render_toolpaths() const +{ + auto set_color = [](GLint current_program_id, const std::array& color) { + if (current_program_id > 0) + { + GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1; + if (color_id >= 0) + { + glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)color.data())); + return; + } + } + BOOST_LOG_TRIVIAL(error) << "Unable to find uniform_color uniform"; + }; + + glsafe(::glCullFace(GL_BACK)); + + unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); + unsigned char end_id = buffer_id(GCodeProcessor::EMoveType::Count); + + for (unsigned char i = begin_id; i < end_id; ++i) + { + const Buffer& buffer = m_buffers[i]; + if (buffer.vbo_id == 0) + continue; + + if (!buffer.visible) + continue; + + if (buffer.shader.is_initialized()) + { + buffer.shader.start_using(); + + GLint current_program_id; + glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id)); + + GCodeProcessor::EMoveType type = buffer_type(i); + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.vbo_id)); + glsafe(::glVertexPointer(3, GL_FLOAT, Buffer::vertex_size_bytes(), (const void*)0)); + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + + switch (type) + { + case GCodeProcessor::EMoveType::Tool_change: + { + std::array color = { 1.0f, 1.0f, 1.0f, 1.0f }; + set_color(current_program_id, color); + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glDrawArrays(GL_POINTS, 0, (GLsizei)(buffer.data_size / Buffer::vertex_size()))); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + break; + } + case GCodeProcessor::EMoveType::Retract: + { + std::array color = { 1.0f, 0.0f, 1.0f, 1.0f }; + set_color(current_program_id, color); + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glDrawArrays(GL_POINTS, 0, (GLsizei)(buffer.data_size / Buffer::vertex_size()))); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + break; + } + case GCodeProcessor::EMoveType::Unretract: + { + std::array color = { 0.0f, 1.0f, 0.0f, 1.0f }; + set_color(current_program_id, color); + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glDrawArrays(GL_POINTS, 0, (GLsizei)(buffer.data_size / Buffer::vertex_size()))); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + break; + } + case GCodeProcessor::EMoveType::Extrude: + { + std::array color = { 1.0f, 0.0f, 0.0f, 1.0f }; + set_color(current_program_id, color); + glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)(buffer.data_size / Buffer::vertex_size()))); + break; + } + case GCodeProcessor::EMoveType::Travel: + { + std::array color = { 1.0f, 1.0f, 0.0f, 1.0f }; + set_color(current_program_id, color); + glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)(buffer.data_size / Buffer::vertex_size()))); + break; + } + default: + { + break; + } + } + + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + buffer.shader.stop_using(); + } + } +} + +void GCodeViewer::render_shells() const +{ + if (!m_shells.visible || m_shells.volumes.empty() || !m_shells.shader.is_initialized()) + return; + +// glsafe(::glDepthMask(GL_FALSE)); + + m_shells.shader.start_using(); + m_shells.volumes.render(GLVolumeCollection::Transparent, true, wxGetApp().plater()->get_camera().get_view_matrix()); + m_shells.shader.stop_using(); + +// glsafe(::glDepthMask(GL_TRUE)); +} + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 0ed5c337c4..92929cffe9 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -4,11 +4,13 @@ #if ENABLE_GCODE_VIEWER #include "GLShader.hpp" +#include "3DScene.hpp" #include "libslic3r/GCode/GCodeProcessor.hpp" #include namespace Slic3r { +class Print; namespace GUI { class GCodeViewer @@ -18,26 +20,34 @@ class GCodeViewer unsigned int vbo_id{ 0 }; Shader shader; std::vector data; + size_t data_size{ 0 }; bool visible{ false }; void reset(); static size_t vertex_size() { return 3; } - static size_t vertex_size_bytes() { return vertex_size() * sizeof(float); } }; + struct Shells + { + GLVolumeCollection volumes; + bool visible{ false }; + Shader shader; + }; + std::vector m_buffers{ static_cast(GCodeProcessor::EMoveType::Extrude) }; unsigned int m_last_result_id{ 0 }; std::vector m_layers_zs; + Shells m_shells; public: GCodeViewer() = default; ~GCodeViewer() { reset(); } bool init() { set_toolpath_visible(GCodeProcessor::EMoveType::Extrude, true); return init_shaders(); } - void generate(const GCodeProcessor::Result& gcode_result); + void load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized); void reset(); void render() const; @@ -46,8 +56,15 @@ public: bool is_toolpath_visible(GCodeProcessor::EMoveType type) const; void set_toolpath_visible(GCodeProcessor::EMoveType type, bool visible); + bool are_shells_visible() const { return m_shells.visible; } + void set_shells_visible(bool visible) { m_shells.visible = visible; } + private: bool init_shaders(); + void load_toolpaths(const GCodeProcessor::Result& gcode_result); + void load_shells(const Print& print, bool initialized); + void render_toolpaths() const; + void render_shells() const; }; } // namespace GUI diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 66120668c6..4b8ca69d21 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2122,7 +2122,8 @@ void GLCanvas3D::render() _render_objects(); #if ENABLE_GCODE_VIEWER - _render_gcode(); + if (!m_main_toolbar.is_enabled()) + _render_gcode(); #endif // ENABLE_GCODE_VIEWER _render_sla_slices(); _render_selection(); @@ -2318,6 +2319,11 @@ void GLCanvas3D::set_toolpath_visible(GCodeProcessor::EMoveType type, bool visib { m_gcode_viewer.set_toolpath_visible(type, visible); } + +void GLCanvas3D::set_shells_visible(bool visible) +{ + m_gcode_viewer.set_shells_visible(visible); +} #else std::vector GLCanvas3D::get_current_print_zs(bool active_only) const { @@ -2768,6 +2774,7 @@ static void reserve_new_volume_finalize_old_volume(GLVolume& vol_new, GLVolume& vol_old.finalize_geometry(gl_initialized); } +#if !ENABLE_GCODE_VIEWER static void load_gcode_retractions(const GCodePreviewData::Retraction& retractions, GLCanvas3D::GCodePreviewVolumeIndex::EType extrusion_type, GLVolumeCollection &volumes, GLCanvas3D::GCodePreviewVolumeIndex &volume_index, bool gl_initialized) { // nothing to render, return @@ -2798,6 +2805,7 @@ static void load_gcode_retractions(const GCodePreviewData::Retraction& retractio } volume->indexed_vertex_array.finalize_geometry(gl_initialized); } +#endif // !ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER void GLCanvas3D::load_gcode_preview_2(const GCodeProcessor::Result& gcode_result) @@ -2817,11 +2825,12 @@ void GLCanvas3D::load_gcode_preview_2(const GCodeProcessor::Result& gcode_result out.close(); } - m_gcode_viewer.generate(gcode_result); + m_gcode_viewer.load(gcode_result , *this->fff_print(), m_initialized); #endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT } #endif // ENABLE_GCODE_VIEWER +#if !ENABLE_GCODE_VIEWER void GLCanvas3D::load_gcode_preview(const GCodePreviewData& preview_data, const std::vector& str_tool_colors) { const Print *print = this->fff_print(); @@ -2890,6 +2899,7 @@ void GLCanvas3D::load_gcode_preview(const GCodePreviewData& preview_data, const _generate_legend_texture(preview_data, tool_colors); } } +#endif // !ENABLE_GCODE_VIEWER void GLCanvas3D::load_sla_preview() { @@ -6547,6 +6557,7 @@ static inline int hex_digit_to_int(const char c) (c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1; } +#if !ENABLE_GCODE_VIEWER void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_data, const std::vector& tool_colors) { BOOST_LOG_TRIVIAL(debug) << "Loading G-code extrusion paths - start" << m_volumes.log_memory_info() << log_memory_info(); @@ -6866,6 +6877,7 @@ void GLCanvas3D::_load_fff_shells() } } } +#endif // !ENABLE_GCODE_VIEWER // While it looks like we can call // this->reload_scene(true, true) diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 592c85c03f..7033f05a0b 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -642,6 +642,7 @@ public: #if ENABLE_GCODE_VIEWER const std::vector& get_layers_zs() const; void set_toolpath_visible(GCodeProcessor::EMoveType type, bool visible); + void set_shells_visible(bool visible); #else std::vector get_current_print_zs(bool active_only) const; #endif // ENABLE_GCODE_VIEWER @@ -656,9 +657,9 @@ public: #if ENABLE_GCODE_VIEWER void load_gcode_preview_2(const GCodeProcessor::Result& gcode_result); -#endif // ENABLE_GCODE_VIEWER - +#else void load_gcode_preview(const GCodePreviewData& preview_data, const std::vector& str_tool_colors); +#endif // ENABLE_GCODE_VIEWER void load_sla_preview(); void load_preview(const std::vector& str_tool_colors, const std::vector& color_print_values); void bind_event_handlers(); @@ -833,12 +834,14 @@ private: // Create 3D thick extrusion lines for wipe tower extrusions void _load_wipe_tower_toolpaths(const std::vector& str_tool_colors); +#if !ENABLE_GCODE_VIEWER // generates gcode extrusion paths geometry void _load_gcode_extrusion_paths(const GCodePreviewData& preview_data, const std::vector& tool_colors); // generates gcode travel paths geometry void _load_gcode_travel_paths(const GCodePreviewData& preview_data, const std::vector& tool_colors); // generates objects and wipe tower geometry void _load_fff_shells(); +#endif // !ENABLE_GCODE_VIEWER // Load SLA objects and support structures for objects, for which the slaposSliceSupports step has been finished. void _load_sla_shells(); // sets gcode geometry visibility according to user selection diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 2e0c71268c..0c4f655c58 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -650,7 +650,11 @@ void Preview::on_checkbox_unretractions(wxCommandEvent& evt) void Preview::on_checkbox_shells(wxCommandEvent& evt) { +#if ENABLE_GCODE_VIEWER + m_canvas->set_shells_visible(m_checkbox_shells->IsChecked()); +#else m_gcode_preview_data->shell.is_visible = m_checkbox_shells->IsChecked(); +#endif // ENABLE_GCODE_VIEWER refresh_print(); } From 61ab7bbebfaabc21a5a6a08750c8230c9a9bbb39 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 15 Apr 2020 16:29:11 +0200 Subject: [PATCH 017/255] GCodeViewer -> Basic indexed rendering --- resources/shaders/retractions.vs | 2 +- resources/shaders/toolchanges.vs | 2 +- resources/shaders/unretractions.vs | 2 +- src/slic3r/GUI/GCodeViewer.cpp | 153 +++++++++++++++++------------ src/slic3r/GUI/GCodeViewer.hpp | 25 +++-- 5 files changed, 113 insertions(+), 71 deletions(-) diff --git a/resources/shaders/retractions.vs b/resources/shaders/retractions.vs index ba18073356..2cf5ca2dd0 100644 --- a/resources/shaders/retractions.vs +++ b/resources/shaders/retractions.vs @@ -13,5 +13,5 @@ void main() // world_normal_z = gl_Normal.z; gl_Position = ftransform(); - gl_PointSize = 3.0; + gl_PointSize = 5.0; } diff --git a/resources/shaders/toolchanges.vs b/resources/shaders/toolchanges.vs index ba18073356..2cf5ca2dd0 100644 --- a/resources/shaders/toolchanges.vs +++ b/resources/shaders/toolchanges.vs @@ -13,5 +13,5 @@ void main() // world_normal_z = gl_Normal.z; gl_Position = ftransform(); - gl_PointSize = 3.0; + gl_PointSize = 5.0; } diff --git a/resources/shaders/unretractions.vs b/resources/shaders/unretractions.vs index ba18073356..2cf5ca2dd0 100644 --- a/resources/shaders/unretractions.vs +++ b/resources/shaders/unretractions.vs @@ -13,5 +13,5 @@ void main() // world_normal_z = gl_Normal.z; gl_Position = ftransform(); - gl_PointSize = 3.0; + gl_PointSize = 5.0; } diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 155c7d765d..963f8d2269 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -25,14 +25,23 @@ static GCodeProcessor::EMoveType buffer_type(unsigned char id) { return static_cast(static_cast(GCodeProcessor::EMoveType::Retract) + id); } -void GCodeViewer::Buffer::reset() +void GCodeViewer::VBuffer::reset() { // release gpu memory if (vbo_id > 0) glsafe(::glDeleteBuffers(1, &vbo_id)); + vertices_count = 0; +} + +void GCodeViewer::IBuffer::reset() +{ + // release gpu memory + if (ibo_id > 0) + glsafe(::glDeleteBuffers(1, &ibo_id)); + // release cpu memory - data = std::vector(); + data = std::vector(); data_size = 0; } @@ -52,7 +61,9 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& void GCodeViewer::reset() { - for (Buffer& buffer : m_buffers) + m_vertices.reset(); + + for (IBuffer& buffer : m_buffers) { buffer.reset(); } @@ -150,9 +161,32 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) { auto start_time = std::chrono::high_resolution_clock::now(); - // convert data - size_t vertices_count = gcode_result.moves.size(); - for (size_t i = 0; i < vertices_count; ++i) + // vertex data + m_vertices.vertices_count = gcode_result.moves.size(); + if (m_vertices.vertices_count == 0) + return; + + // vertex data -> extract from result + std::vector vertices_data; + for (const GCodeProcessor::MoveVertex& move : gcode_result.moves) + { + for (int j = 0; j < 3; ++j) + { + vertices_data.insert(vertices_data.end(), move.position[j]); + } + } + + // vertex data -> send to gpu + glsafe(::glGenBuffers(1, &m_vertices.vbo_id)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vertices.vbo_id)); + glsafe(::glBufferData(GL_ARRAY_BUFFER, vertices_data.size() * sizeof(float), vertices_data.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + + // vertex data -> free ram + vertices_data = std::vector(); + + // indices data -> extract from result + for (size_t i = 0; i < m_vertices.vertices_count; ++i) { // skip first vertex if (i == 0) @@ -161,7 +195,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) const GCodeProcessor::MoveVertex& prev = gcode_result.moves[i - 1]; const GCodeProcessor::MoveVertex& curr = gcode_result.moves[i]; - Buffer& buffer = m_buffers[buffer_id(curr.type)]; + IBuffer& buffer = m_buffers[buffer_id(curr.type)]; switch (curr.type) { @@ -169,23 +203,14 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) case GCodeProcessor::EMoveType::Retract: case GCodeProcessor::EMoveType::Unretract: { - for (int j = 0; j < 3; ++j) - { - buffer.data.insert(buffer.data.end(), curr.position[j]); - } + buffer.data.push_back(static_cast(i)); break; } case GCodeProcessor::EMoveType::Extrude: case GCodeProcessor::EMoveType::Travel: { - for (int j = 0; j < 3; ++j) - { - buffer.data.insert(buffer.data.end(), prev.position[j]); - } - for (int j = 0; j < 3; ++j) - { - buffer.data.insert(buffer.data.end(), curr.position[j]); - } + buffer.data.push_back(static_cast(i - 1)); + buffer.data.push_back(static_cast(i)); break; } default: @@ -193,14 +218,35 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) continue; } } - - if (curr.type == GCodeProcessor::EMoveType::Extrude) - m_layers_zs.emplace_back(curr.position[2]); } + // indices data -> send data to gpu + for (IBuffer& buffer : m_buffers) + { + buffer.data_size = buffer.data.size(); + if (buffer.data_size > 0) + { + glsafe(::glGenBuffers(1, &buffer.ibo_id)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.ibo_id)); + glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, buffer.data_size * sizeof(unsigned int), buffer.data.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + + // indices data -> free ram + buffer.data = std::vector(); + } + } + + // layers zs -> extract from result + for (const GCodeProcessor::MoveVertex& move : gcode_result.moves) + { + if (move.type == GCodeProcessor::EMoveType::Extrude) + m_layers_zs.emplace_back(move.position[2]); + } + + // layers zs -> sort std::sort(m_layers_zs.begin(), m_layers_zs.end()); - // Replace intervals of layers with similar top positions with their average value. + // layers zs -> replace intervals of layers with similar top positions with their average value. int n = int(m_layers_zs.size()); int k = 0; for (int i = 0; i < n;) { @@ -213,20 +259,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) if (k < n) m_layers_zs.erase(m_layers_zs.begin() + k, m_layers_zs.end()); - // send data to gpu - for (Buffer& buffer : m_buffers) - { - buffer.data_size = buffer.data.size(); - if (buffer.data_size > 0) - { - glsafe(::glGenBuffers(1, &buffer.vbo_id)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.vbo_id)); - glsafe(::glBufferData(GL_ARRAY_BUFFER, buffer.data_size * sizeof(float), buffer.data.data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - buffer.data = std::vector(); - } - } - auto end_time = std::chrono::high_resolution_clock::now(); std::cout << "toolpaths generation time: " << std::chrono::duration_cast(end_time - start_time).count() << "ms \n"; } @@ -285,11 +317,9 @@ void GCodeViewer::load_shells(const Print& print, bool initialized) void GCodeViewer::render_toolpaths() const { auto set_color = [](GLint current_program_id, const std::array& color) { - if (current_program_id > 0) - { + if (current_program_id > 0) { GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1; - if (color_id >= 0) - { + if (color_id >= 0) { glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)color.data())); return; } @@ -302,27 +332,29 @@ void GCodeViewer::render_toolpaths() const unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); unsigned char end_id = buffer_id(GCodeProcessor::EMoveType::Count); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vertices.vbo_id)); + glsafe(::glVertexPointer(3, GL_FLOAT, VBuffer::vertex_size_bytes(), (const void*)0)); + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + for (unsigned char i = begin_id; i < end_id; ++i) { - const Buffer& buffer = m_buffers[i]; - if (buffer.vbo_id == 0) + const IBuffer& buffer = m_buffers[i]; + if (buffer.ibo_id == 0) continue; - + if (!buffer.visible) continue; if (buffer.shader.is_initialized()) { - buffer.shader.start_using(); + GCodeProcessor::EMoveType type = buffer_type(i); + buffer.shader.start_using(); + GLint current_program_id; glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id)); - GCodeProcessor::EMoveType type = buffer_type(i); - - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.vbo_id)); - glsafe(::glVertexPointer(3, GL_FLOAT, Buffer::vertex_size_bytes(), (const void*)0)); - glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.ibo_id)); switch (type) { @@ -331,7 +363,7 @@ void GCodeViewer::render_toolpaths() const std::array color = { 1.0f, 1.0f, 1.0f, 1.0f }; set_color(current_program_id, color); glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawArrays(GL_POINTS, 0, (GLsizei)(buffer.data_size / Buffer::vertex_size()))); + glsafe(::glDrawElements(GL_POINTS, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); break; } @@ -340,7 +372,7 @@ void GCodeViewer::render_toolpaths() const std::array color = { 1.0f, 0.0f, 1.0f, 1.0f }; set_color(current_program_id, color); glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawArrays(GL_POINTS, 0, (GLsizei)(buffer.data_size / Buffer::vertex_size()))); + glsafe(::glDrawElements(GL_POINTS, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); break; } @@ -349,7 +381,7 @@ void GCodeViewer::render_toolpaths() const std::array color = { 0.0f, 1.0f, 0.0f, 1.0f }; set_color(current_program_id, color); glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawArrays(GL_POINTS, 0, (GLsizei)(buffer.data_size / Buffer::vertex_size()))); + glsafe(::glDrawElements(GL_POINTS, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); break; } @@ -357,28 +389,25 @@ void GCodeViewer::render_toolpaths() const { std::array color = { 1.0f, 0.0f, 0.0f, 1.0f }; set_color(current_program_id, color); - glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)(buffer.data_size / Buffer::vertex_size()))); + glsafe(::glDrawElements(GL_LINES, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); break; } case GCodeProcessor::EMoveType::Travel: { std::array color = { 1.0f, 1.0f, 0.0f, 1.0f }; set_color(current_program_id, color); - glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)(buffer.data_size / Buffer::vertex_size()))); - break; - } - default: - { + glsafe(::glDrawElements(GL_LINES, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); break; } } - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); - - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); buffer.shader.stop_using(); } } + + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); } void GCodeViewer::render_shells() const diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 92929cffe9..6d6a6f8e01 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -15,13 +15,13 @@ namespace GUI { class GCodeViewer { - struct Buffer + // buffer containing vertices data + struct VBuffer { unsigned int vbo_id{ 0 }; - Shader shader; - std::vector data; - size_t data_size{ 0 }; - bool visible{ false }; + size_t vertices_count{ 0 }; + + size_t data_size_bytes() { return vertices_count * vertex_size_bytes(); } void reset(); @@ -29,6 +29,18 @@ class GCodeViewer static size_t vertex_size_bytes() { return vertex_size() * sizeof(float); } }; + // buffer containing indices data + struct IBuffer + { + unsigned int ibo_id{ 0 }; + Shader shader; + std::vector data; + size_t data_size{ 0 }; + bool visible{ false }; + + void reset(); + }; + struct Shells { GLVolumeCollection volumes; @@ -36,7 +48,8 @@ class GCodeViewer Shader shader; }; - std::vector m_buffers{ static_cast(GCodeProcessor::EMoveType::Extrude) }; + VBuffer m_vertices; + std::vector m_buffers{ static_cast(GCodeProcessor::EMoveType::Extrude) }; unsigned int m_last_result_id{ 0 }; std::vector m_layers_zs; From 75d1e8373d9ed949468b3bd733dee3c2a83fb951 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 16 Apr 2020 15:09:04 +0200 Subject: [PATCH 018/255] GCodeViewer -> extrusion paths colored by extrusion role --- src/libslic3r/GCode/GCodeProcessor.cpp | 2 +- src/libslic3r/GCode/GCodeProcessor.hpp | 6 +- src/slic3r/GUI/GCodeViewer.cpp | 100 ++++++++++++++++++------- src/slic3r/GUI/GCodeViewer.hpp | 28 ++++++- src/slic3r/GUI/GLCanvas3D.cpp | 3 + 5 files changed, 105 insertions(+), 34 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index c75c240020..78943dca89 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -1,4 +1,4 @@ -#include "../libslic3r.h" +#include "libslic3r/libslic3r.h" #include "GCodeProcessor.hpp" #include diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 1f7af9c29d..623a2ae3bd 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -2,9 +2,9 @@ #define slic3r_GCodeProcessor_hpp_ #if ENABLE_GCODE_VIEWER -#include "../GCodeReader.hpp" -#include "../Point.hpp" -#include "../ExtrusionEntity.hpp" +#include "libslic3r/GCodeReader.hpp" +#include "libslic3r/Point.hpp" +#include "libslic3r/ExtrusionEntity.hpp" #include #include diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 963f8d2269..a554ecb8ba 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -43,8 +43,44 @@ void GCodeViewer::IBuffer::reset() // release cpu memory data = std::vector(); data_size = 0; + paths = std::vector(); } +bool GCodeViewer::IBuffer::init_shader(const std::string& vertex_shader_src, const std::string& fragment_shader_src) +{ + if (!shader.init(vertex_shader_src, fragment_shader_src)) + { + BOOST_LOG_TRIVIAL(error) << "Unable to initialize toolpaths shader: please, check that the files " << vertex_shader_src << " and " << fragment_shader_src << " are available"; + return false; + } + + return true; +} + +void GCodeViewer::IBuffer::add_path(GCodeProcessor::EMoveType type, ExtrusionRole role) +{ + unsigned int id = static_cast(data.size()); + paths.push_back({ type, role, id, id }); +} + +const std::array, erCount> GCodeViewer::Default_Extrusion_Role_Colors {{ + { 0.00f, 0.00f, 0.00f, 1.0f }, // erNone + { 1.00f, 1.00f, 0.40f, 1.0f }, // erPerimeter + { 1.00f, 0.65f, 0.00f, 1.0f }, // erExternalPerimeter + { 0.00f, 0.00f, 1.00f, 1.0f }, // erOverhangPerimeter + { 0.69f, 0.19f, 0.16f, 1.0f }, // erInternalInfill + { 0.84f, 0.20f, 0.84f, 1.0f }, // erSolidInfill + { 1.00f, 0.10f, 0.10f, 1.0f }, // erTopSolidInfill + { 0.60f, 0.60f, 1.00f, 1.0f }, // erBridgeInfill + { 1.00f, 1.00f, 1.00f, 1.0f }, // erGapFill + { 0.52f, 0.48f, 0.13f, 1.0f }, // erSkirt + { 0.00f, 1.00f, 0.00f, 1.0f }, // erSupportMaterial + { 0.00f, 0.50f, 0.00f, 1.0f }, // erSupportMaterialInterface + { 0.70f, 0.89f, 0.67f, 1.0f }, // erWipeTower + { 0.16f, 0.80f, 0.58f, 1.0f }, // erCustom + { 0.00f, 0.00f, 0.00f, 1.0f } // erMixed +}}; + void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized) { if (m_last_result_id == gcode_result.id) @@ -99,40 +135,41 @@ bool GCodeViewer::init_shaders() for (unsigned char i = begin_id; i < end_id; ++i) { - Shader& shader = m_buffers[i].shader; - std::string vertex_shader_src; - std::string fragment_shader_src; - GCodeProcessor::EMoveType type = buffer_type(i); - switch (type) + switch (buffer_type(i)) { case GCodeProcessor::EMoveType::Tool_change: { - vertex_shader_src = "toolchanges.vs"; - fragment_shader_src = "toolchanges.fs"; + if (!m_buffers[i].init_shader("toolchanges.vs", "toolchanges.fs")) + return false; + break; } case GCodeProcessor::EMoveType::Retract: { - vertex_shader_src = "retractions.vs"; - fragment_shader_src = "retractions.fs"; + if (!m_buffers[i].init_shader("retractions.vs", "retractions.fs")) + return false; + break; } case GCodeProcessor::EMoveType::Unretract: { - vertex_shader_src = "unretractions.vs"; - fragment_shader_src = "unretractions.fs"; + if (!m_buffers[i].init_shader("unretractions.vs", "unretractions.fs")) + return false; + break; } case GCodeProcessor::EMoveType::Extrude: { - vertex_shader_src = "extrusions.vs"; - fragment_shader_src = "extrusions.fs"; + if (!m_buffers[i].init_shader("extrusions.vs", "extrusions.fs")) + return false; + break; } case GCodeProcessor::EMoveType::Travel: { - vertex_shader_src = "travels.vs"; - fragment_shader_src = "travels.fs"; + if (!m_buffers[i].init_shader("travels.vs", "travels.fs")) + return false; + break; } default: @@ -140,12 +177,6 @@ bool GCodeViewer::init_shaders() break; } } - - if (!shader.init(vertex_shader_src, fragment_shader_src)) - { - BOOST_LOG_TRIVIAL(error) << "Unable to initialize toolpaths shader: please, check that the files " << vertex_shader_src << " and " << fragment_shader_src << " are available"; - return false; - } } if (!m_shells.shader.init("shells.vs", "shells.fs")) @@ -203,13 +234,20 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) case GCodeProcessor::EMoveType::Retract: case GCodeProcessor::EMoveType::Unretract: { + buffer.add_path(curr.type, curr.extrusion_role); buffer.data.push_back(static_cast(i)); break; } case GCodeProcessor::EMoveType::Extrude: case GCodeProcessor::EMoveType::Travel: { - buffer.data.push_back(static_cast(i - 1)); + if (prev.type != curr.type) + { + buffer.add_path(curr.type, curr.extrusion_role); + buffer.data.push_back(static_cast(i - 1)); + } + + buffer.paths.back().last = static_cast(buffer.data.size()); buffer.data.push_back(static_cast(i)); break; } @@ -387,16 +425,26 @@ void GCodeViewer::render_toolpaths() const } case GCodeProcessor::EMoveType::Extrude: { - std::array color = { 1.0f, 0.0f, 0.0f, 1.0f }; - set_color(current_program_id, color); - glsafe(::glDrawElements(GL_LINES, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); + for (const Path& path : buffer.paths) + { + unsigned int color_id = static_cast(path.role); + if (color_id >= erCount) + color_id = 0; + + set_color(current_program_id, m_extrusion_role_colors[color_id]); + + glsafe(::glDrawElements(GL_LINE_STRIP, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); + } break; } case GCodeProcessor::EMoveType::Travel: { std::array color = { 1.0f, 1.0f, 0.0f, 1.0f }; set_color(current_program_id, color); - glsafe(::glDrawElements(GL_LINES, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); + for (const Path& path : buffer.paths) + { + glsafe(::glDrawElements(GL_LINE_STRIP, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); + } break; } } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 6d6a6f8e01..e44fb01800 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -7,14 +7,14 @@ #include "3DScene.hpp" #include "libslic3r/GCode/GCodeProcessor.hpp" -#include - namespace Slic3r { class Print; namespace GUI { class GCodeViewer { + static const std::array, erCount> Default_Extrusion_Role_Colors; + // buffer containing vertices data struct VBuffer { @@ -29,16 +29,30 @@ class GCodeViewer static size_t vertex_size_bytes() { return vertex_size() * sizeof(float); } }; - // buffer containing indices data + struct Path + { + GCodeProcessor::EMoveType type{ GCodeProcessor::EMoveType::Noop }; + ExtrusionRole role{ erNone }; + unsigned int first{ 0 }; + unsigned int last{ 0 }; + + bool matches(GCodeProcessor::EMoveType type, ExtrusionRole role) const { return this->type == type && this->role == role; } + }; + + // buffer containing indices data and shader for a specific toolpath type struct IBuffer { unsigned int ibo_id{ 0 }; Shader shader; std::vector data; size_t data_size{ 0 }; + std::vector paths; bool visible{ false }; void reset(); + bool init_shader(const std::string& vertex_shader_src, const std::string& fragment_shader_src); + + void add_path(GCodeProcessor::EMoveType type, ExtrusionRole role); }; struct Shells @@ -55,11 +69,17 @@ class GCodeViewer std::vector m_layers_zs; Shells m_shells; + std::array, erCount> m_extrusion_role_colors; + public: GCodeViewer() = default; ~GCodeViewer() { reset(); } - bool init() { set_toolpath_visible(GCodeProcessor::EMoveType::Extrude, true); return init_shaders(); } + bool init() { + m_extrusion_role_colors = Default_Extrusion_Role_Colors; + set_toolpath_visible(GCodeProcessor::EMoveType::Extrude, true); + return init_shaders(); + } void load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized); void reset(); void render() const; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 4b8ca69d21..c7c3eaaf59 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2140,6 +2140,9 @@ void GLCanvas3D::render() // we need to set the mouse's scene position here because the depth buffer // could be invalidated by the following gizmo render methods // this position is used later into on_mouse() to drag the objects +#if ENABLE_GCODE_VIEWER + if (m_picking_enabled) +#endif // ENABLE_GCODE_VIEWER m_mouse.scene_position = _mouse_to_3d(m_mouse.position.cast()); _render_current_gizmo(); From 7b0e35e70d8cc63343d4ca9b57769e870728a977 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 16 Apr 2020 15:59:36 +0200 Subject: [PATCH 019/255] GCodeViewer -> Selection of extrusions view type --- src/slic3r/GUI/GCodeViewer.cpp | 36 ++++++++++++++++++++++++++++------ src/slic3r/GUI/GCodeViewer.hpp | 25 +++++++++++++++++++++++ src/slic3r/GUI/GLCanvas3D.cpp | 5 +++++ src/slic3r/GUI/GLCanvas3D.hpp | 1 + src/slic3r/GUI/GUI_Preview.cpp | 7 +++++++ 5 files changed, 68 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index a554ecb8ba..d6fc7fd8ef 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -354,6 +354,35 @@ void GCodeViewer::load_shells(const Print& print, bool initialized) void GCodeViewer::render_toolpaths() const { + auto extrusion_color = [this](const Path& path) { + std::array color; + switch (m_view_type) + { + case EViewType::FeatureType: + { + unsigned int color_id = static_cast(path.role); + if (color_id >= erCount) + color_id = 0; + + color = m_extrusion_role_colors[color_id]; + break; + } + case EViewType::Height: + case EViewType::Width: + case EViewType::Feedrate: + case EViewType::FanSpeed: + case EViewType::VolumetricRate: + case EViewType::Tool: + case EViewType::ColorPrint: + default: + { + color = { 1.0f, 1.0f, 1.0f, 1.0f }; + break; + } + } + return color; + }; + auto set_color = [](GLint current_program_id, const std::array& color) { if (current_program_id > 0) { GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1; @@ -427,12 +456,7 @@ void GCodeViewer::render_toolpaths() const { for (const Path& path : buffer.paths) { - unsigned int color_id = static_cast(path.role); - if (color_id >= erCount) - color_id = 0; - - set_color(current_program_id, m_extrusion_role_colors[color_id]); - + set_color(current_program_id, extrusion_color(path)); glsafe(::glDrawElements(GL_LINE_STRIP, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); } break; diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index e44fb01800..9bc644c4eb 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -62,6 +62,21 @@ class GCodeViewer Shader shader; }; +public: + enum class EViewType : unsigned char + { + FeatureType, + Height, + Width, + Feedrate, + FanSpeed, + VolumetricRate, + Tool, + ColorPrint, + Count + }; + +private: VBuffer m_vertices; std::vector m_buffers{ static_cast(GCodeProcessor::EMoveType::Extrude) }; @@ -71,6 +86,8 @@ class GCodeViewer std::array, erCount> m_extrusion_role_colors; + EViewType m_view_type{ EViewType::FeatureType }; + public: GCodeViewer() = default; ~GCodeViewer() { reset(); } @@ -86,6 +103,14 @@ public: const std::vector& get_layers_zs() const { return m_layers_zs; }; + EViewType get_view_type() const { return m_view_type; } + void set_view_type(EViewType type) { + if (type == EViewType::Count) + type = EViewType::FeatureType; + + m_view_type = type; + } + bool is_toolpath_visible(GCodeProcessor::EMoveType type) const; void set_toolpath_visible(GCodeProcessor::EMoveType type, bool visible); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index c7c3eaaf59..9f3c9653c5 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2323,6 +2323,11 @@ void GLCanvas3D::set_toolpath_visible(GCodeProcessor::EMoveType type, bool visib m_gcode_viewer.set_toolpath_visible(type, visible); } +void GLCanvas3D::set_toolpath_view_type(GCodeViewer::EViewType type) +{ + m_gcode_viewer.set_view_type(type); +} + void GLCanvas3D::set_shells_visible(bool visible) { m_gcode_viewer.set_shells_visible(visible); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 7033f05a0b..246a298fe4 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -642,6 +642,7 @@ public: #if ENABLE_GCODE_VIEWER const std::vector& get_layers_zs() const; void set_toolpath_visible(GCodeProcessor::EMoveType type, bool visible); + void set_toolpath_view_type(GCodeViewer::EViewType type); void set_shells_visible(bool visible); #else std::vector get_current_print_zs(bool active_only) const; diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 0c4f655c58..f2a56e8a20 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -602,10 +602,17 @@ void Preview::on_choice_view_type(wxCommandEvent& evt) { m_preferred_color_mode = (m_choice_view_type->GetStringSelection() == L("Tool")) ? "tool" : "feature"; int selection = m_choice_view_type->GetCurrentSelection(); +#if ENABLE_GCODE_VIEWER + if (0 <= selection && selection < static_cast(GCodeViewer::EViewType::Count)) + m_canvas->set_toolpath_view_type(static_cast(selection)); + + refresh_print(); +#else if ((0 <= selection) && (selection < (int)GCodePreviewData::Extrusion::Num_View_Types)) m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)selection; reload_print(); +#endif // ENABLE_GCODE_VIEWER } void Preview::on_combochecklist_features(wxCommandEvent& evt) From 9776d7c5a1333787ae88915b6f8e1b01380953cf Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 17 Apr 2020 10:43:29 +0200 Subject: [PATCH 020/255] GCodeViewer -> Toggle visibility of extrusions roles --- src/slic3r/GUI/GCodeViewer.cpp | 12 ++++++++++-- src/slic3r/GUI/GCodeViewer.hpp | 29 +++++++++++++++++++++++------ src/slic3r/GUI/GLCanvas3D.cpp | 9 +++++++-- src/slic3r/GUI/GLCanvas3D.hpp | 3 ++- src/slic3r/GUI/GUI_Preview.cpp | 13 ++++++++++--- 5 files changed, 52 insertions(+), 14 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index d6fc7fd8ef..fb899164d3 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -104,6 +104,7 @@ void GCodeViewer::reset() buffer.reset(); } + m_extrusions.reset_role_visibility_flags(); m_shells.volumes.clear(); m_layers_zs = std::vector(); } @@ -121,7 +122,7 @@ bool GCodeViewer::is_toolpath_visible(GCodeProcessor::EMoveType type) const return (id < m_buffers.size()) ? m_buffers[id].visible : false; } -void GCodeViewer::set_toolpath_visible(GCodeProcessor::EMoveType type, bool visible) +void GCodeViewer::set_toolpath_move_type_visible(GCodeProcessor::EMoveType type, bool visible) { size_t id = static_cast(buffer_id(type)); if (id < m_buffers.size()) @@ -364,7 +365,7 @@ void GCodeViewer::render_toolpaths() const if (color_id >= erCount) color_id = 0; - color = m_extrusion_role_colors[color_id]; + color = m_extrusions.role_colors[color_id]; break; } case EViewType::Height: @@ -394,6 +395,10 @@ void GCodeViewer::render_toolpaths() const BOOST_LOG_TRIVIAL(error) << "Unable to find uniform_color uniform"; }; + auto is_path_visible = [](unsigned int flags, const Path& path) { + return Extrusions::is_role_visible(flags, path.role); + }; + glsafe(::glCullFace(GL_BACK)); unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); @@ -456,6 +461,9 @@ void GCodeViewer::render_toolpaths() const { for (const Path& path : buffer.paths) { + if (!is_path_visible(m_extrusions.role_visibility_flags, path)) + continue; + set_color(current_program_id, extrusion_color(path)); glsafe(::glDrawElements(GL_LINE_STRIP, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 9bc644c4eb..1020606b86 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -62,6 +62,24 @@ class GCodeViewer Shader shader; }; + struct Extrusions + { + std::array, erCount> role_colors; + unsigned int role_visibility_flags{ 0 }; + + void reset_role_visibility_flags() { + role_visibility_flags = 0; + for (unsigned int i = 0; i < erCount; ++i) + { + role_visibility_flags |= 1 << i; + } + } + + static bool is_role_visible(unsigned int flags, ExtrusionRole role) { + return role < erCount && (flags & (1 << role)) != 0; + } + }; + public: enum class EViewType : unsigned char { @@ -82,10 +100,8 @@ private: unsigned int m_last_result_id{ 0 }; std::vector m_layers_zs; + Extrusions m_extrusions; Shells m_shells; - - std::array, erCount> m_extrusion_role_colors; - EViewType m_view_type{ EViewType::FeatureType }; public: @@ -93,8 +109,8 @@ public: ~GCodeViewer() { reset(); } bool init() { - m_extrusion_role_colors = Default_Extrusion_Role_Colors; - set_toolpath_visible(GCodeProcessor::EMoveType::Extrude, true); + m_extrusions.role_colors = Default_Extrusion_Role_Colors; + set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Extrude, true); return init_shaders(); } void load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized); @@ -112,7 +128,8 @@ public: } bool is_toolpath_visible(GCodeProcessor::EMoveType type) const; - void set_toolpath_visible(GCodeProcessor::EMoveType type, bool visible); + void set_toolpath_move_type_visible(GCodeProcessor::EMoveType type, bool visible); + void set_toolpath_role_visibility_flags(unsigned int flags) { m_extrusions.role_visibility_flags = flags; } bool are_shells_visible() const { return m_shells.visible; } void set_shells_visible(bool visible) { m_shells.visible = visible; } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 8d01d2c566..fcefc8f8a8 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2322,9 +2322,14 @@ const std::vector& GLCanvas3D::get_layers_zs() const return m_gcode_viewer.get_layers_zs(); } -void GLCanvas3D::set_toolpath_visible(GCodeProcessor::EMoveType type, bool visible) +void GLCanvas3D::set_toolpath_move_type_visible(GCodeProcessor::EMoveType type, bool visible) { - m_gcode_viewer.set_toolpath_visible(type, visible); + m_gcode_viewer.set_toolpath_move_type_visible(type, visible); +} + +void GLCanvas3D::set_toolpath_role_visibility_flags(unsigned int flags) +{ + m_gcode_viewer.set_toolpath_role_visibility_flags(flags); } void GLCanvas3D::set_toolpath_view_type(GCodeViewer::EViewType type) diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 246a298fe4..fce805b51d 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -641,7 +641,8 @@ public: #if ENABLE_GCODE_VIEWER const std::vector& get_layers_zs() const; - void set_toolpath_visible(GCodeProcessor::EMoveType type, bool visible); + void set_toolpath_move_type_visible(GCodeProcessor::EMoveType type, bool visible); + void set_toolpath_role_visibility_flags(unsigned int flags); void set_toolpath_view_type(GCodeViewer::EViewType type); void set_shells_visible(bool visible); #else diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index f2a56e8a20..6b13304c0e 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -308,6 +308,9 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view m_combochecklist_features->Create(this, wxID_ANY, _(L("Feature types")), wxDefaultPosition, wxSize(15 * wxGetApp().em_unit(), -1), wxCB_READONLY); std::string feature_text = GUI::into_u8(_(L("Feature types"))); std::string feature_items = GUI::into_u8( +#if ENABLE_GCODE_VIEWER + _L("Unknown") + "|" + +#endif // ENABLE_GCODE_VIEWER _(L("Perimeter")) + "|" + _(L("External perimeter")) + "|" + _(L("Overhang perimeter")) + "|" + @@ -618,14 +621,18 @@ void Preview::on_choice_view_type(wxCommandEvent& evt) void Preview::on_combochecklist_features(wxCommandEvent& evt) { int flags = Slic3r::GUI::combochecklist_get_flags(m_combochecklist_features); +#if ENABLE_GCODE_VIEWER + m_canvas->set_toolpath_role_visibility_flags(static_cast(flags)); +#else m_gcode_preview_data->extrusion.role_flags = (unsigned int)flags; +#endif // ENABLE_GCODE_VIEWER refresh_print(); } void Preview::on_checkbox_travel(wxCommandEvent& evt) { #if ENABLE_GCODE_VIEWER - m_canvas->set_toolpath_visible(GCodeProcessor::EMoveType::Travel, m_checkbox_travel->IsChecked()); + m_canvas->set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Travel, m_checkbox_travel->IsChecked()); refresh_print(); #else m_gcode_preview_data->travel.is_visible = m_checkbox_travel->IsChecked(); @@ -638,7 +645,7 @@ void Preview::on_checkbox_travel(wxCommandEvent& evt) void Preview::on_checkbox_retractions(wxCommandEvent& evt) { #if ENABLE_GCODE_VIEWER - m_canvas->set_toolpath_visible(GCodeProcessor::EMoveType::Retract, m_checkbox_retractions->IsChecked()); + m_canvas->set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Retract, m_checkbox_retractions->IsChecked()); #else m_gcode_preview_data->retraction.is_visible = m_checkbox_retractions->IsChecked(); #endif // ENABLE_GCODE_VIEWER @@ -648,7 +655,7 @@ void Preview::on_checkbox_retractions(wxCommandEvent& evt) void Preview::on_checkbox_unretractions(wxCommandEvent& evt) { #if ENABLE_GCODE_VIEWER - m_canvas->set_toolpath_visible(GCodeProcessor::EMoveType::Unretract, m_checkbox_unretractions->IsChecked()); + m_canvas->set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Unretract, m_checkbox_unretractions->IsChecked()); #else m_gcode_preview_data->unretraction.is_visible = m_checkbox_unretractions->IsChecked(); #endif // ENABLE_GCODE_VIEWER From 83816afb3f9a09050769e5896d50de2f9205fa72 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 17 Apr 2020 13:28:25 +0200 Subject: [PATCH 021/255] GCodeViewer -> Added bounding box to fix camera frustum tighting --- src/slic3r/GUI/GCodeViewer.cpp | 4 +++- src/slic3r/GUI/GCodeViewer.hpp | 2 ++ src/slic3r/GUI/GLCanvas3D.cpp | 9 +++++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index fb899164d3..e458d933bb 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -104,6 +104,7 @@ void GCodeViewer::reset() buffer.reset(); } + m_bounding_box = BoundingBoxf3(); m_extrusions.reset_role_visibility_flags(); m_shells.volumes.clear(); m_layers_zs = std::vector(); @@ -198,13 +199,14 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) if (m_vertices.vertices_count == 0) return; - // vertex data -> extract from result + // vertex data / bounding box -> extract from result std::vector vertices_data; for (const GCodeProcessor::MoveVertex& move : gcode_result.moves) { for (int j = 0; j < 3; ++j) { vertices_data.insert(vertices_data.end(), move.position[j]); + m_bounding_box.merge(move.position.cast()); } } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 1020606b86..aff2a807dd 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -97,6 +97,7 @@ public: private: VBuffer m_vertices; std::vector m_buffers{ static_cast(GCodeProcessor::EMoveType::Extrude) }; + BoundingBoxf3 m_bounding_box; unsigned int m_last_result_id{ 0 }; std::vector m_layers_zs; @@ -117,6 +118,7 @@ public: void reset(); void render() const; + const BoundingBoxf3& get_bounding_box() const { return m_bounding_box; } const std::vector& get_layers_zs() const { return m_layers_zs; }; EViewType get_view_type() const { return m_view_type; } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index fcefc8f8a8..604f98a79c 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2841,9 +2841,8 @@ void GLCanvas3D::load_gcode_preview_2(const GCodeProcessor::Result& gcode_result } out.close(); } - - m_gcode_viewer.load(gcode_result , *this->fff_print(), m_initialized); #endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT + m_gcode_viewer.load(gcode_result, *this->fff_print(), m_initialized); } #endif // ENABLE_GCODE_VIEWER @@ -5213,6 +5212,12 @@ BoundingBoxf3 GLCanvas3D::_max_bounding_box(bool include_gizmos, bool include_be #else bb.merge(m_bed.get_bounding_box(include_bed_model)); #endif // ENABLE_NON_STATIC_CANVAS_MANAGER + +#if ENABLE_GCODE_VIEWER + if (!m_main_toolbar.is_enabled()) + bb.merge(m_gcode_viewer.get_bounding_box()); +#endif // ENABLE_GCODE_VIEWER + return bb; } From 3a07e8730f0888fd3a401aa375d19b073e08c865 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Sat, 18 Apr 2020 10:41:37 +0200 Subject: [PATCH 022/255] GCodeViewer -> Basic legend using imgui --- src/libslic3r/ExtrusionEntity.cpp | 4 ++ src/slic3r/GUI/GCodeViewer.cpp | 85 +++++++++++++++++++++++++++---- src/slic3r/GUI/GCodeViewer.hpp | 6 +++ src/slic3r/GUI/GLCanvas3D.cpp | 4 ++ 4 files changed, 90 insertions(+), 9 deletions(-) diff --git a/src/libslic3r/ExtrusionEntity.cpp b/src/libslic3r/ExtrusionEntity.cpp index c0d08c84b7..0b09d16020 100644 --- a/src/libslic3r/ExtrusionEntity.cpp +++ b/src/libslic3r/ExtrusionEntity.cpp @@ -306,7 +306,11 @@ double ExtrusionLoop::min_mm3_per_mm() const std::string ExtrusionEntity::role_to_string(ExtrusionRole role) { switch (role) { +#if ENABLE_GCODE_VIEWER + case erNone : return L("Unknown"); +#else case erNone : return L("None"); +#endif // ENABLE_GCODE_VIEWER case erPerimeter : return L("Perimeter"); case erExternalPerimeter : return L("External perimeter"); case erOverhangPerimeter : return L("Overhang perimeter"); diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index e458d933bb..be05030da2 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -6,6 +6,8 @@ #include "GUI_App.hpp" #include "PresetBundle.hpp" #include "Camera.hpp" +#include "I18N.hpp" +#include "libslic3r/I18N.hpp" #include #include @@ -108,6 +110,7 @@ void GCodeViewer::reset() m_extrusions.reset_role_visibility_flags(); m_shells.volumes.clear(); m_layers_zs = std::vector(); + m_roles = std::vector(); } void GCodeViewer::render() const @@ -115,6 +118,7 @@ void GCodeViewer::render() const glsafe(::glEnable(GL_DEPTH_TEST)); render_toolpaths(); render_shells(); + render_overlay(); } bool GCodeViewer::is_toolpath_visible(GCodeProcessor::EMoveType type) const @@ -277,17 +281,17 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) } } - // layers zs -> extract from result + // layers zs / roles -> extract from result for (const GCodeProcessor::MoveVertex& move : gcode_result.moves) { if (move.type == GCodeProcessor::EMoveType::Extrude) m_layers_zs.emplace_back(move.position[2]); + + m_roles.emplace_back(move.extrusion_role); } - // layers zs -> sort - std::sort(m_layers_zs.begin(), m_layers_zs.end()); - // layers zs -> replace intervals of layers with similar top positions with their average value. + std::sort(m_layers_zs.begin(), m_layers_zs.end()); int n = int(m_layers_zs.size()); int k = 0; for (int i = 0; i < n;) { @@ -300,6 +304,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) if (k < n) m_layers_zs.erase(m_layers_zs.begin() + k, m_layers_zs.end()); + // roles -> remove duplicates + std::sort(m_roles.begin(), m_roles.end()); + m_roles.erase(std::unique(m_roles.begin(), m_roles.end()), m_roles.end()); + auto end_time = std::chrono::high_resolution_clock::now(); std::cout << "toolpaths generation time: " << std::chrono::duration_cast(end_time - start_time).count() << "ms \n"; } @@ -363,11 +371,7 @@ void GCodeViewer::render_toolpaths() const { case EViewType::FeatureType: { - unsigned int color_id = static_cast(path.role); - if (color_id >= erCount) - color_id = 0; - - color = m_extrusions.role_colors[color_id]; + color = m_extrusions.role_colors[static_cast(path.role)]; break; } case EViewType::Height: @@ -506,6 +510,69 @@ void GCodeViewer::render_shells() const // glsafe(::glDepthMask(GL_TRUE)); } +void GCodeViewer::render_overlay() const +{ + static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); + static const float ICON_SIZE = 20.0f; + static const ImU32 ICON_BORDER_COLOR = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); + + if (!m_legend_enabled || m_roles.empty()) + return; + + ImGuiWrapper& imgui = *wxGetApp().imgui(); + + imgui.set_next_window_pos(0, 0, ImGuiCond_Always); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + imgui.begin(_L("Legend"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); + + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + switch (m_view_type) + { + case EViewType::FeatureType: { imgui.text(Slic3r::I18N::translate(L("Feature type"))); break; } + case EViewType::Height: { imgui.text(Slic3r::I18N::translate(L("Height (mm)"))); break; } + case EViewType::Width: { imgui.text(Slic3r::I18N::translate(L("Width (mm)"))); break; } + case EViewType::Feedrate: { imgui.text(Slic3r::I18N::translate(L("Speed (mm/s)"))); break; } + case EViewType::FanSpeed: { imgui.text(Slic3r::I18N::translate(L("Fan Speed (%)"))); break; } + case EViewType::VolumetricRate: { imgui.text(Slic3r::I18N::translate(L("Volumetric flow rate (mm³/s)"))); break; } + case EViewType::Tool: { imgui.text(Slic3r::I18N::translate(L("Tool"))); break; } + case EViewType::ColorPrint: { imgui.text(Slic3r::I18N::translate(L("Color Print"))); break; } + } + ImGui::PopStyleColor(); + + ImGui::Separator(); + + switch (m_view_type) + { + case EViewType::FeatureType: + { + for (ExtrusionRole role : m_roles) + { + ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f); + draw_list->AddRect(ImVec2(pos.x, pos.y), ImVec2(pos.x + ICON_SIZE, pos.y + ICON_SIZE), ICON_BORDER_COLOR, 0.0f, 0); + const std::array& role_color = m_extrusions.role_colors[static_cast(role)]; + ImU32 fill_color = ImGui::GetColorU32(ImVec4(role_color[0], role_color[1], role_color[2], role_color[3])); + draw_list->AddRectFilled(ImVec2(pos.x + 1.0f, pos.y + 1.0f), ImVec2(pos.x + ICON_SIZE - 1.0f, pos.y + ICON_SIZE - 1.0f), fill_color); + ImGui::SetCursorPosX(pos.x + ICON_SIZE + 4.0f); + ImGui::AlignTextToFramePadding(); + imgui.text(Slic3r::I18N::translate(ExtrusionEntity::role_to_string(role))); + } + break; + } + case EViewType::Height: { break; } + case EViewType::Width: { break; } + case EViewType::Feedrate: { break; } + case EViewType::FanSpeed: { break; } + case EViewType::VolumetricRate: { break; } + case EViewType::Tool: { break; } + case EViewType::ColorPrint: { break; } + } + + imgui.end(); + ImGui::PopStyleVar(); +} + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index aff2a807dd..4ee187144c 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -101,9 +101,11 @@ private: unsigned int m_last_result_id{ 0 }; std::vector m_layers_zs; + std::vector m_roles; Extrusions m_extrusions; Shells m_shells; EViewType m_view_type{ EViewType::FeatureType }; + bool m_legend_enabled{ true }; public: GCodeViewer() = default; @@ -136,12 +138,16 @@ public: bool are_shells_visible() const { return m_shells.visible; } void set_shells_visible(bool visible) { m_shells.visible = visible; } + bool is_legend_enabled() const { return m_legend_enabled; } + void enable_legend(bool enable) { m_legend_enabled = enable; } + private: bool init_shaders(); void load_toolpaths(const GCodeProcessor::Result& gcode_result); void load_shells(const Print& print, bool initialized); void render_toolpaths() const; void render_shells() const; + void render_overlay() const; }; } // namespace GUI diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 604f98a79c..ac773102ce 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1941,7 +1941,11 @@ void GLCanvas3D::enable_layers_editing(bool enable) void GLCanvas3D::enable_legend_texture(bool enable) { +#if ENABLE_GCODE_VIEWER + m_gcode_viewer.enable_legend(enable); +#else m_legend_texture_enabled = enable; +#endif // ENABLE_GCODE_VIEWER } void GLCanvas3D::enable_picking(bool enable) From 179dbc7d0e10c6a7d76f1a0438de78d19e3d4e03 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Sat, 18 Apr 2020 11:49:20 +0200 Subject: [PATCH 023/255] Tech ENABLE_GCODE_VIEWER -> removed legend texture from GLCanvas3D --- src/slic3r/GUI/GCodeViewer.cpp | 8 ++++---- src/slic3r/GUI/GLCanvas3D.cpp | 14 ++++++++++++++ src/slic3r/GUI/GLCanvas3D.hpp | 12 ++++++++++++ src/slic3r/GUI/GUI_Preview.cpp | 5 ++++- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index be05030da2..1c828198da 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -513,7 +513,7 @@ void GCodeViewer::render_shells() const void GCodeViewer::render_overlay() const { static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); - static const float ICON_SIZE = 20.0f; + static const float ICON_BORDER_SIZE = 20.0f; static const ImU32 ICON_BORDER_COLOR = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); if (!m_legend_enabled || m_roles.empty()) @@ -550,11 +550,11 @@ void GCodeViewer::render_overlay() const for (ExtrusionRole role : m_roles) { ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f); - draw_list->AddRect(ImVec2(pos.x, pos.y), ImVec2(pos.x + ICON_SIZE, pos.y + ICON_SIZE), ICON_BORDER_COLOR, 0.0f, 0); + draw_list->AddRect(ImVec2(pos.x, pos.y), ImVec2(pos.x + ICON_BORDER_SIZE, pos.y + ICON_BORDER_SIZE), ICON_BORDER_COLOR, 0.0f, 0); const std::array& role_color = m_extrusions.role_colors[static_cast(role)]; ImU32 fill_color = ImGui::GetColorU32(ImVec4(role_color[0], role_color[1], role_color[2], role_color[3])); - draw_list->AddRectFilled(ImVec2(pos.x + 1.0f, pos.y + 1.0f), ImVec2(pos.x + ICON_SIZE - 1.0f, pos.y + ICON_SIZE - 1.0f), fill_color); - ImGui::SetCursorPosX(pos.x + ICON_SIZE + 4.0f); + draw_list->AddRectFilled(ImVec2(pos.x + 1.0f, pos.y + 1.0f), ImVec2(pos.x + ICON_BORDER_SIZE - 1.0f, pos.y + ICON_BORDER_SIZE - 1.0f), fill_color); + ImGui::SetCursorPosX(pos.x + ICON_BORDER_SIZE + 4.0f); ImGui::AlignTextToFramePadding(); imgui.text(Slic3r::I18N::translate(ExtrusionEntity::role_to_string(role))); } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ac773102ce..8c3af4a587 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -901,6 +901,7 @@ void GLCanvas3D::WarningTexture::msw_rescale(const GLCanvas3D& canvas) generate(m_msg_text, canvas, true, m_is_colored_red); } +#if !ENABLE_GCODE_VIEWER const unsigned char GLCanvas3D::LegendTexture::Squares_Border_Color[3] = { 64, 64, 64 }; const unsigned char GLCanvas3D::LegendTexture::Default_Background_Color[3] = { (unsigned char)(DEFAULT_BG_LIGHT_COLOR[0] * 255.0f), (unsigned char)(DEFAULT_BG_LIGHT_COLOR[1] * 255.0f), (unsigned char)(DEFAULT_BG_LIGHT_COLOR[2] * 255.0f) }; const unsigned char GLCanvas3D::LegendTexture::Error_Background_Color[3] = { (unsigned char)(ERROR_BG_LIGHT_COLOR[0] * 255.0f), (unsigned char)(ERROR_BG_LIGHT_COLOR[1] * 255.0f), (unsigned char)(ERROR_BG_LIGHT_COLOR[2] * 255.0f) }; @@ -1267,6 +1268,7 @@ void GLCanvas3D::LegendTexture::render(const GLCanvas3D& canvas) const GLTexture::render_sub_texture(m_id, left, right, bottom, top, uvs); } } +#endif // !ENABLE_GCODE_VIEWER void GLCanvas3D::Labels::render(const std::vector& sorted_instances) const { @@ -1574,7 +1576,9 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar , m_dirty(true) , m_initialized(false) , m_apply_zoom_to_volumes_filter(false) +#if !ENABLE_GCODE_VIEWER , m_legend_texture_enabled(false) +#endif // !ENABLE_GCODE_VIEWER , m_picking_enabled(false) , m_moving_enabled(false) , m_dynamic_background_enabled(false) @@ -2953,6 +2957,7 @@ void GLCanvas3D::load_preview(const std::vector& str_tool_colors, c _update_toolpath_volumes_outside_state(); _show_warning_texture_if_needed(WarningTexture::ToolpathOutside); +#if !ENABLE_GCODE_VIEWER if (color_print_values.empty()) reset_legend_texture(); else { @@ -2961,6 +2966,7 @@ void GLCanvas3D::load_preview(const std::vector& str_tool_colors, c const std::vector tool_colors = _parse_colors(str_tool_colors); _generate_legend_texture(preview_data, tool_colors); } +#endif // !ENABLE_GCODE_VIEWER } void GLCanvas3D::bind_event_handlers() @@ -4080,6 +4086,7 @@ Vec2d GLCanvas3D::get_local_mouse_position() const return Vec2d(factor * mouse_pos.x, factor * mouse_pos.y); } +#if !ENABLE_GCODE_VIEWER void GLCanvas3D::reset_legend_texture() { if (m_legend_texture.get_id() != 0) @@ -4088,6 +4095,7 @@ void GLCanvas3D::reset_legend_texture() m_legend_texture.reset(); } } +#endif // !ENABLE_GCODE_VIEWER void GLCanvas3D::set_tooltip(const std::string& tooltip) const { @@ -5556,7 +5564,9 @@ void GLCanvas3D::_render_overlays() const _render_gizmos_overlay(); _render_warning_texture(); +#if !ENABLE_GCODE_VIEWER _render_legend_texture(); +#endif // !ENABLE_GCODE_VIEWER // main toolbar and undoredo toolbar need to be both updated before rendering because both their sizes are needed // to correctly place them @@ -5600,6 +5610,7 @@ void GLCanvas3D::_render_warning_texture() const m_warning_texture.render(*this); } +#if !ENABLE_GCODE_VIEWER void GLCanvas3D::_render_legend_texture() const { if (!m_legend_texture_enabled) @@ -5607,6 +5618,7 @@ void GLCanvas3D::_render_legend_texture() const m_legend_texture.render(*this); } +#endif // !ENABLE_GCODE_VIEWER void GLCanvas3D::_render_volumes_for_picking() const { @@ -7096,10 +7108,12 @@ std::vector GLCanvas3D::_parse_colors(const std::vector& col return output; } +#if !ENABLE_GCODE_VIEWER void GLCanvas3D::_generate_legend_texture(const GCodePreviewData& preview_data, const std::vector& tool_colors) { m_legend_texture.generate(preview_data, tool_colors, *this, true); } +#endif // !ENABLE_GCODE_VIEWER void GLCanvas3D::_set_warning_texture(WarningTexture::Warning warning, bool state) { diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index fce805b51d..af1f6149c8 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -345,6 +345,7 @@ private: bool generate(const std::string& msg, const GLCanvas3D& canvas, bool compress, bool red_colored = false); }; +#if !ENABLE_GCODE_VIEWER class LegendTexture : public GUI::GLTexture { static const int Px_Title_Offset = 5; @@ -371,6 +372,7 @@ private: void render(const GLCanvas3D& canvas) const; }; +#endif // !ENABLE_GCODE_VIEWER #if ENABLE_RENDER_STATISTICS struct RenderStats @@ -445,7 +447,9 @@ private: std::unique_ptr m_retina_helper; #endif bool m_in_render; +#if !ENABLE_GCODE_VIEWER LegendTexture m_legend_texture; +#endif // !ENABLE_GCODE_VIEWER WarningTexture m_warning_texture; wxTimer m_timer; #if !ENABLE_NON_STATIC_CANVAS_MANAGER @@ -483,7 +487,9 @@ private: bool m_initialized; bool m_apply_zoom_to_volumes_filter; mutable std::vector m_hover_volume_idxs; +#if !ENABLE_GCODE_VIEWER bool m_legend_texture_enabled; +#endif // !ENABLE_GCODE_VIEWER bool m_picking_enabled; bool m_moving_enabled; bool m_dynamic_background_enabled; @@ -679,7 +685,9 @@ public: Size get_canvas_size() const; Vec2d get_local_mouse_position() const; +#if !ENABLE_GCODE_VIEWER void reset_legend_texture(); +#endif // !ENABLE_GCODE_VIEWER void set_tooltip(const std::string& tooltip) const; @@ -790,7 +798,9 @@ private: #endif // ENABLE_RENDER_SELECTION_CENTER void _render_overlays() const; void _render_warning_texture() const; +#if !ENABLE_GCODE_VIEWER void _render_legend_texture() const; +#endif // !ENABLE_GCODE_VIEWER void _render_volumes_for_picking() const; void _render_current_gizmo() const; void _render_gizmos_overlay() const; @@ -852,8 +862,10 @@ private: void _update_sla_shells_outside_state(); void _show_warning_texture_if_needed(WarningTexture::Warning warning); +#if !ENABLE_GCODE_VIEWER // generates the legend texture in dependence of the current shown view type void _generate_legend_texture(const GCodePreviewData& preview_data, const std::vector& tool_colors); +#endif // !ENABLE_GCODE_VIEWER // generates a warning texture containing the given message void _set_warning_texture(WarningTexture::Warning warning, bool state); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 6b13304c0e..562058dd95 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -479,8 +479,9 @@ void Preview::reload_print(bool keep_volumes) m_canvas->reset_volumes(); #if ENABLE_GCODE_VIEWER m_canvas->reset_gcode_toolpaths(); -#endif // ENABLE_GCODE_VIEWER +#else m_canvas->reset_legend_texture(); +#endif // ENABLE_GCODE_VIEWER m_loaded = false; #ifdef __linux__ m_volumes_cleanup_required = false; @@ -937,7 +938,9 @@ void Preview::load_print_as_fff(bool keep_z_range) if (! has_layers) { reset_sliders(true); +#if !ENABLE_GCODE_VIEWER m_canvas->reset_legend_texture(); +#endif // !ENABLE_GCODE_VIEWER m_canvas_widget->Refresh(); return; } From 6e5a6f3b43f7a29c6bd0d79207068298772c5be4 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 20 Apr 2020 10:52:16 +0200 Subject: [PATCH 024/255] GCodeViewer -> Extrusion toolpaths colored by height --- src/libslic3r/GCode/PreviewData.hpp | 11 ++-- src/slic3r/GUI/GCodeViewer.cpp | 88 +++++++++++++++++++++++++---- src/slic3r/GUI/GCodeViewer.hpp | 58 ++++++++++++++++++- 3 files changed, 137 insertions(+), 20 deletions(-) diff --git a/src/libslic3r/GCode/PreviewData.hpp b/src/libslic3r/GCode/PreviewData.hpp index 35bbfa50ac..c0f768088e 100644 --- a/src/libslic3r/GCode/PreviewData.hpp +++ b/src/libslic3r/GCode/PreviewData.hpp @@ -56,8 +56,7 @@ public: // Color mapping to convert a float into a smooth rainbow of 10 colors. class RangeBase { - public: - + public: virtual void reset() = 0; virtual bool empty() const = 0; virtual float min() const = 0; @@ -73,7 +72,7 @@ public: // Color mapping converting a float in a range between a min and a max into a smooth rainbow of 10 colors. class Range : public RangeBase { - public: + public: Range(); // RangeBase Overrides @@ -97,8 +96,7 @@ public: template class MultiRange : public RangeBase { - public: - + public: void reset() override { bounds = decltype(bounds){}; @@ -160,8 +158,7 @@ public: mode.set(static_cast(range_type_value), enable); } - private: - + private: // Interval bounds struct Bounds { diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 1c828198da..10282642c3 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -59,14 +59,38 @@ bool GCodeViewer::IBuffer::init_shader(const std::string& vertex_shader_src, con return true; } -void GCodeViewer::IBuffer::add_path(GCodeProcessor::EMoveType type, ExtrusionRole role) +void GCodeViewer::IBuffer::add_path(GCodeProcessor::EMoveType type, ExtrusionRole role, float height) { unsigned int id = static_cast(data.size()); - paths.push_back({ type, role, id, id }); + paths.push_back({ type, role, id, id, height }); +} + +std::array GCodeViewer::Extrusions::Range::get_color_at(float value, const std::array, Default_Range_Colors_Count>& colors) const +{ + // Input value scaled to the color range + const float step = step_size(); + const float global_t = (step != 0.0f) ? std::max(0.0f, value - min) / step : 0.0f; // lower limit of 0.0f + + const size_t color_max_idx = colors.size() - 1; + + // Compute the two colors just below (low) and above (high) the input value + const size_t color_low_idx = std::clamp(static_cast(global_t), std::size_t{ 0 }, color_max_idx); + const size_t color_high_idx = std::clamp(color_low_idx + 1, std::size_t{ 0 }, color_max_idx); + + // Compute how far the value is between the low and high colors so that they can be interpolated + const float local_t = std::min(global_t - static_cast(color_low_idx), 1.0f); // upper limit of 1.0f + + // Interpolate between the low and high colors in RGB space to find exactly which color the input value should get + std::array ret; + for (unsigned int i = 0; i < 4; ++i) + { + ret[i] = lerp(colors[color_low_idx][i], colors[color_high_idx][i], local_t); + } + return ret; } const std::array, erCount> GCodeViewer::Default_Extrusion_Role_Colors {{ - { 0.00f, 0.00f, 0.00f, 1.0f }, // erNone + { 1.00f, 1.00f, 1.00f, 1.0f }, // erNone { 1.00f, 1.00f, 0.40f, 1.0f }, // erPerimeter { 1.00f, 0.65f, 0.00f, 1.0f }, // erExternalPerimeter { 0.00f, 0.00f, 1.00f, 1.0f }, // erOverhangPerimeter @@ -83,6 +107,19 @@ const std::array, erCount> GCodeViewer::Default_Extrusion_R { 0.00f, 0.00f, 0.00f, 1.0f } // erMixed }}; +const std::array, GCodeViewer::Default_Range_Colors_Count> GCodeViewer::Default_Range_Colors {{ + { 0.043f, 0.173f, 0.478f, 1.0f }, + { 0.075f, 0.349f, 0.522f, 1.0f }, + { 0.110f, 0.533f, 0.569f, 1.0f }, + { 0.016f, 0.839f, 0.059f, 1.0f }, + { 0.667f, 0.949f, 0.000f, 1.0f }, + { 0.988f, 0.975f, 0.012f, 1.0f }, + { 0.961f, 0.808f, 0.039f, 1.0f }, + { 0.890f, 0.533f, 0.125f, 1.0f }, + { 0.820f, 0.408f, 0.188f, 1.0f }, + { 0.761f, 0.322f, 0.235f, 1.0f } +}}; + void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized) { if (m_last_result_id == gcode_result.id) @@ -108,6 +145,7 @@ void GCodeViewer::reset() m_bounding_box = BoundingBoxf3(); m_extrusions.reset_role_visibility_flags(); + m_extrusions.reset_ranges(); m_shells.volumes.clear(); m_layers_zs = std::vector(); m_roles = std::vector(); @@ -241,17 +279,22 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) case GCodeProcessor::EMoveType::Retract: case GCodeProcessor::EMoveType::Unretract: { - buffer.add_path(curr.type, curr.extrusion_role); + buffer.add_path(curr.type, curr.extrusion_role, curr.height); buffer.data.push_back(static_cast(i)); break; } case GCodeProcessor::EMoveType::Extrude: case GCodeProcessor::EMoveType::Travel: { - if (prev.type != curr.type) + if (prev.type != curr.type || !buffer.paths.back().matches(curr)) { - buffer.add_path(curr.type, curr.extrusion_role); + buffer.add_path(curr.type, curr.extrusion_role, curr.height); buffer.data.push_back(static_cast(i - 1)); + + if (curr.type == GCodeProcessor::EMoveType::Extrude) + { + m_extrusions.ranges.height.update_from(curr.height); + } } buffer.paths.back().last = static_cast(buffer.data.size()); @@ -375,6 +418,10 @@ void GCodeViewer::render_toolpaths() const break; } case EViewType::Height: + { + color = m_extrusions.ranges.height.get_color_at(path.height, m_extrusions.ranges.colors); + break; + } case EViewType::Width: case EViewType::Feedrate: case EViewType::FanSpeed: @@ -513,8 +560,9 @@ void GCodeViewer::render_shells() const void GCodeViewer::render_overlay() const { static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); - static const float ICON_BORDER_SIZE = 20.0f; + static const float ICON_BORDER_SIZE = 25.0f; static const ImU32 ICON_BORDER_COLOR = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); + static const float GAP_ICON_TEXT = 5.0f; if (!m_legend_enabled || m_roles.empty()) return; @@ -551,16 +599,34 @@ void GCodeViewer::render_overlay() const { ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f); draw_list->AddRect(ImVec2(pos.x, pos.y), ImVec2(pos.x + ICON_BORDER_SIZE, pos.y + ICON_BORDER_SIZE), ICON_BORDER_COLOR, 0.0f, 0); - const std::array& role_color = m_extrusions.role_colors[static_cast(role)]; - ImU32 fill_color = ImGui::GetColorU32(ImVec4(role_color[0], role_color[1], role_color[2], role_color[3])); + const std::array& color = m_extrusions.role_colors[static_cast(role)]; + ImU32 fill_color = ImGui::GetColorU32(ImVec4(color[0], color[1], color[2], color[3])); draw_list->AddRectFilled(ImVec2(pos.x + 1.0f, pos.y + 1.0f), ImVec2(pos.x + ICON_BORDER_SIZE - 1.0f, pos.y + ICON_BORDER_SIZE - 1.0f), fill_color); - ImGui::SetCursorPosX(pos.x + ICON_BORDER_SIZE + 4.0f); + ImGui::SetCursorPosX(pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT); ImGui::AlignTextToFramePadding(); imgui.text(Slic3r::I18N::translate(ExtrusionEntity::role_to_string(role))); } break; } - case EViewType::Height: { break; } + case EViewType::Height: + { + float step_size = m_extrusions.ranges.height.step_size(); + for (int i = Default_Range_Colors_Count - 1; i >= 0; --i) + { + ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f); + draw_list->AddRect(ImVec2(pos.x, pos.y), ImVec2(pos.x + ICON_BORDER_SIZE, pos.y + ICON_BORDER_SIZE), ICON_BORDER_COLOR, 0.0f, 0); + const std::array& color = m_extrusions.ranges.colors[i]; + ImU32 fill_color = ImGui::GetColorU32(ImVec4(color[0], color[1], color[2], color[3])); + draw_list->AddRectFilled(ImVec2(pos.x + 1.0f, pos.y + 1.0f), ImVec2(pos.x + ICON_BORDER_SIZE - 1.0f, pos.y + ICON_BORDER_SIZE - 1.0f), fill_color); + ImGui::SetCursorPosX(pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT); + ImGui::AlignTextToFramePadding(); + char buf[1024]; + ::sprintf(buf, "%.*f", 3, m_extrusions.ranges.height.min + static_cast(i) * step_size); + imgui.text(buf); + } + + break; + } case EViewType::Width: { break; } case EViewType::Feedrate: { break; } case EViewType::FanSpeed: { break; } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 4ee187144c..5185f54090 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -7,6 +7,8 @@ #include "3DScene.hpp" #include "libslic3r/GCode/GCodeProcessor.hpp" +#include + namespace Slic3r { class Print; namespace GUI { @@ -14,6 +16,8 @@ namespace GUI { class GCodeViewer { static const std::array, erCount> Default_Extrusion_Role_Colors; + static const size_t Default_Range_Colors_Count = 10; + static const std::array, Default_Range_Colors_Count> Default_Range_Colors; // buffer containing vertices data struct VBuffer @@ -29,14 +33,16 @@ class GCodeViewer static size_t vertex_size_bytes() { return vertex_size() * sizeof(float); } }; + // Used to identify different toolpath sub-types inside a IBuffer struct Path { GCodeProcessor::EMoveType type{ GCodeProcessor::EMoveType::Noop }; ExtrusionRole role{ erNone }; unsigned int first{ 0 }; unsigned int last{ 0 }; + float height{ 0.0f }; - bool matches(GCodeProcessor::EMoveType type, ExtrusionRole role) const { return this->type == type && this->role == role; } + bool matches(const GCodeProcessor::MoveVertex& move) const { return type == move.type && role == move.extrusion_role && height == move.height; } }; // buffer containing indices data and shader for a specific toolpath type @@ -52,7 +58,7 @@ class GCodeViewer void reset(); bool init_shader(const std::string& vertex_shader_src, const std::string& fragment_shader_src); - void add_path(GCodeProcessor::EMoveType type, ExtrusionRole role); + void add_path(GCodeProcessor::EMoveType type, ExtrusionRole role, float height); }; struct Shells @@ -62,10 +68,55 @@ class GCodeViewer Shader shader; }; + // helper to render extrusion paths struct Extrusions { + struct Range + { + float min; + float max; + + Range() { reset(); } + + void update_from(const float value) + { + min = std::min(min, value); + max = std::max(max, value); + } + + void reset() + { + min = FLT_MAX; + max = -FLT_MAX; + } + + float step_size() const { return (max - min) / static_cast(Default_Range_Colors_Count); } + std::array get_color_at(float value, const std::array, Default_Range_Colors_Count>& colors) const; + }; + + struct Ranges + { + std::array, Default_Range_Colors_Count> colors; + + // Color mapping by layer height. + Range height; +// // Color mapping by extrusion width. +// Range width; +// // Color mapping by feedrate. +// MultiRange feedrate; +// // Color mapping by fan speed. +// Range fan_speed; +// // Color mapping by volumetric extrusion rate. +// Range volumetric_rate; + + void reset() { + height.reset(); + } + }; + std::array, erCount> role_colors; unsigned int role_visibility_flags{ 0 }; + Ranges ranges; void reset_role_visibility_flags() { role_visibility_flags = 0; @@ -75,6 +126,8 @@ class GCodeViewer } } + void reset_ranges() { ranges.reset(); } + static bool is_role_visible(unsigned int flags, ExtrusionRole role) { return role < erCount && (flags & (1 << role)) != 0; } @@ -113,6 +166,7 @@ public: bool init() { m_extrusions.role_colors = Default_Extrusion_Role_Colors; + m_extrusions.ranges.colors = Default_Range_Colors; set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Extrude, true); return init_shaders(); } From aee80dbd01ff0ba8d2ae7a3881e3fd21d22835cd Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 20 Apr 2020 13:24:25 +0200 Subject: [PATCH 025/255] GCodeViewer -> Extrusion toolpaths colored by width --- src/libslic3r/Technologies.hpp | 2 +- src/slic3r/GUI/GCodeViewer.cpp | 75 +++++++++++++++++++--------------- src/slic3r/GUI/GCodeViewer.hpp | 15 ++++--- 3 files changed, 52 insertions(+), 40 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 51d5b0fa70..1ed939ba3e 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -58,7 +58,7 @@ // Enable G-Code viewer #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) -#define ENABLE_GCODE_VIEWER_DEBUG_OUTPUT (1 && ENABLE_GCODE_VIEWER) +#define ENABLE_GCODE_VIEWER_DEBUG_OUTPUT (0 && ENABLE_GCODE_VIEWER) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 10282642c3..b240d76f55 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -59,10 +59,10 @@ bool GCodeViewer::IBuffer::init_shader(const std::string& vertex_shader_src, con return true; } -void GCodeViewer::IBuffer::add_path(GCodeProcessor::EMoveType type, ExtrusionRole role, float height) +void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move) { unsigned int id = static_cast(data.size()); - paths.push_back({ type, role, id, id, height }); + paths.push_back({ move.type, move.extrusion_role, id, id, move.height, move.width }); } std::array GCodeViewer::Extrusions::Range::get_color_at(float value, const std::array, Default_Range_Colors_Count>& colors) const @@ -74,8 +74,8 @@ std::array GCodeViewer::Extrusions::Range::get_color_at(float value, c const size_t color_max_idx = colors.size() - 1; // Compute the two colors just below (low) and above (high) the input value - const size_t color_low_idx = std::clamp(static_cast(global_t), std::size_t{ 0 }, color_max_idx); - const size_t color_high_idx = std::clamp(color_low_idx + 1, std::size_t{ 0 }, color_max_idx); + const size_t color_low_idx = std::clamp(static_cast(global_t), 0, color_max_idx); + const size_t color_high_idx = std::clamp(color_low_idx + 1, 0, color_max_idx); // Compute how far the value is between the low and high colors so that they can be interpolated const float local_t = std::min(global_t - static_cast(color_low_idx), 1.0f); // upper limit of 1.0f @@ -279,7 +279,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) case GCodeProcessor::EMoveType::Retract: case GCodeProcessor::EMoveType::Unretract: { - buffer.add_path(curr.type, curr.extrusion_role, curr.height); + buffer.add_path(curr); buffer.data.push_back(static_cast(i)); break; } @@ -288,12 +288,13 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) { if (prev.type != curr.type || !buffer.paths.back().matches(curr)) { - buffer.add_path(curr.type, curr.extrusion_role, curr.height); + buffer.add_path(curr); buffer.data.push_back(static_cast(i - 1)); if (curr.type == GCodeProcessor::EMoveType::Extrude) { m_extrusions.ranges.height.update_from(curr.height); + m_extrusions.ranges.width.update_from(curr.width); } } @@ -412,17 +413,9 @@ void GCodeViewer::render_toolpaths() const std::array color; switch (m_view_type) { - case EViewType::FeatureType: - { - color = m_extrusions.role_colors[static_cast(path.role)]; - break; - } - case EViewType::Height: - { - color = m_extrusions.ranges.height.get_color_at(path.height, m_extrusions.ranges.colors); - break; - } - case EViewType::Width: + case EViewType::FeatureType: { color = m_extrusions.role_colors[static_cast(path.role)]; break; } + case EViewType::Height: { color = m_extrusions.ranges.height.get_color_at(path.height, m_extrusions.ranges.colors); break; } + case EViewType::Width: { color = m_extrusions.ranges.width.get_color_at(path.width, m_extrusions.ranges.colors); break; } case EViewType::Feedrate: case EViewType::FanSpeed: case EViewType::VolumetricRate: @@ -575,6 +568,32 @@ void GCodeViewer::render_overlay() const ImDrawList* draw_list = ImGui::GetWindowDrawList(); + auto add_range = [this, draw_list, &imgui](const Extrusions::Range& range) { + auto add_item = [this, draw_list, &imgui](int i, float value) { + ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f); + draw_list->AddRect(ImVec2(pos.x, pos.y), ImVec2(pos.x + ICON_BORDER_SIZE, pos.y + ICON_BORDER_SIZE), ICON_BORDER_COLOR, 0.0f, 0); + const std::array& color = m_extrusions.ranges.colors[i]; + ImU32 fill_color = ImGui::GetColorU32(ImVec4(color[0], color[1], color[2], color[3])); + draw_list->AddRectFilled(ImVec2(pos.x + 1.0f, pos.y + 1.0f), ImVec2(pos.x + ICON_BORDER_SIZE - 1.0f, pos.y + ICON_BORDER_SIZE - 1.0f), fill_color); + ImGui::SetCursorPosX(pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT); + ImGui::AlignTextToFramePadding(); + char buf[1024]; + ::sprintf(buf, "%.*f", 3, value); + imgui.text(buf); + }; + + float step_size = range.step_size(); + if (step_size == 0.0f) + add_item(0, range.min); + else + { + for (int i = Default_Range_Colors_Count - 1; i >= 0; --i) + { + add_item(i, range.min + static_cast(i) * step_size); + } + } + }; + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); switch (m_view_type) { @@ -610,24 +629,14 @@ void GCodeViewer::render_overlay() const } case EViewType::Height: { - float step_size = m_extrusions.ranges.height.step_size(); - for (int i = Default_Range_Colors_Count - 1; i >= 0; --i) - { - ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f); - draw_list->AddRect(ImVec2(pos.x, pos.y), ImVec2(pos.x + ICON_BORDER_SIZE, pos.y + ICON_BORDER_SIZE), ICON_BORDER_COLOR, 0.0f, 0); - const std::array& color = m_extrusions.ranges.colors[i]; - ImU32 fill_color = ImGui::GetColorU32(ImVec4(color[0], color[1], color[2], color[3])); - draw_list->AddRectFilled(ImVec2(pos.x + 1.0f, pos.y + 1.0f), ImVec2(pos.x + ICON_BORDER_SIZE - 1.0f, pos.y + ICON_BORDER_SIZE - 1.0f), fill_color); - ImGui::SetCursorPosX(pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT); - ImGui::AlignTextToFramePadding(); - char buf[1024]; - ::sprintf(buf, "%.*f", 3, m_extrusions.ranges.height.min + static_cast(i) * step_size); - imgui.text(buf); - } - + add_range(m_extrusions.ranges.height); + break; + } + case EViewType::Width: + { + add_range(m_extrusions.ranges.width); break; } - case EViewType::Width: { break; } case EViewType::Feedrate: { break; } case EViewType::FanSpeed: { break; } case EViewType::VolumetricRate: { break; } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 5185f54090..342f3ba901 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -41,8 +41,11 @@ class GCodeViewer unsigned int first{ 0 }; unsigned int last{ 0 }; float height{ 0.0f }; + float width{ 0.0f }; - bool matches(const GCodeProcessor::MoveVertex& move) const { return type == move.type && role == move.extrusion_role && height == move.height; } + bool matches(const GCodeProcessor::MoveVertex& move) const { + return type == move.type && role == move.extrusion_role && height == move.height && width == move.width; + } }; // buffer containing indices data and shader for a specific toolpath type @@ -57,8 +60,7 @@ class GCodeViewer void reset(); bool init_shader(const std::string& vertex_shader_src, const std::string& fragment_shader_src); - - void add_path(GCodeProcessor::EMoveType type, ExtrusionRole role, float height); + void add_path(const GCodeProcessor::MoveVertex& move); }; struct Shells @@ -90,7 +92,7 @@ class GCodeViewer max = -FLT_MAX; } - float step_size() const { return (max - min) / static_cast(Default_Range_Colors_Count); } + float step_size() const { return (max - min) / (static_cast(Default_Range_Colors_Count) - 1.0f); } std::array get_color_at(float value, const std::array, Default_Range_Colors_Count>& colors) const; }; @@ -100,8 +102,8 @@ class GCodeViewer // Color mapping by layer height. Range height; -// // Color mapping by extrusion width. -// Range width; + // Color mapping by extrusion width. + Range width; // // Color mapping by feedrate. // MultiRange feedrate; // // Color mapping by fan speed. @@ -111,6 +113,7 @@ class GCodeViewer void reset() { height.reset(); + width.reset(); } }; From dc3c5db9fe6251306159889ffed1b8ba3035aee5 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 20 Apr 2020 13:44:14 +0200 Subject: [PATCH 026/255] GCodeViewer -> Use rgb instead of rgba colors --- resources/shaders/extrusions.fs | 4 +- resources/shaders/retractions.fs | 4 +- resources/shaders/toolchanges.fs | 4 +- resources/shaders/travels.fs | 4 +- resources/shaders/unretractions.fs | 4 +- src/slic3r/GUI/GCodeViewer.cpp | 82 +++++++++++++++--------------- src/slic3r/GUI/GCodeViewer.hpp | 10 ++-- 7 files changed, 56 insertions(+), 56 deletions(-) diff --git a/resources/shaders/extrusions.fs b/resources/shaders/extrusions.fs index 046dade8a9..fc81e487fb 100644 --- a/resources/shaders/extrusions.fs +++ b/resources/shaders/extrusions.fs @@ -13,7 +13,7 @@ const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0); #define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) -uniform vec4 uniform_color; +uniform vec3 uniform_color; varying vec3 eye_position; varying vec3 eye_normal; @@ -41,5 +41,5 @@ void main() // if (world_normal_z < 0.0) // intensity.x *= (1.0 + world_normal_z * (1.0 - INTENSITY_AMBIENT)); - gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color.rgb * intensity.x, uniform_color.a); + gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color * intensity.x, 1.0); } diff --git a/resources/shaders/retractions.fs b/resources/shaders/retractions.fs index 046dade8a9..fc81e487fb 100644 --- a/resources/shaders/retractions.fs +++ b/resources/shaders/retractions.fs @@ -13,7 +13,7 @@ const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0); #define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) -uniform vec4 uniform_color; +uniform vec3 uniform_color; varying vec3 eye_position; varying vec3 eye_normal; @@ -41,5 +41,5 @@ void main() // if (world_normal_z < 0.0) // intensity.x *= (1.0 + world_normal_z * (1.0 - INTENSITY_AMBIENT)); - gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color.rgb * intensity.x, uniform_color.a); + gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color * intensity.x, 1.0); } diff --git a/resources/shaders/toolchanges.fs b/resources/shaders/toolchanges.fs index 046dade8a9..fc81e487fb 100644 --- a/resources/shaders/toolchanges.fs +++ b/resources/shaders/toolchanges.fs @@ -13,7 +13,7 @@ const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0); #define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) -uniform vec4 uniform_color; +uniform vec3 uniform_color; varying vec3 eye_position; varying vec3 eye_normal; @@ -41,5 +41,5 @@ void main() // if (world_normal_z < 0.0) // intensity.x *= (1.0 + world_normal_z * (1.0 - INTENSITY_AMBIENT)); - gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color.rgb * intensity.x, uniform_color.a); + gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color * intensity.x, 1.0); } diff --git a/resources/shaders/travels.fs b/resources/shaders/travels.fs index 046dade8a9..fc81e487fb 100644 --- a/resources/shaders/travels.fs +++ b/resources/shaders/travels.fs @@ -13,7 +13,7 @@ const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0); #define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) -uniform vec4 uniform_color; +uniform vec3 uniform_color; varying vec3 eye_position; varying vec3 eye_normal; @@ -41,5 +41,5 @@ void main() // if (world_normal_z < 0.0) // intensity.x *= (1.0 + world_normal_z * (1.0 - INTENSITY_AMBIENT)); - gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color.rgb * intensity.x, uniform_color.a); + gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color * intensity.x, 1.0); } diff --git a/resources/shaders/unretractions.fs b/resources/shaders/unretractions.fs index 046dade8a9..fc81e487fb 100644 --- a/resources/shaders/unretractions.fs +++ b/resources/shaders/unretractions.fs @@ -13,7 +13,7 @@ const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0); #define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) -uniform vec4 uniform_color; +uniform vec3 uniform_color; varying vec3 eye_position; varying vec3 eye_normal; @@ -41,5 +41,5 @@ void main() // if (world_normal_z < 0.0) // intensity.x *= (1.0 + world_normal_z * (1.0 - INTENSITY_AMBIENT)); - gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color.rgb * intensity.x, uniform_color.a); + gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color * intensity.x, 1.0); } diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index b240d76f55..52d3927982 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -65,7 +65,7 @@ void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move) paths.push_back({ move.type, move.extrusion_role, id, id, move.height, move.width }); } -std::array GCodeViewer::Extrusions::Range::get_color_at(float value, const std::array, Default_Range_Colors_Count>& colors) const +std::array GCodeViewer::Extrusions::Range::get_color_at(float value, const std::array, Default_Range_Colors_Count>& colors) const { // Input value scaled to the color range const float step = step_size(); @@ -81,43 +81,43 @@ std::array GCodeViewer::Extrusions::Range::get_color_at(float value, c const float local_t = std::min(global_t - static_cast(color_low_idx), 1.0f); // upper limit of 1.0f // Interpolate between the low and high colors in RGB space to find exactly which color the input value should get - std::array ret; - for (unsigned int i = 0; i < 4; ++i) + std::array ret; + for (unsigned int i = 0; i < 3; ++i) { ret[i] = lerp(colors[color_low_idx][i], colors[color_high_idx][i], local_t); } return ret; } -const std::array, erCount> GCodeViewer::Default_Extrusion_Role_Colors {{ - { 1.00f, 1.00f, 1.00f, 1.0f }, // erNone - { 1.00f, 1.00f, 0.40f, 1.0f }, // erPerimeter - { 1.00f, 0.65f, 0.00f, 1.0f }, // erExternalPerimeter - { 0.00f, 0.00f, 1.00f, 1.0f }, // erOverhangPerimeter - { 0.69f, 0.19f, 0.16f, 1.0f }, // erInternalInfill - { 0.84f, 0.20f, 0.84f, 1.0f }, // erSolidInfill - { 1.00f, 0.10f, 0.10f, 1.0f }, // erTopSolidInfill - { 0.60f, 0.60f, 1.00f, 1.0f }, // erBridgeInfill - { 1.00f, 1.00f, 1.00f, 1.0f }, // erGapFill - { 0.52f, 0.48f, 0.13f, 1.0f }, // erSkirt - { 0.00f, 1.00f, 0.00f, 1.0f }, // erSupportMaterial - { 0.00f, 0.50f, 0.00f, 1.0f }, // erSupportMaterialInterface - { 0.70f, 0.89f, 0.67f, 1.0f }, // erWipeTower - { 0.16f, 0.80f, 0.58f, 1.0f }, // erCustom - { 0.00f, 0.00f, 0.00f, 1.0f } // erMixed +const std::array, erCount> GCodeViewer::Default_Extrusion_Role_Colors {{ + { 1.00f, 1.00f, 1.00f }, // erNone + { 1.00f, 1.00f, 0.40f }, // erPerimeter + { 1.00f, 0.65f, 0.00f }, // erExternalPerimeter + { 0.00f, 0.00f, 1.00f }, // erOverhangPerimeter + { 0.69f, 0.19f, 0.16f }, // erInternalInfill + { 0.84f, 0.20f, 0.84f }, // erSolidInfill + { 1.00f, 0.10f, 0.10f }, // erTopSolidInfill + { 0.60f, 0.60f, 1.00f }, // erBridgeInfill + { 1.00f, 1.00f, 1.00f }, // erGapFill + { 0.52f, 0.48f, 0.13f }, // erSkirt + { 0.00f, 1.00f, 0.00f }, // erSupportMaterial + { 0.00f, 0.50f, 0.00f }, // erSupportMaterialInterface + { 0.70f, 0.89f, 0.67f }, // erWipeTower + { 0.16f, 0.80f, 0.58f }, // erCustom + { 0.00f, 0.00f, 0.00f } // erMixed }}; -const std::array, GCodeViewer::Default_Range_Colors_Count> GCodeViewer::Default_Range_Colors {{ - { 0.043f, 0.173f, 0.478f, 1.0f }, - { 0.075f, 0.349f, 0.522f, 1.0f }, - { 0.110f, 0.533f, 0.569f, 1.0f }, - { 0.016f, 0.839f, 0.059f, 1.0f }, - { 0.667f, 0.949f, 0.000f, 1.0f }, - { 0.988f, 0.975f, 0.012f, 1.0f }, - { 0.961f, 0.808f, 0.039f, 1.0f }, - { 0.890f, 0.533f, 0.125f, 1.0f }, - { 0.820f, 0.408f, 0.188f, 1.0f }, - { 0.761f, 0.322f, 0.235f, 1.0f } +const std::array, GCodeViewer::Default_Range_Colors_Count> GCodeViewer::Default_Range_Colors {{ + { 0.043f, 0.173f, 0.478f }, + { 0.075f, 0.349f, 0.522f }, + { 0.110f, 0.533f, 0.569f }, + { 0.016f, 0.839f, 0.059f }, + { 0.667f, 0.949f, 0.000f }, + { 0.988f, 0.975f, 0.012f }, + { 0.961f, 0.808f, 0.039f }, + { 0.890f, 0.533f, 0.125f }, + { 0.820f, 0.408f, 0.188f }, + { 0.761f, 0.322f, 0.235f } }}; void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized) @@ -410,7 +410,7 @@ void GCodeViewer::load_shells(const Print& print, bool initialized) void GCodeViewer::render_toolpaths() const { auto extrusion_color = [this](const Path& path) { - std::array color; + std::array color; switch (m_view_type) { case EViewType::FeatureType: { color = m_extrusions.role_colors[static_cast(path.role)]; break; } @@ -423,18 +423,18 @@ void GCodeViewer::render_toolpaths() const case EViewType::ColorPrint: default: { - color = { 1.0f, 1.0f, 1.0f, 1.0f }; + color = { 1.0f, 1.0f, 1.0f }; break; } } return color; }; - auto set_color = [](GLint current_program_id, const std::array& color) { + auto set_color = [](GLint current_program_id, const std::array& color) { if (current_program_id > 0) { GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1; if (color_id >= 0) { - glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)color.data())); + glsafe(::glUniform3fv(color_id, 1, (const GLfloat*)color.data())); return; } } @@ -478,7 +478,7 @@ void GCodeViewer::render_toolpaths() const { case GCodeProcessor::EMoveType::Tool_change: { - std::array color = { 1.0f, 1.0f, 1.0f, 1.0f }; + std::array color = { 1.0f, 1.0f, 1.0f }; set_color(current_program_id, color); glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); glsafe(::glDrawElements(GL_POINTS, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); @@ -487,7 +487,7 @@ void GCodeViewer::render_toolpaths() const } case GCodeProcessor::EMoveType::Retract: { - std::array color = { 1.0f, 0.0f, 1.0f, 1.0f }; + std::array color = { 1.0f, 0.0f, 1.0f }; set_color(current_program_id, color); glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); glsafe(::glDrawElements(GL_POINTS, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); @@ -496,7 +496,7 @@ void GCodeViewer::render_toolpaths() const } case GCodeProcessor::EMoveType::Unretract: { - std::array color = { 0.0f, 1.0f, 0.0f, 1.0f }; + std::array color = { 0.0f, 1.0f, 0.0f }; set_color(current_program_id, color); glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); glsafe(::glDrawElements(GL_POINTS, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); @@ -517,7 +517,7 @@ void GCodeViewer::render_toolpaths() const } case GCodeProcessor::EMoveType::Travel: { - std::array color = { 1.0f, 1.0f, 0.0f, 1.0f }; + std::array color = { 1.0f, 1.0f, 0.0f }; set_color(current_program_id, color); for (const Path& path : buffer.paths) { @@ -572,8 +572,8 @@ void GCodeViewer::render_overlay() const auto add_item = [this, draw_list, &imgui](int i, float value) { ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f); draw_list->AddRect(ImVec2(pos.x, pos.y), ImVec2(pos.x + ICON_BORDER_SIZE, pos.y + ICON_BORDER_SIZE), ICON_BORDER_COLOR, 0.0f, 0); - const std::array& color = m_extrusions.ranges.colors[i]; - ImU32 fill_color = ImGui::GetColorU32(ImVec4(color[0], color[1], color[2], color[3])); + const std::array& color = m_extrusions.ranges.colors[i]; + ImU32 fill_color = ImGui::GetColorU32(ImVec4(color[0], color[1], color[2], 1.0f)); draw_list->AddRectFilled(ImVec2(pos.x + 1.0f, pos.y + 1.0f), ImVec2(pos.x + ICON_BORDER_SIZE - 1.0f, pos.y + ICON_BORDER_SIZE - 1.0f), fill_color); ImGui::SetCursorPosX(pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT); ImGui::AlignTextToFramePadding(); @@ -618,7 +618,7 @@ void GCodeViewer::render_overlay() const { ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f); draw_list->AddRect(ImVec2(pos.x, pos.y), ImVec2(pos.x + ICON_BORDER_SIZE, pos.y + ICON_BORDER_SIZE), ICON_BORDER_COLOR, 0.0f, 0); - const std::array& color = m_extrusions.role_colors[static_cast(role)]; + const std::array& color = m_extrusions.role_colors[static_cast(role)]; ImU32 fill_color = ImGui::GetColorU32(ImVec4(color[0], color[1], color[2], color[3])); draw_list->AddRectFilled(ImVec2(pos.x + 1.0f, pos.y + 1.0f), ImVec2(pos.x + ICON_BORDER_SIZE - 1.0f, pos.y + ICON_BORDER_SIZE - 1.0f), fill_color); ImGui::SetCursorPosX(pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 342f3ba901..39361050b8 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -15,9 +15,9 @@ namespace GUI { class GCodeViewer { - static const std::array, erCount> Default_Extrusion_Role_Colors; + static const std::array, erCount> Default_Extrusion_Role_Colors; static const size_t Default_Range_Colors_Count = 10; - static const std::array, Default_Range_Colors_Count> Default_Range_Colors; + static const std::array, Default_Range_Colors_Count> Default_Range_Colors; // buffer containing vertices data struct VBuffer @@ -93,12 +93,12 @@ class GCodeViewer } float step_size() const { return (max - min) / (static_cast(Default_Range_Colors_Count) - 1.0f); } - std::array get_color_at(float value, const std::array, Default_Range_Colors_Count>& colors) const; + std::array get_color_at(float value, const std::array, Default_Range_Colors_Count>& colors) const; }; struct Ranges { - std::array, Default_Range_Colors_Count> colors; + std::array, Default_Range_Colors_Count> colors; // Color mapping by layer height. Range height; @@ -117,7 +117,7 @@ class GCodeViewer } }; - std::array, erCount> role_colors; + std::array, erCount> role_colors; unsigned int role_visibility_flags{ 0 }; Ranges ranges; From 3ba6ac7836606049394704621768c6a26196bd51 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 20 Apr 2020 16:04:59 +0200 Subject: [PATCH 027/255] GCodeViewer -> Extrusion toolpaths colored by feedrate and ranges calculations dependent on travel paths visibility --- src/slic3r/GUI/GCodeViewer.cpp | 82 +++++++++++++++++++++++----------- src/slic3r/GUI/GCodeViewer.hpp | 11 +++-- src/slic3r/GUI/GLCanvas3D.cpp | 7 ++- src/slic3r/GUI/GLCanvas3D.hpp | 3 +- src/slic3r/GUI/GUI_Preview.cpp | 3 +- 5 files changed, 74 insertions(+), 32 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 52d3927982..e14969eddc 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -62,7 +62,7 @@ bool GCodeViewer::IBuffer::init_shader(const std::string& vertex_shader_src, con void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move) { unsigned int id = static_cast(data.size()); - paths.push_back({ move.type, move.extrusion_role, id, id, move.height, move.width }); + paths.push_back({ move.type, move.extrusion_role, id, id, move.height, move.width, move.feedrate }); } std::array GCodeViewer::Extrusions::Range::get_color_at(float value, const std::array, Default_Range_Colors_Count>& colors) const @@ -78,7 +78,7 @@ std::array GCodeViewer::Extrusions::Range::get_color_at(float value, c const size_t color_high_idx = std::clamp(color_low_idx + 1, 0, color_max_idx); // Compute how far the value is between the low and high colors so that they can be interpolated - const float local_t = std::min(global_t - static_cast(color_low_idx), 1.0f); // upper limit of 1.0f + const float local_t = std::clamp(global_t - static_cast(color_low_idx), 0.0f, 1.0f); // Interpolate between the low and high colors in RGB space to find exactly which color the input value should get std::array ret; @@ -134,6 +134,42 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& load_shells(print, initialized); } +void GCodeViewer::refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result) +{ + if (m_vertices.vertices_count == 0) + return; + + m_extrusions.reset_ranges(); + + for (size_t i = 0; i < m_vertices.vertices_count; ++i) + { + // skip first vertex + if (i == 0) + continue; + + const GCodeProcessor::MoveVertex& curr = gcode_result.moves[i]; + + switch (curr.type) + { + case GCodeProcessor::EMoveType::Extrude: + case GCodeProcessor::EMoveType::Travel: + { + if (m_buffers[buffer_id(curr.type)].visible) + { + m_extrusions.ranges.height.update_from(curr.height); + m_extrusions.ranges.width.update_from(curr.width); + m_extrusions.ranges.feedrate.update_from(curr.feedrate); + } + break; + } + default: + { + break; + } + } + } +} + void GCodeViewer::reset() { m_vertices.reset(); @@ -290,12 +326,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) { buffer.add_path(curr); buffer.data.push_back(static_cast(i - 1)); - - if (curr.type == GCodeProcessor::EMoveType::Extrude) - { - m_extrusions.ranges.height.update_from(curr.height); - m_extrusions.ranges.width.update_from(curr.width); - } } buffer.paths.back().last = static_cast(buffer.data.size()); @@ -413,19 +443,15 @@ void GCodeViewer::render_toolpaths() const std::array color; switch (m_view_type) { - case EViewType::FeatureType: { color = m_extrusions.role_colors[static_cast(path.role)]; break; } - case EViewType::Height: { color = m_extrusions.ranges.height.get_color_at(path.height, m_extrusions.ranges.colors); break; } - case EViewType::Width: { color = m_extrusions.ranges.width.get_color_at(path.width, m_extrusions.ranges.colors); break; } - case EViewType::Feedrate: + case EViewType::FeatureType: { color = m_extrusions.role_colors[static_cast(path.role)]; break; } + case EViewType::Height: { color = m_extrusions.ranges.height.get_color_at(path.height, m_extrusions.ranges.colors); break; } + case EViewType::Width: { color = m_extrusions.ranges.width.get_color_at(path.width, m_extrusions.ranges.colors); break; } + case EViewType::Feedrate: { color = m_extrusions.ranges.feedrate.get_color_at(path.feedrate, m_extrusions.ranges.colors); break; } case EViewType::FanSpeed: case EViewType::VolumetricRate: case EViewType::Tool: case EViewType::ColorPrint: - default: - { - color = { 1.0f, 1.0f, 1.0f }; - break; - } + default: { color = { 1.0f, 1.0f, 1.0f }; break; } } return color; }; @@ -568,8 +594,8 @@ void GCodeViewer::render_overlay() const ImDrawList* draw_list = ImGui::GetWindowDrawList(); - auto add_range = [this, draw_list, &imgui](const Extrusions::Range& range) { - auto add_item = [this, draw_list, &imgui](int i, float value) { + auto add_range = [this, draw_list, &imgui](const Extrusions::Range& range, unsigned int decimals) { + auto add_item = [this, draw_list, &imgui](int i, float value, unsigned int decimals) { ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f); draw_list->AddRect(ImVec2(pos.x, pos.y), ImVec2(pos.x + ICON_BORDER_SIZE, pos.y + ICON_BORDER_SIZE), ICON_BORDER_COLOR, 0.0f, 0); const std::array& color = m_extrusions.ranges.colors[i]; @@ -578,18 +604,18 @@ void GCodeViewer::render_overlay() const ImGui::SetCursorPosX(pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT); ImGui::AlignTextToFramePadding(); char buf[1024]; - ::sprintf(buf, "%.*f", 3, value); + ::sprintf(buf, "%.*f", decimals, value); imgui.text(buf); }; float step_size = range.step_size(); if (step_size == 0.0f) - add_item(0, range.min); + add_item(0, range.min, decimals); else { for (int i = Default_Range_Colors_Count - 1; i >= 0; --i) { - add_item(i, range.min + static_cast(i) * step_size); + add_item(i, range.min + static_cast(i) * step_size, decimals); } } }; @@ -619,7 +645,7 @@ void GCodeViewer::render_overlay() const ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f); draw_list->AddRect(ImVec2(pos.x, pos.y), ImVec2(pos.x + ICON_BORDER_SIZE, pos.y + ICON_BORDER_SIZE), ICON_BORDER_COLOR, 0.0f, 0); const std::array& color = m_extrusions.role_colors[static_cast(role)]; - ImU32 fill_color = ImGui::GetColorU32(ImVec4(color[0], color[1], color[2], color[3])); + ImU32 fill_color = ImGui::GetColorU32(ImVec4(color[0], color[1], color[2], 1.0)); draw_list->AddRectFilled(ImVec2(pos.x + 1.0f, pos.y + 1.0f), ImVec2(pos.x + ICON_BORDER_SIZE - 1.0f, pos.y + ICON_BORDER_SIZE - 1.0f), fill_color); ImGui::SetCursorPosX(pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT); ImGui::AlignTextToFramePadding(); @@ -629,15 +655,19 @@ void GCodeViewer::render_overlay() const } case EViewType::Height: { - add_range(m_extrusions.ranges.height); + add_range(m_extrusions.ranges.height, 3); break; } case EViewType::Width: { - add_range(m_extrusions.ranges.width); + add_range(m_extrusions.ranges.width, 3); + break; + } + case EViewType::Feedrate: + { + add_range(m_extrusions.ranges.feedrate, 1); break; } - case EViewType::Feedrate: { break; } case EViewType::FanSpeed: { break; } case EViewType::VolumetricRate: { break; } case EViewType::Tool: { break; } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 39361050b8..34b81ad7a6 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -42,9 +42,10 @@ class GCodeViewer unsigned int last{ 0 }; float height{ 0.0f }; float width{ 0.0f }; + float feedrate{ 0.0f }; bool matches(const GCodeProcessor::MoveVertex& move) const { - return type == move.type && role == move.extrusion_role && height == move.height && width == move.width; + return type == move.type && role == move.extrusion_role && height == move.height && width == move.width && feedrate == move.feedrate; } }; @@ -104,8 +105,8 @@ class GCodeViewer Range height; // Color mapping by extrusion width. Range width; -// // Color mapping by feedrate. -// MultiRange feedrate; + // Color mapping by feedrate. + Range feedrate; // // Color mapping by fan speed. // Range fan_speed; // // Color mapping by volumetric extrusion rate. @@ -114,6 +115,7 @@ class GCodeViewer void reset() { height.reset(); width.reset(); + feedrate.reset(); } }; @@ -173,7 +175,10 @@ public: set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Extrude, true); return init_shaders(); } + void load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized); + void refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result); + void reset(); void render() const; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 8c3af4a587..23cccb76f9 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2833,7 +2833,7 @@ static void load_gcode_retractions(const GCodePreviewData::Retraction& retractio #endif // !ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER -void GLCanvas3D::load_gcode_preview_2(const GCodeProcessor::Result& gcode_result) +void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result) { #if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT static unsigned int last_result_id = 0; @@ -2852,6 +2852,11 @@ void GLCanvas3D::load_gcode_preview_2(const GCodeProcessor::Result& gcode_result #endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT m_gcode_viewer.load(gcode_result, *this->fff_print(), m_initialized); } + +void GLCanvas3D::refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result) +{ + m_gcode_viewer.refresh_toolpaths_ranges(gcode_result); +} #endif // ENABLE_GCODE_VIEWER #if !ENABLE_GCODE_VIEWER diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index af1f6149c8..312eeaa3b6 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -664,7 +664,8 @@ public: void reload_scene(bool refresh_immediately, bool force_full_scene_refresh = false); #if ENABLE_GCODE_VIEWER - void load_gcode_preview_2(const GCodeProcessor::Result& gcode_result); + void load_gcode_preview(const GCodeProcessor::Result& gcode_result); + void refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result); #else void load_gcode_preview(const GCodePreviewData& preview_data, const std::vector& str_tool_colors); #endif // ENABLE_GCODE_VIEWER diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 562058dd95..2060511491 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -984,7 +984,8 @@ void Preview::load_print_as_fff(bool keep_z_range) if (gcode_preview_data_valid) { // Load the real G-code preview. #if ENABLE_GCODE_VIEWER - m_canvas->load_gcode_preview_2(*m_gcode_result); + m_canvas->load_gcode_preview(*m_gcode_result); + m_canvas->refresh_toolpaths_ranges(*m_gcode_result); #else m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); #endif // ENABLE_GCODE_VIEWER From 53d758639f5966b524ed6d9a9cb4008123e612f3 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 21 Apr 2020 09:06:43 +0200 Subject: [PATCH 028/255] GCodeViewer -> Extrusion toolpaths colored by fan speed --- src/slic3r/GUI/GCodeViewer.cpp | 33 +++++++++++---------------------- src/slic3r/GUI/GCodeViewer.hpp | 8 +++++--- 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index e14969eddc..4cffb39bd5 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -62,12 +62,12 @@ bool GCodeViewer::IBuffer::init_shader(const std::string& vertex_shader_src, con void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move) { unsigned int id = static_cast(data.size()); - paths.push_back({ move.type, move.extrusion_role, id, id, move.height, move.width, move.feedrate }); + paths.push_back({ move.type, move.extrusion_role, id, id, move.height, move.width, move.feedrate, move.fan_speed }); } std::array GCodeViewer::Extrusions::Range::get_color_at(float value, const std::array, Default_Range_Colors_Count>& colors) const { - // Input value scaled to the color range + // Input value scaled to the colors range const float step = step_size(); const float global_t = (step != 0.0f) ? std::max(0.0f, value - min) / step : 0.0f; // lower limit of 0.0f @@ -80,7 +80,7 @@ std::array GCodeViewer::Extrusions::Range::get_color_at(float value, c // Compute how far the value is between the low and high colors so that they can be interpolated const float local_t = std::clamp(global_t - static_cast(color_low_idx), 0.0f, 1.0f); - // Interpolate between the low and high colors in RGB space to find exactly which color the input value should get + // Interpolate between the low and high colors to find exactly which color the input value should get std::array ret; for (unsigned int i = 0; i < 3; ++i) { @@ -108,7 +108,7 @@ const std::array, erCount> GCodeViewer::Default_Extrusion_R }}; const std::array, GCodeViewer::Default_Range_Colors_Count> GCodeViewer::Default_Range_Colors {{ - { 0.043f, 0.173f, 0.478f }, + { 0.043f, 0.173f, 0.478f }, // bluish { 0.075f, 0.349f, 0.522f }, { 0.110f, 0.533f, 0.569f }, { 0.016f, 0.839f, 0.059f }, @@ -117,7 +117,7 @@ const std::array, GCodeViewer::Default_Range_Colors_Count> { 0.961f, 0.808f, 0.039f }, { 0.890f, 0.533f, 0.125f }, { 0.820f, 0.408f, 0.188f }, - { 0.761f, 0.322f, 0.235f } + { 0.761f, 0.322f, 0.235f } // reddish }}; void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized) @@ -159,6 +159,7 @@ void GCodeViewer::refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_r m_extrusions.ranges.height.update_from(curr.height); m_extrusions.ranges.width.update_from(curr.width); m_extrusions.ranges.feedrate.update_from(curr.feedrate); + m_extrusions.ranges.fan_speed.update_from(curr.fan_speed); } break; } @@ -447,7 +448,7 @@ void GCodeViewer::render_toolpaths() const case EViewType::Height: { color = m_extrusions.ranges.height.get_color_at(path.height, m_extrusions.ranges.colors); break; } case EViewType::Width: { color = m_extrusions.ranges.width.get_color_at(path.width, m_extrusions.ranges.colors); break; } case EViewType::Feedrate: { color = m_extrusions.ranges.feedrate.get_color_at(path.feedrate, m_extrusions.ranges.colors); break; } - case EViewType::FanSpeed: + case EViewType::FanSpeed: { color = m_extrusions.ranges.fan_speed.get_color_at(path.fan_speed, m_extrusions.ranges.colors); break; } case EViewType::VolumetricRate: case EViewType::Tool: case EViewType::ColorPrint: @@ -653,22 +654,10 @@ void GCodeViewer::render_overlay() const } break; } - case EViewType::Height: - { - add_range(m_extrusions.ranges.height, 3); - break; - } - case EViewType::Width: - { - add_range(m_extrusions.ranges.width, 3); - break; - } - case EViewType::Feedrate: - { - add_range(m_extrusions.ranges.feedrate, 1); - break; - } - case EViewType::FanSpeed: { break; } + case EViewType::Height: { add_range(m_extrusions.ranges.height, 3); break; } + case EViewType::Width: { add_range(m_extrusions.ranges.width, 3); break; } + case EViewType::Feedrate: { add_range(m_extrusions.ranges.feedrate, 1); break; } + case EViewType::FanSpeed: { add_range(m_extrusions.ranges.fan_speed, 0); break; } case EViewType::VolumetricRate: { break; } case EViewType::Tool: { break; } case EViewType::ColorPrint: { break; } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 34b81ad7a6..644f088424 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -43,9 +43,10 @@ class GCodeViewer float height{ 0.0f }; float width{ 0.0f }; float feedrate{ 0.0f }; + float fan_speed{ 0.0f }; bool matches(const GCodeProcessor::MoveVertex& move) const { - return type == move.type && role == move.extrusion_role && height == move.height && width == move.width && feedrate == move.feedrate; + return type == move.type && role == move.extrusion_role && height == move.height && width == move.width && feedrate == move.feedrate && fan_speed == move.fan_speed; } }; @@ -107,8 +108,8 @@ class GCodeViewer Range width; // Color mapping by feedrate. Range feedrate; -// // Color mapping by fan speed. -// Range fan_speed; + // Color mapping by fan speed. + Range fan_speed; // // Color mapping by volumetric extrusion rate. // Range volumetric_rate; @@ -116,6 +117,7 @@ class GCodeViewer height.reset(); width.reset(); feedrate.reset(); + fan_speed.reset(); } }; From 443a511420523a68cf4517fa158405358c1f6f97 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 21 Apr 2020 11:38:42 +0200 Subject: [PATCH 029/255] GCodeViewer -> Extrusion toolpaths colored by volumetric rate --- src/libslic3r/GCode/GCodeProcessor.hpp | 2 + src/slic3r/GUI/GCodeViewer.cpp | 72 ++++++++++---------------- src/slic3r/GUI/GCodeViewer.hpp | 22 +++----- 3 files changed, 36 insertions(+), 60 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 623a2ae3bd..38adce3329 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -80,6 +80,8 @@ namespace Slic3r { float mm3_per_mm{ 0.0f }; float fan_speed{ 0.0f }; // percentage + float volumetric_rate() const { return feedrate * mm3_per_mm; } + std::string to_string() const { std::string str = std::to_string((int)type); diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 4cffb39bd5..e02a809934 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -31,7 +31,10 @@ void GCodeViewer::VBuffer::reset() { // release gpu memory if (vbo_id > 0) + { glsafe(::glDeleteBuffers(1, &vbo_id)); + vbo_id = 0; + } vertices_count = 0; } @@ -40,7 +43,10 @@ void GCodeViewer::IBuffer::reset() { // release gpu memory if (ibo_id > 0) + { glsafe(::glDeleteBuffers(1, &ibo_id)); + ibo_id = 0; + } // release cpu memory data = std::vector(); @@ -62,7 +68,7 @@ bool GCodeViewer::IBuffer::init_shader(const std::string& vertex_shader_src, con void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move) { unsigned int id = static_cast(data.size()); - paths.push_back({ move.type, move.extrusion_role, id, id, move.height, move.width, move.feedrate, move.fan_speed }); + paths.push_back({ move.type, move.extrusion_role, id, id, move.height, move.width, move.feedrate, move.fan_speed, move.volumetric_rate() }); } std::array GCodeViewer::Extrusions::Range::get_color_at(float value, const std::array, Default_Range_Colors_Count>& colors) const @@ -160,6 +166,7 @@ void GCodeViewer::refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_r m_extrusions.ranges.width.update_from(curr.width); m_extrusions.ranges.feedrate.update_from(curr.feedrate); m_extrusions.ranges.fan_speed.update_from(curr.fan_speed); + m_extrusions.ranges.volumetric_rate.update_from(curr.volumetric_rate()); } break; } @@ -216,48 +223,21 @@ bool GCodeViewer::init_shaders() for (unsigned char i = begin_id; i < end_id; ++i) { + std::string vertex_shader; + std::string fragment_shader; + switch (buffer_type(i)) { - case GCodeProcessor::EMoveType::Tool_change: - { - if (!m_buffers[i].init_shader("toolchanges.vs", "toolchanges.fs")) - return false; + case GCodeProcessor::EMoveType::Tool_change: { vertex_shader = "toolchanges.vs"; fragment_shader = "toolchanges.fs"; break; } + case GCodeProcessor::EMoveType::Retract: { vertex_shader = "retractions.vs"; fragment_shader = "retractions.fs"; break; } + case GCodeProcessor::EMoveType::Unretract: { vertex_shader = "unretractions.vs"; fragment_shader = "unretractions.fs"; break; } + case GCodeProcessor::EMoveType::Extrude: { vertex_shader = "extrusions.vs"; fragment_shader = "extrusions.fs"; break; } + case GCodeProcessor::EMoveType::Travel: { vertex_shader = "travels.vs"; fragment_shader = "travels.fs"; break; } + default: { break; } + } - break; - } - case GCodeProcessor::EMoveType::Retract: - { - if (!m_buffers[i].init_shader("retractions.vs", "retractions.fs")) - return false; - - break; - } - case GCodeProcessor::EMoveType::Unretract: - { - if (!m_buffers[i].init_shader("unretractions.vs", "unretractions.fs")) - return false; - - break; - } - case GCodeProcessor::EMoveType::Extrude: - { - if (!m_buffers[i].init_shader("extrusions.vs", "extrusions.fs")) - return false; - - break; - } - case GCodeProcessor::EMoveType::Travel: - { - if (!m_buffers[i].init_shader("travels.vs", "travels.fs")) - return false; - - break; - } - default: - { - break; - } - } + if (vertex_shader.empty() || fragment_shader.empty() || !m_buffers[i].init_shader(vertex_shader, fragment_shader)) + return false; } if (!m_shells.shader.init("shells.vs", "shells.fs")) @@ -449,7 +429,7 @@ void GCodeViewer::render_toolpaths() const case EViewType::Width: { color = m_extrusions.ranges.width.get_color_at(path.width, m_extrusions.ranges.colors); break; } case EViewType::Feedrate: { color = m_extrusions.ranges.feedrate.get_color_at(path.feedrate, m_extrusions.ranges.colors); break; } case EViewType::FanSpeed: { color = m_extrusions.ranges.fan_speed.get_color_at(path.fan_speed, m_extrusions.ranges.colors); break; } - case EViewType::VolumetricRate: + case EViewType::VolumetricRate: { color = m_extrusions.ranges.volumetric_rate.get_color_at(path.volumetric_rate, m_extrusions.ranges.colors); break; } case EViewType::Tool: case EViewType::ColorPrint: default: { color = { 1.0f, 1.0f, 1.0f }; break; } @@ -654,11 +634,11 @@ void GCodeViewer::render_overlay() const } break; } - case EViewType::Height: { add_range(m_extrusions.ranges.height, 3); break; } - case EViewType::Width: { add_range(m_extrusions.ranges.width, 3); break; } - case EViewType::Feedrate: { add_range(m_extrusions.ranges.feedrate, 1); break; } - case EViewType::FanSpeed: { add_range(m_extrusions.ranges.fan_speed, 0); break; } - case EViewType::VolumetricRate: { break; } + case EViewType::Height: { add_range(m_extrusions.ranges.height, 3); break; } + case EViewType::Width: { add_range(m_extrusions.ranges.width, 3); break; } + case EViewType::Feedrate: { add_range(m_extrusions.ranges.feedrate, 1); break; } + case EViewType::FanSpeed: { add_range(m_extrusions.ranges.fan_speed, 0); break; } + case EViewType::VolumetricRate: { add_range(m_extrusions.ranges.volumetric_rate, 3); break; } case EViewType::Tool: { break; } case EViewType::ColorPrint: { break; } } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 644f088424..6f27c68522 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -44,9 +44,11 @@ class GCodeViewer float width{ 0.0f }; float feedrate{ 0.0f }; float fan_speed{ 0.0f }; + float volumetric_rate{ 0.0f }; bool matches(const GCodeProcessor::MoveVertex& move) const { - return type == move.type && role == move.extrusion_role && height == move.height && width == move.width && feedrate == move.feedrate && fan_speed == move.fan_speed; + return type == move.type && role == move.extrusion_role && height == move.height && width == move.width && + feedrate == move.feedrate && fan_speed == move.fan_speed && volumetric_rate == move.volumetric_rate(); } }; @@ -82,17 +84,8 @@ class GCodeViewer Range() { reset(); } - void update_from(const float value) - { - min = std::min(min, value); - max = std::max(max, value); - } - - void reset() - { - min = FLT_MAX; - max = -FLT_MAX; - } + void update_from(const float value) { min = std::min(min, value); max = std::max(max, value); } + void reset() { min = FLT_MAX; max = -FLT_MAX; } float step_size() const { return (max - min) / (static_cast(Default_Range_Colors_Count) - 1.0f); } std::array get_color_at(float value, const std::array, Default_Range_Colors_Count>& colors) const; @@ -110,14 +103,15 @@ class GCodeViewer Range feedrate; // Color mapping by fan speed. Range fan_speed; -// // Color mapping by volumetric extrusion rate. -// Range volumetric_rate; + // Color mapping by volumetric extrusion rate. + Range volumetric_rate; void reset() { height.reset(); width.reset(); feedrate.reset(); fan_speed.reset(); + volumetric_rate.reset(); } }; From 61db595f5328b2b04153217ee63994c5719acd61 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 21 Apr 2020 12:51:58 +0200 Subject: [PATCH 030/255] GCodeViewer -> Refactoring --- src/slic3r/GUI/GCodeViewer.cpp | 29 +++++++++++++++-------------- src/slic3r/GUI/GCodeViewer.hpp | 15 +++++---------- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index e02a809934..ad15a0bb9d 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -71,13 +71,13 @@ void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move) paths.push_back({ move.type, move.extrusion_role, id, id, move.height, move.width, move.feedrate, move.fan_speed, move.volumetric_rate() }); } -std::array GCodeViewer::Extrusions::Range::get_color_at(float value, const std::array, Default_Range_Colors_Count>& colors) const +std::array GCodeViewer::Extrusions::Range::get_color_at(float value) const { // Input value scaled to the colors range const float step = step_size(); const float global_t = (step != 0.0f) ? std::max(0.0f, value - min) / step : 0.0f; // lower limit of 0.0f - const size_t color_max_idx = colors.size() - 1; + const size_t color_max_idx = Range_Colors.size() - 1; // Compute the two colors just below (low) and above (high) the input value const size_t color_low_idx = std::clamp(static_cast(global_t), 0, color_max_idx); @@ -90,12 +90,12 @@ std::array GCodeViewer::Extrusions::Range::get_color_at(float value, c std::array ret; for (unsigned int i = 0; i < 3; ++i) { - ret[i] = lerp(colors[color_low_idx][i], colors[color_high_idx][i], local_t); + ret[i] = lerp(Range_Colors[color_low_idx][i], Range_Colors[color_high_idx][i], local_t); } return ret; } -const std::array, erCount> GCodeViewer::Default_Extrusion_Role_Colors {{ +const std::array, erCount> GCodeViewer::Extrusion_Role_Colors{ { { 1.00f, 1.00f, 1.00f }, // erNone { 1.00f, 1.00f, 0.40f }, // erPerimeter { 1.00f, 0.65f, 0.00f }, // erExternalPerimeter @@ -113,7 +113,7 @@ const std::array, erCount> GCodeViewer::Default_Extrusion_R { 0.00f, 0.00f, 0.00f } // erMixed }}; -const std::array, GCodeViewer::Default_Range_Colors_Count> GCodeViewer::Default_Range_Colors {{ +const std::array, GCodeViewer::Range_Colors_Count> GCodeViewer::Range_Colors{ { { 0.043f, 0.173f, 0.478f }, // bluish { 0.075f, 0.349f, 0.522f }, { 0.110f, 0.533f, 0.569f }, @@ -424,12 +424,12 @@ void GCodeViewer::render_toolpaths() const std::array color; switch (m_view_type) { - case EViewType::FeatureType: { color = m_extrusions.role_colors[static_cast(path.role)]; break; } - case EViewType::Height: { color = m_extrusions.ranges.height.get_color_at(path.height, m_extrusions.ranges.colors); break; } - case EViewType::Width: { color = m_extrusions.ranges.width.get_color_at(path.width, m_extrusions.ranges.colors); break; } - case EViewType::Feedrate: { color = m_extrusions.ranges.feedrate.get_color_at(path.feedrate, m_extrusions.ranges.colors); break; } - case EViewType::FanSpeed: { color = m_extrusions.ranges.fan_speed.get_color_at(path.fan_speed, m_extrusions.ranges.colors); break; } - case EViewType::VolumetricRate: { color = m_extrusions.ranges.volumetric_rate.get_color_at(path.volumetric_rate, m_extrusions.ranges.colors); break; } + case EViewType::FeatureType: { color = Extrusion_Role_Colors[static_cast(path.role)]; break; } + case EViewType::Height: { color = m_extrusions.ranges.height.get_color_at(path.height); break; } + case EViewType::Width: { color = m_extrusions.ranges.width.get_color_at(path.width); break; } + case EViewType::Feedrate: { color = m_extrusions.ranges.feedrate.get_color_at(path.feedrate); break; } + case EViewType::FanSpeed: { color = m_extrusions.ranges.fan_speed.get_color_at(path.fan_speed); break; } + case EViewType::VolumetricRate: { color = m_extrusions.ranges.volumetric_rate.get_color_at(path.volumetric_rate); break; } case EViewType::Tool: case EViewType::ColorPrint: default: { color = { 1.0f, 1.0f, 1.0f }; break; } @@ -453,6 +453,7 @@ void GCodeViewer::render_toolpaths() const }; glsafe(::glCullFace(GL_BACK)); + glsafe(::glLineWidth(1.0f)); unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); unsigned char end_id = buffer_id(GCodeProcessor::EMoveType::Count); @@ -579,7 +580,7 @@ void GCodeViewer::render_overlay() const auto add_item = [this, draw_list, &imgui](int i, float value, unsigned int decimals) { ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f); draw_list->AddRect(ImVec2(pos.x, pos.y), ImVec2(pos.x + ICON_BORDER_SIZE, pos.y + ICON_BORDER_SIZE), ICON_BORDER_COLOR, 0.0f, 0); - const std::array& color = m_extrusions.ranges.colors[i]; + const std::array& color = Range_Colors[i]; ImU32 fill_color = ImGui::GetColorU32(ImVec4(color[0], color[1], color[2], 1.0f)); draw_list->AddRectFilled(ImVec2(pos.x + 1.0f, pos.y + 1.0f), ImVec2(pos.x + ICON_BORDER_SIZE - 1.0f, pos.y + ICON_BORDER_SIZE - 1.0f), fill_color); ImGui::SetCursorPosX(pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT); @@ -594,7 +595,7 @@ void GCodeViewer::render_overlay() const add_item(0, range.min, decimals); else { - for (int i = Default_Range_Colors_Count - 1; i >= 0; --i) + for (int i = Range_Colors_Count - 1; i >= 0; --i) { add_item(i, range.min + static_cast(i) * step_size, decimals); } @@ -625,7 +626,7 @@ void GCodeViewer::render_overlay() const { ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f); draw_list->AddRect(ImVec2(pos.x, pos.y), ImVec2(pos.x + ICON_BORDER_SIZE, pos.y + ICON_BORDER_SIZE), ICON_BORDER_COLOR, 0.0f, 0); - const std::array& color = m_extrusions.role_colors[static_cast(role)]; + const std::array& color = Extrusion_Role_Colors[static_cast(role)]; ImU32 fill_color = ImGui::GetColorU32(ImVec4(color[0], color[1], color[2], 1.0)); draw_list->AddRectFilled(ImVec2(pos.x + 1.0f, pos.y + 1.0f), ImVec2(pos.x + ICON_BORDER_SIZE - 1.0f, pos.y + ICON_BORDER_SIZE - 1.0f), fill_color); ImGui::SetCursorPosX(pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 6f27c68522..a4d42556cb 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -15,9 +15,9 @@ namespace GUI { class GCodeViewer { - static const std::array, erCount> Default_Extrusion_Role_Colors; - static const size_t Default_Range_Colors_Count = 10; - static const std::array, Default_Range_Colors_Count> Default_Range_Colors; + static const std::array, erCount> Extrusion_Role_Colors; + static const size_t Range_Colors_Count = 10; + static const std::array, Range_Colors_Count> Range_Colors; // buffer containing vertices data struct VBuffer @@ -87,14 +87,12 @@ class GCodeViewer void update_from(const float value) { min = std::min(min, value); max = std::max(max, value); } void reset() { min = FLT_MAX; max = -FLT_MAX; } - float step_size() const { return (max - min) / (static_cast(Default_Range_Colors_Count) - 1.0f); } - std::array get_color_at(float value, const std::array, Default_Range_Colors_Count>& colors) const; + float step_size() const { return (max - min) / (static_cast(Range_Colors_Count) - 1.0f); } + std::array get_color_at(float value) const; }; struct Ranges { - std::array, Default_Range_Colors_Count> colors; - // Color mapping by layer height. Range height; // Color mapping by extrusion width. @@ -115,7 +113,6 @@ class GCodeViewer } }; - std::array, erCount> role_colors; unsigned int role_visibility_flags{ 0 }; Ranges ranges; @@ -166,8 +163,6 @@ public: ~GCodeViewer() { reset(); } bool init() { - m_extrusions.role_colors = Default_Extrusion_Role_Colors; - m_extrusions.ranges.colors = Default_Range_Colors; set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Extrude, true); return init_shaders(); } From 4c4485a9b5338a17b4838e94d65761659fa6cd9a Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 21 Apr 2020 15:55:26 +0200 Subject: [PATCH 031/255] GCodeViewer -> Extrusion toolpaths colored by tool --- src/slic3r/GUI/BitmapCache.cpp | 5 +++ src/slic3r/GUI/GCodeViewer.cpp | 64 ++++++++++++++++++++++++++++------ src/slic3r/GUI/GCodeViewer.hpp | 12 ++++--- src/slic3r/GUI/GLCanvas3D.cpp | 6 ++-- src/slic3r/GUI/GLCanvas3D.hpp | 2 +- src/slic3r/GUI/GUI_Preview.cpp | 2 +- src/slic3r/GUI/GUI_Utils.hpp | 9 +++++ 7 files changed, 81 insertions(+), 19 deletions(-) diff --git a/src/slic3r/GUI/BitmapCache.cpp b/src/slic3r/GUI/BitmapCache.cpp index 8627ef4cb6..c345f6bf7a 100644 --- a/src/slic3r/GUI/BitmapCache.cpp +++ b/src/slic3r/GUI/BitmapCache.cpp @@ -3,6 +3,9 @@ #include "libslic3r/Utils.hpp" #include "../Utils/MacDarkMode.hpp" #include "GUI.hpp" +#if ENABLE_GCODE_VIEWER +#include "GUI_Utils.hpp" +#endif // ENABLE_GCODE_VIEWER #include @@ -352,6 +355,7 @@ wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsi } +#if !ENABLE_GCODE_VIEWER static inline int hex_digit_to_int(const char c) { return @@ -359,6 +363,7 @@ static inline int hex_digit_to_int(const char c) (c >= 'A' && c <= 'F') ? int(c - 'A') + 10 : (c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1; } +#endif // !ENABLE_GCODE_VIEWER bool BitmapCache::parse_color(const std::string& scolor, unsigned char* rgb_out) { diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index ad15a0bb9d..0b5be19743 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -8,6 +8,9 @@ #include "Camera.hpp" #include "I18N.hpp" #include "libslic3r/I18N.hpp" +#if ENABLE_GCODE_VIEWER +#include "GUI_Utils.hpp" +#endif // ENABLE_GCODE_VIEWER #include #include @@ -27,6 +30,31 @@ static GCodeProcessor::EMoveType buffer_type(unsigned char id) { return static_cast(static_cast(GCodeProcessor::EMoveType::Retract) + id); } +std::vector> decode_colors(const std::vector& colors) +{ + static const float INV_255 = 1.0f / 255.0f; + + std::vector> output(colors.size(), {0.0f, 0.0f, 0.0f} ); + for (size_t i = 0; i < colors.size(); ++i) + { + const std::string& color = colors[i]; + const char* c = color.data() + 1; + if ((color.size() == 7) && (color.front() == '#')) + { + for (size_t j = 0; j < 3; ++j) + { + int digit1 = hex_digit_to_int(*c++); + int digit2 = hex_digit_to_int(*c++); + if ((digit1 == -1) || (digit2 == -1)) + break; + + output[i][j] = float(digit1 * 16 + digit2) * INV_255; + } + } + } + return output; +} + void GCodeViewer::VBuffer::reset() { // release gpu memory @@ -68,7 +96,7 @@ bool GCodeViewer::IBuffer::init_shader(const std::string& vertex_shader_src, con void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move) { unsigned int id = static_cast(data.size()); - paths.push_back({ move.type, move.extrusion_role, id, id, move.height, move.width, move.feedrate, move.fan_speed, move.volumetric_rate() }); + paths.push_back({ move.type, move.extrusion_role, id, id, move.height, move.width, move.feedrate, move.fan_speed, move.volumetric_rate(), move.extruder_id }); } std::array GCodeViewer::Extrusions::Range::get_color_at(float value) const @@ -95,7 +123,7 @@ std::array GCodeViewer::Extrusions::Range::get_color_at(float value) c return ret; } -const std::array, erCount> GCodeViewer::Extrusion_Role_Colors{ { +const std::array, erCount> GCodeViewer::Extrusion_Role_Colors {{ { 1.00f, 1.00f, 1.00f }, // erNone { 1.00f, 1.00f, 0.40f }, // erPerimeter { 1.00f, 0.65f, 0.00f }, // erExternalPerimeter @@ -113,7 +141,7 @@ const std::array, erCount> GCodeViewer::Extrusion_Role_Colo { 0.00f, 0.00f, 0.00f } // erMixed }}; -const std::array, GCodeViewer::Range_Colors_Count> GCodeViewer::Range_Colors{ { +const std::array, GCodeViewer::Range_Colors_Count> GCodeViewer::Range_Colors {{ { 0.043f, 0.173f, 0.478f }, // bluish { 0.075f, 0.349f, 0.522f }, { 0.110f, 0.533f, 0.569f }, @@ -126,8 +154,9 @@ const std::array, GCodeViewer::Range_Colors_Count> GCodeVie { 0.761f, 0.322f, 0.235f } // reddish }}; -void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized) +void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors, const Print& print, bool initialized) { + // avoid processing if called with the same gcode_result if (m_last_result_id == gcode_result.id) return; @@ -136,6 +165,8 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& // release gpu memory, if used reset(); + m_tool_colors = decode_colors(str_tool_colors); + load_toolpaths(gcode_result); load_shells(print, initialized); } @@ -170,10 +201,7 @@ void GCodeViewer::refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_r } break; } - default: - { - break; - } + default: { break; } } } } @@ -188,6 +216,7 @@ void GCodeViewer::reset() } m_bounding_box = BoundingBoxf3(); + m_tool_colors = std::vector>(); m_extrusions.reset_role_visibility_flags(); m_extrusions.reset_ranges(); m_shells.volumes.clear(); @@ -430,7 +459,7 @@ void GCodeViewer::render_toolpaths() const case EViewType::Feedrate: { color = m_extrusions.ranges.feedrate.get_color_at(path.feedrate); break; } case EViewType::FanSpeed: { color = m_extrusions.ranges.fan_speed.get_color_at(path.fan_speed); break; } case EViewType::VolumetricRate: { color = m_extrusions.ranges.volumetric_rate.get_color_at(path.volumetric_rate); break; } - case EViewType::Tool: + case EViewType::Tool: { color = m_tool_colors[path.extruder_id]; break; } case EViewType::ColorPrint: default: { color = { 1.0f, 1.0f, 1.0f }; break; } } @@ -640,7 +669,22 @@ void GCodeViewer::render_overlay() const case EViewType::Feedrate: { add_range(m_extrusions.ranges.feedrate, 1); break; } case EViewType::FanSpeed: { add_range(m_extrusions.ranges.fan_speed, 0); break; } case EViewType::VolumetricRate: { add_range(m_extrusions.ranges.volumetric_rate, 3); break; } - case EViewType::Tool: { break; } + case EViewType::Tool: + { + size_t tools_count = m_tool_colors.size(); + for (size_t i = 0; i < tools_count; ++i) + { + ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f); + draw_list->AddRect(ImVec2(pos.x, pos.y), ImVec2(pos.x + ICON_BORDER_SIZE, pos.y + ICON_BORDER_SIZE), ICON_BORDER_COLOR, 0.0f, 0); + const std::array& color = m_tool_colors[i]; + ImU32 fill_color = ImGui::GetColorU32(ImVec4(color[0], color[1], color[2], 1.0)); + draw_list->AddRectFilled(ImVec2(pos.x + 1.0f, pos.y + 1.0f), ImVec2(pos.x + ICON_BORDER_SIZE - 1.0f, pos.y + ICON_BORDER_SIZE - 1.0f), fill_color); + ImGui::SetCursorPosX(pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT); + ImGui::AlignTextToFramePadding(); + imgui.text((boost::format(Slic3r::I18N::translate(L("Extruder %d"))) % (i + 1)).str()); + } + break; + } case EViewType::ColorPrint: { break; } } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index a4d42556cb..956dd0b5d0 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -45,10 +45,12 @@ class GCodeViewer float feedrate{ 0.0f }; float fan_speed{ 0.0f }; float volumetric_rate{ 0.0f }; + unsigned char extruder_id{ 0 }; bool matches(const GCodeProcessor::MoveVertex& move) const { return type == move.type && role == move.extrusion_role && height == move.height && width == move.width && - feedrate == move.feedrate && fan_speed == move.fan_speed && volumetric_rate == move.volumetric_rate(); + feedrate == move.feedrate && fan_speed == move.fan_speed && volumetric_rate == move.volumetric_rate() && + extruder_id == move.extruder_id; } }; @@ -146,11 +148,11 @@ public: }; private: + unsigned int m_last_result_id{ 0 }; VBuffer m_vertices; std::vector m_buffers{ static_cast(GCodeProcessor::EMoveType::Extrude) }; BoundingBoxf3 m_bounding_box; - - unsigned int m_last_result_id{ 0 }; + std::vector> m_tool_colors; std::vector m_layers_zs; std::vector m_roles; Extrusions m_extrusions; @@ -167,7 +169,9 @@ public: return init_shaders(); } - void load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized); + // extract rendering data from the given parameters + void load(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors, const Print& print, bool initialized); + // recalculate ranges in dependence of what is visible void refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result); void reset(); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index e174a57833..540896a59f 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2835,7 +2835,7 @@ static void load_gcode_retractions(const GCodePreviewData::Retraction& retractio #endif // !ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER -void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result) +void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors) { #if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT static unsigned int last_result_id = 0; @@ -2852,7 +2852,7 @@ void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result) out.close(); } #endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT - m_gcode_viewer.load(gcode_result, *this->fff_print(), m_initialized); + m_gcode_viewer.load(gcode_result, str_tool_colors , *this->fff_print(), m_initialized); } void GLCanvas3D::refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result) @@ -6594,6 +6594,7 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector& str_ BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - end" << m_volumes.log_memory_info() << log_memory_info(); } +#if !ENABLE_GCODE_VIEWER static inline int hex_digit_to_int(const char c) { return @@ -6602,7 +6603,6 @@ static inline int hex_digit_to_int(const char c) (c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1; } -#if !ENABLE_GCODE_VIEWER void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_data, const std::vector& tool_colors) { BOOST_LOG_TRIVIAL(debug) << "Loading G-code extrusion paths - start" << m_volumes.log_memory_info() << log_memory_info(); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 312eeaa3b6..54f6e181e5 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -664,7 +664,7 @@ public: void reload_scene(bool refresh_immediately, bool force_full_scene_refresh = false); #if ENABLE_GCODE_VIEWER - void load_gcode_preview(const GCodeProcessor::Result& gcode_result); + void load_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors); void refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result); #else void load_gcode_preview(const GCodePreviewData& preview_data, const std::vector& str_tool_colors); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 2060511491..9476ad1f0b 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -984,7 +984,7 @@ void Preview::load_print_as_fff(bool keep_z_range) if (gcode_preview_data_valid) { // Load the real G-code preview. #if ENABLE_GCODE_VIEWER - m_canvas->load_gcode_preview(*m_gcode_result); + m_canvas->load_gcode_preview(*m_gcode_result, colors); m_canvas->refresh_toolpaths_ranges(*m_gcode_result); #else m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); diff --git a/src/slic3r/GUI/GUI_Utils.hpp b/src/slic3r/GUI/GUI_Utils.hpp index 0d5249e254..057c72b1d3 100644 --- a/src/slic3r/GUI/GUI_Utils.hpp +++ b/src/slic3r/GUI/GUI_Utils.hpp @@ -343,6 +343,15 @@ public: std::ostream& operator<<(std::ostream &os, const WindowMetrics& metrics); +#if ENABLE_GCODE_VIEWER +inline int hex_digit_to_int(const char c) +{ + return + (c >= '0' && c <= '9') ? int(c - '0') : + (c >= 'A' && c <= 'F') ? int(c - 'A') + 10 : + (c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1; +} +#endif // ENABLE_GCODE_VIEWER }} From 7a0df4bcb487c6f6e6fd3d3505ee12a5416df368 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 22 Apr 2020 16:29:07 +0200 Subject: [PATCH 032/255] GCodeViewer -> Extrusion toolpaths colored by color print (wip) + visualization of tool changes, color changes, pause prints, custom gcodes + refactoring --- resources/shaders/colorchanges.fs | 45 +++++ resources/shaders/colorchanges.vs | 17 ++ resources/shaders/customs.fs | 45 +++++ resources/shaders/customs.vs | 17 ++ resources/shaders/pauses.fs | 45 +++++ resources/shaders/pauses.vs | 17 ++ src/libslic3r/GCode.cpp | 2 + src/libslic3r/GCode/GCodeProcessor.cpp | 31 +++- src/libslic3r/GCode/GCodeProcessor.hpp | 7 + src/libslic3r/Technologies.hpp | 1 + src/slic3r/GUI/GCodeViewer.cpp | 226 +++++++++++++++++++------ src/slic3r/GUI/GCodeViewer.hpp | 18 +- src/slic3r/GUI/GLCanvas3D.cpp | 8 +- src/slic3r/GUI/GLCanvas3D.hpp | 6 +- src/slic3r/GUI/GUI_Preview.cpp | 96 ++++++++++- src/slic3r/GUI/GUI_Preview.hpp | 12 ++ 16 files changed, 516 insertions(+), 77 deletions(-) create mode 100644 resources/shaders/colorchanges.fs create mode 100644 resources/shaders/colorchanges.vs create mode 100644 resources/shaders/customs.fs create mode 100644 resources/shaders/customs.vs create mode 100644 resources/shaders/pauses.fs create mode 100644 resources/shaders/pauses.vs diff --git a/resources/shaders/colorchanges.fs b/resources/shaders/colorchanges.fs new file mode 100644 index 0000000000..fc81e487fb --- /dev/null +++ b/resources/shaders/colorchanges.fs @@ -0,0 +1,45 @@ +#version 110 + +#define INTENSITY_AMBIENT 0.3 +#define INTENSITY_CORRECTION 0.6 + +// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) +const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); +#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SHININESS 20.0 + +// normalized values for (1./1.43, 0.2/1.43, 1./1.43) +const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0); +#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) + +uniform vec3 uniform_color; + +varying vec3 eye_position; +varying vec3 eye_normal; +//varying float world_normal_z; + +// x = tainted, y = specular; +vec2 intensity; + +void main() +{ + vec3 normal = normalize(eye_normal); + + // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. + // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. + float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0); + + intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); + + // Perform the same lighting calculation for the 2nd light source (no specular applied). + NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + +// // darkens fragments whose normal points downward +// if (world_normal_z < 0.0) +// intensity.x *= (1.0 + world_normal_z * (1.0 - INTENSITY_AMBIENT)); + + gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color * intensity.x, 1.0); +} diff --git a/resources/shaders/colorchanges.vs b/resources/shaders/colorchanges.vs new file mode 100644 index 0000000000..3b78a59700 --- /dev/null +++ b/resources/shaders/colorchanges.vs @@ -0,0 +1,17 @@ +#version 110 + +varying vec3 eye_position; +varying vec3 eye_normal; +//// world z component of the normal used to darken the lower side of the toolpaths +//varying float world_normal_z; + +void main() +{ + eye_position = (gl_ModelViewMatrix * gl_Vertex).xyz; + eye_normal = gl_NormalMatrix * vec3(0.0, 0.0, 1.0); +// eye_normal = gl_NormalMatrix * gl_Normal; +// world_normal_z = gl_Normal.z; + gl_Position = ftransform(); + + gl_PointSize = 15.0; +} diff --git a/resources/shaders/customs.fs b/resources/shaders/customs.fs new file mode 100644 index 0000000000..fc81e487fb --- /dev/null +++ b/resources/shaders/customs.fs @@ -0,0 +1,45 @@ +#version 110 + +#define INTENSITY_AMBIENT 0.3 +#define INTENSITY_CORRECTION 0.6 + +// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) +const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); +#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SHININESS 20.0 + +// normalized values for (1./1.43, 0.2/1.43, 1./1.43) +const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0); +#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) + +uniform vec3 uniform_color; + +varying vec3 eye_position; +varying vec3 eye_normal; +//varying float world_normal_z; + +// x = tainted, y = specular; +vec2 intensity; + +void main() +{ + vec3 normal = normalize(eye_normal); + + // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. + // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. + float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0); + + intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); + + // Perform the same lighting calculation for the 2nd light source (no specular applied). + NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + +// // darkens fragments whose normal points downward +// if (world_normal_z < 0.0) +// intensity.x *= (1.0 + world_normal_z * (1.0 - INTENSITY_AMBIENT)); + + gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color * intensity.x, 1.0); +} diff --git a/resources/shaders/customs.vs b/resources/shaders/customs.vs new file mode 100644 index 0000000000..45fa543f45 --- /dev/null +++ b/resources/shaders/customs.vs @@ -0,0 +1,17 @@ +#version 110 + +varying vec3 eye_position; +varying vec3 eye_normal; +//// world z component of the normal used to darken the lower side of the toolpaths +//varying float world_normal_z; + +void main() +{ + eye_position = (gl_ModelViewMatrix * gl_Vertex).xyz; + eye_normal = gl_NormalMatrix * vec3(0.0, 0.0, 1.0); +// eye_normal = gl_NormalMatrix * gl_Normal; +// world_normal_z = gl_Normal.z; + gl_Position = ftransform(); + + gl_PointSize = 10.0; +} diff --git a/resources/shaders/pauses.fs b/resources/shaders/pauses.fs new file mode 100644 index 0000000000..fc81e487fb --- /dev/null +++ b/resources/shaders/pauses.fs @@ -0,0 +1,45 @@ +#version 110 + +#define INTENSITY_AMBIENT 0.3 +#define INTENSITY_CORRECTION 0.6 + +// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) +const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); +#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SHININESS 20.0 + +// normalized values for (1./1.43, 0.2/1.43, 1./1.43) +const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0); +#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) + +uniform vec3 uniform_color; + +varying vec3 eye_position; +varying vec3 eye_normal; +//varying float world_normal_z; + +// x = tainted, y = specular; +vec2 intensity; + +void main() +{ + vec3 normal = normalize(eye_normal); + + // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. + // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. + float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0); + + intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); + + // Perform the same lighting calculation for the 2nd light source (no specular applied). + NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + +// // darkens fragments whose normal points downward +// if (world_normal_z < 0.0) +// intensity.x *= (1.0 + world_normal_z * (1.0 - INTENSITY_AMBIENT)); + + gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color * intensity.x, 1.0); +} diff --git a/resources/shaders/pauses.vs b/resources/shaders/pauses.vs new file mode 100644 index 0000000000..45fa543f45 --- /dev/null +++ b/resources/shaders/pauses.vs @@ -0,0 +1,17 @@ +#version 110 + +varying vec3 eye_position; +varying vec3 eye_normal; +//// world z component of the normal used to darken the lower side of the toolpaths +//varying float world_normal_z; + +void main() +{ + eye_position = (gl_ModelViewMatrix * gl_Vertex).xyz; + eye_normal = gl_NormalMatrix * vec3(0.0, 0.0, 1.0); +// eye_normal = gl_NormalMatrix * gl_Normal; +// world_normal_z = gl_Normal.z; + gl_Position = ftransform(); + + gl_PointSize = 10.0; +} diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index ee7be7fea7..a1114e938e 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2329,11 +2329,13 @@ void GCode::process_layer( gcode += "\n; " + GCodeAnalyzer::End_Pause_Print_Or_Custom_Code_Tag + "\n"; #if ENABLE_GCODE_VIEWER +#if !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT // add tag for processor if (gcode.find(GCodeProcessor::Pause_Print_Tag) != gcode.npos) gcode += "\n; " + GCodeProcessor::End_Pause_Print_Or_Custom_Code_Tag + "\n"; else if (gcode.find(GCodeProcessor::Custom_Code_Tag) != gcode.npos) gcode += "\n; " + GCodeProcessor::End_Pause_Print_Or_Custom_Code_Tag + "\n"; +#endif // !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT #endif // ENABLE_GCODE_VIEWER #ifdef HAS_PRESSURE_EQUALIZER diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 78943dca89..2219facb51 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -24,7 +24,9 @@ const std::string GCodeProcessor::Mm3_Per_Mm_Tag = "_PROCESSOR_MM3_PER_MM:"; const std::string GCodeProcessor::Color_Change_Tag = "_PROCESSOR_COLOR_CHANGE"; const std::string GCodeProcessor::Pause_Print_Tag = "_PROCESSOR_PAUSE_PRINT"; const std::string GCodeProcessor::Custom_Code_Tag = "_PROCESSOR_CUSTOM_CODE"; +#if !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT const std::string GCodeProcessor::End_Pause_Print_Or_Custom_Code_Tag = "_PROCESSOR_END_PAUSE_PRINT_OR_CUSTOM_CODE"; +#endif // !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT void GCodeProcessor::CachedPosition::reset() { @@ -236,13 +238,20 @@ void GCodeProcessor::process_tags(const std::string& comment) pos = comment.find_last_of(",T"); try { - unsigned char extruder_id = (pos == comment.npos) ? 0 : static_cast(std::stoi(comment.substr(pos + 1, comment.npos))); + unsigned char extruder_id = (pos == comment.npos) ? 0 : static_cast(std::stoi(comment.substr(pos + 1))); m_extruders_color[extruder_id] = static_cast(m_extruder_offsets.size()) + m_cp_color.counter; // color_change position in list of color for preview ++m_cp_color.counter; + if (m_cp_color.counter == UCHAR_MAX) + m_cp_color.counter = 0; if (m_extruder_id == extruder_id) + { m_cp_color.current = m_extruders_color[extruder_id]; +#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT + store_move_vertex(EMoveType::Color_change); +#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT + } } catch (...) { @@ -256,7 +265,11 @@ void GCodeProcessor::process_tags(const std::string& comment) pos = comment.find(Pause_Print_Tag); if (pos != comment.npos) { - m_cp_color.current = 255; +#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT + store_move_vertex(EMoveType::Pause_Print); +#else + m_cp_color.current = UCHAR_MAX; +#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT return; } @@ -264,19 +277,25 @@ void GCodeProcessor::process_tags(const std::string& comment) pos = comment.find(Custom_Code_Tag); if (pos != comment.npos) { - m_cp_color.current = 255; +#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT + store_move_vertex(EMoveType::Custom_GCode); +#else + m_cp_color.current = UCHAR_MAX; +#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT return; } +#if !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT // end pause print or custom code tag pos = comment.find(End_Pause_Print_Or_Custom_Code_Tag); if (pos != comment.npos) { - if (m_cp_color.current == 255) + if (m_cp_color.current == UCHAR_MAX) m_cp_color.current = m_extruders_color[m_extruder_id]; return; } +#endif // !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT } void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) @@ -569,7 +588,9 @@ void GCodeProcessor::process_T(const std::string& command) else { m_extruder_id = id; - if (m_cp_color.current != 255) +#if !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT + if (m_cp_color.current != UCHAR_MAX) +#endif // !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT m_cp_color.current = m_extruders_color[id]; } diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 38adce3329..cd4e021cae 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -21,7 +21,9 @@ namespace Slic3r { static const std::string Color_Change_Tag; static const std::string Pause_Print_Tag; static const std::string Custom_Code_Tag; +#if !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT static const std::string End_Pause_Print_Or_Custom_Code_Tag; +#endif // !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT private: using AxisCoords = std::array; @@ -62,6 +64,11 @@ namespace Slic3r { Retract, Unretract, Tool_change, +#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT + Color_change, + Pause_Print, + Custom_GCode, +#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT Travel, Extrude, Count diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 1ed939ba3e..8d1e19eceb 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -59,6 +59,7 @@ // Enable G-Code viewer #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) #define ENABLE_GCODE_VIEWER_DEBUG_OUTPUT (0 && ENABLE_GCODE_VIEWER) +#define ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT (1 && ENABLE_GCODE_VIEWER) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 0b5be19743..2f039da0b3 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -7,9 +7,10 @@ #include "PresetBundle.hpp" #include "Camera.hpp" #include "I18N.hpp" -#include "libslic3r/I18N.hpp" #if ENABLE_GCODE_VIEWER #include "GUI_Utils.hpp" +#include "DoubleSlider.hpp" +#include "libslic3r/Model.hpp" #endif // ENABLE_GCODE_VIEWER #include @@ -96,7 +97,7 @@ bool GCodeViewer::IBuffer::init_shader(const std::string& vertex_shader_src, con void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move) { unsigned int id = static_cast(data.size()); - paths.push_back({ move.type, move.extrusion_role, id, id, move.height, move.width, move.feedrate, move.fan_speed, move.volumetric_rate(), move.extruder_id }); + paths.push_back({ move.type, move.extrusion_role, id, id, move.height, move.width, move.feedrate, move.fan_speed, move.volumetric_rate(), move.extruder_id, move.cp_color_id }); } std::array GCodeViewer::Extrusions::Range::get_color_at(float value) const @@ -123,8 +124,8 @@ std::array GCodeViewer::Extrusions::Range::get_color_at(float value) c return ret; } -const std::array, erCount> GCodeViewer::Extrusion_Role_Colors {{ - { 1.00f, 1.00f, 1.00f }, // erNone +const std::vector> GCodeViewer::Extrusion_Role_Colors {{ + { 0.50f, 0.50f, 0.50f }, // erNone { 1.00f, 1.00f, 0.40f }, // erPerimeter { 1.00f, 0.65f, 0.00f }, // erExternalPerimeter { 0.00f, 0.00f, 1.00f }, // erOverhangPerimeter @@ -141,7 +142,7 @@ const std::array, erCount> GCodeViewer::Extrusion_Role_Colo { 0.00f, 0.00f, 0.00f } // erMixed }}; -const std::array, GCodeViewer::Range_Colors_Count> GCodeViewer::Range_Colors {{ +const std::vector> GCodeViewer::Range_Colors {{ { 0.043f, 0.173f, 0.478f }, // bluish { 0.075f, 0.349f, 0.522f }, { 0.110f, 0.533f, 0.569f }, @@ -154,7 +155,7 @@ const std::array, GCodeViewer::Range_Colors_Count> GCodeVie { 0.761f, 0.322f, 0.235f } // reddish }}; -void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors, const Print& print, bool initialized) +void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized) { // avoid processing if called with the same gcode_result if (m_last_result_id == gcode_result.id) @@ -165,17 +166,17 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const std::ve // release gpu memory, if used reset(); - m_tool_colors = decode_colors(str_tool_colors); - load_toolpaths(gcode_result); load_shells(print, initialized); } -void GCodeViewer::refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result) +void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors) { if (m_vertices.vertices_count == 0) return; + m_tool_colors = decode_colors(str_tool_colors); + m_extrusions.reset_ranges(); for (size_t i = 0; i < m_vertices.vertices_count; ++i) @@ -217,6 +218,8 @@ void GCodeViewer::reset() m_bounding_box = BoundingBoxf3(); m_tool_colors = std::vector>(); + m_extruder_ids = std::vector(); +// m_cp_color_ids = std::vector(); m_extrusions.reset_role_visibility_flags(); m_extrusions.reset_ranges(); m_shells.volumes.clear(); @@ -257,11 +260,16 @@ bool GCodeViewer::init_shaders() switch (buffer_type(i)) { - case GCodeProcessor::EMoveType::Tool_change: { vertex_shader = "toolchanges.vs"; fragment_shader = "toolchanges.fs"; break; } - case GCodeProcessor::EMoveType::Retract: { vertex_shader = "retractions.vs"; fragment_shader = "retractions.fs"; break; } - case GCodeProcessor::EMoveType::Unretract: { vertex_shader = "unretractions.vs"; fragment_shader = "unretractions.fs"; break; } - case GCodeProcessor::EMoveType::Extrude: { vertex_shader = "extrusions.vs"; fragment_shader = "extrusions.fs"; break; } - case GCodeProcessor::EMoveType::Travel: { vertex_shader = "travels.vs"; fragment_shader = "travels.fs"; break; } + case GCodeProcessor::EMoveType::Tool_change: { vertex_shader = "toolchanges.vs"; fragment_shader = "toolchanges.fs"; break; } +#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT + case GCodeProcessor::EMoveType::Color_change: { vertex_shader = "colorchanges.vs"; fragment_shader = "colorchanges.fs"; break; } + case GCodeProcessor::EMoveType::Pause_Print: { vertex_shader = "pauses.vs"; fragment_shader = "pauses.fs"; break; } + case GCodeProcessor::EMoveType::Custom_GCode: { vertex_shader = "customs.vs"; fragment_shader = "customs.fs"; break; } +#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT + case GCodeProcessor::EMoveType::Retract: { vertex_shader = "retractions.vs"; fragment_shader = "retractions.fs"; break; } + case GCodeProcessor::EMoveType::Unretract: { vertex_shader = "unretractions.vs"; fragment_shader = "unretractions.fs"; break; } + case GCodeProcessor::EMoveType::Extrude: { vertex_shader = "extrusions.vs"; fragment_shader = "extrusions.fs"; break; } + case GCodeProcessor::EMoveType::Travel: { vertex_shader = "travels.vs"; fragment_shader = "travels.fs"; break; } default: { break; } } @@ -322,6 +330,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) switch (curr.type) { case GCodeProcessor::EMoveType::Tool_change: +#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT + case GCodeProcessor::EMoveType::Color_change: + case GCodeProcessor::EMoveType::Pause_Print: + case GCodeProcessor::EMoveType::Custom_GCode: +#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT case GCodeProcessor::EMoveType::Retract: case GCodeProcessor::EMoveType::Unretract: { @@ -365,13 +378,15 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) } } - // layers zs / roles -> extract from result + // layers zs / roles / extruder ids / cp color ids -> extract from result for (const GCodeProcessor::MoveVertex& move : gcode_result.moves) { if (move.type == GCodeProcessor::EMoveType::Extrude) m_layers_zs.emplace_back(move.position[2]); m_roles.emplace_back(move.extrusion_role); + m_extruder_ids.emplace_back(move.extruder_id); +// m_cp_color_ids.emplace_back(move.cp_color_id); } // layers zs -> replace intervals of layers with similar top positions with their average value. @@ -392,6 +407,14 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) std::sort(m_roles.begin(), m_roles.end()); m_roles.erase(std::unique(m_roles.begin(), m_roles.end()), m_roles.end()); + // extruder ids -> remove duplicates + std::sort(m_extruder_ids.begin(), m_extruder_ids.end()); + m_extruder_ids.erase(std::unique(m_extruder_ids.begin(), m_extruder_ids.end()), m_extruder_ids.end()); + +// // cp color ids -> remove duplicates +// std::sort(m_cp_color_ids.begin(), m_cp_color_ids.end()); +// m_cp_color_ids.erase(std::unique(m_cp_color_ids.begin(), m_cp_color_ids.end()), m_cp_color_ids.end()); + auto end_time = std::chrono::high_resolution_clock::now(); std::cout << "toolpaths generation time: " << std::chrono::duration_cast(end_time - start_time).count() << "ms \n"; } @@ -460,7 +483,7 @@ void GCodeViewer::render_toolpaths() const case EViewType::FanSpeed: { color = m_extrusions.ranges.fan_speed.get_color_at(path.fan_speed); break; } case EViewType::VolumetricRate: { color = m_extrusions.ranges.volumetric_rate.get_color_at(path.volumetric_rate); break; } case EViewType::Tool: { color = m_tool_colors[path.extruder_id]; break; } - case EViewType::ColorPrint: + case EViewType::ColorPrint: { color = m_tool_colors[path.cp_color_id]; break; } default: { color = { 1.0f, 1.0f, 1.0f }; break; } } return color; @@ -482,7 +505,7 @@ void GCodeViewer::render_toolpaths() const }; glsafe(::glCullFace(GL_BACK)); - glsafe(::glLineWidth(1.0f)); + glsafe(::glLineWidth(3.0f)); unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); unsigned char end_id = buffer_id(GCodeProcessor::EMoveType::Count); @@ -522,6 +545,35 @@ void GCodeViewer::render_toolpaths() const glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); break; } +#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT + case GCodeProcessor::EMoveType::Color_change: + { + std::array color = { 1.0f, 0.0f, 0.0f }; + set_color(current_program_id, color); + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glDrawElements(GL_POINTS, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + break; + } + case GCodeProcessor::EMoveType::Pause_Print: + { + std::array color = { 0.0f, 1.0f, 0.0f }; + set_color(current_program_id, color); + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glDrawElements(GL_POINTS, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + break; + } + case GCodeProcessor::EMoveType::Custom_GCode: + { + std::array color = { 0.0f, 0.0f, 1.0f }; + set_color(current_program_id, color); + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glDrawElements(GL_POINTS, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + break; + } +#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT case GCodeProcessor::EMoveType::Retract: { std::array color = { 1.0f, 0.0f, 1.0f }; @@ -533,7 +585,7 @@ void GCodeViewer::render_toolpaths() const } case GCodeProcessor::EMoveType::Unretract: { - std::array color = { 0.0f, 1.0f, 0.0f }; + std::array color = { 0.0f, 1.0f, 1.0f }; set_color(current_program_id, color); glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); glsafe(::glDrawElements(GL_POINTS, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); @@ -605,28 +657,32 @@ void GCodeViewer::render_overlay() const ImDrawList* draw_list = ImGui::GetWindowDrawList(); - auto add_range = [this, draw_list, &imgui](const Extrusions::Range& range, unsigned int decimals) { - auto add_item = [this, draw_list, &imgui](int i, float value, unsigned int decimals) { - ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f); - draw_list->AddRect(ImVec2(pos.x, pos.y), ImVec2(pos.x + ICON_BORDER_SIZE, pos.y + ICON_BORDER_SIZE), ICON_BORDER_COLOR, 0.0f, 0); - const std::array& color = Range_Colors[i]; - ImU32 fill_color = ImGui::GetColorU32(ImVec4(color[0], color[1], color[2], 1.0f)); - draw_list->AddRectFilled(ImVec2(pos.x + 1.0f, pos.y + 1.0f), ImVec2(pos.x + ICON_BORDER_SIZE - 1.0f, pos.y + ICON_BORDER_SIZE - 1.0f), fill_color); - ImGui::SetCursorPosX(pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT); - ImGui::AlignTextToFramePadding(); + auto add_item = [draw_list, &imgui](const std::array& color, const std::string& label) { + ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f); + draw_list->AddRect(ImVec2(pos.x, pos.y), ImVec2(pos.x + ICON_BORDER_SIZE, pos.y + ICON_BORDER_SIZE), ICON_BORDER_COLOR, 0.0f, 0); + ImU32 fill_color = ImGui::GetColorU32(ImVec4(color[0], color[1], color[2], 1.0f)); + draw_list->AddRectFilled(ImVec2(pos.x + 1.0f, pos.y + 1.0f), ImVec2(pos.x + ICON_BORDER_SIZE - 1.0f, pos.y + ICON_BORDER_SIZE - 1.0f), fill_color); + ImGui::SetCursorPosX(pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT); + ImGui::AlignTextToFramePadding(); + imgui.text(label); + }; + + auto add_range = [this, draw_list, &imgui, add_item](const Extrusions::Range& range, unsigned int decimals) { + auto add_range_item = [this, draw_list, &imgui, add_item](int i, float value, unsigned int decimals) { char buf[1024]; ::sprintf(buf, "%.*f", decimals, value); - imgui.text(buf); + add_item(Range_Colors[i], buf); }; float step_size = range.step_size(); if (step_size == 0.0f) - add_item(0, range.min, decimals); + // single item use case + add_range_item(0, range.min, decimals); else { - for (int i = Range_Colors_Count - 1; i >= 0; --i) + for (int i = static_cast(Range_Colors.size()) - 1; i >= 0; --i) { - add_item(i, range.min + static_cast(i) * step_size, decimals); + add_range_item(i, range.min + static_cast(i) * step_size, decimals); } } }; @@ -634,14 +690,15 @@ void GCodeViewer::render_overlay() const ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); switch (m_view_type) { - case EViewType::FeatureType: { imgui.text(Slic3r::I18N::translate(L("Feature type"))); break; } - case EViewType::Height: { imgui.text(Slic3r::I18N::translate(L("Height (mm)"))); break; } - case EViewType::Width: { imgui.text(Slic3r::I18N::translate(L("Width (mm)"))); break; } - case EViewType::Feedrate: { imgui.text(Slic3r::I18N::translate(L("Speed (mm/s)"))); break; } - case EViewType::FanSpeed: { imgui.text(Slic3r::I18N::translate(L("Fan Speed (%)"))); break; } - case EViewType::VolumetricRate: { imgui.text(Slic3r::I18N::translate(L("Volumetric flow rate (mm³/s)"))); break; } - case EViewType::Tool: { imgui.text(Slic3r::I18N::translate(L("Tool"))); break; } - case EViewType::ColorPrint: { imgui.text(Slic3r::I18N::translate(L("Color Print"))); break; } + case EViewType::FeatureType: { imgui.text(I18N::translate_utf8(L("Feature type"))); break; } + case EViewType::Height: { imgui.text(I18N::translate_utf8(L("Height (mm)"))); break; } + case EViewType::Width: { imgui.text(I18N::translate_utf8(L("Width (mm)"))); break; } + case EViewType::Feedrate: { imgui.text(I18N::translate_utf8(L("Speed (mm/s)"))); break; } + case EViewType::FanSpeed: { imgui.text(I18N::translate_utf8(L("Fan Speed (%)"))); break; } + case EViewType::VolumetricRate: { imgui.text(I18N::translate_utf8(L("Volumetric flow rate (mm³/s)"))); break; } + case EViewType::Tool: { imgui.text(I18N::translate_utf8(L("Tool"))); break; } + case EViewType::ColorPrint: { imgui.text(I18N::translate_utf8(L("Color Print"))); break; } + default: { break; } } ImGui::PopStyleColor(); @@ -653,14 +710,7 @@ void GCodeViewer::render_overlay() const { for (ExtrusionRole role : m_roles) { - ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f); - draw_list->AddRect(ImVec2(pos.x, pos.y), ImVec2(pos.x + ICON_BORDER_SIZE, pos.y + ICON_BORDER_SIZE), ICON_BORDER_COLOR, 0.0f, 0); - const std::array& color = Extrusion_Role_Colors[static_cast(role)]; - ImU32 fill_color = ImGui::GetColorU32(ImVec4(color[0], color[1], color[2], 1.0)); - draw_list->AddRectFilled(ImVec2(pos.x + 1.0f, pos.y + 1.0f), ImVec2(pos.x + ICON_BORDER_SIZE - 1.0f, pos.y + ICON_BORDER_SIZE - 1.0f), fill_color); - ImGui::SetCursorPosX(pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT); - ImGui::AlignTextToFramePadding(); - imgui.text(Slic3r::I18N::translate(ExtrusionEntity::role_to_string(role))); + add_item(Extrusion_Role_Colors[static_cast(role)], I18N::translate_utf8(ExtrusionEntity::role_to_string(role))); } break; } @@ -674,18 +724,82 @@ void GCodeViewer::render_overlay() const size_t tools_count = m_tool_colors.size(); for (size_t i = 0; i < tools_count; ++i) { - ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f); - draw_list->AddRect(ImVec2(pos.x, pos.y), ImVec2(pos.x + ICON_BORDER_SIZE, pos.y + ICON_BORDER_SIZE), ICON_BORDER_COLOR, 0.0f, 0); - const std::array& color = m_tool_colors[i]; - ImU32 fill_color = ImGui::GetColorU32(ImVec4(color[0], color[1], color[2], 1.0)); - draw_list->AddRectFilled(ImVec2(pos.x + 1.0f, pos.y + 1.0f), ImVec2(pos.x + ICON_BORDER_SIZE - 1.0f, pos.y + ICON_BORDER_SIZE - 1.0f), fill_color); - ImGui::SetCursorPosX(pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT); - ImGui::AlignTextToFramePadding(); - imgui.text((boost::format(Slic3r::I18N::translate(L("Extruder %d"))) % (i + 1)).str()); + auto it = std::find(m_extruder_ids.begin(), m_extruder_ids.end(), static_cast(i)); + if (it == m_extruder_ids.end()) + continue; + + add_item(m_tool_colors[i], (boost::format(I18N::translate_utf8(L("Extruder %d"))) % (i + 1)).str()); } break; } - case EViewType::ColorPrint: { break; } + case EViewType::ColorPrint: + { + const std::vector& custom_gcode_per_print_z = wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes; + const int extruders_count = wxGetApp().extruders_edited_cnt(); + if (extruders_count == 1) // single extruder use case + { + if (custom_gcode_per_print_z.empty()) + // no data to show + add_item(m_tool_colors.front(), I18N::translate_utf8(L("Default print color"))); + else + { + std::vector> cp_values; + cp_values.reserve(custom_gcode_per_print_z.size()); + + for (auto custom_code : custom_gcode_per_print_z) + { + if (custom_code.gcode != ColorChangeCode) + continue; + + auto lower_b = std::lower_bound(m_layers_zs.begin(), m_layers_zs.end(), custom_code.print_z - Slic3r::DoubleSlider::epsilon()); + + if (lower_b == m_layers_zs.end()) + continue; + + double current_z = *lower_b; + double previous_z = lower_b == m_layers_zs.begin() ? 0.0 : *(--lower_b); + + // to avoid duplicate values, check adding values + if (cp_values.empty() || + !(cp_values.back().first == previous_z && cp_values.back().second == current_z)) + cp_values.emplace_back(std::make_pair(previous_z, current_z)); + } + + const int items_cnt = static_cast(cp_values.size()); + if (items_cnt == 0) // There is no one color change, but there are some pause print or custom Gcode + { + add_item(m_tool_colors.front(), I18N::translate_utf8(L("Default print color"))); +#if !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT + add_item(m_tool_colors.back(), I18N::translate_utf8(L("Pause print or custom G-code"))); +#endif // !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT + } + else + { + for (int i = items_cnt; i >= 0; --i) + { + // create label for color print item + std::string id_str = std::to_string(i + 1) + ": "; + + if (i == 0) { + add_item(m_tool_colors[i], id_str + (boost::format(I18N::translate_utf8(L("up to %.2f mm"))) % cp_values.front().first).str()); + break; + } + else if (i == items_cnt) { + add_item(m_tool_colors[i], id_str + (boost::format(I18N::translate_utf8(L("above %.2f mm"))) % cp_values[i - 1].second).str()); + continue; + } + add_item(m_tool_colors[i], id_str + (boost::format(I18N::translate_utf8(L("%.2f - %.2f mm"))) % cp_values[i - 1].second % cp_values[i].first).str()); + } + } + } + } + else + { + } + + break; + } + default: { break; } } imgui.end(); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 956dd0b5d0..5ce497c976 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -15,9 +15,8 @@ namespace GUI { class GCodeViewer { - static const std::array, erCount> Extrusion_Role_Colors; - static const size_t Range_Colors_Count = 10; - static const std::array, Range_Colors_Count> Range_Colors; + static const std::vector> Extrusion_Role_Colors; + static const std::vector> Range_Colors; // buffer containing vertices data struct VBuffer @@ -46,11 +45,12 @@ class GCodeViewer float fan_speed{ 0.0f }; float volumetric_rate{ 0.0f }; unsigned char extruder_id{ 0 }; + unsigned char cp_color_id{ 0 }; bool matches(const GCodeProcessor::MoveVertex& move) const { return type == move.type && role == move.extrusion_role && height == move.height && width == move.width && feedrate == move.feedrate && fan_speed == move.fan_speed && volumetric_rate == move.volumetric_rate() && - extruder_id == move.extruder_id; + extruder_id == move.extruder_id && cp_color_id == move.cp_color_id; } }; @@ -89,7 +89,7 @@ class GCodeViewer void update_from(const float value) { min = std::min(min, value); max = std::max(max, value); } void reset() { min = FLT_MAX; max = -FLT_MAX; } - float step_size() const { return (max - min) / (static_cast(Range_Colors_Count) - 1.0f); } + float step_size() const { return (max - min) / (static_cast(Range_Colors.size()) - 1.0f); } std::array get_color_at(float value) const; }; @@ -155,6 +155,8 @@ private: std::vector> m_tool_colors; std::vector m_layers_zs; std::vector m_roles; + std::vector m_extruder_ids; +// std::vector m_cp_color_ids; Extrusions m_extrusions; Shells m_shells; EViewType m_view_type{ EViewType::FeatureType }; @@ -170,9 +172,9 @@ public: } // extract rendering data from the given parameters - void load(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors, const Print& print, bool initialized); - // recalculate ranges in dependence of what is visible - void refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result); + void load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized); + // recalculate ranges in dependence of what is visible and sets tool/print colors + void refresh(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors); void reset(); void render() const; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 540896a59f..225fb427cf 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2835,7 +2835,7 @@ static void load_gcode_retractions(const GCodePreviewData::Retraction& retractio #endif // !ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER -void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors) +void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result) { #if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT static unsigned int last_result_id = 0; @@ -2852,12 +2852,12 @@ void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result, out.close(); } #endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT - m_gcode_viewer.load(gcode_result, str_tool_colors , *this->fff_print(), m_initialized); + m_gcode_viewer.load(gcode_result, *this->fff_print(), m_initialized); } -void GLCanvas3D::refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result) +void GLCanvas3D::refresh_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors) { - m_gcode_viewer.refresh_toolpaths_ranges(gcode_result); + m_gcode_viewer.refresh(gcode_result, str_tool_colors); } #endif // ENABLE_GCODE_VIEWER diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 54f6e181e5..25647b5e55 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -664,8 +664,10 @@ public: void reload_scene(bool refresh_immediately, bool force_full_scene_refresh = false); #if ENABLE_GCODE_VIEWER - void load_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors); - void refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result); + void load_gcode_preview(const GCodeProcessor::Result& gcode_result); + void refresh_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors); + void set_gcode_view_preview_type(GCodeViewer::EViewType type) { return m_gcode_viewer.set_view_type(type); } + GCodeViewer::EViewType get_gcode_view_preview_type() const { return m_gcode_viewer.get_view_type(); } #else void load_gcode_preview(const GCodePreviewData& preview_data, const std::vector& str_tool_colors); #endif // ENABLE_GCODE_VIEWER diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 9476ad1f0b..520534ca7d 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -229,6 +229,12 @@ Preview::Preview( , m_checkbox_travel(nullptr) , m_checkbox_retractions(nullptr) , m_checkbox_unretractions(nullptr) +#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT + , m_checkbox_tool_changes(nullptr) + , m_checkbox_color_changes(nullptr) + , m_checkbox_pause_prints(nullptr) + , m_checkbox_custom_gcodes(nullptr) +#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT , m_checkbox_shells(nullptr) , m_checkbox_legend(nullptr) , m_config(config) @@ -330,6 +336,12 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view m_checkbox_travel = new wxCheckBox(this, wxID_ANY, _(L("Travel"))); m_checkbox_retractions = new wxCheckBox(this, wxID_ANY, _(L("Retractions"))); m_checkbox_unretractions = new wxCheckBox(this, wxID_ANY, _(L("Unretractions"))); +#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT + m_checkbox_tool_changes = new wxCheckBox(this, wxID_ANY, _(L("Tool changes"))); + m_checkbox_color_changes = new wxCheckBox(this, wxID_ANY, _(L("Color changes"))); + m_checkbox_pause_prints = new wxCheckBox(this, wxID_ANY, _(L("Pause prints"))); + m_checkbox_custom_gcodes = new wxCheckBox(this, wxID_ANY, _(L("Custom GCodes"))); +#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT m_checkbox_shells = new wxCheckBox(this, wxID_ANY, _(L("Shells"))); m_checkbox_legend = new wxCheckBox(this, wxID_ANY, _(L("Legend"))); m_checkbox_legend->SetValue(true); @@ -351,6 +363,16 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view bottom_sizer->AddSpacer(10); bottom_sizer->Add(m_checkbox_unretractions, 0, wxEXPAND | wxALL, 5); bottom_sizer->AddSpacer(10); +#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT + bottom_sizer->Add(m_checkbox_tool_changes, 0, wxEXPAND | wxALL, 5); + bottom_sizer->AddSpacer(10); + bottom_sizer->Add(m_checkbox_color_changes, 0, wxEXPAND | wxALL, 5); + bottom_sizer->AddSpacer(10); + bottom_sizer->Add(m_checkbox_pause_prints, 0, wxEXPAND | wxALL, 5); + bottom_sizer->AddSpacer(10); + bottom_sizer->Add(m_checkbox_custom_gcodes, 0, wxEXPAND | wxALL, 5); + bottom_sizer->AddSpacer(10); +#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT bottom_sizer->Add(m_checkbox_shells, 0, wxEXPAND | wxALL, 5); bottom_sizer->AddSpacer(20); bottom_sizer->Add(m_checkbox_legend, 0, wxEXPAND | wxALL, 5); @@ -533,6 +555,12 @@ void Preview::bind_event_handlers() m_checkbox_travel->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_travel, this); m_checkbox_retractions->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_retractions, this); m_checkbox_unretractions->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_unretractions, this); +#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT + m_checkbox_tool_changes->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_tool_changes, this); + m_checkbox_color_changes->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_color_changes, this); + m_checkbox_pause_prints->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_pause_prints, this); + m_checkbox_custom_gcodes->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_custom_gcodes, this); +#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT m_checkbox_shells->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_shells, this); m_checkbox_legend->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_legend, this); } @@ -545,6 +573,12 @@ void Preview::unbind_event_handlers() m_checkbox_travel->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_travel, this); m_checkbox_retractions->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_retractions, this); m_checkbox_unretractions->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_unretractions, this); +#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT + m_checkbox_tool_changes->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_tool_changes, this); + m_checkbox_color_changes->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_color_changes, this); + m_checkbox_pause_prints->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_pause_prints, this); + m_checkbox_custom_gcodes->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_custom_gcodes, this); +#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT m_checkbox_shells->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_shells, this); m_checkbox_legend->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_legend, this); } @@ -557,6 +591,12 @@ void Preview::show_hide_ui_elements(const std::string& what) m_checkbox_travel->Enable(enable); m_checkbox_retractions->Enable(enable); m_checkbox_unretractions->Enable(enable); +#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT + m_checkbox_tool_changes->Enable(enable); + m_checkbox_color_changes->Enable(enable); + m_checkbox_pause_prints->Enable(enable); + m_checkbox_custom_gcodes->Enable(enable); +#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT m_checkbox_shells->Enable(enable); m_checkbox_legend->Enable(enable); @@ -570,6 +610,12 @@ void Preview::show_hide_ui_elements(const std::string& what) m_checkbox_travel->Show(visible); m_checkbox_retractions->Show(visible); m_checkbox_unretractions->Show(visible); +#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT + m_checkbox_tool_changes->Show(visible); + m_checkbox_color_changes->Show(visible); + m_checkbox_pause_prints->Show(visible); + m_checkbox_custom_gcodes->Show(visible); +#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT m_checkbox_shells->Show(visible); m_checkbox_legend->Show(visible); m_label_view_type->Show(visible); @@ -663,6 +709,32 @@ void Preview::on_checkbox_unretractions(wxCommandEvent& evt) refresh_print(); } +#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT +void Preview::on_checkbox_tool_changes(wxCommandEvent& evt) +{ + m_canvas->set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Tool_change, m_checkbox_tool_changes->IsChecked()); + refresh_print(); +} + +void Preview::on_checkbox_color_changes(wxCommandEvent& evt) +{ + m_canvas->set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Color_change, m_checkbox_color_changes->IsChecked()); + refresh_print(); +} + +void Preview::on_checkbox_pause_prints(wxCommandEvent& evt) +{ + m_canvas->set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Pause_Print, m_checkbox_pause_prints->IsChecked()); + refresh_print(); +} + +void Preview::on_checkbox_custom_gcodes(wxCommandEvent& evt) +{ + m_canvas->set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Custom_GCode, m_checkbox_custom_gcodes->IsChecked()); + refresh_print(); +} +#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT + void Preview::on_checkbox_shells(wxCommandEvent& evt) { #if ENABLE_GCODE_VIEWER @@ -953,26 +1025,46 @@ void Preview::load_print_as_fff(bool keep_z_range) int tool_idx = m_choice_view_type->FindString(_(L("Tool"))); int type = (number_extruders > 1) ? tool_idx /* color by a tool number */ : 0; // color by a feature type m_choice_view_type->SetSelection(type); +#if ENABLE_GCODE_VIEWER + if (0 <= type && type < static_cast(GCodeViewer::EViewType::Count)) + m_canvas->set_gcode_view_preview_type(static_cast(type)); +#else if ((0 <= type) && (type < (int)GCodePreviewData::Extrusion::Num_View_Types)) m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)type; +#endif // ENABLE_GCODE_VIEWER // If the->SetSelection changed the following line, revert it to "decide yourself". m_preferred_color_mode = "tool_or_feature"; } +#if ENABLE_GCODE_VIEWER + GCodeViewer::EViewType gcode_view_type = m_canvas->get_gcode_view_preview_type(); + bool gcode_preview_data_valid = print->is_step_done(psGCodeExport); +#else bool gcode_preview_data_valid = print->is_step_done(psGCodeExport) && ! m_gcode_preview_data->empty(); +#endif // ENABLE_GCODE_VIEWER // Collect colors per extruder. std::vector colors; std::vector color_print_values = {}; // set color print values, if it si selected "ColorPrint" view type +#if ENABLE_GCODE_VIEWER + if (gcode_view_type == GCodeViewer::EViewType::ColorPrint) +#else if (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint) +#endif // ENABLE_GCODE_VIEWER { colors = wxGetApp().plater()->get_colors_for_color_print(); +#if !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT colors.push_back("#808080"); // gray color for pause print or custom G-code +#endif // !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT if (!gcode_preview_data_valid) color_print_values = wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes; } +#if ENABLE_GCODE_VIEWER + else if (gcode_preview_data_valid || gcode_view_type == GCodeViewer::EViewType::Tool) +#else else if (gcode_preview_data_valid || (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::Tool) ) +#endif // ENABLE_GCODE_VIEWER { colors = wxGetApp().plater()->get_extruder_colors_from_plater_config(); color_print_values.clear(); @@ -984,8 +1076,8 @@ void Preview::load_print_as_fff(bool keep_z_range) if (gcode_preview_data_valid) { // Load the real G-code preview. #if ENABLE_GCODE_VIEWER - m_canvas->load_gcode_preview(*m_gcode_result, colors); - m_canvas->refresh_toolpaths_ranges(*m_gcode_result); + m_canvas->load_gcode_preview(*m_gcode_result); + m_canvas->refresh_gcode_preview(*m_gcode_result, colors); #else m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); #endif // ENABLE_GCODE_VIEWER diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 654ce4dbf2..a5d93a1925 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -98,6 +98,12 @@ class Preview : public wxPanel wxCheckBox* m_checkbox_travel; wxCheckBox* m_checkbox_retractions; wxCheckBox* m_checkbox_unretractions; +#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT + wxCheckBox* m_checkbox_tool_changes; + wxCheckBox* m_checkbox_color_changes; + wxCheckBox* m_checkbox_pause_prints; + wxCheckBox* m_checkbox_custom_gcodes; +#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT wxCheckBox* m_checkbox_shells; wxCheckBox* m_checkbox_legend; @@ -189,6 +195,12 @@ private: void on_checkbox_travel(wxCommandEvent& evt); void on_checkbox_retractions(wxCommandEvent& evt); void on_checkbox_unretractions(wxCommandEvent& evt); +#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT + void on_checkbox_tool_changes(wxCommandEvent& evt); + void on_checkbox_color_changes(wxCommandEvent& evt); + void on_checkbox_pause_prints(wxCommandEvent& evt); + void on_checkbox_custom_gcodes(wxCommandEvent& evt); +#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT void on_checkbox_shells(wxCommandEvent& evt); void on_checkbox_legend(wxCommandEvent& evt); From 7be12e8f1eb2f2e37c39b1a778402a6a2e06fec1 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 23 Apr 2020 10:24:03 +0200 Subject: [PATCH 033/255] GCodeViewer -> Completed extrusion toolpaths colored by color print --- src/slic3r/GUI/GCodeViewer.cpp | 120 +++++++++++++++------------------ src/slic3r/GUI/GCodeViewer.hpp | 4 +- 2 files changed, 56 insertions(+), 68 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 2f039da0b3..75b2fa98de 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -40,10 +40,8 @@ std::vector> decode_colors(const std::vector& { const std::string& color = colors[i]; const char* c = color.data() + 1; - if ((color.size() == 7) && (color.front() == '#')) - { - for (size_t j = 0; j < 3; ++j) - { + if ((color.size() == 7) && (color.front() == '#')) { + for (size_t j = 0; j < 3; ++j) { int digit1 = hex_digit_to_int(*c++); int digit2 = hex_digit_to_int(*c++); if ((digit1 == -1) || (digit2 == -1)) @@ -59,8 +57,7 @@ std::vector> decode_colors(const std::vector& void GCodeViewer::VBuffer::reset() { // release gpu memory - if (vbo_id > 0) - { + if (vbo_id > 0) { glsafe(::glDeleteBuffers(1, &vbo_id)); vbo_id = 0; } @@ -71,8 +68,7 @@ void GCodeViewer::VBuffer::reset() void GCodeViewer::IBuffer::reset() { // release gpu memory - if (ibo_id > 0) - { + if (ibo_id > 0) { glsafe(::glDeleteBuffers(1, &ibo_id)); ibo_id = 0; } @@ -85,8 +81,7 @@ void GCodeViewer::IBuffer::reset() bool GCodeViewer::IBuffer::init_shader(const std::string& vertex_shader_src, const std::string& fragment_shader_src) { - if (!shader.init(vertex_shader_src, fragment_shader_src)) - { + if (!shader.init(vertex_shader_src, fragment_shader_src)) { BOOST_LOG_TRIVIAL(error) << "Unable to initialize toolpaths shader: please, check that the files " << vertex_shader_src << " and " << fragment_shader_src << " are available"; return false; } @@ -117,8 +112,7 @@ std::array GCodeViewer::Extrusions::Range::get_color_at(float value) c // Interpolate between the low and high colors to find exactly which color the input value should get std::array ret; - for (unsigned int i = 0; i < 3; ++i) - { + for (unsigned int i = 0; i < 3; ++i) { ret[i] = lerp(Range_Colors[color_low_idx][i], Range_Colors[color_high_idx][i], local_t); } return ret; @@ -192,8 +186,7 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: case GCodeProcessor::EMoveType::Extrude: case GCodeProcessor::EMoveType::Travel: { - if (m_buffers[buffer_id(curr.type)].visible) - { + if (m_buffers[buffer_id(curr.type)].visible) { m_extrusions.ranges.height.update_from(curr.height); m_extrusions.ranges.width.update_from(curr.width); m_extrusions.ranges.feedrate.update_from(curr.feedrate); @@ -211,8 +204,7 @@ void GCodeViewer::reset() { m_vertices.reset(); - for (IBuffer& buffer : m_buffers) - { + for (IBuffer& buffer : m_buffers) { buffer.reset(); } @@ -235,7 +227,7 @@ void GCodeViewer::render() const render_overlay(); } -bool GCodeViewer::is_toolpath_visible(GCodeProcessor::EMoveType type) const +bool GCodeViewer::is_toolpath_move_type_visible(GCodeProcessor::EMoveType type) const { size_t id = static_cast(buffer_id(type)); return (id < m_buffers.size()) ? m_buffers[id].visible : false; @@ -277,8 +269,7 @@ bool GCodeViewer::init_shaders() return false; } - if (!m_shells.shader.init("shells.vs", "shells.fs")) - { + if (!m_shells.shader.init("shells.vs", "shells.fs")) { BOOST_LOG_TRIVIAL(error) << "Unable to initialize shells shader: please, check that the files shells.vs and shells.fs are available"; return false; } @@ -297,10 +288,8 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) // vertex data / bounding box -> extract from result std::vector vertices_data; - for (const GCodeProcessor::MoveVertex& move : gcode_result.moves) - { - for (int j = 0; j < 3; ++j) - { + for (const GCodeProcessor::MoveVertex& move : gcode_result.moves) { + for (int j = 0; j < 3; ++j) { vertices_data.insert(vertices_data.end(), move.position[j]); m_bounding_box.merge(move.position.cast()); } @@ -345,8 +334,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) case GCodeProcessor::EMoveType::Extrude: case GCodeProcessor::EMoveType::Travel: { - if (prev.type != curr.type || !buffer.paths.back().matches(curr)) - { + if (prev.type != curr.type || !buffer.paths.back().matches(curr)) { buffer.add_path(curr); buffer.data.push_back(static_cast(i - 1)); } @@ -366,8 +354,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) for (IBuffer& buffer : m_buffers) { buffer.data_size = buffer.data.size(); - if (buffer.data_size > 0) - { + if (buffer.data_size > 0) { glsafe(::glGenBuffers(1, &buffer.ibo_id)); glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.ibo_id)); glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, buffer.data_size * sizeof(unsigned int), buffer.data.data(), GL_STATIC_DRAW)); @@ -379,8 +366,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) } // layers zs / roles / extruder ids / cp color ids -> extract from result - for (const GCodeProcessor::MoveVertex& move : gcode_result.moves) - { + for (const GCodeProcessor::MoveVertex& move : gcode_result.moves) { if (move.type == GCodeProcessor::EMoveType::Extrude) m_layers_zs.emplace_back(move.position[2]); @@ -432,8 +418,7 @@ void GCodeViewer::load_shells(const Print& print, bool initialized) const ModelObject* model_obj = obj->model_object(); std::vector instance_ids(model_obj->instances.size()); - for (int i = 0; i < (int)model_obj->instances.size(); ++i) - { + for (int i = 0; i < (int)model_obj->instances.size(); ++i) { instance_ids[i] = i; } @@ -448,7 +433,6 @@ void GCodeViewer::load_shells(const Print& print, bool initialized) const PrintConfig& config = print.config(); size_t extruders_count = config.nozzle_diameter.size(); if ((extruders_count > 1) && config.wipe_tower && !config.complete_objects) { - const DynamicPrintConfig& print_config = wxGetApp().preset_bundle->prints.get_edited_preset().config; double layer_height = print_config.opt_float("layer_height"); double first_layer_height = print_config.get_abs_value("first_layer_height", layer_height); @@ -514,8 +498,7 @@ void GCodeViewer::render_toolpaths() const glsafe(::glVertexPointer(3, GL_FLOAT, VBuffer::vertex_size_bytes(), (const void*)0)); glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - for (unsigned char i = begin_id; i < end_id; ++i) - { + for (unsigned char i = begin_id; i < end_id; ++i) { const IBuffer& buffer = m_buffers[i]; if (buffer.ibo_id == 0) continue; @@ -523,8 +506,7 @@ void GCodeViewer::render_toolpaths() const if (!buffer.visible) continue; - if (buffer.shader.is_initialized()) - { + if (buffer.shader.is_initialized()) { GCodeProcessor::EMoveType type = buffer_type(i); buffer.shader.start_using(); @@ -594,8 +576,7 @@ void GCodeViewer::render_toolpaths() const } case GCodeProcessor::EMoveType::Extrude: { - for (const Path& path : buffer.paths) - { + for (const Path& path : buffer.paths) { if (!is_path_visible(m_extrusions.role_visibility_flags, path)) continue; @@ -608,8 +589,7 @@ void GCodeViewer::render_toolpaths() const { std::array color = { 1.0f, 1.0f, 0.0f }; set_color(current_program_id, color); - for (const Path& path : buffer.paths) - { + for (const Path& path : buffer.paths) { glsafe(::glDrawElements(GL_LINE_STRIP, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); } break; @@ -680,8 +660,7 @@ void GCodeViewer::render_overlay() const add_range_item(0, range.min, decimals); else { - for (int i = static_cast(Range_Colors.size()) - 1; i >= 0; --i) - { + for (int i = static_cast(Range_Colors.size()) - 1; i >= 0; --i) { add_range_item(i, range.min + static_cast(i) * step_size, decimals); } } @@ -708,8 +687,7 @@ void GCodeViewer::render_overlay() const { case EViewType::FeatureType: { - for (ExtrusionRole role : m_roles) - { + for (ExtrusionRole role : m_roles) { add_item(Extrusion_Role_Colors[static_cast(role)], I18N::translate_utf8(ExtrusionEntity::role_to_string(role))); } break; @@ -722,8 +700,8 @@ void GCodeViewer::render_overlay() const case EViewType::Tool: { size_t tools_count = m_tool_colors.size(); - for (size_t i = 0; i < tools_count; ++i) - { + for (size_t i = 0; i < tools_count; ++i) { + // shows only extruders actually used auto it = std::find(m_extruder_ids.begin(), m_extruder_ids.end(), static_cast(i)); if (it == m_extruder_ids.end()) continue; @@ -736,18 +714,15 @@ void GCodeViewer::render_overlay() const { const std::vector& custom_gcode_per_print_z = wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes; const int extruders_count = wxGetApp().extruders_edited_cnt(); - if (extruders_count == 1) // single extruder use case - { + if (extruders_count == 1) { // single extruder use case if (custom_gcode_per_print_z.empty()) // no data to show add_item(m_tool_colors.front(), I18N::translate_utf8(L("Default print color"))); - else - { + else { std::vector> cp_values; cp_values.reserve(custom_gcode_per_print_z.size()); - for (auto custom_code : custom_gcode_per_print_z) - { + for (auto custom_code : custom_gcode_per_print_z) { if (custom_code.gcode != ColorChangeCode) continue; @@ -760,41 +735,54 @@ void GCodeViewer::render_overlay() const double previous_z = lower_b == m_layers_zs.begin() ? 0.0 : *(--lower_b); // to avoid duplicate values, check adding values - if (cp_values.empty() || - !(cp_values.back().first == previous_z && cp_values.back().second == current_z)) + if (cp_values.empty() || !(cp_values.back().first == previous_z && cp_values.back().second == current_z)) cp_values.emplace_back(std::make_pair(previous_z, current_z)); } const int items_cnt = static_cast(cp_values.size()); - if (items_cnt == 0) // There is no one color change, but there are some pause print or custom Gcode - { + if (items_cnt == 0) { // There is no one color change, but there are some pause print or custom Gcode add_item(m_tool_colors.front(), I18N::translate_utf8(L("Default print color"))); #if !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT add_item(m_tool_colors.back(), I18N::translate_utf8(L("Pause print or custom G-code"))); #endif // !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT } - else - { - for (int i = items_cnt; i >= 0; --i) - { - // create label for color print item - std::string id_str = std::to_string(i + 1) + ": "; + else { + for (int i = items_cnt; i >= 0; --i) { + // create label for color change item + std::string id_str = " (" + std::to_string(i + 1) + ")"; if (i == 0) { - add_item(m_tool_colors[i], id_str + (boost::format(I18N::translate_utf8(L("up to %.2f mm"))) % cp_values.front().first).str()); + add_item(m_tool_colors[i], (boost::format(I18N::translate_utf8(L("up to %.2f mm"))) % cp_values.front().first).str() + id_str); break; } else if (i == items_cnt) { - add_item(m_tool_colors[i], id_str + (boost::format(I18N::translate_utf8(L("above %.2f mm"))) % cp_values[i - 1].second).str()); + add_item(m_tool_colors[i], (boost::format(I18N::translate_utf8(L("above %.2f mm"))) % cp_values[i - 1].second).str() + id_str); continue; } - add_item(m_tool_colors[i], id_str + (boost::format(I18N::translate_utf8(L("%.2f - %.2f mm"))) % cp_values[i - 1].second % cp_values[i].first).str()); + add_item(m_tool_colors[i], (boost::format(I18N::translate_utf8(L("%.2f - %.2f mm"))) % cp_values[i - 1].second % cp_values[i].first).str() + id_str); } } } } - else + else // multi extruder use case { + // extruders + for (unsigned int i = 0; i < (unsigned int)extruders_count; ++i) { + add_item(m_tool_colors[i], (boost::format(I18N::translate_utf8(L("Extruder %d"))) % (i + 1)).str()); + } + + // color changes + int color_change_idx = 1 + static_cast(m_tool_colors.size()) - extruders_count; + size_t last_color_id = m_tool_colors.size() - 1; + for (int i = static_cast(custom_gcode_per_print_z.size()) - 1; i >= 0; --i) { + if (custom_gcode_per_print_z[i].gcode == ColorChangeCode) { + // create label for color change item + std::string id_str = " (" + std::to_string(color_change_idx--) + ")"; + + add_item(m_tool_colors[last_color_id--], + (boost::format(I18N::translate_utf8(L("Color change for Extruder %d at %.2f mm"))) % custom_gcode_per_print_z[i].extruder % custom_gcode_per_print_z[i].print_z).str() + id_str); + } + } } break; diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 5ce497c976..669d56cf49 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -150,7 +150,7 @@ public: private: unsigned int m_last_result_id{ 0 }; VBuffer m_vertices; - std::vector m_buffers{ static_cast(GCodeProcessor::EMoveType::Extrude) }; + mutable std::vector m_buffers{ static_cast(GCodeProcessor::EMoveType::Extrude) }; BoundingBoxf3 m_bounding_box; std::vector> m_tool_colors; std::vector m_layers_zs; @@ -190,7 +190,7 @@ public: m_view_type = type; } - bool is_toolpath_visible(GCodeProcessor::EMoveType type) const; + bool is_toolpath_move_type_visible(GCodeProcessor::EMoveType type) const; void set_toolpath_move_type_visible(GCodeProcessor::EMoveType type, bool visible); void set_toolpath_role_visibility_flags(unsigned int flags) { m_extrusions.role_visibility_flags = flags; } From 6e2307f56d85dae6cce9eb3ab228dc356ed35698 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 23 Apr 2020 14:02:47 +0200 Subject: [PATCH 034/255] GCodeViewer -> Refactoring --- src/slic3r/GUI/GCodeViewer.cpp | 36 +++++++++++++++++++++------------- src/slic3r/GUI/GCodeViewer.hpp | 5 +++-- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 75b2fa98de..8079008ed3 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -10,6 +10,8 @@ #if ENABLE_GCODE_VIEWER #include "GUI_Utils.hpp" #include "DoubleSlider.hpp" +#include "GLToolbar.hpp" +#include "GLCanvas3D.hpp" #include "libslic3r/Model.hpp" #endif // ENABLE_GCODE_VIEWER @@ -211,7 +213,6 @@ void GCodeViewer::reset() m_bounding_box = BoundingBoxf3(); m_tool_colors = std::vector>(); m_extruder_ids = std::vector(); -// m_cp_color_ids = std::vector(); m_extrusions.reset_role_visibility_flags(); m_extrusions.reset_ranges(); m_shells.volumes.clear(); @@ -372,7 +373,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) m_roles.emplace_back(move.extrusion_role); m_extruder_ids.emplace_back(move.extruder_id); -// m_cp_color_ids.emplace_back(move.cp_color_id); } // layers zs -> replace intervals of layers with similar top positions with their average value. @@ -397,10 +397,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) std::sort(m_extruder_ids.begin(), m_extruder_ids.end()); m_extruder_ids.erase(std::unique(m_extruder_ids.begin(), m_extruder_ids.end()), m_extruder_ids.end()); -// // cp color ids -> remove duplicates -// std::sort(m_cp_color_ids.begin(), m_cp_color_ids.end()); -// m_cp_color_ids.erase(std::unique(m_cp_color_ids.begin(), m_cp_color_ids.end()), m_cp_color_ids.end()); - auto end_time = std::chrono::high_resolution_clock::now(); std::cout << "toolpaths generation time: " << std::chrono::duration_cast(end_time - start_time).count() << "ms \n"; } @@ -620,11 +616,17 @@ void GCodeViewer::render_shells() const } void GCodeViewer::render_overlay() const +{ + render_legend(); + render_toolbar(); +} + +void GCodeViewer::render_legend() const { static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); static const float ICON_BORDER_SIZE = 25.0f; static const ImU32 ICON_BORDER_COLOR = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); - static const float GAP_ICON_TEXT = 5.0f; + static const float GAP_ICON_TEXT = 7.5f; if (!m_legend_enabled || m_roles.empty()) return; @@ -633,17 +635,19 @@ void GCodeViewer::render_overlay() const imgui.set_next_window_pos(0, 0, ImGuiCond_Always); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); - imgui.begin(_L("Legend"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); + imgui.begin(std::string("Legend"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); ImDrawList* draw_list = ImGui::GetWindowDrawList(); auto add_item = [draw_list, &imgui](const std::array& color, const std::string& label) { + // draw icon ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f); - draw_list->AddRect(ImVec2(pos.x, pos.y), ImVec2(pos.x + ICON_BORDER_SIZE, pos.y + ICON_BORDER_SIZE), ICON_BORDER_COLOR, 0.0f, 0); - ImU32 fill_color = ImGui::GetColorU32(ImVec4(color[0], color[1], color[2], 1.0f)); - draw_list->AddRectFilled(ImVec2(pos.x + 1.0f, pos.y + 1.0f), ImVec2(pos.x + ICON_BORDER_SIZE - 1.0f, pos.y + ICON_BORDER_SIZE - 1.0f), fill_color); - ImGui::SetCursorPosX(pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT); - ImGui::AlignTextToFramePadding(); + draw_list->AddRect({ pos.x, pos.y }, { pos.x + ICON_BORDER_SIZE, pos.y + ICON_BORDER_SIZE }, ICON_BORDER_COLOR, 0.0f, 0); + draw_list->AddRectFilled({ pos.x + 1.0f, pos.y + 1.0f }, + { pos.x + ICON_BORDER_SIZE - 1.0f, pos.y + ICON_BORDER_SIZE - 1.0f }, + ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f })); + // draw text + ImGui::SetCursorPos({ pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT, pos.y + 0.5f * (ICON_BORDER_SIZE - ImGui::GetTextLineHeight()) }); imgui.text(label); }; @@ -673,7 +677,7 @@ void GCodeViewer::render_overlay() const case EViewType::Height: { imgui.text(I18N::translate_utf8(L("Height (mm)"))); break; } case EViewType::Width: { imgui.text(I18N::translate_utf8(L("Width (mm)"))); break; } case EViewType::Feedrate: { imgui.text(I18N::translate_utf8(L("Speed (mm/s)"))); break; } - case EViewType::FanSpeed: { imgui.text(I18N::translate_utf8(L("Fan Speed (%)"))); break; } + case EViewType::FanSpeed: { imgui.text(I18N::translate_utf8(L("Fan Speed (%%)"))); break; } case EViewType::VolumetricRate: { imgui.text(I18N::translate_utf8(L("Volumetric flow rate (mm³/s)"))); break; } case EViewType::Tool: { imgui.text(I18N::translate_utf8(L("Tool"))); break; } case EViewType::ColorPrint: { imgui.text(I18N::translate_utf8(L("Color Print"))); break; } @@ -794,6 +798,10 @@ void GCodeViewer::render_overlay() const ImGui::PopStyleVar(); } +void GCodeViewer::render_toolbar() const +{ +} + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 669d56cf49..53d1fbd75e 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -156,10 +156,9 @@ private: std::vector m_layers_zs; std::vector m_roles; std::vector m_extruder_ids; -// std::vector m_cp_color_ids; Extrusions m_extrusions; Shells m_shells; - EViewType m_view_type{ EViewType::FeatureType }; + mutable EViewType m_view_type{ EViewType::FeatureType }; bool m_legend_enabled{ true }; public: @@ -207,6 +206,8 @@ private: void render_toolpaths() const; void render_shells() const; void render_overlay() const; + void render_legend() const; + void render_toolbar() const; }; } // namespace GUI From 66964c44c10ff7f36c01f80ceedf9bfb483e247b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 23 Apr 2020 15:12:40 +0200 Subject: [PATCH 035/255] GCodeViewer -> Refactoring and code cleanup --- src/libslic3r/GCode.cpp | 10 ------- src/libslic3r/GCode/GCodeProcessor.cpp | 30 +-------------------- src/libslic3r/GCode/GCodeProcessor.hpp | 5 ---- src/libslic3r/GCode/ToolOrdering.cpp | 4 ++- src/libslic3r/Technologies.hpp | 1 - src/slic3r/GUI/GCodeViewer.cpp | 9 ------- src/slic3r/GUI/GUI_Preview.cpp | 36 +++++++++++++------------- src/slic3r/GUI/GUI_Preview.hpp | 8 +++--- 8 files changed, 26 insertions(+), 77 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index a1114e938e..58eb2e5ae7 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2328,16 +2328,6 @@ void GCode::process_layer( else if (gcode.find(GCodeAnalyzer::Custom_Code_Tag) != gcode.npos) gcode += "\n; " + GCodeAnalyzer::End_Pause_Print_Or_Custom_Code_Tag + "\n"; -#if ENABLE_GCODE_VIEWER -#if !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT - // add tag for processor - if (gcode.find(GCodeProcessor::Pause_Print_Tag) != gcode.npos) - gcode += "\n; " + GCodeProcessor::End_Pause_Print_Or_Custom_Code_Tag + "\n"; - else if (gcode.find(GCodeProcessor::Custom_Code_Tag) != gcode.npos) - gcode += "\n; " + GCodeProcessor::End_Pause_Print_Or_Custom_Code_Tag + "\n"; -#endif // !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT -#endif // ENABLE_GCODE_VIEWER - #ifdef HAS_PRESSURE_EQUALIZER // Apply pressure equalization if enabled; // printf("G-code before filter:\n%s\n", gcode.c_str()); diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 2219facb51..6d491a88c9 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -24,9 +24,6 @@ const std::string GCodeProcessor::Mm3_Per_Mm_Tag = "_PROCESSOR_MM3_PER_MM:"; const std::string GCodeProcessor::Color_Change_Tag = "_PROCESSOR_COLOR_CHANGE"; const std::string GCodeProcessor::Pause_Print_Tag = "_PROCESSOR_PAUSE_PRINT"; const std::string GCodeProcessor::Custom_Code_Tag = "_PROCESSOR_CUSTOM_CODE"; -#if !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT -const std::string GCodeProcessor::End_Pause_Print_Or_Custom_Code_Tag = "_PROCESSOR_END_PAUSE_PRINT_OR_CUSTOM_CODE"; -#endif // !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT void GCodeProcessor::CachedPosition::reset() { @@ -248,9 +245,7 @@ void GCodeProcessor::process_tags(const std::string& comment) if (m_extruder_id == extruder_id) { m_cp_color.current = m_extruders_color[extruder_id]; -#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT store_move_vertex(EMoveType::Color_change); -#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT } } catch (...) @@ -265,11 +260,7 @@ void GCodeProcessor::process_tags(const std::string& comment) pos = comment.find(Pause_Print_Tag); if (pos != comment.npos) { -#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT store_move_vertex(EMoveType::Pause_Print); -#else - m_cp_color.current = UCHAR_MAX; -#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT return; } @@ -277,25 +268,9 @@ void GCodeProcessor::process_tags(const std::string& comment) pos = comment.find(Custom_Code_Tag); if (pos != comment.npos) { -#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT store_move_vertex(EMoveType::Custom_GCode); -#else - m_cp_color.current = UCHAR_MAX; -#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT return; } - -#if !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT - // end pause print or custom code tag - pos = comment.find(End_Pause_Print_Or_Custom_Code_Tag); - if (pos != comment.npos) - { - if (m_cp_color.current == UCHAR_MAX) - m_cp_color.current = m_extruders_color[m_extruder_id]; - - return; - } -#endif // !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT } void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) @@ -588,10 +563,7 @@ void GCodeProcessor::process_T(const std::string& command) else { m_extruder_id = id; -#if !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT - if (m_cp_color.current != UCHAR_MAX) -#endif // !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT - m_cp_color.current = m_extruders_color[id]; + m_cp_color.current = m_extruders_color[id]; } // store tool change move diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index cd4e021cae..05aca4e089 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -21,9 +21,6 @@ namespace Slic3r { static const std::string Color_Change_Tag; static const std::string Pause_Print_Tag; static const std::string Custom_Code_Tag; -#if !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT - static const std::string End_Pause_Print_Or_Custom_Code_Tag; -#endif // !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT private: using AxisCoords = std::array; @@ -64,11 +61,9 @@ namespace Slic3r { Retract, Unretract, Tool_change, -#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT Color_change, Pause_Print, Custom_GCode, -#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT Travel, Extrude, Count diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index db398f06c8..7be15bd351 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -400,7 +400,9 @@ void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_ // and maybe other problems. We will therefore go through layer_tools and detect and fix this. // So, if there is a non-object layer starting with different extruder than the last one ended with (or containing more than one extruder), // we'll mark it with has_wipe tower. - assert(! m_layer_tools.empty() && m_layer_tools.front().has_wipe_tower); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// assert(! m_layer_tools.empty() && m_layer_tools.front().has_wipe_tower); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (! m_layer_tools.empty() && m_layer_tools.front().has_wipe_tower) { for (size_t i = 0; i + 1 < m_layer_tools.size();) { const LayerTools < = m_layer_tools[i]; diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 8d1e19eceb..1ed939ba3e 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -59,7 +59,6 @@ // Enable G-Code viewer #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) #define ENABLE_GCODE_VIEWER_DEBUG_OUTPUT (0 && ENABLE_GCODE_VIEWER) -#define ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT (1 && ENABLE_GCODE_VIEWER) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 8079008ed3..86a9d38a7c 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -254,11 +254,9 @@ bool GCodeViewer::init_shaders() switch (buffer_type(i)) { case GCodeProcessor::EMoveType::Tool_change: { vertex_shader = "toolchanges.vs"; fragment_shader = "toolchanges.fs"; break; } -#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT case GCodeProcessor::EMoveType::Color_change: { vertex_shader = "colorchanges.vs"; fragment_shader = "colorchanges.fs"; break; } case GCodeProcessor::EMoveType::Pause_Print: { vertex_shader = "pauses.vs"; fragment_shader = "pauses.fs"; break; } case GCodeProcessor::EMoveType::Custom_GCode: { vertex_shader = "customs.vs"; fragment_shader = "customs.fs"; break; } -#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT case GCodeProcessor::EMoveType::Retract: { vertex_shader = "retractions.vs"; fragment_shader = "retractions.fs"; break; } case GCodeProcessor::EMoveType::Unretract: { vertex_shader = "unretractions.vs"; fragment_shader = "unretractions.fs"; break; } case GCodeProcessor::EMoveType::Extrude: { vertex_shader = "extrusions.vs"; fragment_shader = "extrusions.fs"; break; } @@ -320,11 +318,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) switch (curr.type) { case GCodeProcessor::EMoveType::Tool_change: -#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT case GCodeProcessor::EMoveType::Color_change: case GCodeProcessor::EMoveType::Pause_Print: case GCodeProcessor::EMoveType::Custom_GCode: -#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT case GCodeProcessor::EMoveType::Retract: case GCodeProcessor::EMoveType::Unretract: { @@ -523,7 +519,6 @@ void GCodeViewer::render_toolpaths() const glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); break; } -#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT case GCodeProcessor::EMoveType::Color_change: { std::array color = { 1.0f, 0.0f, 0.0f }; @@ -551,7 +546,6 @@ void GCodeViewer::render_toolpaths() const glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); break; } -#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT case GCodeProcessor::EMoveType::Retract: { std::array color = { 1.0f, 0.0f, 1.0f }; @@ -746,9 +740,6 @@ void GCodeViewer::render_legend() const const int items_cnt = static_cast(cp_values.size()); if (items_cnt == 0) { // There is no one color change, but there are some pause print or custom Gcode add_item(m_tool_colors.front(), I18N::translate_utf8(L("Default print color"))); -#if !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT - add_item(m_tool_colors.back(), I18N::translate_utf8(L("Pause print or custom G-code"))); -#endif // !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT } else { for (int i = items_cnt; i >= 0; --i) { diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 520534ca7d..6c961a4902 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -229,12 +229,12 @@ Preview::Preview( , m_checkbox_travel(nullptr) , m_checkbox_retractions(nullptr) , m_checkbox_unretractions(nullptr) -#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT +#if ENABLE_GCODE_VIEWER , m_checkbox_tool_changes(nullptr) , m_checkbox_color_changes(nullptr) , m_checkbox_pause_prints(nullptr) , m_checkbox_custom_gcodes(nullptr) -#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT +#endif // ENABLE_GCODE_VIEWER , m_checkbox_shells(nullptr) , m_checkbox_legend(nullptr) , m_config(config) @@ -336,12 +336,12 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view m_checkbox_travel = new wxCheckBox(this, wxID_ANY, _(L("Travel"))); m_checkbox_retractions = new wxCheckBox(this, wxID_ANY, _(L("Retractions"))); m_checkbox_unretractions = new wxCheckBox(this, wxID_ANY, _(L("Unretractions"))); -#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT +#if ENABLE_GCODE_VIEWER m_checkbox_tool_changes = new wxCheckBox(this, wxID_ANY, _(L("Tool changes"))); m_checkbox_color_changes = new wxCheckBox(this, wxID_ANY, _(L("Color changes"))); m_checkbox_pause_prints = new wxCheckBox(this, wxID_ANY, _(L("Pause prints"))); m_checkbox_custom_gcodes = new wxCheckBox(this, wxID_ANY, _(L("Custom GCodes"))); -#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT +#endif // ENABLE_GCODE_VIEWER m_checkbox_shells = new wxCheckBox(this, wxID_ANY, _(L("Shells"))); m_checkbox_legend = new wxCheckBox(this, wxID_ANY, _(L("Legend"))); m_checkbox_legend->SetValue(true); @@ -363,7 +363,7 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view bottom_sizer->AddSpacer(10); bottom_sizer->Add(m_checkbox_unretractions, 0, wxEXPAND | wxALL, 5); bottom_sizer->AddSpacer(10); -#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT +#if ENABLE_GCODE_VIEWER bottom_sizer->Add(m_checkbox_tool_changes, 0, wxEXPAND | wxALL, 5); bottom_sizer->AddSpacer(10); bottom_sizer->Add(m_checkbox_color_changes, 0, wxEXPAND | wxALL, 5); @@ -372,7 +372,7 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view bottom_sizer->AddSpacer(10); bottom_sizer->Add(m_checkbox_custom_gcodes, 0, wxEXPAND | wxALL, 5); bottom_sizer->AddSpacer(10); -#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT +#endif // ENABLE_GCODE_VIEWER bottom_sizer->Add(m_checkbox_shells, 0, wxEXPAND | wxALL, 5); bottom_sizer->AddSpacer(20); bottom_sizer->Add(m_checkbox_legend, 0, wxEXPAND | wxALL, 5); @@ -555,12 +555,12 @@ void Preview::bind_event_handlers() m_checkbox_travel->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_travel, this); m_checkbox_retractions->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_retractions, this); m_checkbox_unretractions->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_unretractions, this); -#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT +#if ENABLE_GCODE_VIEWER m_checkbox_tool_changes->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_tool_changes, this); m_checkbox_color_changes->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_color_changes, this); m_checkbox_pause_prints->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_pause_prints, this); m_checkbox_custom_gcodes->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_custom_gcodes, this); -#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT +#endif // ENABLE_GCODE_VIEWER m_checkbox_shells->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_shells, this); m_checkbox_legend->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_legend, this); } @@ -573,12 +573,12 @@ void Preview::unbind_event_handlers() m_checkbox_travel->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_travel, this); m_checkbox_retractions->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_retractions, this); m_checkbox_unretractions->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_unretractions, this); -#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT +#if ENABLE_GCODE_VIEWER m_checkbox_tool_changes->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_tool_changes, this); m_checkbox_color_changes->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_color_changes, this); m_checkbox_pause_prints->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_pause_prints, this); m_checkbox_custom_gcodes->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_custom_gcodes, this); -#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT +#endif // ENABLE_GCODE_VIEWER m_checkbox_shells->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_shells, this); m_checkbox_legend->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_legend, this); } @@ -591,12 +591,12 @@ void Preview::show_hide_ui_elements(const std::string& what) m_checkbox_travel->Enable(enable); m_checkbox_retractions->Enable(enable); m_checkbox_unretractions->Enable(enable); -#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT +#if ENABLE_GCODE_VIEWER m_checkbox_tool_changes->Enable(enable); m_checkbox_color_changes->Enable(enable); m_checkbox_pause_prints->Enable(enable); m_checkbox_custom_gcodes->Enable(enable); -#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT +#endif // ENABLE_GCODE_VIEWER m_checkbox_shells->Enable(enable); m_checkbox_legend->Enable(enable); @@ -610,12 +610,12 @@ void Preview::show_hide_ui_elements(const std::string& what) m_checkbox_travel->Show(visible); m_checkbox_retractions->Show(visible); m_checkbox_unretractions->Show(visible); -#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT +#if ENABLE_GCODE_VIEWER m_checkbox_tool_changes->Show(visible); m_checkbox_color_changes->Show(visible); m_checkbox_pause_prints->Show(visible); m_checkbox_custom_gcodes->Show(visible); -#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT +#endif // ENABLE_GCODE_VIEWER m_checkbox_shells->Show(visible); m_checkbox_legend->Show(visible); m_label_view_type->Show(visible); @@ -709,7 +709,7 @@ void Preview::on_checkbox_unretractions(wxCommandEvent& evt) refresh_print(); } -#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT +#if ENABLE_GCODE_VIEWER void Preview::on_checkbox_tool_changes(wxCommandEvent& evt) { m_canvas->set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Tool_change, m_checkbox_tool_changes->IsChecked()); @@ -733,7 +733,7 @@ void Preview::on_checkbox_custom_gcodes(wxCommandEvent& evt) m_canvas->set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Custom_GCode, m_checkbox_custom_gcodes->IsChecked()); refresh_print(); } -#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT +#endif // ENABLE_GCODE_VIEWER void Preview::on_checkbox_shells(wxCommandEvent& evt) { @@ -1053,9 +1053,9 @@ void Preview::load_print_as_fff(bool keep_z_range) #endif // ENABLE_GCODE_VIEWER { colors = wxGetApp().plater()->get_colors_for_color_print(); -#if !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT +#if !ENABLE_GCODE_VIEWER colors.push_back("#808080"); // gray color for pause print or custom G-code -#endif // !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT +#endif // !ENABLE_GCODE_VIEWER if (!gcode_preview_data_valid) color_print_values = wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes; diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index a5d93a1925..bdbbe79daa 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -98,12 +98,12 @@ class Preview : public wxPanel wxCheckBox* m_checkbox_travel; wxCheckBox* m_checkbox_retractions; wxCheckBox* m_checkbox_unretractions; -#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT +#if ENABLE_GCODE_VIEWER wxCheckBox* m_checkbox_tool_changes; wxCheckBox* m_checkbox_color_changes; wxCheckBox* m_checkbox_pause_prints; wxCheckBox* m_checkbox_custom_gcodes; -#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT +#endif // ENABLE_GCODE_VIEWER wxCheckBox* m_checkbox_shells; wxCheckBox* m_checkbox_legend; @@ -195,12 +195,12 @@ private: void on_checkbox_travel(wxCommandEvent& evt); void on_checkbox_retractions(wxCommandEvent& evt); void on_checkbox_unretractions(wxCommandEvent& evt); -#if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT +#if ENABLE_GCODE_VIEWER void on_checkbox_tool_changes(wxCommandEvent& evt); void on_checkbox_color_changes(wxCommandEvent& evt); void on_checkbox_pause_prints(wxCommandEvent& evt); void on_checkbox_custom_gcodes(wxCommandEvent& evt); -#endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT +#endif // ENABLE_GCODE_VIEWER void on_checkbox_shells(wxCommandEvent& evt); void on_checkbox_legend(wxCommandEvent& evt); From 90d5cf173596063e2ccf323c01ec81d88e2a5f68 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 23 Apr 2020 15:46:21 +0200 Subject: [PATCH 036/255] Fix to previous commit --- src/libslic3r/GCode/ToolOrdering.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index 7be15bd351..db398f06c8 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -400,9 +400,7 @@ void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_ // and maybe other problems. We will therefore go through layer_tools and detect and fix this. // So, if there is a non-object layer starting with different extruder than the last one ended with (or containing more than one extruder), // we'll mark it with has_wipe tower. -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// assert(! m_layer_tools.empty() && m_layer_tools.front().has_wipe_tower); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + assert(! m_layer_tools.empty() && m_layer_tools.front().has_wipe_tower); if (! m_layer_tools.empty() && m_layer_tools.front().has_wipe_tower) { for (size_t i = 0; i + 1 < m_layer_tools.size();) { const LayerTools < = m_layer_tools[i]; From 81a29169aee1e9af381c360a8005897189b06b6e Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 24 Apr 2020 08:46:31 +0200 Subject: [PATCH 037/255] GCodeViewer -> Coloring of travel paths --- src/libslic3r/GCode/GCodeProcessor.cpp | 3 ++- src/libslic3r/GCode/GCodeProcessor.hpp | 1 + src/slic3r/GUI/GCodeViewer.cpp | 28 +++++++++++++++++++------- src/slic3r/GUI/GCodeViewer.hpp | 2 ++ 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 6d491a88c9..9dc3964436 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -582,7 +582,8 @@ void GCodeProcessor::store_move_vertex(EMoveType type) MoveVertex vertex; vertex.type = type; vertex.extrusion_role = m_extrusion_role; - vertex.position = Vec3f(m_end_position[0], m_end_position[1], m_end_position[2]) + m_extruder_offsets[m_extruder_id]; + vertex.position = Vec3f(m_end_position[X], m_end_position[Y], m_end_position[Z]) + m_extruder_offsets[m_extruder_id]; + vertex.delta_extruder = m_end_position[E] - m_start_position[E]; vertex.feedrate = m_feedrate; vertex.width = m_width; vertex.height = m_height; diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 05aca4e089..2212148367 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -76,6 +76,7 @@ namespace Slic3r { unsigned char extruder_id{ 0 }; unsigned char cp_color_id{ 0 }; Vec3f position{ Vec3f::Zero() }; // mm + float delta_extruder{ 0.0f }; // mm float feedrate{ 0.0f }; // mm/s float width{ 0.0f }; // mm float height{ 0.0f }; // mm diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 86a9d38a7c..aac22be6f6 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -94,7 +94,7 @@ bool GCodeViewer::IBuffer::init_shader(const std::string& vertex_shader_src, con void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move) { unsigned int id = static_cast(data.size()); - paths.push_back({ move.type, move.extrusion_role, id, id, move.height, move.width, move.feedrate, move.fan_speed, move.volumetric_rate(), move.extruder_id, move.cp_color_id }); + paths.push_back({ move.type, move.extrusion_role, id, id, move.delta_extruder, move.height, move.width, move.feedrate, move.fan_speed, move.volumetric_rate(), move.extruder_id, move.cp_color_id }); } std::array GCodeViewer::Extrusions::Range::get_color_at(float value) const @@ -138,6 +138,12 @@ const std::vector> GCodeViewer::Extrusion_Role_Colors {{ { 0.00f, 0.00f, 0.00f } // erMixed }}; +const std::vector> GCodeViewer::Travel_Colors {{ + { 0.0f, 0.0f, 0.5f }, // Move + { 0.0f, 0.5f, 0.0f }, // Extrude + { 0.5f, 0.0f, 0.0f } // Retract +}}; + const std::vector> GCodeViewer::Range_Colors {{ { 0.043f, 0.173f, 0.478f }, // bluish { 0.075f, 0.349f, 0.522f }, @@ -186,14 +192,17 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: switch (curr.type) { case GCodeProcessor::EMoveType::Extrude: + { + m_extrusions.ranges.height.update_from(curr.height); + m_extrusions.ranges.width.update_from(curr.width); + m_extrusions.ranges.fan_speed.update_from(curr.fan_speed); + m_extrusions.ranges.volumetric_rate.update_from(curr.volumetric_rate()); + [[fallthrough]]; + } case GCodeProcessor::EMoveType::Travel: { if (m_buffers[buffer_id(curr.type)].visible) { - m_extrusions.ranges.height.update_from(curr.height); - m_extrusions.ranges.width.update_from(curr.width); m_extrusions.ranges.feedrate.update_from(curr.feedrate); - m_extrusions.ranges.fan_speed.update_from(curr.fan_speed); - m_extrusions.ranges.volumetric_rate.update_from(curr.volumetric_rate()); } break; } @@ -465,6 +474,12 @@ void GCodeViewer::render_toolpaths() const return color; }; + auto travel_color = [this](const Path& path) { + return (path.delta_extruder < 0.0f) ? Travel_Colors[2] /* Retract */ : + ((path.delta_extruder > 0.0f) ? Travel_Colors[1] /* Extrude */ : + Travel_Colors[0] /* Move */); + }; + auto set_color = [](GLint current_program_id, const std::array& color) { if (current_program_id > 0) { GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1; @@ -577,9 +592,8 @@ void GCodeViewer::render_toolpaths() const } case GCodeProcessor::EMoveType::Travel: { - std::array color = { 1.0f, 1.0f, 0.0f }; - set_color(current_program_id, color); for (const Path& path : buffer.paths) { + set_color(current_program_id, (m_view_type == EViewType::Feedrate || m_view_type == EViewType::Tool || m_view_type == EViewType::ColorPrint) ? extrusion_color(path) : travel_color(path)); glsafe(::glDrawElements(GL_LINE_STRIP, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); } break; diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 53d1fbd75e..70e20ce0b1 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -16,6 +16,7 @@ namespace GUI { class GCodeViewer { static const std::vector> Extrusion_Role_Colors; + static const std::vector> Travel_Colors; static const std::vector> Range_Colors; // buffer containing vertices data @@ -39,6 +40,7 @@ class GCodeViewer ExtrusionRole role{ erNone }; unsigned int first{ 0 }; unsigned int last{ 0 }; + float delta_extruder{ 0.0f }; float height{ 0.0f }; float width{ 0.0f }; float feedrate{ 0.0f }; From d8091b7ad76fb580b8f22b151bc4c76134d6f3e2 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 24 Apr 2020 16:12:38 +0200 Subject: [PATCH 038/255] ENABLE_GCODE_VIEWER -> Preview toolbar checkboxes moved into a new combo --- src/slic3r/GUI/GCodeViewer.cpp | 17 +++ src/slic3r/GUI/GCodeViewer.hpp | 4 +- src/slic3r/GUI/GLCanvas3D.cpp | 9 +- src/slic3r/GUI/GLCanvas3D.hpp | 3 +- src/slic3r/GUI/GUI.cpp | 25 ++--- src/slic3r/GUI/GUI.hpp | 6 +- src/slic3r/GUI/GUI_Preview.cpp | 190 +++++++++++++-------------------- src/slic3r/GUI/GUI_Preview.hpp | 22 ++-- 8 files changed, 123 insertions(+), 153 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 3d8d288d17..e6ddba8d11 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -250,6 +250,23 @@ void GCodeViewer::set_toolpath_move_type_visible(GCodeProcessor::EMoveType type, m_buffers[id].visible = visible; } +void GCodeViewer::set_options_visibility_from_flags(unsigned int flags) +{ + auto is_flag_set = [flags](unsigned int flag) { + return (flags& (1 << flag)) != 0; + }; + + set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Travel, is_flag_set(0)); + set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Retract, is_flag_set(1)); + set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Unretract, is_flag_set(2)); + set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Tool_change, is_flag_set(3)); + set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Color_change, is_flag_set(4)); + set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Pause_Print, is_flag_set(5)); + set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Custom_GCode, is_flag_set(6)); + m_shells.visible = is_flag_set(7); + enable_legend(is_flag_set(8)); +} + bool GCodeViewer::init_shaders() { unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 6e7cc2f172..bfd61e8d4c 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -194,9 +194,7 @@ public: bool is_toolpath_move_type_visible(GCodeProcessor::EMoveType type) const; void set_toolpath_move_type_visible(GCodeProcessor::EMoveType type, bool visible); void set_toolpath_role_visibility_flags(unsigned int flags) { m_extrusions.role_visibility_flags = flags; } - - bool are_shells_visible() const { return m_shells.visible; } - void set_shells_visible(bool visible) { m_shells.visible = visible; } + void set_options_visibility_from_flags(unsigned int flags); bool is_legend_enabled() const { return m_legend_enabled; } void enable_legend(bool enable) { m_legend_enabled = enable; } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 225fb427cf..ab2dee6938 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2332,9 +2332,9 @@ const std::vector& GLCanvas3D::get_layers_zs() const return m_gcode_viewer.get_layers_zs(); } -void GLCanvas3D::set_toolpath_move_type_visible(GCodeProcessor::EMoveType type, bool visible) +void GLCanvas3D::set_gcode_options_visibility_from_flags(unsigned int flags) { - m_gcode_viewer.set_toolpath_move_type_visible(type, visible); + m_gcode_viewer.set_options_visibility_from_flags(flags); } void GLCanvas3D::set_toolpath_role_visibility_flags(unsigned int flags) @@ -2346,11 +2346,6 @@ void GLCanvas3D::set_toolpath_view_type(GCodeViewer::EViewType type) { m_gcode_viewer.set_view_type(type); } - -void GLCanvas3D::set_shells_visible(bool visible) -{ - m_gcode_viewer.set_shells_visible(visible); -} #else std::vector GLCanvas3D::get_current_print_zs(bool active_only) const { diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 25647b5e55..7a295b900d 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -647,10 +647,9 @@ public: #if ENABLE_GCODE_VIEWER const std::vector& get_layers_zs() const; - void set_toolpath_move_type_visible(GCodeProcessor::EMoveType type, bool visible); + void set_gcode_options_visibility_from_flags(unsigned int flags); void set_toolpath_role_visibility_flags(unsigned int flags); void set_toolpath_view_type(GCodeViewer::EViewType type); - void set_shells_visible(bool visible); #else std::vector get_current_print_zs(bool active_only) const; #endif // ENABLE_GCODE_VIEWER diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp index caeb8da034..dd9ddcab8f 100644 --- a/src/slic3r/GUI/GUI.cpp +++ b/src/slic3r/GUI/GUI.cpp @@ -259,7 +259,7 @@ void warning_catcher(wxWindow* parent, const wxString& message) msg.ShowModal(); } -void create_combochecklist(wxComboCtrl* comboCtrl, std::string text, std::string items, bool initial_value) +void create_combochecklist(wxComboCtrl* comboCtrl, const std::string& text, const std::string& items) { if (comboCtrl == nullptr) return; @@ -273,8 +273,9 @@ void create_combochecklist(wxComboCtrl* comboCtrl, std::string text, std::string comboCtrl->EnablePopupAnimation(false); comboCtrl->SetPopupControl(popup); - popup->SetStringValue(from_u8(text)); - popup->Bind(wxEVT_CHECKLISTBOX, [popup](wxCommandEvent& evt) { popup->OnCheckListBox(evt); }); + wxString title = from_u8(text); + popup->SetStringValue(title); + popup->Bind(wxEVT_CHECKLISTBOX, [popup](wxCommandEvent& evt) { popup->OnCheckListBox(evt); }); popup->Bind(wxEVT_LISTBOX, [popup](wxCommandEvent& evt) { popup->OnListBoxSelection(evt); }); popup->Bind(wxEVT_KEY_DOWN, [popup](wxKeyEvent& evt) { popup->OnKeyEvent(evt); }); popup->Bind(wxEVT_KEY_UP, [popup](wxKeyEvent& evt) { popup->OnKeyEvent(evt); }); @@ -282,16 +283,16 @@ void create_combochecklist(wxComboCtrl* comboCtrl, std::string text, std::string std::vector items_str; boost::split(items_str, items, boost::is_any_of("|"), boost::token_compress_off); - for (const std::string& item : items_str) - { - popup->Append(from_u8(item)); - } + // each item must be composed by 2 parts + assert(items_str.size() %2 == 0); - for (unsigned int i = 0; i < popup->GetCount(); ++i) - { - popup->Check(i, initial_value); - } - } + for (size_t i = 0; i < items_str.size(); i += 2) + { + wxString label = from_u8(items_str[i]); + popup->Append(label); + popup->Check(i / 2, items_str[i + 1] == "1"); + } + } } int combochecklist_get_flags(wxComboCtrl* comboCtrl) diff --git a/src/slic3r/GUI/GUI.hpp b/src/slic3r/GUI/GUI.hpp index a54288df45..6690b21207 100644 --- a/src/slic3r/GUI/GUI.hpp +++ b/src/slic3r/GUI/GUI.hpp @@ -49,9 +49,9 @@ inline void show_info(wxWindow* parent, const std::string& message,const std::st void warning_catcher(wxWindow* parent, const wxString& message); // Creates a wxCheckListBoxComboPopup inside the given wxComboCtrl, filled with the given text and items. -// Items are all initialized to the given value. -// Items must be separated by '|', for example "Item1|Item2|Item3", and so on. -void create_combochecklist(wxComboCtrl* comboCtrl, std::string text, std::string items, bool initial_value); +// Items data must be separated by '|', and contain the item name to be shown followed by its initial value (0 for false, 1 for true). +// For example "Item1|0|Item2|1|Item3|0", and so on. +void create_combochecklist(wxComboCtrl* comboCtrl, const std::string& text, const std::string& items); // Returns the current state of the items listed in the wxCheckListBoxComboPopup contained in the given wxComboCtrl, // encoded inside an int. diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 6c961a4902..876d212fb4 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -224,19 +224,17 @@ Preview::Preview( , m_double_slider_sizer(nullptr) , m_label_view_type(nullptr) , m_choice_view_type(nullptr) - , m_label_show_features(nullptr) + , m_label_show(nullptr) , m_combochecklist_features(nullptr) +#if ENABLE_GCODE_VIEWER + , m_combochecklist_options(nullptr) +#else , m_checkbox_travel(nullptr) , m_checkbox_retractions(nullptr) , m_checkbox_unretractions(nullptr) -#if ENABLE_GCODE_VIEWER - , m_checkbox_tool_changes(nullptr) - , m_checkbox_color_changes(nullptr) - , m_checkbox_pause_prints(nullptr) - , m_checkbox_custom_gcodes(nullptr) -#endif // ENABLE_GCODE_VIEWER , m_checkbox_shells(nullptr) , m_checkbox_legend(nullptr) +#endif // ENABLE_GCODE_VIEWER , m_config(config) , m_process(process) , m_gcode_preview_data(gcode_preview_data) @@ -308,43 +306,53 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view m_choice_view_type->Append(_(L("Color Print"))); m_choice_view_type->SetSelection(0); - m_label_show_features = new wxStaticText(this, wxID_ANY, _(L("Show"))); + m_label_show = new wxStaticText(this, wxID_ANY, _(L("Show"))); m_combochecklist_features = new wxComboCtrl(); m_combochecklist_features->Create(this, wxID_ANY, _(L("Feature types")), wxDefaultPosition, wxSize(15 * wxGetApp().em_unit(), -1), wxCB_READONLY); - std::string feature_text = GUI::into_u8(_(L("Feature types"))); std::string feature_items = GUI::into_u8( #if ENABLE_GCODE_VIEWER - _L("Unknown") + "|" + + _L("Unknown") + "|1|" + #endif // ENABLE_GCODE_VIEWER - _(L("Perimeter")) + "|" + - _(L("External perimeter")) + "|" + - _(L("Overhang perimeter")) + "|" + - _(L("Internal infill")) + "|" + - _(L("Solid infill")) + "|" + - _(L("Top solid infill")) + "|" + - _(L("Bridge infill")) + "|" + - _(L("Gap fill")) + "|" + - _(L("Skirt")) + "|" + - _(L("Support material")) + "|" + - _(L("Support material interface")) + "|" + - _(L("Wipe tower")) + "|" + - _(L("Custom")) + _(L("Perimeter")) + "|1|" + + _(L("External perimeter")) + "|1|" + + _(L("Overhang perimeter")) + "|1|" + + _(L("Internal infill")) + "|1|" + + _(L("Solid infill")) + "|1|" + + _(L("Top solid infill")) + "|1|" + + _(L("Bridge infill")) + "|1|" + + _(L("Gap fill")) + "|1|" + + _(L("Skirt")) + "|1|" + + _(L("Support material")) + "|1|" + + _(L("Support material interface")) + "|1|" + + _(L("Wipe tower")) + "|1|" + + _(L("Custom")) + "|1" ); - Slic3r::GUI::create_combochecklist(m_combochecklist_features, feature_text, feature_items, true); + Slic3r::GUI::create_combochecklist(m_combochecklist_features, GUI::into_u8(_(L("Feature types"))), feature_items); +#if ENABLE_GCODE_VIEWER + m_combochecklist_options = new wxComboCtrl(); + m_combochecklist_options->Create(this, wxID_ANY, _(L("Options")), wxDefaultPosition, wxSize(15 * wxGetApp().em_unit(), -1), wxCB_READONLY); + std::string options_items = GUI::into_u8( + _(L("Travel")) + "|0|" + + _(L("Retractions")) + "|0|" + + _(L("Unretractions")) + "|0|" + + _(L("Tool changes")) + "|0|" + + _(L("Color changes")) + "|0|" + + _(L("Pause prints")) + "|0|" + + _(L("Custom GCodes")) + "|0|" + + _(L("Shells")) + "|0|" + + _(L("Legend")) + "|1" + ); + Slic3r::GUI::create_combochecklist(m_combochecklist_options, GUI::into_u8(_(L("Options"))), options_items); +#else m_checkbox_travel = new wxCheckBox(this, wxID_ANY, _(L("Travel"))); m_checkbox_retractions = new wxCheckBox(this, wxID_ANY, _(L("Retractions"))); m_checkbox_unretractions = new wxCheckBox(this, wxID_ANY, _(L("Unretractions"))); -#if ENABLE_GCODE_VIEWER - m_checkbox_tool_changes = new wxCheckBox(this, wxID_ANY, _(L("Tool changes"))); - m_checkbox_color_changes = new wxCheckBox(this, wxID_ANY, _(L("Color changes"))); - m_checkbox_pause_prints = new wxCheckBox(this, wxID_ANY, _(L("Pause prints"))); - m_checkbox_custom_gcodes = new wxCheckBox(this, wxID_ANY, _(L("Custom GCodes"))); -#endif // ENABLE_GCODE_VIEWER m_checkbox_shells = new wxCheckBox(this, wxID_ANY, _(L("Shells"))); m_checkbox_legend = new wxCheckBox(this, wxID_ANY, _(L("Legend"))); m_checkbox_legend->SetValue(true); +#endif // ENABLE_GCODE_VIEWER wxBoxSizer* top_sizer = new wxBoxSizer(wxHORIZONTAL); top_sizer->Add(m_canvas_widget, 1, wxALL | wxEXPAND, 0); @@ -354,8 +362,11 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view bottom_sizer->Add(m_label_view_type, 0, wxALIGN_CENTER_VERTICAL, 5); bottom_sizer->Add(m_choice_view_type, 0, wxEXPAND | wxALL, 5); bottom_sizer->AddSpacer(10); - bottom_sizer->Add(m_label_show_features, 0, wxALIGN_CENTER_VERTICAL, 5); + bottom_sizer->Add(m_label_show, 0, wxALIGN_CENTER_VERTICAL, 5); bottom_sizer->Add(m_combochecklist_features, 0, wxEXPAND | wxALL, 5); +#if ENABLE_GCODE_VIEWER + bottom_sizer->Add(m_combochecklist_options, 0, wxEXPAND | wxALL, 5); +#else bottom_sizer->AddSpacer(20); bottom_sizer->Add(m_checkbox_travel, 0, wxEXPAND | wxALL, 5); bottom_sizer->AddSpacer(10); @@ -363,19 +374,10 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view bottom_sizer->AddSpacer(10); bottom_sizer->Add(m_checkbox_unretractions, 0, wxEXPAND | wxALL, 5); bottom_sizer->AddSpacer(10); -#if ENABLE_GCODE_VIEWER - bottom_sizer->Add(m_checkbox_tool_changes, 0, wxEXPAND | wxALL, 5); - bottom_sizer->AddSpacer(10); - bottom_sizer->Add(m_checkbox_color_changes, 0, wxEXPAND | wxALL, 5); - bottom_sizer->AddSpacer(10); - bottom_sizer->Add(m_checkbox_pause_prints, 0, wxEXPAND | wxALL, 5); - bottom_sizer->AddSpacer(10); - bottom_sizer->Add(m_checkbox_custom_gcodes, 0, wxEXPAND | wxALL, 5); - bottom_sizer->AddSpacer(10); -#endif // ENABLE_GCODE_VIEWER bottom_sizer->Add(m_checkbox_shells, 0, wxEXPAND | wxALL, 5); bottom_sizer->AddSpacer(20); bottom_sizer->Add(m_checkbox_legend, 0, wxEXPAND | wxALL, 5); +#endif // ENABLE_GCODE_VIEWER wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); main_sizer->Add(top_sizer, 1, wxALL | wxEXPAND, 0); @@ -552,17 +554,15 @@ void Preview::bind_event_handlers() this->Bind(wxEVT_SIZE, &Preview::on_size, this); m_choice_view_type->Bind(wxEVT_CHOICE, &Preview::on_choice_view_type, this); m_combochecklist_features->Bind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_features, this); +#if ENABLE_GCODE_VIEWER + m_combochecklist_options->Bind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_options, this); +#else m_checkbox_travel->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_travel, this); m_checkbox_retractions->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_retractions, this); m_checkbox_unretractions->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_unretractions, this); -#if ENABLE_GCODE_VIEWER - m_checkbox_tool_changes->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_tool_changes, this); - m_checkbox_color_changes->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_color_changes, this); - m_checkbox_pause_prints->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_pause_prints, this); - m_checkbox_custom_gcodes->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_custom_gcodes, this); -#endif // ENABLE_GCODE_VIEWER m_checkbox_shells->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_shells, this); m_checkbox_legend->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_legend, this); +#endif // ENABLE_GCODE_VIEWER } void Preview::unbind_event_handlers() @@ -570,54 +570,48 @@ void Preview::unbind_event_handlers() this->Unbind(wxEVT_SIZE, &Preview::on_size, this); m_choice_view_type->Unbind(wxEVT_CHOICE, &Preview::on_choice_view_type, this); m_combochecklist_features->Unbind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_features, this); +#if ENABLE_GCODE_VIEWER + m_combochecklist_options->Unbind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_options, this); +#else m_checkbox_travel->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_travel, this); m_checkbox_retractions->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_retractions, this); m_checkbox_unretractions->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_unretractions, this); -#if ENABLE_GCODE_VIEWER - m_checkbox_tool_changes->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_tool_changes, this); - m_checkbox_color_changes->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_color_changes, this); - m_checkbox_pause_prints->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_pause_prints, this); - m_checkbox_custom_gcodes->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_custom_gcodes, this); -#endif // ENABLE_GCODE_VIEWER m_checkbox_shells->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_shells, this); m_checkbox_legend->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_legend, this); +#endif // ENABLE_GCODE_VIEWER } void Preview::show_hide_ui_elements(const std::string& what) { bool enable = (what == "full"); - m_label_show_features->Enable(enable); + m_label_show->Enable(enable); m_combochecklist_features->Enable(enable); - m_checkbox_travel->Enable(enable); +#if ENABLE_GCODE_VIEWER + m_combochecklist_options->Enable(enable); +#else + m_checkbox_travel->Enable(enable); m_checkbox_retractions->Enable(enable); m_checkbox_unretractions->Enable(enable); -#if ENABLE_GCODE_VIEWER - m_checkbox_tool_changes->Enable(enable); - m_checkbox_color_changes->Enable(enable); - m_checkbox_pause_prints->Enable(enable); - m_checkbox_custom_gcodes->Enable(enable); -#endif // ENABLE_GCODE_VIEWER m_checkbox_shells->Enable(enable); m_checkbox_legend->Enable(enable); +#endif // ENABLE_GCODE_VIEWER enable = (what != "none"); m_label_view_type->Enable(enable); m_choice_view_type->Enable(enable); bool visible = (what != "none"); - m_label_show_features->Show(visible); + m_label_show->Show(visible); m_combochecklist_features->Show(visible); +#if ENABLE_GCODE_VIEWER + m_combochecklist_options->Show(visible); +#else m_checkbox_travel->Show(visible); m_checkbox_retractions->Show(visible); m_checkbox_unretractions->Show(visible); -#if ENABLE_GCODE_VIEWER - m_checkbox_tool_changes->Show(visible); - m_checkbox_color_changes->Show(visible); - m_checkbox_pause_prints->Show(visible); - m_checkbox_custom_gcodes->Show(visible); -#endif // ENABLE_GCODE_VIEWER m_checkbox_shells->Show(visible); m_checkbox_legend->Show(visible); +#endif // ENABLE_GCODE_VIEWER m_label_view_type->Show(visible); m_choice_view_type->Show(visible); } @@ -676,72 +670,36 @@ void Preview::on_combochecklist_features(wxCommandEvent& evt) refresh_print(); } +#if ENABLE_GCODE_VIEWER +void Preview::on_combochecklist_options(wxCommandEvent& evt) +{ + m_canvas->set_gcode_options_visibility_from_flags(static_cast(Slic3r::GUI::combochecklist_get_flags(m_combochecklist_options))); + refresh_print(); +} +#else void Preview::on_checkbox_travel(wxCommandEvent& evt) { -#if ENABLE_GCODE_VIEWER - m_canvas->set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Travel, m_checkbox_travel->IsChecked()); - refresh_print(); -#else m_gcode_preview_data->travel.is_visible = m_checkbox_travel->IsChecked(); m_gcode_preview_data->ranges.feedrate.set_mode(GCodePreviewData::FeedrateKind::TRAVEL, m_gcode_preview_data->travel.is_visible); // Rather than refresh, reload print so that speed color ranges get recomputed (affected by travel visibility) reload_print(); -#endif // ENABLE_GCODE_VIEWER } void Preview::on_checkbox_retractions(wxCommandEvent& evt) { -#if ENABLE_GCODE_VIEWER - m_canvas->set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Retract, m_checkbox_retractions->IsChecked()); -#else m_gcode_preview_data->retraction.is_visible = m_checkbox_retractions->IsChecked(); -#endif // ENABLE_GCODE_VIEWER refresh_print(); } void Preview::on_checkbox_unretractions(wxCommandEvent& evt) { -#if ENABLE_GCODE_VIEWER - m_canvas->set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Unretract, m_checkbox_unretractions->IsChecked()); -#else m_gcode_preview_data->unretraction.is_visible = m_checkbox_unretractions->IsChecked(); -#endif // ENABLE_GCODE_VIEWER refresh_print(); } -#if ENABLE_GCODE_VIEWER -void Preview::on_checkbox_tool_changes(wxCommandEvent& evt) -{ - m_canvas->set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Tool_change, m_checkbox_tool_changes->IsChecked()); - refresh_print(); -} - -void Preview::on_checkbox_color_changes(wxCommandEvent& evt) -{ - m_canvas->set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Color_change, m_checkbox_color_changes->IsChecked()); - refresh_print(); -} - -void Preview::on_checkbox_pause_prints(wxCommandEvent& evt) -{ - m_canvas->set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Pause_Print, m_checkbox_pause_prints->IsChecked()); - refresh_print(); -} - -void Preview::on_checkbox_custom_gcodes(wxCommandEvent& evt) -{ - m_canvas->set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Custom_GCode, m_checkbox_custom_gcodes->IsChecked()); - refresh_print(); -} -#endif // ENABLE_GCODE_VIEWER - void Preview::on_checkbox_shells(wxCommandEvent& evt) { -#if ENABLE_GCODE_VIEWER - m_canvas->set_shells_visible(m_checkbox_shells->IsChecked()); -#else m_gcode_preview_data->shell.is_visible = m_checkbox_shells->IsChecked(); -#endif // ENABLE_GCODE_VIEWER refresh_print(); } @@ -750,6 +708,7 @@ void Preview::on_checkbox_legend(wxCommandEvent& evt) m_canvas->enable_legend_texture(m_checkbox_legend->IsChecked()); m_canvas_widget->Refresh(); } +#endif // ENABLE_GCODE_VIEWER void Preview::update_view_type(bool slice_completed) { @@ -969,11 +928,13 @@ void Preview::update_double_slider_from_canvas(wxKeyEvent& event) m_slider->SetHigherValue(new_pos); if (event.ShiftDown() || m_slider->is_one_layer()) m_slider->SetLowerValue(m_slider->GetHigherValue()); } +#if !ENABLE_GCODE_VIEWER else if (key == 'L') { m_checkbox_legend->SetValue(!m_checkbox_legend->GetValue()); auto evt = wxCommandEvent(); on_checkbox_legend(evt); } +#endif // !ENABLE_GCODE_VIEWER else if (key == 'S') m_slider->ChangeOneLayerLock(); else if (key == WXK_SHIFT) @@ -1078,6 +1039,7 @@ void Preview::load_print_as_fff(bool keep_z_range) #if ENABLE_GCODE_VIEWER m_canvas->load_gcode_preview(*m_gcode_result); m_canvas->refresh_gcode_preview(*m_gcode_result, colors); + show_hide_ui_elements(gcode_preview_data_valid ? "full" : "simple"); #else m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); #endif // ENABLE_GCODE_VIEWER @@ -1085,12 +1047,14 @@ void Preview::load_print_as_fff(bool keep_z_range) } else { // Load the initial preview based on slices, not the final G-code. m_canvas->load_preview(colors, color_print_values); +#if ENABLE_GCODE_VIEWER + show_hide_ui_elements("none"); +#endif // ENABLE_GCODE_VIEWER } - show_hide_ui_elements(gcode_preview_data_valid ? "full" : "simple"); - // recalculates zs and update sliders accordingly #if ENABLE_GCODE_VIEWER const std::vector& zs = m_canvas->get_layers_zs(); #else + show_hide_ui_elements(gcode_preview_data_valid ? "full" : "simple"); std::vector zs = m_canvas->get_current_print_zs(true); #endif // ENABLE_GCODE_VIEWER if (zs.empty()) { diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index bdbbe79daa..c4ad4eb79c 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -93,19 +93,17 @@ class Preview : public wxPanel wxBoxSizer* m_double_slider_sizer; wxStaticText* m_label_view_type; wxChoice* m_choice_view_type; - wxStaticText* m_label_show_features; + wxStaticText* m_label_show; wxComboCtrl* m_combochecklist_features; +#if ENABLE_GCODE_VIEWER + wxComboCtrl* m_combochecklist_options; +#else wxCheckBox* m_checkbox_travel; wxCheckBox* m_checkbox_retractions; wxCheckBox* m_checkbox_unretractions; -#if ENABLE_GCODE_VIEWER - wxCheckBox* m_checkbox_tool_changes; - wxCheckBox* m_checkbox_color_changes; - wxCheckBox* m_checkbox_pause_prints; - wxCheckBox* m_checkbox_custom_gcodes; -#endif // ENABLE_GCODE_VIEWER wxCheckBox* m_checkbox_shells; wxCheckBox* m_checkbox_legend; +#endif // ENABLE_GCODE_VIEWER DynamicPrintConfig* m_config; BackgroundSlicingProcess* m_process; @@ -192,17 +190,15 @@ private: void on_size(wxSizeEvent& evt); void on_choice_view_type(wxCommandEvent& evt); void on_combochecklist_features(wxCommandEvent& evt); +#if ENABLE_GCODE_VIEWER + void on_combochecklist_options(wxCommandEvent& evt); +#else void on_checkbox_travel(wxCommandEvent& evt); void on_checkbox_retractions(wxCommandEvent& evt); void on_checkbox_unretractions(wxCommandEvent& evt); -#if ENABLE_GCODE_VIEWER - void on_checkbox_tool_changes(wxCommandEvent& evt); - void on_checkbox_color_changes(wxCommandEvent& evt); - void on_checkbox_pause_prints(wxCommandEvent& evt); - void on_checkbox_custom_gcodes(wxCommandEvent& evt); -#endif // ENABLE_GCODE_VIEWER void on_checkbox_shells(wxCommandEvent& evt); void on_checkbox_legend(wxCommandEvent& evt); +#endif // ENABLE_GCODE_VIEWER // Create/Update/Reset double slider on 3dPreview void create_double_slider(); From 85676af17131eebebd61ed747d7827d2411bb9e0 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Sat, 25 Apr 2020 10:36:51 +0200 Subject: [PATCH 039/255] Modified wxCheckListBoxComboPopup::GetAdjustedSize() and create_combochecklist() to size the combo control taking in account the items width --- src/slic3r/GUI/GUI.cpp | 6 ++++++ src/slic3r/GUI/wxExtensions.cpp | 14 +++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp index dd9ddcab8f..a66396b277 100644 --- a/src/slic3r/GUI/GUI.cpp +++ b/src/slic3r/GUI/GUI.cpp @@ -271,9 +271,12 @@ void create_combochecklist(wxComboCtrl* comboCtrl, const std::string& text, cons // On the other side, with this line the combo box popup cannot be closed by clicking on the combo button on Windows 10. comboCtrl->UseAltPopupWindow(); + int max_width = 0; + comboCtrl->EnablePopupAnimation(false); comboCtrl->SetPopupControl(popup); wxString title = from_u8(text); + max_width = std::max(max_width, 60 + comboCtrl->GetTextExtent(title).x); popup->SetStringValue(title); popup->Bind(wxEVT_CHECKLISTBOX, [popup](wxCommandEvent& evt) { popup->OnCheckListBox(evt); }); popup->Bind(wxEVT_LISTBOX, [popup](wxCommandEvent& evt) { popup->OnListBoxSelection(evt); }); @@ -289,9 +292,12 @@ void create_combochecklist(wxComboCtrl* comboCtrl, const std::string& text, cons for (size_t i = 0; i < items_str.size(); i += 2) { wxString label = from_u8(items_str[i]); + max_width = std::max(max_width, 60 + popup->GetTextExtent(label).x); popup->Append(label); popup->Check(i / 2, items_str[i + 1] == "1"); } + + comboCtrl->SetMinClientSize(wxSize(max_width, -1)); } } diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index b3f2791961..3e55f6ae30 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -197,8 +197,8 @@ wxString wxCheckListBoxComboPopup::GetStringValue() const wxSize wxCheckListBoxComboPopup::GetAdjustedSize(int minWidth, int prefHeight, int maxHeight) { - // matches owner wxComboCtrl's width - // and sets height dinamically in dependence of contained items count + // set width dinamically in dependence of items text + // and set height dinamically in dependence of items count wxComboCtrl* cmb = GetComboCtrl(); if (cmb != nullptr) @@ -207,7 +207,15 @@ wxSize wxCheckListBoxComboPopup::GetAdjustedSize(int minWidth, int prefHeight, i unsigned int count = GetCount(); if (count > 0) - size.SetHeight(count * DefaultItemHeight); + { + int max_width = size.x; + for (unsigned int i = 0; i < count; ++i) + { + max_width = std::max(max_width, 60 + GetTextExtent(GetString(i)).x); + } + size.SetWidth(max_width); + size.SetHeight(count * GetTextExtent(GetString(0)).y); + } else size.SetHeight(DefaultHeight); From eadad6c1d1c37a5afd8a7beb059fb2005621d3c1 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Sat, 25 Apr 2020 11:16:28 +0200 Subject: [PATCH 040/255] GCodeViewer -> Add travel paths to legend --- src/slic3r/GUI/GCodeViewer.cpp | 41 ++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index e6ddba8d11..73f41cb85e 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -177,10 +177,11 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: if (m_vertices.vertices_count == 0) return; + // update tool colors m_tool_colors = decode_colors(str_tool_colors); + // update ranges m_extrusions.reset_ranges(); - for (size_t i = 0; i < m_vertices.vertices_count; ++i) { // skip first vertex @@ -201,9 +202,9 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: } case GCodeProcessor::EMoveType::Travel: { - if (m_buffers[buffer_id(curr.type)].visible) { + if (m_buffers[buffer_id(curr.type)].visible) m_extrusions.ranges.feedrate.update_from(curr.feedrate); - } + break; } default: { break; } @@ -689,6 +690,7 @@ void GCodeViewer::render_overlay() const } }; + // extrusion paths -> title ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); switch (m_view_type) { @@ -703,9 +705,9 @@ void GCodeViewer::render_overlay() const default: { break; } } ImGui::PopStyleColor(); - ImGui::Separator(); + // extrusion paths -> items switch (m_view_type) { case EViewType::FeatureType: @@ -810,6 +812,37 @@ void GCodeViewer::render_overlay() const default: { break; } } + // travel paths + if (m_buffers[buffer_id(GCodeProcessor::EMoveType::Travel)].visible) + { + switch (m_view_type) + { + case EViewType::Feedrate: + case EViewType::Tool: + case EViewType::ColorPrint: + { + break; + } + default: + { + // title + ImGui::Spacing(); + ImGui::Spacing(); + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + imgui.text(I18N::translate_utf8(L("Travel"))); + ImGui::PopStyleColor(); + ImGui::Separator(); + + // items + add_item(Travel_Colors[0], I18N::translate_utf8(L("Movement"))); + add_item(Travel_Colors[1], I18N::translate_utf8(L("Extrusion"))); + add_item(Travel_Colors[2], I18N::translate_utf8(L("Retraction"))); + + break; + } + } + } + imgui.end(); ImGui::PopStyleVar(); } From 4ea96340d8817df9df627d9a54adefb65d07739d Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Sat, 25 Apr 2020 12:24:56 +0200 Subject: [PATCH 041/255] GCodeViewer -> Draw alphed extrusion paths into legend when set as not visible --- src/slic3r/GUI/GCodeViewer.cpp | 19 ++++++++++++------- src/slic3r/GUI/GCodeViewer.hpp | 6 ++++++ src/slic3r/GUI/GUI_Preview.cpp | 4 ++-- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 73f41cb85e..e6878c6191 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -33,8 +33,7 @@ static GCodeProcessor::EMoveType buffer_type(unsigned char id) { return static_cast(static_cast(GCodeProcessor::EMoveType::Retract) + id); } -std::vector> decode_colors(const std::vector& colors) -{ +std::vector> decode_colors(const std::vector& colors) { static const float INV_255 = 1.0f / 255.0f; std::vector> output(colors.size(), {0.0f, 0.0f, 0.0f} ); @@ -67,6 +66,10 @@ void GCodeViewer::VBuffer::reset() vertices_count = 0; } +bool GCodeViewer::Path::is_path_visible(unsigned int flags, const Path& path) { + return Extrusions::is_role_visible(flags, path.role); +}; + void GCodeViewer::IBuffer::reset() { // release gpu memory @@ -509,10 +512,6 @@ void GCodeViewer::render_toolpaths() const BOOST_LOG_TRIVIAL(error) << "Unable to find uniform_color uniform"; }; - auto is_path_visible = [](unsigned int flags, const Path& path) { - return Extrusions::is_role_visible(flags, path.role); - }; - glsafe(::glCullFace(GL_BACK)); glsafe(::glLineWidth(3.0f)); @@ -600,7 +599,7 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Extrude: { for (const Path& path : buffer.paths) { - if (!is_path_visible(m_extrusions.role_visibility_flags, path)) + if (!Path::is_path_visible(m_extrusions.role_visibility_flags, path)) continue; set_color(current_program_id, extrusion_color(path)); @@ -713,7 +712,13 @@ void GCodeViewer::render_overlay() const case EViewType::FeatureType: { for (ExtrusionRole role : m_roles) { + bool visible = m_extrusions.is_role_visible(role); + if (!visible) + ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.3333f); + add_item(Extrusion_Role_Colors[static_cast(role)], I18N::translate_utf8(ExtrusionEntity::role_to_string(role))); + if (!visible) + ImGui::PopStyleVar(); } break; } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index bfd61e8d4c..f644d3481e 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -54,6 +54,8 @@ class GCodeViewer feedrate == move.feedrate && fan_speed == move.fan_speed && volumetric_rate == move.volumetric_rate() && extruder_id == move.extruder_id && cp_color_id == move.cp_color_id; } + + static bool is_path_visible(unsigned int flags, const Path& path); }; // buffer containing indices data and shader for a specific toolpath type @@ -130,6 +132,10 @@ class GCodeViewer void reset_ranges() { ranges.reset(); } + bool is_role_visible(ExtrusionRole role) const { + return role < erCount && (role_visibility_flags & (1 << role)) != 0; + } + static bool is_role_visible(unsigned int flags, ExtrusionRole role) { return role < erCount && (flags & (1 << role)) != 0; } diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 876d212fb4..65adfe8def 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -332,7 +332,7 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view #if ENABLE_GCODE_VIEWER m_combochecklist_options = new wxComboCtrl(); - m_combochecklist_options->Create(this, wxID_ANY, _(L("Options")), wxDefaultPosition, wxSize(15 * wxGetApp().em_unit(), -1), wxCB_READONLY); + m_combochecklist_options->Create(this, wxID_ANY, _(L("Others")), wxDefaultPosition, wxSize(15 * wxGetApp().em_unit(), -1), wxCB_READONLY); std::string options_items = GUI::into_u8( _(L("Travel")) + "|0|" + _(L("Retractions")) + "|0|" + @@ -344,7 +344,7 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view _(L("Shells")) + "|0|" + _(L("Legend")) + "|1" ); - Slic3r::GUI::create_combochecklist(m_combochecklist_options, GUI::into_u8(_(L("Options"))), options_items); + Slic3r::GUI::create_combochecklist(m_combochecklist_options, GUI::into_u8(_(L("Others"))), options_items); #else m_checkbox_travel = new wxCheckBox(this, wxID_ANY, _(L("Travel"))); m_checkbox_retractions = new wxCheckBox(this, wxID_ANY, _(L("Retractions"))); From c76bf934f73bf5c1097bf558ff1606a8b0769c44 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 27 Apr 2020 08:19:48 +0200 Subject: [PATCH 042/255] GCodeViewer -> Shortcut to show/hide legend --- src/slic3r/GUI/GCodeViewer.cpp | 1 - src/slic3r/GUI/GLCanvas3D.cpp | 11 +++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index e6878c6191..2baaedbc2f 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -10,7 +10,6 @@ #if ENABLE_GCODE_VIEWER #include "GUI_Utils.hpp" #include "DoubleSlider.hpp" -#include "GLToolbar.hpp" #include "GLCanvas3D.hpp" #include "libslic3r/Model.hpp" #endif // ENABLE_GCODE_VIEWER diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ab2dee6938..3e4487c70c 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3202,6 +3202,17 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) #else case 'k': { m_camera.select_next_type(); m_dirty = true; break; } #endif // ENABLE_NON_STATIC_CANVAS_MANAGER +#if ENABLE_GCODE_VIEWER + case 'L': + case 'l': { + if (!m_main_toolbar.is_enabled()) + { + m_gcode_viewer.enable_legend(!m_gcode_viewer.is_legend_enabled()); + m_dirty = true; + } + break; + } +#endif // ENABLE_GCODE_VIEWER case 'O': case 'o': { _update_camera_zoom(-1.0); break; } #if ENABLE_RENDER_PICKING_PASS From a6ed1d817a0327745aed6a907af652ee2ad9a441 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 27 Apr 2020 11:44:29 +0200 Subject: [PATCH 043/255] GCodeViewer -> Layers z slider wip --- resources/shaders/customs.vs | 2 +- resources/shaders/pauses.vs | 2 +- resources/shaders/retractions.vs | 2 +- resources/shaders/toolchanges.vs | 2 +- resources/shaders/unretractions.vs | 2 +- src/slic3r/GUI/3DScene.cpp | 2 + src/slic3r/GUI/3DScene.hpp | 4 ++ src/slic3r/GUI/GCodeViewer.cpp | 97 +++++++++++++++++++++++------- src/slic3r/GUI/GCodeViewer.hpp | 7 ++- src/slic3r/GUI/GLCanvas3D.cpp | 7 ++- src/slic3r/GUI/GLCanvas3D.hpp | 2 + src/slic3r/GUI/GUI_Preview.cpp | 5 ++ 12 files changed, 104 insertions(+), 30 deletions(-) diff --git a/resources/shaders/customs.vs b/resources/shaders/customs.vs index 45fa543f45..3b78a59700 100644 --- a/resources/shaders/customs.vs +++ b/resources/shaders/customs.vs @@ -13,5 +13,5 @@ void main() // world_normal_z = gl_Normal.z; gl_Position = ftransform(); - gl_PointSize = 10.0; + gl_PointSize = 15.0; } diff --git a/resources/shaders/pauses.vs b/resources/shaders/pauses.vs index 45fa543f45..3b78a59700 100644 --- a/resources/shaders/pauses.vs +++ b/resources/shaders/pauses.vs @@ -13,5 +13,5 @@ void main() // world_normal_z = gl_Normal.z; gl_Position = ftransform(); - gl_PointSize = 10.0; + gl_PointSize = 15.0; } diff --git a/resources/shaders/retractions.vs b/resources/shaders/retractions.vs index 2cf5ca2dd0..3b78a59700 100644 --- a/resources/shaders/retractions.vs +++ b/resources/shaders/retractions.vs @@ -13,5 +13,5 @@ void main() // world_normal_z = gl_Normal.z; gl_Position = ftransform(); - gl_PointSize = 5.0; + gl_PointSize = 15.0; } diff --git a/resources/shaders/toolchanges.vs b/resources/shaders/toolchanges.vs index 2cf5ca2dd0..3b78a59700 100644 --- a/resources/shaders/toolchanges.vs +++ b/resources/shaders/toolchanges.vs @@ -13,5 +13,5 @@ void main() // world_normal_z = gl_Normal.z; gl_Position = ftransform(); - gl_PointSize = 5.0; + gl_PointSize = 15.0; } diff --git a/resources/shaders/unretractions.vs b/resources/shaders/unretractions.vs index 2cf5ca2dd0..3b78a59700 100644 --- a/resources/shaders/unretractions.vs +++ b/resources/shaders/unretractions.vs @@ -13,5 +13,5 @@ void main() // world_normal_z = gl_Normal.z; gl_Position = ftransform(); - gl_PointSize = 5.0; + gl_PointSize = 15.0; } diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index e60676ca31..63cacdd457 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -341,6 +341,7 @@ BoundingBoxf3 GLVolume::transformed_convex_hull_bounding_box(const Transform3d & } +#if !ENABLE_GCODE_VIEWER void GLVolume::set_range(double min_z, double max_z) { this->qverts_range.first = 0; @@ -375,6 +376,7 @@ void GLVolume::set_range(double min_z, double max_z) } } } +#endif // !ENABLE_GCODE_VIEWER void GLVolume::render() const { diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 70d6fb016a..28295a35f7 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -442,7 +442,9 @@ public: bool empty() const { return this->indexed_vertex_array.empty(); } +#if !ENABLE_GCODE_VIEWER void set_range(double low, double high); +#endif // !ENABLE_GCODE_VIEWER void render() const; #if !ENABLE_SLOPE_RENDERING @@ -560,7 +562,9 @@ public: void clear() { for (auto *v : volumes) delete v; volumes.clear(); } bool empty() const { return volumes.empty(); } +#if !ENABLE_GCODE_VIEWER void set_range(double low, double high) { for (GLVolume *vol : this->volumes) vol->set_range(low, high); } +#endif // !ENABLE_GCODE_VIEWER void set_print_box(float min_x, float min_y, float min_z, float max_x, float max_y, float max_z) { m_print_box_min[0] = min_x; m_print_box_min[1] = min_y; m_print_box_min[2] = min_z; diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 2baaedbc2f..045f6ed570 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -65,10 +65,19 @@ void GCodeViewer::VBuffer::reset() vertices_count = 0; } -bool GCodeViewer::Path::is_path_visible(unsigned int flags, const Path& path) { +bool GCodeViewer::Path::is_path_visible(const Path& path, unsigned int flags) { return Extrusions::is_role_visible(flags, path.role); }; +bool GCodeViewer::Path::is_path_in_z_range(const Path& path, const std::array& z_range) +{ + auto in_z_range = [z_range](double z) { + return z > z_range[0] - EPSILON && z < z_range[1] + EPSILON; + }; + + return in_z_range(path.first_z) || in_z_range(path.last_z); +} + void GCodeViewer::IBuffer::reset() { // release gpu memory @@ -96,7 +105,8 @@ bool GCodeViewer::IBuffer::init_shader(const std::string& vertex_shader_src, con void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move) { unsigned int id = static_cast(data.size()); - paths.push_back({ move.type, move.extrusion_role, id, id, move.delta_extruder, move.height, move.width, move.feedrate, move.fan_speed, move.volumetric_rate(), move.extruder_id, move.cp_color_id }); + double z = static_cast(move.position[2]); + paths.push_back({ move.type, move.extrusion_role, id, id, z, z, move.delta_extruder, move.height, move.width, move.feedrate, move.fan_speed, move.volumetric_rate(), move.extruder_id, move.cp_color_id }); } std::array GCodeViewer::Extrusions::Range::get_color_at(float value) const @@ -182,7 +192,7 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: // update tool colors m_tool_colors = decode_colors(str_tool_colors); - // update ranges + // update ranges for coloring / legend m_extrusions.reset_ranges(); for (size_t i = 0; i < m_vertices.vertices_count; ++i) { @@ -229,6 +239,7 @@ void GCodeViewer::reset() m_extrusions.reset_ranges(); m_shells.volumes.clear(); m_layers_zs = std::vector(); + m_layers_z_range = { 0.0, 0.0 }; m_roles = std::vector(); } @@ -394,7 +405,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) // layers zs / roles / extruder ids / cp color ids -> extract from result for (const GCodeProcessor::MoveVertex& move : gcode_result.moves) { if (move.type == GCodeProcessor::EMoveType::Extrude) - m_layers_zs.emplace_back(move.position[2]); + m_layers_zs.emplace_back(static_cast(move.position[2])); m_roles.emplace_back(move.extrusion_role); m_extruder_ids.emplace_back(move.extruder_id); @@ -414,6 +425,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) if (k < n) m_layers_zs.erase(m_layers_zs.begin() + k, m_layers_zs.end()); + // set layers z range + m_layers_z_range = { m_layers_zs.front(), m_layers_zs.back() }; + // roles -> remove duplicates std::sort(m_roles.begin(), m_roles.end()); m_roles.erase(std::unique(m_roles.begin(), m_roles.end()), m_roles.end()); @@ -545,60 +559,90 @@ void GCodeViewer::render_toolpaths() const { std::array color = { 1.0f, 1.0f, 1.0f }; set_color(current_program_id, color); - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawElements(GL_POINTS, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + for (const Path& path : buffer.paths) { + if (!Path::is_path_in_z_range(path, m_layers_z_range)) + continue; + + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + } break; } case GCodeProcessor::EMoveType::Color_change: { std::array color = { 1.0f, 0.0f, 0.0f }; set_color(current_program_id, color); - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawElements(GL_POINTS, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + for (const Path& path : buffer.paths) { + if (!Path::is_path_in_z_range(path, m_layers_z_range)) + continue; + + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + } break; } case GCodeProcessor::EMoveType::Pause_Print: { std::array color = { 0.0f, 1.0f, 0.0f }; set_color(current_program_id, color); - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawElements(GL_POINTS, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + for (const Path& path : buffer.paths) { + if (!Path::is_path_in_z_range(path, m_layers_z_range)) + continue; + + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + } break; } case GCodeProcessor::EMoveType::Custom_GCode: { std::array color = { 0.0f, 0.0f, 1.0f }; set_color(current_program_id, color); - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawElements(GL_POINTS, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + for (const Path& path : buffer.paths) { + if (!Path::is_path_in_z_range(path, m_layers_z_range)) + continue; + + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + } break; } case GCodeProcessor::EMoveType::Retract: { std::array color = { 1.0f, 0.0f, 1.0f }; set_color(current_program_id, color); - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawElements(GL_POINTS, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + for (const Path& path : buffer.paths) { + if (!Path::is_path_in_z_range(path, m_layers_z_range)) + continue; + + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + } break; } case GCodeProcessor::EMoveType::Unretract: { std::array color = { 0.0f, 1.0f, 1.0f }; set_color(current_program_id, color); - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawElements(GL_POINTS, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + for (const Path& path : buffer.paths) { + if (!Path::is_path_in_z_range(path, m_layers_z_range)) + continue; + + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + } break; } case GCodeProcessor::EMoveType::Extrude: { for (const Path& path : buffer.paths) { - if (!Path::is_path_visible(m_extrusions.role_visibility_flags, path)) + if (!Path::is_path_visible(path, m_extrusions.role_visibility_flags) || !Path::is_path_in_z_range(path, m_layers_z_range)) continue; set_color(current_program_id, extrusion_color(path)); @@ -609,6 +653,9 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Travel: { for (const Path& path : buffer.paths) { + if (!Path::is_path_in_z_range(path, m_layers_z_range)) + continue; + set_color(current_program_id, (m_view_type == EViewType::Feedrate || m_view_type == EViewType::Tool || m_view_type == EViewType::ColorPrint) ? extrusion_color(path) : travel_color(path)); glsafe(::glDrawElements(GL_LINE_STRIP, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); } @@ -655,6 +702,10 @@ void GCodeViewer::render_overlay() const ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); imgui.begin(std::string("Legend"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); + if (ImGui::IsWindowAppearing()) + // force an extra farme + wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); auto add_item = [draw_list, &imgui](const std::array& color, const std::string& label) { diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index f644d3481e..3c73cee5a2 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -40,6 +40,8 @@ class GCodeViewer ExtrusionRole role{ erNone }; unsigned int first{ 0 }; unsigned int last{ 0 }; + double first_z{ 0.0f }; + double last_z{ 0.0f }; float delta_extruder{ 0.0f }; float height{ 0.0f }; float width{ 0.0f }; @@ -55,7 +57,8 @@ class GCodeViewer extruder_id == move.extruder_id && cp_color_id == move.cp_color_id; } - static bool is_path_visible(unsigned int flags, const Path& path); + static bool is_path_visible(const Path& path, unsigned int flags); + static bool is_path_in_z_range(const Path& path, const std::array& z_range); }; // buffer containing indices data and shader for a specific toolpath type @@ -162,6 +165,7 @@ private: BoundingBoxf3 m_bounding_box; std::vector> m_tool_colors; std::vector m_layers_zs; + std::array m_layers_z_range; std::vector m_roles; std::vector m_extruder_ids; Extrusions m_extrusions; @@ -201,6 +205,7 @@ public: void set_toolpath_move_type_visible(GCodeProcessor::EMoveType type, bool visible); void set_toolpath_role_visibility_flags(unsigned int flags) { m_extrusions.role_visibility_flags = flags; } void set_options_visibility_from_flags(unsigned int flags); + void set_layers_z_range(const std::array& layers_z_range) { m_layers_z_range = layers_z_range; } bool is_legend_enabled() const { return m_legend_enabled; } void enable_legend(bool enable) { m_legend_enabled = enable; } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 3e4487c70c..6e7b53f689 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2346,17 +2346,22 @@ void GLCanvas3D::set_toolpath_view_type(GCodeViewer::EViewType type) { m_gcode_viewer.set_view_type(type); } + +void GLCanvas3D::set_toolpaths_z_range(const std::array& range) +{ + m_gcode_viewer.set_layers_z_range(range); +} #else std::vector GLCanvas3D::get_current_print_zs(bool active_only) const { return m_volumes.get_current_print_zs(active_only); } -#endif // ENABLE_GCODE_VIEWER void GLCanvas3D::set_toolpaths_range(double low, double high) { m_volumes.set_range(low, high); } +#endif // ENABLE_GCODE_VIEWER std::vector GLCanvas3D::load_object(const ModelObject& model_object, int obj_idx, std::vector instance_idxs) { diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 7a295b900d..152658b13a 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -650,8 +650,10 @@ public: void set_gcode_options_visibility_from_flags(unsigned int flags); void set_toolpath_role_visibility_flags(unsigned int flags); void set_toolpath_view_type(GCodeViewer::EViewType type); + void set_toolpaths_z_range(const std::array& range); #else std::vector get_current_print_zs(bool active_only) const; + void set_toolpaths_range(double low, double high); #endif // ENABLE_GCODE_VIEWER void set_toolpaths_range(double low, double high); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 65adfe8def..3e0d5cd5a4 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -1113,9 +1113,14 @@ void Preview::on_sliders_scroll_changed(wxCommandEvent& event) PrinterTechnology tech = m_process->current_printer_technology(); if (tech == ptFFF) { +#if ENABLE_GCODE_VIEWER + m_canvas->set_toolpaths_z_range({ m_slider->GetLowerValueD(), m_slider->GetHigherValueD() }); + m_canvas->set_as_dirty(); +#else m_canvas->set_toolpaths_range(m_slider->GetLowerValueD() - 1e-6, m_slider->GetHigherValueD() + 1e-6); m_canvas->render(); m_canvas->set_use_clipping_planes(false); +#endif // ENABLE_GCODE_VIEWER } else if (tech == ptSLA) { From c1246f86eb7cd1c92f8a3c57ba924bc2f9b1ce9a Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 27 Apr 2020 12:43:51 +0200 Subject: [PATCH 044/255] GCodeViewer -> Refactoring --- src/slic3r/GUI/GCodeViewer.cpp | 53 ++++++++++++++-------------------- src/slic3r/GUI/GCodeViewer.hpp | 22 +++++++------- src/slic3r/GUI/GLCanvas3D.cpp | 2 ++ 3 files changed, 35 insertions(+), 42 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 045f6ed570..268b998fa4 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -65,19 +65,6 @@ void GCodeViewer::VBuffer::reset() vertices_count = 0; } -bool GCodeViewer::Path::is_path_visible(const Path& path, unsigned int flags) { - return Extrusions::is_role_visible(flags, path.role); -}; - -bool GCodeViewer::Path::is_path_in_z_range(const Path& path, const std::array& z_range) -{ - auto in_z_range = [z_range](double z) { - return z > z_range[0] - EPSILON && z < z_range[1] + EPSILON; - }; - - return in_z_range(path.first_z) || in_z_range(path.last_z); -} - void GCodeViewer::IBuffer::reset() { // release gpu memory @@ -186,6 +173,8 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors) { + auto start_time = std::chrono::high_resolution_clock::now(); + if (m_vertices.vertices_count == 0) return; @@ -222,6 +211,9 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: default: { break; } } } + + auto end_time = std::chrono::high_resolution_clock::now(); + std::cout << "refresh: " << std::chrono::duration_cast(end_time - start_time).count() << "ms \n"; } void GCodeViewer::reset() @@ -560,7 +552,7 @@ void GCodeViewer::render_toolpaths() const std::array color = { 1.0f, 1.0f, 1.0f }; set_color(current_program_id, color); for (const Path& path : buffer.paths) { - if (!Path::is_path_in_z_range(path, m_layers_z_range)) + if (!is_in_z_range(path)) continue; glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); @@ -574,7 +566,7 @@ void GCodeViewer::render_toolpaths() const std::array color = { 1.0f, 0.0f, 0.0f }; set_color(current_program_id, color); for (const Path& path : buffer.paths) { - if (!Path::is_path_in_z_range(path, m_layers_z_range)) + if (!is_in_z_range(path)) continue; glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); @@ -588,7 +580,7 @@ void GCodeViewer::render_toolpaths() const std::array color = { 0.0f, 1.0f, 0.0f }; set_color(current_program_id, color); for (const Path& path : buffer.paths) { - if (!Path::is_path_in_z_range(path, m_layers_z_range)) + if (!is_in_z_range(path)) continue; glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); @@ -602,7 +594,7 @@ void GCodeViewer::render_toolpaths() const std::array color = { 0.0f, 0.0f, 1.0f }; set_color(current_program_id, color); for (const Path& path : buffer.paths) { - if (!Path::is_path_in_z_range(path, m_layers_z_range)) + if (!is_in_z_range(path)) continue; glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); @@ -616,7 +608,7 @@ void GCodeViewer::render_toolpaths() const std::array color = { 1.0f, 0.0f, 1.0f }; set_color(current_program_id, color); for (const Path& path : buffer.paths) { - if (!Path::is_path_in_z_range(path, m_layers_z_range)) + if (!is_in_z_range(path)) continue; glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); @@ -630,7 +622,7 @@ void GCodeViewer::render_toolpaths() const std::array color = { 0.0f, 1.0f, 1.0f }; set_color(current_program_id, color); for (const Path& path : buffer.paths) { - if (!Path::is_path_in_z_range(path, m_layers_z_range)) + if (!is_in_z_range(path)) continue; glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); @@ -642,7 +634,7 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Extrude: { for (const Path& path : buffer.paths) { - if (!Path::is_path_visible(path, m_extrusions.role_visibility_flags) || !Path::is_path_in_z_range(path, m_layers_z_range)) + if (!is_visible(path) || !is_in_z_range(path)) continue; set_color(current_program_id, extrusion_color(path)); @@ -653,7 +645,7 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Travel: { for (const Path& path : buffer.paths) { - if (!Path::is_path_in_z_range(path, m_layers_z_range)) + if (!is_in_z_range(path)) continue; set_color(current_program_id, (m_view_type == EViewType::Feedrate || m_view_type == EViewType::Tool || m_view_type == EViewType::ColorPrint) ? extrusion_color(path) : travel_color(path)); @@ -689,9 +681,7 @@ void GCodeViewer::render_shells() const void GCodeViewer::render_overlay() const { static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); - static const float ICON_BORDER_SIZE = 25.0f; static const ImU32 ICON_BORDER_COLOR = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); - static const float GAP_ICON_TEXT = 7.5f; if (!m_legend_enabled || m_roles.empty()) return; @@ -709,14 +699,15 @@ void GCodeViewer::render_overlay() const ImDrawList* draw_list = ImGui::GetWindowDrawList(); auto add_item = [draw_list, &imgui](const std::array& color, const std::string& label) { - // draw icon - ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f); - draw_list->AddRect({ pos.x, pos.y }, { pos.x + ICON_BORDER_SIZE, pos.y + ICON_BORDER_SIZE }, ICON_BORDER_COLOR, 0.0f, 0); - draw_list->AddRectFilled({ pos.x + 1.0f, pos.y + 1.0f }, - { pos.x + ICON_BORDER_SIZE - 1.0f, pos.y + ICON_BORDER_SIZE - 1.0f }, - ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f })); + float icon_size = ImGui::GetTextLineHeight(); + ImVec2 pos = ImGui::GetCursorPos(); + draw_list->AddRect({ pos.x, pos.y }, { pos.x + icon_size, pos.y + icon_size }, ICON_BORDER_COLOR, 0.0f, 0); + draw_list->AddRectFilled({ pos.x + 1.0f, pos.y + 1.0f }, { pos.x + icon_size - 1.0f, pos.y + icon_size - 1.0f }, + ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f })); + // draw text - ImGui::SetCursorPos({ pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT, pos.y + 0.5f * (ICON_BORDER_SIZE - ImGui::GetTextLineHeight()) }); + ImGui::Dummy({ icon_size, icon_size }); + ImGui::SameLine(); imgui.text(label); }; @@ -762,7 +753,7 @@ void GCodeViewer::render_overlay() const case EViewType::FeatureType: { for (ExtrusionRole role : m_roles) { - bool visible = m_extrusions.is_role_visible(role); + bool visible = is_visible(role); if (!visible) ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.3333f); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 3c73cee5a2..d2eb103f65 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -56,9 +56,6 @@ class GCodeViewer feedrate == move.feedrate && fan_speed == move.fan_speed && volumetric_rate == move.volumetric_rate() && extruder_id == move.extruder_id && cp_color_id == move.cp_color_id; } - - static bool is_path_visible(const Path& path, unsigned int flags); - static bool is_path_in_z_range(const Path& path, const std::array& z_range); }; // buffer containing indices data and shader for a specific toolpath type @@ -134,14 +131,6 @@ class GCodeViewer } void reset_ranges() { ranges.reset(); } - - bool is_role_visible(ExtrusionRole role) const { - return role < erCount && (role_visibility_flags & (1 << role)) != 0; - } - - static bool is_role_visible(unsigned int flags, ExtrusionRole role) { - return role < erCount && (flags & (1 << role)) != 0; - } }; public: @@ -217,6 +206,17 @@ private: void render_toolpaths() const; void render_shells() const; void render_overlay() const; + bool is_visible(ExtrusionRole role) const { + return role < erCount && (m_extrusions.role_visibility_flags & (1 << role)) != 0; + } + bool is_visible(const Path& path) const { return is_visible(path.role); } + bool is_in_z_range(const Path& path) const { + auto in_z_range = [this](double z) { + return z > m_layers_z_range[0] - EPSILON && z < m_layers_z_range[1] + EPSILON; + }; + + return in_z_range(path.first_z) || in_z_range(path.last_z); + } }; } // namespace GUI diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 6e7b53f689..fa38aca470 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2858,6 +2858,8 @@ void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result) void GLCanvas3D::refresh_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors) { m_gcode_viewer.refresh(gcode_result, str_tool_colors); + set_as_dirty(); + request_extra_frame(); } #endif // ENABLE_GCODE_VIEWER From eac4b3c15ac2866b59062f9e45988b3bccf2e849 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 27 Apr 2020 14:10:18 +0200 Subject: [PATCH 045/255] GCodeViewer -> Added debug statistics imgui dialog --- src/libslic3r/Technologies.hpp | 1 + src/slic3r/GUI/GCodeViewer.cpp | 136 ++++++++++++++++++++++++++++++--- src/slic3r/GUI/GCodeViewer.hpp | 42 +++++++++- src/slic3r/GUI/GLCanvas3D.cpp | 4 + 4 files changed, 169 insertions(+), 14 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 1ed939ba3e..d04bc97fa4 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -59,6 +59,7 @@ // Enable G-Code viewer #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) #define ENABLE_GCODE_VIEWER_DEBUG_OUTPUT (0 && ENABLE_GCODE_VIEWER) +#define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_2_3_0_ALPHA1) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 268b998fa4..7426eafc9e 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -7,12 +7,13 @@ #include "PresetBundle.hpp" #include "Camera.hpp" #include "I18N.hpp" -#if ENABLE_GCODE_VIEWER #include "GUI_Utils.hpp" #include "DoubleSlider.hpp" #include "GLCanvas3D.hpp" #include "libslic3r/Model.hpp" -#endif // ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER_STATISTICS +#include +#endif // ENABLE_GCODE_VIEWER_STATISTICS #include #include @@ -173,7 +174,9 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors) { +#if ENABLE_GCODE_VIEWER_STATISTICS auto start_time = std::chrono::high_resolution_clock::now(); +#endif // ENABLE_GCODE_VIEWER_STATISTICS if (m_vertices.vertices_count == 0) return; @@ -212,8 +215,9 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: } } - auto end_time = std::chrono::high_resolution_clock::now(); - std::cout << "refresh: " << std::chrono::duration_cast(end_time - start_time).count() << "ms \n"; +#if ENABLE_GCODE_VIEWER_STATISTICS + m_statistics.refresh_time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); +#endif // ENABLE_GCODE_VIEWER_STATISTICS } void GCodeViewer::reset() @@ -233,14 +237,25 @@ void GCodeViewer::reset() m_layers_zs = std::vector(); m_layers_z_range = { 0.0, 0.0 }; m_roles = std::vector(); + +#if ENABLE_GCODE_VIEWER_STATISTICS + m_statistics.reset_all(); +#endif // ENABLE_GCODE_VIEWER_STATISTICS } void GCodeViewer::render() const { +#if ENABLE_GCODE_VIEWER_STATISTICS + m_statistics.reset_opengl(); +#endif // ENABLE_GCODE_VIEWER_STATISTICS + glsafe(::glEnable(GL_DEPTH_TEST)); render_toolpaths(); render_shells(); - render_overlay(); + render_legend(); +#if ENABLE_GCODE_VIEWER_STATISTICS + render_statistics(); +#endif // ENABLE_GCODE_VIEWER_STATISTICS } bool GCodeViewer::is_toolpath_move_type_visible(GCodeProcessor::EMoveType type) const @@ -310,7 +325,9 @@ bool GCodeViewer::init_shaders() void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) { +#if ENABLE_GCODE_VIEWER_STATISTICS auto start_time = std::chrono::high_resolution_clock::now(); +#endif // ENABLE_GCODE_VIEWER_STATISTICS // vertex data m_vertices.vertices_count = gcode_result.moves.size(); @@ -326,6 +343,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) } } +#if ENABLE_GCODE_VIEWER_STATISTICS + m_statistics.vertices_size = vertices_data.size() * sizeof(float); +#endif // ENABLE_GCODE_VIEWER_STATISTICS + // vertex data -> send to gpu glsafe(::glGenBuffers(1, &m_vertices.vbo_id)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vertices.vbo_id)); @@ -383,6 +404,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) for (IBuffer& buffer : m_buffers) { buffer.data_size = buffer.data.size(); +#if ENABLE_GCODE_VIEWER_STATISTICS + m_statistics.indices_size += buffer.data_size * sizeof(unsigned int); +#endif // ENABLE_GCODE_VIEWER_STATISTICS + if (buffer.data_size > 0) { glsafe(::glGenBuffers(1, &buffer.ibo_id)); glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.ibo_id)); @@ -428,8 +453,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) std::sort(m_extruder_ids.begin(), m_extruder_ids.end()); m_extruder_ids.erase(std::unique(m_extruder_ids.begin(), m_extruder_ids.end()), m_extruder_ids.end()); - auto end_time = std::chrono::high_resolution_clock::now(); - std::cout << "toolpaths generation time: " << std::chrono::duration_cast(end_time - start_time).count() << "ms \n"; +#if ENABLE_GCODE_VIEWER_STATISTICS + m_statistics.load_time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); +#endif // ENABLE_GCODE_VIEWER_STATISTICS } void GCodeViewer::load_shells(const Print& print, bool initialized) @@ -558,6 +584,10 @@ void GCodeViewer::render_toolpaths() const glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + +#if ENABLE_GCODE_VIEWER_STATISTICS + ++m_statistics.gl_points_calls_count; +#endif // ENABLE_GCODE_VIEWER_STATISTICS } break; } @@ -572,6 +602,10 @@ void GCodeViewer::render_toolpaths() const glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + +#if ENABLE_GCODE_VIEWER_STATISTICS + ++m_statistics.gl_points_calls_count; +#endif // ENABLE_GCODE_VIEWER_STATISTICS } break; } @@ -586,6 +620,10 @@ void GCodeViewer::render_toolpaths() const glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + +#if ENABLE_GCODE_VIEWER_STATISTICS + ++m_statistics.gl_points_calls_count; +#endif // ENABLE_GCODE_VIEWER_STATISTICS } break; } @@ -600,6 +638,10 @@ void GCodeViewer::render_toolpaths() const glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + +#if ENABLE_GCODE_VIEWER_STATISTICS + ++m_statistics.gl_points_calls_count; +#endif // ENABLE_GCODE_VIEWER_STATISTICS } break; } @@ -614,6 +656,10 @@ void GCodeViewer::render_toolpaths() const glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + +#if ENABLE_GCODE_VIEWER_STATISTICS + ++m_statistics.gl_points_calls_count; +#endif // ENABLE_GCODE_VIEWER_STATISTICS } break; } @@ -628,6 +674,10 @@ void GCodeViewer::render_toolpaths() const glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + +#if ENABLE_GCODE_VIEWER_STATISTICS + ++m_statistics.gl_points_calls_count; +#endif // ENABLE_GCODE_VIEWER_STATISTICS } break; } @@ -639,6 +689,10 @@ void GCodeViewer::render_toolpaths() const set_color(current_program_id, extrusion_color(path)); glsafe(::glDrawElements(GL_LINE_STRIP, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); + +#if ENABLE_GCODE_VIEWER_STATISTICS + ++m_statistics.gl_line_strip_calls_count; +#endif // ENABLE_GCODE_VIEWER_STATISTICS } break; } @@ -650,6 +704,10 @@ void GCodeViewer::render_toolpaths() const set_color(current_program_id, (m_view_type == EViewType::Feedrate || m_view_type == EViewType::Tool || m_view_type == EViewType::ColorPrint) ? extrusion_color(path) : travel_color(path)); glsafe(::glDrawElements(GL_LINE_STRIP, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); + +#if ENABLE_GCODE_VIEWER_STATISTICS + ++m_statistics.gl_line_strip_calls_count; +#endif // ENABLE_GCODE_VIEWER_STATISTICS } break; } @@ -678,7 +736,7 @@ void GCodeViewer::render_shells() const // glsafe(::glDepthMask(GL_TRUE)); } -void GCodeViewer::render_overlay() const +void GCodeViewer::render_legend() const { static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); static const ImU32 ICON_BORDER_COLOR = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); @@ -692,10 +750,6 @@ void GCodeViewer::render_overlay() const ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); imgui.begin(std::string("Legend"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); - if (ImGui::IsWindowAppearing()) - // force an extra farme - wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); - ImDrawList* draw_list = ImGui::GetWindowDrawList(); auto add_item = [draw_list, &imgui](const std::array& color, const std::string& label) { @@ -893,6 +947,64 @@ void GCodeViewer::render_overlay() const ImGui::PopStyleVar(); } +#if ENABLE_GCODE_VIEWER_STATISTICS +void GCodeViewer::render_statistics() const +{ + static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); + static const float offset = 250.0f; + + if (!m_legend_enabled || m_roles.empty()) + return; + + ImGuiWrapper& imgui = *wxGetApp().imgui(); + + imgui.begin(std::string("Statistics"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); + ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindow()); + + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + imgui.text(std::string("Load time:")); + ImGui::PopStyleColor(); + ImGui::SameLine(offset); + imgui.text(std::to_string(m_statistics.load_time) + "ms"); + + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + imgui.text(std::string("Resfresh time:")); + ImGui::PopStyleColor(); + ImGui::SameLine(offset); + imgui.text(std::to_string(m_statistics.refresh_time) + "ms"); + + ImGui::Separator(); + + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + imgui.text(std::string("GL_POINTS calls:")); + ImGui::PopStyleColor(); + ImGui::SameLine(offset); + imgui.text(std::to_string(m_statistics.gl_points_calls_count)); + + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + imgui.text(std::string("GL_LINE_STRIP calls:")); + ImGui::PopStyleColor(); + ImGui::SameLine(offset); + imgui.text(std::to_string(m_statistics.gl_line_strip_calls_count)); + + ImGui::Separator(); + + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + imgui.text(std::string("Vertices:")); + ImGui::PopStyleColor(); + ImGui::SameLine(offset); + imgui.text(std::to_string(m_statistics.vertices_size) + " bytes"); + + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + imgui.text(std::string("Indices:")); + ImGui::PopStyleColor(); + ImGui::SameLine(offset); + imgui.text(std::to_string(m_statistics.indices_size) + " bytes"); + + imgui.end(); +} +#endif // ENABLE_GCODE_VIEWER_STATISTICS + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index d2eb103f65..be239e20ce 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -2,7 +2,6 @@ #define slic3r_GCodeViewer_hpp_ #if ENABLE_GCODE_VIEWER - #include "GLShader.hpp" #include "3DScene.hpp" #include "libslic3r/GCode/GCodeProcessor.hpp" @@ -133,6 +132,39 @@ class GCodeViewer void reset_ranges() { ranges.reset(); } }; +#if ENABLE_GCODE_VIEWER_STATISTICS + struct Statistics + { + long long load_time{ 0 }; + long long refresh_time{ 0 }; + long long gl_points_calls_count{ 0 }; + long long gl_line_strip_calls_count{ 0 }; + long long vertices_size{ 0 }; + long long indices_size{ 0 }; + + void reset_all() { + reset_times(); + reset_opengl(); + reset_sizes(); + } + + void reset_times() { + load_time = 0; + refresh_time = 0; + } + + void reset_opengl() { + gl_points_calls_count = 0; + gl_line_strip_calls_count = 0; + } + + void reset_sizes() { + vertices_size = 0; + indices_size = 0; + } + }; +#endif // ENABLE_GCODE_VIEWER_STATISTICS + public: enum class EViewType : unsigned char { @@ -161,6 +193,9 @@ private: Shells m_shells; EViewType m_view_type{ EViewType::FeatureType }; bool m_legend_enabled{ true }; +#if ENABLE_GCODE_VIEWER_STATISTICS + mutable Statistics m_statistics; +#endif // ENABLE_GCODE_VIEWER_STATISTICS public: GCodeViewer() = default; @@ -205,7 +240,10 @@ private: void load_shells(const Print& print, bool initialized); void render_toolpaths() const; void render_shells() const; - void render_overlay() const; + void render_legend() const; +#if ENABLE_GCODE_VIEWER_STATISTICS + void render_statistics() const; +#endif // ENABLE_GCODE_VIEWER_STATISTICS bool is_visible(ExtrusionRole role) const { return role < erCount && (m_extrusions.role_visibility_flags & (1 << role)) != 0; } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index fa38aca470..91b8e37929 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4050,9 +4050,13 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) if (m_selection.is_empty()) m_gizmos.reset_all_states(); +#if ENABLE_GCODE_VIEWER + m_dirty = true; +#else // Only refresh if picking is enabled, in that case the objects may get highlighted if the mouse cursor hovers over. if (m_picking_enabled) m_dirty = true; +#endif // ENABLE_GCODE_VIEWER } else evt.Skip(); From 2a4d011817912c4420a9c8458df9eb8451e12e2b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 28 Apr 2020 08:50:52 +0200 Subject: [PATCH 046/255] GCodeViewer -> Toggle extrusion role visibility by clicking on legend --- src/libslic3r/Technologies.hpp | 2 +- src/slic3r/GUI/GCodeViewer.cpp | 41 ++++++++++++++++++++--- src/slic3r/GUI/GCodeViewer.hpp | 4 ++- src/slic3r/GUI/GLCanvas3D.hpp | 3 ++ src/slic3r/GUI/GUI.cpp | 36 ++++++++++++++------- src/slic3r/GUI/GUI.hpp | 8 +++-- src/slic3r/GUI/GUI_Preview.cpp | 59 +++++++++++++++++++++++++++------- src/slic3r/GUI/GUI_Preview.hpp | 9 ++++++ src/slic3r/GUI/Plater.cpp | 17 ++++++++++ src/slic3r/GUI/Plater.hpp | 4 +++ 10 files changed, 152 insertions(+), 31 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index d04bc97fa4..255afc631e 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -59,7 +59,7 @@ // Enable G-Code viewer #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) #define ENABLE_GCODE_VIEWER_DEBUG_OUTPUT (0 && ENABLE_GCODE_VIEWER) -#define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_2_3_0_ALPHA1) +#define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 7426eafc9e..71053819dc 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -271,10 +271,29 @@ void GCodeViewer::set_toolpath_move_type_visible(GCodeProcessor::EMoveType type, m_buffers[id].visible = visible; } +unsigned int GCodeViewer::get_options_visibility_flags() const +{ + auto set_flag = [](unsigned int flags, unsigned int flag, bool active) { + return active ? (flags | (1 << flag)) : flags; + }; + + unsigned int flags = 0; + flags = set_flag(flags, 0, is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Travel)); + flags = set_flag(flags, 1, is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Retract)); + flags = set_flag(flags, 2, is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Unretract)); + flags = set_flag(flags, 3, is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Tool_change)); + flags = set_flag(flags, 4, is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Color_change)); + flags = set_flag(flags, 5, is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Pause_Print)); + flags = set_flag(flags, 6, is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Custom_GCode)); + flags = set_flag(flags, 7, m_shells.visible); + flags = set_flag(flags, 8, is_legend_enabled()); + return flags; +} + void GCodeViewer::set_options_visibility_from_flags(unsigned int flags) { auto is_flag_set = [flags](unsigned int flag) { - return (flags& (1 << flag)) != 0; + return (flags & (1 << flag)) != 0; }; set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Travel, is_flag_set(0)); @@ -752,7 +771,7 @@ void GCodeViewer::render_legend() const ImDrawList* draw_list = ImGui::GetWindowDrawList(); - auto add_item = [draw_list, &imgui](const std::array& color, const std::string& label) { + auto add_item = [draw_list, &imgui](const std::array& color, const std::string& label, std::function callback = nullptr) { float icon_size = ImGui::GetTextLineHeight(); ImVec2 pos = ImGui::GetCursorPos(); draw_list->AddRect({ pos.x, pos.y }, { pos.x + icon_size, pos.y + icon_size }, ICON_BORDER_COLOR, 0.0f, 0); @@ -762,7 +781,13 @@ void GCodeViewer::render_legend() const // draw text ImGui::Dummy({ icon_size, icon_size }); ImGui::SameLine(); - imgui.text(label); + if (callback != nullptr) + { + if (ImGui::MenuItem(label.c_str())) + callback(); + } + else + imgui.text(label); }; auto add_range = [this, draw_list, &imgui, add_item](const Extrusions::Range& range, unsigned int decimals) { @@ -811,7 +836,15 @@ void GCodeViewer::render_legend() const if (!visible) ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.3333f); - add_item(Extrusion_Role_Colors[static_cast(role)], I18N::translate_utf8(ExtrusionEntity::role_to_string(role))); + add_item(Extrusion_Role_Colors[static_cast(role)], I18N::translate_utf8(ExtrusionEntity::role_to_string(role)), [this, role]() { + if (role < erCount) + { + m_extrusions.role_visibility_flags = is_visible(role) ? m_extrusions.role_visibility_flags & ~(1 << role) : m_extrusions.role_visibility_flags | (1 << role); + wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); + wxGetApp().plater()->update_preview_bottom_toolbar(); + } + }); + if (!visible) ImGui::PopStyleVar(); } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index be239e20ce..a8816f7a16 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -189,7 +189,7 @@ private: std::array m_layers_z_range; std::vector m_roles; std::vector m_extruder_ids; - Extrusions m_extrusions; + mutable Extrusions m_extrusions; Shells m_shells; EViewType m_view_type{ EViewType::FeatureType }; bool m_legend_enabled{ true }; @@ -227,7 +227,9 @@ public: bool is_toolpath_move_type_visible(GCodeProcessor::EMoveType type) const; void set_toolpath_move_type_visible(GCodeProcessor::EMoveType type, bool visible); + unsigned int get_toolpath_role_visibility_flags() const { return m_extrusions.role_visibility_flags; } void set_toolpath_role_visibility_flags(unsigned int flags) { m_extrusions.role_visibility_flags = flags; } + unsigned int get_options_visibility_flags() const; void set_options_visibility_from_flags(unsigned int flags); void set_layers_z_range(const std::array& layers_z_range) { m_layers_z_range = layers_z_range; } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 152658b13a..bbe53c5cd2 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -646,8 +646,11 @@ public: void ensure_on_bed(unsigned int object_idx); #if ENABLE_GCODE_VIEWER + GCodeViewer::EViewType get_gcode_view_type() const { return m_gcode_viewer.get_view_type(); } const std::vector& get_layers_zs() const; + unsigned int get_gcode_options_visibility_flags() const { return m_gcode_viewer.get_options_visibility_flags(); } void set_gcode_options_visibility_from_flags(unsigned int flags); + unsigned int get_toolpath_role_visibility_flags() const { return m_gcode_viewer.get_toolpath_role_visibility_flags(); } void set_toolpath_role_visibility_flags(unsigned int flags); void set_toolpath_view_type(GCodeViewer::EViewType type); void set_toolpaths_z_range(const std::array& range); diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp index a66396b277..ebdc51c6b4 100644 --- a/src/slic3r/GUI/GUI.cpp +++ b/src/slic3r/GUI/GUI.cpp @@ -301,21 +301,33 @@ void create_combochecklist(wxComboCtrl* comboCtrl, const std::string& text, cons } } -int combochecklist_get_flags(wxComboCtrl* comboCtrl) +unsigned int combochecklist_get_flags(wxComboCtrl* comboCtrl) { - int flags = 0; + unsigned int flags = 0; - wxCheckListBoxComboPopup* popup = wxDynamicCast(comboCtrl->GetPopupControl(), wxCheckListBoxComboPopup); - if (popup != nullptr) - { - for (unsigned int i = 0; i < popup->GetCount(); ++i) - { - if (popup->IsChecked(i)) - flags |= 1 << i; - } - } + wxCheckListBoxComboPopup* popup = wxDynamicCast(comboCtrl->GetPopupControl(), wxCheckListBoxComboPopup); + if (popup != nullptr) + { + for (unsigned int i = 0; i < popup->GetCount(); ++i) + { + if (popup->IsChecked(i)) + flags |= 1 << i; + } + } - return flags; + return flags; +} + +void combochecklist_set_flags(wxComboCtrl* comboCtrl, unsigned int flags) +{ + wxCheckListBoxComboPopup* popup = wxDynamicCast(comboCtrl->GetPopupControl(), wxCheckListBoxComboPopup); + if (popup != nullptr) + { + for (unsigned int i = 0; i < popup->GetCount(); ++i) + { + popup->Check(i, (flags & (1 << i)) != 0); + } + } } AppConfig* get_app_config() diff --git a/src/slic3r/GUI/GUI.hpp b/src/slic3r/GUI/GUI.hpp index 6690b21207..cf133971e3 100644 --- a/src/slic3r/GUI/GUI.hpp +++ b/src/slic3r/GUI/GUI.hpp @@ -54,8 +54,12 @@ void warning_catcher(wxWindow* parent, const wxString& message); void create_combochecklist(wxComboCtrl* comboCtrl, const std::string& text, const std::string& items); // Returns the current state of the items listed in the wxCheckListBoxComboPopup contained in the given wxComboCtrl, -// encoded inside an int. -int combochecklist_get_flags(wxComboCtrl* comboCtrl); +// encoded inside an unsigned int. +unsigned int combochecklist_get_flags(wxComboCtrl* comboCtrl); + +// Sets the current state of the items listed in the wxCheckListBoxComboPopup contained in the given wxComboCtrl, +// with the flags encoded in the given unsigned int. +void combochecklist_set_flags(wxComboCtrl* comboCtrl, unsigned int flags); // wxString conversions: diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 3e0d5cd5a4..e84d1a9d56 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -222,6 +222,9 @@ Preview::Preview( : m_canvas_widget(nullptr) , m_canvas(nullptr) , m_double_slider_sizer(nullptr) +#if ENABLE_GCODE_VIEWER + , m_bottom_toolbar_sizer(nullptr) +#endif // ENABLE_GCODE_VIEWER , m_label_view_type(nullptr) , m_choice_view_type(nullptr) , m_label_show(nullptr) @@ -256,7 +259,9 @@ Preview::Preview( if (init(parent, bed, camera, view_toolbar, model)) #endif // ENABLE_NON_STATIC_CANVAS_MANAGER { +#if !ENABLE_GCODE_VIEWER show_hide_ui_elements("none"); +#endif // !ENABLE_GCODE_VIEWER load_print(); } } @@ -358,15 +363,21 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view top_sizer->Add(m_canvas_widget, 1, wxALL | wxEXPAND, 0); top_sizer->Add(m_double_slider_sizer, 0, wxEXPAND, 0); +#if ENABLE_GCODE_VIEWER + m_bottom_toolbar_sizer = new wxBoxSizer(wxHORIZONTAL); + m_bottom_toolbar_sizer->Add(m_label_view_type, 0, wxALIGN_CENTER_VERTICAL, 5); + m_bottom_toolbar_sizer->Add(m_choice_view_type, 0, wxEXPAND | wxALL, 5); + m_bottom_toolbar_sizer->AddSpacer(10); + m_bottom_toolbar_sizer->Add(m_label_show, 0, wxALIGN_CENTER_VERTICAL, 5); + m_bottom_toolbar_sizer->Add(m_combochecklist_features, 0, wxEXPAND | wxALL, 5); + m_bottom_toolbar_sizer->Add(m_combochecklist_options, 0, wxEXPAND | wxALL, 5); +#else wxBoxSizer* bottom_sizer = new wxBoxSizer(wxHORIZONTAL); bottom_sizer->Add(m_label_view_type, 0, wxALIGN_CENTER_VERTICAL, 5); bottom_sizer->Add(m_choice_view_type, 0, wxEXPAND | wxALL, 5); bottom_sizer->AddSpacer(10); bottom_sizer->Add(m_label_show, 0, wxALIGN_CENTER_VERTICAL, 5); bottom_sizer->Add(m_combochecklist_features, 0, wxEXPAND | wxALL, 5); -#if ENABLE_GCODE_VIEWER - bottom_sizer->Add(m_combochecklist_options, 0, wxEXPAND | wxALL, 5); -#else bottom_sizer->AddSpacer(20); bottom_sizer->Add(m_checkbox_travel, 0, wxEXPAND | wxALL, 5); bottom_sizer->AddSpacer(10); @@ -381,8 +392,12 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); main_sizer->Add(top_sizer, 1, wxALL | wxEXPAND, 0); +#if ENABLE_GCODE_VIEWER + main_sizer->Add(m_bottom_toolbar_sizer, 0, wxALL | wxEXPAND, 0); + main_sizer->Hide(m_bottom_toolbar_sizer); +#else main_sizer->Add(bottom_sizer, 0, wxALL | wxEXPAND, 0); - +#endif // ENABLE_GCODE_VIEWER SetSizer(main_sizer); SetMinSize(GetSize()); GetSizer()->SetSizeHints(this); @@ -480,6 +495,9 @@ void Preview::load_print(bool keep_z_range) else if (tech == ptSLA) load_print_as_sla(); +#if ENABLE_GCODE_VIEWER + update_bottom_toolbar(); +#endif // ENABLE_GCODE_VIEWER Layout(); } @@ -581,6 +599,7 @@ void Preview::unbind_event_handlers() #endif // ENABLE_GCODE_VIEWER } +#if !ENABLE_GCODE_VIEWER void Preview::show_hide_ui_elements(const std::string& what) { bool enable = (what == "full"); @@ -615,6 +634,7 @@ void Preview::show_hide_ui_elements(const std::string& what) m_label_view_type->Show(visible); m_choice_view_type->Show(visible); } +#endif // !ENABLE_GCODE_VIEWER void Preview::reset_sliders(bool reset_all) { @@ -661,11 +681,11 @@ void Preview::on_choice_view_type(wxCommandEvent& evt) void Preview::on_combochecklist_features(wxCommandEvent& evt) { - int flags = Slic3r::GUI::combochecklist_get_flags(m_combochecklist_features); + unsigned int flags = Slic3r::GUI::combochecklist_get_flags(m_combochecklist_features); #if ENABLE_GCODE_VIEWER - m_canvas->set_toolpath_role_visibility_flags(static_cast(flags)); + m_canvas->set_toolpath_role_visibility_flags(flags); #else - m_gcode_preview_data->extrusion.role_flags = (unsigned int)flags; + m_gcode_preview_data->extrusion.role_flags = flags; #endif // ENABLE_GCODE_VIEWER refresh_print(); } @@ -673,7 +693,7 @@ void Preview::on_combochecklist_features(wxCommandEvent& evt) #if ENABLE_GCODE_VIEWER void Preview::on_combochecklist_options(wxCommandEvent& evt) { - m_canvas->set_gcode_options_visibility_from_flags(static_cast(Slic3r::GUI::combochecklist_get_flags(m_combochecklist_options))); + m_canvas->set_gcode_options_visibility_from_flags(Slic3r::GUI::combochecklist_get_flags(m_combochecklist_options)); refresh_print(); } #else @@ -730,6 +750,17 @@ void Preview::update_view_type(bool slice_completed) } } +#if ENABLE_GCODE_VIEWER +void Preview::update_bottom_toolbar() +{ + combochecklist_set_flags(m_combochecklist_features, m_canvas->get_toolpath_role_visibility_flags()); + combochecklist_set_flags(m_combochecklist_options, m_canvas->get_gcode_options_visibility_flags()); + + m_bottom_toolbar_sizer->Show(m_combochecklist_features, m_canvas->get_gcode_view_type() != GCodeViewer::EViewType::FeatureType); + m_bottom_toolbar_sizer->Layout(); +} +#endif // ENABLE_GCODE_VIEWER + void Preview::create_double_slider() { m_slider = new DoubleSlider::Control(this, wxID_ANY, 0, 0, 0, 100); @@ -1039,7 +1070,8 @@ void Preview::load_print_as_fff(bool keep_z_range) #if ENABLE_GCODE_VIEWER m_canvas->load_gcode_preview(*m_gcode_result); m_canvas->refresh_gcode_preview(*m_gcode_result, colors); - show_hide_ui_elements(gcode_preview_data_valid ? "full" : "simple"); + GetSizer()->Show(m_bottom_toolbar_sizer); + GetSizer()->Layout(); #else m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); #endif // ENABLE_GCODE_VIEWER @@ -1048,7 +1080,8 @@ void Preview::load_print_as_fff(bool keep_z_range) // Load the initial preview based on slices, not the final G-code. m_canvas->load_preview(colors, color_print_values); #if ENABLE_GCODE_VIEWER - show_hide_ui_elements("none"); + GetSizer()->Hide(m_bottom_toolbar_sizer); + GetSizer()->Layout(); #endif // ENABLE_GCODE_VIEWER } #if ENABLE_GCODE_VIEWER @@ -1097,7 +1130,12 @@ void Preview::load_print_as_sla() if (IsShown()) { m_canvas->load_sla_preview(); +#if ENABLE_GCODE_VIEWER + GetSizer()->Hide(m_bottom_toolbar_sizer); + GetSizer()->Layout(); +#else show_hide_ui_elements("none"); +#endif // ENABLE_GCODE_VIEWER if (n_layers > 0) update_sliders(zs); @@ -1132,6 +1170,5 @@ void Preview::on_sliders_scroll_changed(wxCommandEvent& event) } } - } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index c4ad4eb79c..a7db054bc3 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -91,6 +91,9 @@ class Preview : public wxPanel wxGLCanvas* m_canvas_widget; GLCanvas3D* m_canvas; wxBoxSizer* m_double_slider_sizer; +#if ENABLE_GCODE_VIEWER + wxBoxSizer* m_bottom_toolbar_sizer; +#endif // ENABLE_GCODE_VIEWER wxStaticText* m_label_view_type; wxChoice* m_choice_view_type; wxStaticText* m_label_show; @@ -172,6 +175,10 @@ public: bool is_loaded() const { return m_loaded; } +#if ENABLE_GCODE_VIEWER + void update_bottom_toolbar(); +#endif // ENABLE_GCODE_VIEWER + private: #if ENABLE_NON_STATIC_CANVAS_MANAGER bool init(wxWindow* parent, Model* model); @@ -182,7 +189,9 @@ private: void bind_event_handlers(); void unbind_event_handlers(); +#if !ENABLE_GCODE_VIEWER void show_hide_ui_elements(const std::string& what); +#endif // !ENABLE_GCODE_VIEWER void reset_sliders(bool reset_all); void update_sliders(const std::vector& layers_z, bool keep_z_range = false); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index b64f705dd0..861e0e55fe 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1570,6 +1570,9 @@ struct Plater::priv #endif // ENABLE_NON_STATIC_CANVAS_MANAGER bool init_view_toolbar(); +#if ENABLE_GCODE_VIEWER + void update_preview_bottom_toolbar(); +#endif // ENABLE_GCODE_VIEWER void reset_all_gizmos(); void update_ui_from_settings(); @@ -3765,6 +3768,13 @@ bool Plater::priv::init_view_toolbar() return true; } +#if ENABLE_GCODE_VIEWER +void Plater::priv::update_preview_bottom_toolbar() +{ + preview->update_bottom_toolbar(); +} +#endif // ENABLE_GCODE_VIEWER + bool Plater::priv::can_set_instance_to_object() const { const int obj_idx = get_selected_object_idx(); @@ -5313,6 +5323,13 @@ GLToolbar& Plater::get_view_toolbar() } #endif // ENABLE_NON_STATIC_CANVAS_MANAGER +#if ENABLE_GCODE_VIEWER +void Plater::update_preview_bottom_toolbar() +{ + p->update_preview_bottom_toolbar(); +} +#endif // ENABLE_GCODE_VIEWER + const Mouse3DController& Plater::get_mouse3d_controller() const { return p->mouse3d_controller; diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 2ac4f23c18..f4ca22578f 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -310,6 +310,10 @@ public: GLToolbar& get_view_toolbar(); #endif // ENABLE_NON_STATIC_CANVAS_MANAGER +#if ENABLE_GCODE_VIEWER + void update_preview_bottom_toolbar(); +#endif // ENABLE_GCODE_VIEWER + const Mouse3DController& get_mouse3d_controller() const; Mouse3DController& get_mouse3d_controller(); From a77461b467ba68d6650452d82979476cc4581f70 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 28 Apr 2020 09:09:24 +0200 Subject: [PATCH 047/255] GCodeViewer -> Fixed synchronization between legend and bottom toolbar --- src/slic3r/GUI/GLCanvas3D.cpp | 1 + src/slic3r/GUI/GLCanvas3D.hpp | 1 + src/slic3r/GUI/GUI_Preview.cpp | 5 +++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 91b8e37929..080ba2045b 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3216,6 +3216,7 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) { m_gcode_viewer.enable_legend(!m_gcode_viewer.is_legend_enabled()); m_dirty = true; + wxGetApp().plater()->update_preview_bottom_toolbar(); } break; } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index bbe53c5cd2..c640108fdf 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -646,6 +646,7 @@ public: void ensure_on_bed(unsigned int object_idx); #if ENABLE_GCODE_VIEWER + bool is_gcode_legend_enabled() const { return m_gcode_viewer.is_legend_enabled(); } GCodeViewer::EViewType get_gcode_view_type() const { return m_gcode_viewer.get_view_type(); } const std::vector& get_layers_zs() const; unsigned int get_gcode_options_visibility_flags() const { return m_gcode_viewer.get_options_visibility_flags(); } diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index e84d1a9d56..28fd45b6c2 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -369,8 +369,8 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view m_bottom_toolbar_sizer->Add(m_choice_view_type, 0, wxEXPAND | wxALL, 5); m_bottom_toolbar_sizer->AddSpacer(10); m_bottom_toolbar_sizer->Add(m_label_show, 0, wxALIGN_CENTER_VERTICAL, 5); - m_bottom_toolbar_sizer->Add(m_combochecklist_features, 0, wxEXPAND | wxALL, 5); m_bottom_toolbar_sizer->Add(m_combochecklist_options, 0, wxEXPAND | wxALL, 5); + m_bottom_toolbar_sizer->Add(m_combochecklist_features, 0, wxEXPAND | wxALL, 5); #else wxBoxSizer* bottom_sizer = new wxBoxSizer(wxHORIZONTAL); bottom_sizer->Add(m_label_view_type, 0, wxALIGN_CENTER_VERTICAL, 5); @@ -756,7 +756,8 @@ void Preview::update_bottom_toolbar() combochecklist_set_flags(m_combochecklist_features, m_canvas->get_toolpath_role_visibility_flags()); combochecklist_set_flags(m_combochecklist_options, m_canvas->get_gcode_options_visibility_flags()); - m_bottom_toolbar_sizer->Show(m_combochecklist_features, m_canvas->get_gcode_view_type() != GCodeViewer::EViewType::FeatureType); + m_bottom_toolbar_sizer->Show(m_combochecklist_features, + !m_canvas->is_gcode_legend_enabled() || m_canvas->get_gcode_view_type() != GCodeViewer::EViewType::FeatureType); m_bottom_toolbar_sizer->Layout(); } #endif // ENABLE_GCODE_VIEWER From 1cb0f044db9ec1430074e4de59a32ed299c28912 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 28 Apr 2020 10:29:25 +0200 Subject: [PATCH 048/255] GCodeProcessor::MoveVertex -> added placeholder for time --- src/libslic3r/GCode/GCodeProcessor.cpp | 1 + src/libslic3r/GCode/GCodeProcessor.hpp | 1 + src/slic3r/GUI/GCodeViewer.cpp | 7 +++++++ src/slic3r/GUI/GCodeViewer.hpp | 2 ++ 4 files changed, 11 insertions(+) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 9dc3964436..9fda79a136 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -591,6 +591,7 @@ void GCodeProcessor::store_move_vertex(EMoveType type) vertex.fan_speed = m_fan_speed; vertex.extruder_id = m_extruder_id; vertex.cp_color_id = m_cp_color.current; + vertex.time = static_cast(m_result.moves.size()); m_result.moves.emplace_back(vertex); } diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 2212148367..4f6cf7430f 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -82,6 +82,7 @@ namespace Slic3r { float height{ 0.0f }; // mm float mm3_per_mm{ 0.0f }; float fan_speed{ 0.0f }; // percentage + float time{ 0.0f }; // s float volumetric_rate() const { return feedrate * mm3_per_mm; } diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 71053819dc..d60b5e9b89 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -346,6 +346,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) { #if ENABLE_GCODE_VIEWER_STATISTICS auto start_time = std::chrono::high_resolution_clock::now(); + m_statistics.results_size = gcode_result.moves.size() * sizeof(GCodeProcessor::MoveVertex); #endif // ENABLE_GCODE_VIEWER_STATISTICS // vertex data @@ -1022,6 +1023,12 @@ void GCodeViewer::render_statistics() const ImGui::Separator(); + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + imgui.text(std::string("Results:")); + ImGui::PopStyleColor(); + ImGui::SameLine(offset); + imgui.text(std::to_string(m_statistics.results_size) + " bytes"); + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); imgui.text(std::string("Vertices:")); ImGui::PopStyleColor(); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index a8816f7a16..be1c7e9986 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -139,6 +139,7 @@ class GCodeViewer long long refresh_time{ 0 }; long long gl_points_calls_count{ 0 }; long long gl_line_strip_calls_count{ 0 }; + long long results_size{ 0 }; long long vertices_size{ 0 }; long long indices_size{ 0 }; @@ -159,6 +160,7 @@ class GCodeViewer } void reset_sizes() { + results_size = 0; vertices_size = 0; indices_size = 0; } From d265c84b76241dae01ade0658cc645bddbc29893 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 28 Apr 2020 12:24:03 +0200 Subject: [PATCH 049/255] GCodeViewer -> Refactoring --- src/slic3r/GUI/GCodeViewer.cpp | 25 ++++++++++++------------- src/slic3r/GUI/GCodeViewer.hpp | 14 +++++++++----- src/slic3r/GUI/GUI_Preview.cpp | 14 +++----------- 3 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index d60b5e9b89..db16354ebe 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -92,9 +92,8 @@ bool GCodeViewer::IBuffer::init_shader(const std::string& vertex_shader_src, con void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move) { - unsigned int id = static_cast(data.size()); - double z = static_cast(move.position[2]); - paths.push_back({ move.type, move.extrusion_role, id, id, z, z, move.delta_extruder, move.height, move.width, move.feedrate, move.fan_speed, move.volumetric_rate(), move.extruder_id, move.cp_color_id }); + Path::Endpoint endpoint = { static_cast(data.size()), static_cast(move.position[2]) }; + paths.push_back({ move.type, move.extrusion_role, endpoint, endpoint, move.delta_extruder, move.height, move.width, move.feedrate, move.fan_speed, move.volumetric_rate(), move.extruder_id, move.cp_color_id }); } std::array GCodeViewer::Extrusions::Range::get_color_at(float value) const @@ -409,13 +408,13 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) buffer.data.push_back(static_cast(i - 1)); } - buffer.paths.back().last = static_cast(buffer.data.size()); + buffer.paths.back().last.id = static_cast(buffer.data.size()); buffer.data.push_back(static_cast(i)); break; } default: { - continue; + break; } } } @@ -602,7 +601,7 @@ void GCodeViewer::render_toolpaths() const continue; glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); + glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last.id - path.first.id + 1), GL_UNSIGNED_INT, (const void*)(path.first.id * sizeof(GLuint)))); glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); #if ENABLE_GCODE_VIEWER_STATISTICS @@ -620,7 +619,7 @@ void GCodeViewer::render_toolpaths() const continue; glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); + glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last.id - path.first.id + 1), GL_UNSIGNED_INT, (const void*)(path.first.id * sizeof(GLuint)))); glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); #if ENABLE_GCODE_VIEWER_STATISTICS @@ -638,7 +637,7 @@ void GCodeViewer::render_toolpaths() const continue; glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); + glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last.id - path.first.id + 1), GL_UNSIGNED_INT, (const void*)(path.first.id * sizeof(GLuint)))); glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); #if ENABLE_GCODE_VIEWER_STATISTICS @@ -656,7 +655,7 @@ void GCodeViewer::render_toolpaths() const continue; glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); + glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last.id - path.first.id + 1), GL_UNSIGNED_INT, (const void*)(path.first.id * sizeof(GLuint)))); glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); #if ENABLE_GCODE_VIEWER_STATISTICS @@ -674,7 +673,7 @@ void GCodeViewer::render_toolpaths() const continue; glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); + glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last.id - path.first.id + 1), GL_UNSIGNED_INT, (const void*)(path.first.id * sizeof(GLuint)))); glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); #if ENABLE_GCODE_VIEWER_STATISTICS @@ -692,7 +691,7 @@ void GCodeViewer::render_toolpaths() const continue; glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); + glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last.id - path.first.id + 1), GL_UNSIGNED_INT, (const void*)(path.first.id * sizeof(GLuint)))); glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); #if ENABLE_GCODE_VIEWER_STATISTICS @@ -708,7 +707,7 @@ void GCodeViewer::render_toolpaths() const continue; set_color(current_program_id, extrusion_color(path)); - glsafe(::glDrawElements(GL_LINE_STRIP, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); + glsafe(::glDrawElements(GL_LINE_STRIP, GLsizei(path.last.id - path.first.id + 1), GL_UNSIGNED_INT, (const void*)(path.first.id * sizeof(GLuint)))); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_line_strip_calls_count; @@ -723,7 +722,7 @@ void GCodeViewer::render_toolpaths() const continue; set_color(current_program_id, (m_view_type == EViewType::Feedrate || m_view_type == EViewType::Tool || m_view_type == EViewType::ColorPrint) ? extrusion_color(path) : travel_color(path)); - glsafe(::glDrawElements(GL_LINE_STRIP, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); + glsafe(::glDrawElements(GL_LINE_STRIP, GLsizei(path.last.id - path.first.id + 1), GL_UNSIGNED_INT, (const void*)(path.first.id * sizeof(GLuint)))); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_line_strip_calls_count; diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index be1c7e9986..9688c5c4b8 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -35,12 +35,16 @@ class GCodeViewer // Used to identify different toolpath sub-types inside a IBuffer struct Path { + struct Endpoint + { + unsigned int id{ 0u }; + double z{ 0.0 }; + }; + GCodeProcessor::EMoveType type{ GCodeProcessor::EMoveType::Noop }; ExtrusionRole role{ erNone }; - unsigned int first{ 0 }; - unsigned int last{ 0 }; - double first_z{ 0.0f }; - double last_z{ 0.0f }; + Endpoint first; + Endpoint last; float delta_extruder{ 0.0f }; float height{ 0.0f }; float width{ 0.0f }; @@ -257,7 +261,7 @@ private: return z > m_layers_z_range[0] - EPSILON && z < m_layers_z_range[1] + EPSILON; }; - return in_z_range(path.first_z) || in_z_range(path.last_z); + return in_z_range(path.first.z) || in_z_range(path.last.z); } }; diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 28fd45b6c2..72f40bb6b7 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -314,7 +314,7 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view m_label_show = new wxStaticText(this, wxID_ANY, _(L("Show"))); m_combochecklist_features = new wxComboCtrl(); - m_combochecklist_features->Create(this, wxID_ANY, _(L("Feature types")), wxDefaultPosition, wxSize(15 * wxGetApp().em_unit(), -1), wxCB_READONLY); + m_combochecklist_features->Create(this, wxID_ANY, _(L("Feature types")), wxDefaultPosition, wxDefaultSize, wxCB_READONLY); std::string feature_items = GUI::into_u8( #if ENABLE_GCODE_VIEWER _L("Unknown") + "|1|" + @@ -337,7 +337,7 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view #if ENABLE_GCODE_VIEWER m_combochecklist_options = new wxComboCtrl(); - m_combochecklist_options->Create(this, wxID_ANY, _(L("Others")), wxDefaultPosition, wxSize(15 * wxGetApp().em_unit(), -1), wxCB_READONLY); + m_combochecklist_options->Create(this, wxID_ANY, _(L("Options")), wxDefaultPosition, wxDefaultSize, wxCB_READONLY); std::string options_items = GUI::into_u8( _(L("Travel")) + "|0|" + _(L("Retractions")) + "|0|" + @@ -349,7 +349,7 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view _(L("Shells")) + "|0|" + _(L("Legend")) + "|1" ); - Slic3r::GUI::create_combochecklist(m_combochecklist_options, GUI::into_u8(_(L("Others"))), options_items); + Slic3r::GUI::create_combochecklist(m_combochecklist_options, GUI::into_u8(_(L("Options"))), options_items); #else m_checkbox_travel = new wxCheckBox(this, wxID_ANY, _(L("Travel"))); m_checkbox_retractions = new wxCheckBox(this, wxID_ANY, _(L("Retractions"))); @@ -605,15 +605,11 @@ void Preview::show_hide_ui_elements(const std::string& what) bool enable = (what == "full"); m_label_show->Enable(enable); m_combochecklist_features->Enable(enable); -#if ENABLE_GCODE_VIEWER - m_combochecklist_options->Enable(enable); -#else m_checkbox_travel->Enable(enable); m_checkbox_retractions->Enable(enable); m_checkbox_unretractions->Enable(enable); m_checkbox_shells->Enable(enable); m_checkbox_legend->Enable(enable); -#endif // ENABLE_GCODE_VIEWER enable = (what != "none"); m_label_view_type->Enable(enable); @@ -622,15 +618,11 @@ void Preview::show_hide_ui_elements(const std::string& what) bool visible = (what != "none"); m_label_show->Show(visible); m_combochecklist_features->Show(visible); -#if ENABLE_GCODE_VIEWER - m_combochecklist_options->Show(visible); -#else m_checkbox_travel->Show(visible); m_checkbox_retractions->Show(visible); m_checkbox_unretractions->Show(visible); m_checkbox_shells->Show(visible); m_checkbox_legend->Show(visible); -#endif // ENABLE_GCODE_VIEWER m_label_view_type->Show(visible); m_choice_view_type->Show(visible); } From 3267d3368f0d80921df5d045ed096afb248f141d Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 28 Apr 2020 15:08:36 +0200 Subject: [PATCH 050/255] GCodeViewer -> Use glMultiDrawElements() in place of glDrawElements() to draw extrude and travel paths --- src/libslic3r/Technologies.hpp | 1 + src/slic3r/GUI/GCodeViewer.cpp | 135 +++++++++++++++++++++++++++++++-- src/slic3r/GUI/GCodeViewer.hpp | 28 +++++++ 3 files changed, 157 insertions(+), 7 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 255afc631e..3f821ddce0 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -59,6 +59,7 @@ // Enable G-Code viewer #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) #define ENABLE_GCODE_VIEWER_DEBUG_OUTPUT (0 && ENABLE_GCODE_VIEWER) +#define ENABLE_GCODE_VIEWER_GL_OPTIMIZATION (1 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index db16354ebe..64c027a7b2 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -214,6 +214,11 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: } } +#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION + // update buffers' render paths + refresh_render_paths(); +#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION + #if ENABLE_GCODE_VIEWER_STATISTICS m_statistics.refresh_time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -345,7 +350,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) { #if ENABLE_GCODE_VIEWER_STATISTICS auto start_time = std::chrono::high_resolution_clock::now(); - m_statistics.results_size = gcode_result.moves.size() * sizeof(GCodeProcessor::MoveVertex); + m_statistics.results_size = SLIC3R_STDVEC_MEMSIZE(gcode_result.moves, GCodeProcessor::MoveVertex); #endif // ENABLE_GCODE_VIEWER_STATISTICS // vertex data @@ -363,7 +368,8 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) } #if ENABLE_GCODE_VIEWER_STATISTICS - m_statistics.vertices_size = vertices_data.size() * sizeof(float); + m_statistics.vertices_size = SLIC3R_STDVEC_MEMSIZE(vertices_data, float); + m_statistics.vertices_gpu_size = vertices_data.size() * sizeof(float); #endif // ENABLE_GCODE_VIEWER_STATISTICS // vertex data -> send to gpu @@ -424,7 +430,8 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) { buffer.data_size = buffer.data.size(); #if ENABLE_GCODE_VIEWER_STATISTICS - m_statistics.indices_size += buffer.data_size * sizeof(unsigned int); + m_statistics.indices_size += SLIC3R_STDVEC_MEMSIZE(buffer.data, unsigned int); + m_statistics.indices_gpu_size += buffer.data_size * sizeof(unsigned int); #endif // ENABLE_GCODE_VIEWER_STATISTICS if (buffer.data_size > 0) { @@ -526,7 +533,8 @@ void GCodeViewer::load_shells(const Print& print, bool initialized) } } -void GCodeViewer::render_toolpaths() const +#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION +void GCodeViewer::refresh_render_paths() const { auto extrusion_color = [this](const Path& path) { std::array color; @@ -551,6 +559,65 @@ void GCodeViewer::render_toolpaths() const Travel_Colors[0] /* Move */); }; + + for (IBuffer& buffer : m_buffers) { + buffer.render_paths = std::vector(); + for (const Path& path : buffer.paths) + { + if (!is_in_z_range(path)) + continue; + + if (path.type == GCodeProcessor::EMoveType::Extrude && !is_visible(path)) + continue; + + std::array color = { 0.0f, 0.0f, 0.0f }; + switch (path.type) + { + case GCodeProcessor::EMoveType::Extrude: { color = extrusion_color(path); break; } + case GCodeProcessor::EMoveType::Travel: { color = (m_view_type == EViewType::Feedrate || m_view_type == EViewType::Tool || m_view_type == EViewType::ColorPrint) ? extrusion_color(path) : travel_color(path); break; } + } + + auto it = std::find_if(buffer.render_paths.begin(), buffer.render_paths.end(), [color](const RenderPath& path) { return path.color == color; }); + if (it == buffer.render_paths.end()) + { + it = buffer.render_paths.insert(buffer.render_paths.end(), RenderPath()); + it->color = color; + } + + it->sizes.push_back(path.last.id - path.first.id + 1); + it->offsets.push_back(static_cast(path.first.id * sizeof(unsigned int))); + } + } +} +#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION + +void GCodeViewer::render_toolpaths() const +{ +#if !ENABLE_GCODE_VIEWER_GL_OPTIMIZATION + auto extrusion_color = [this](const Path& path) { + std::array color; + switch (m_view_type) + { + case EViewType::FeatureType: { color = Extrusion_Role_Colors[static_cast(path.role)]; break; } + case EViewType::Height: { color = m_extrusions.ranges.height.get_color_at(path.height); break; } + case EViewType::Width: { color = m_extrusions.ranges.width.get_color_at(path.width); break; } + case EViewType::Feedrate: { color = m_extrusions.ranges.feedrate.get_color_at(path.feedrate); break; } + case EViewType::FanSpeed: { color = m_extrusions.ranges.fan_speed.get_color_at(path.fan_speed); break; } + case EViewType::VolumetricRate: { color = m_extrusions.ranges.volumetric_rate.get_color_at(path.volumetric_rate); break; } + case EViewType::Tool: { color = m_tool_colors[path.extruder_id]; break; } + case EViewType::ColorPrint: { color = m_tool_colors[path.cp_color_id]; break; } + default: { color = { 1.0f, 1.0f, 1.0f }; break; } + } + return color; + }; + + auto travel_color = [this](const Path& path) { + return (path.delta_extruder < 0.0f) ? Travel_Colors[2] /* Retract */ : + ((path.delta_extruder > 0.0f) ? Travel_Colors[1] /* Extrude */ : + Travel_Colors[0] /* Move */); + }; +#endif // !ENABLE_GCODE_VIEWER_GL_OPTIMIZATION + auto set_color = [](GLint current_program_id, const std::array& color) { if (current_program_id > 0) { GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1; @@ -702,6 +769,17 @@ void GCodeViewer::render_toolpaths() const } case GCodeProcessor::EMoveType::Extrude: { +#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION + for (const RenderPath& path : buffer.render_paths) + { + set_color(current_program_id, path.color); + glsafe(::glMultiDrawElements(GL_LINE_STRIP, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); +#if ENABLE_GCODE_VIEWER_STATISTICS + ++m_statistics.gl_multi_line_strip_calls_count; +#endif // ENABLE_GCODE_VIEWER_STATISTICS + + } +#else for (const Path& path : buffer.paths) { if (!is_visible(path) || !is_in_z_range(path)) continue; @@ -713,10 +791,22 @@ void GCodeViewer::render_toolpaths() const ++m_statistics.gl_line_strip_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } +#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION break; } case GCodeProcessor::EMoveType::Travel: { +#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION + for (const RenderPath& path : buffer.render_paths) + { + set_color(current_program_id, path.color); + glsafe(::glMultiDrawElements(GL_LINE_STRIP, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); +#if ENABLE_GCODE_VIEWER_STATISTICS + ++m_statistics.gl_multi_line_strip_calls_count; +#endif // ENABLE_GCODE_VIEWER_STATISTICS + + } +#else for (const Path& path : buffer.paths) { if (!is_in_z_range(path)) continue; @@ -728,6 +818,7 @@ void GCodeViewer::render_toolpaths() const ++m_statistics.gl_line_strip_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } +#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION break; } } @@ -840,6 +931,10 @@ void GCodeViewer::render_legend() const if (role < erCount) { m_extrusions.role_visibility_flags = is_visible(role) ? m_extrusions.role_visibility_flags & ~(1 << role) : m_extrusions.role_visibility_flags | (1 << role); +#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION + // update buffers' render paths + refresh_render_paths(); +#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); wxGetApp().plater()->update_preview_bottom_toolbar(); } @@ -986,7 +1081,7 @@ void GCodeViewer::render_statistics() const static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); static const float offset = 250.0f; - if (!m_legend_enabled || m_roles.empty()) + if (m_roles.empty()) return; ImGuiWrapper& imgui = *wxGetApp().imgui(); @@ -1020,6 +1115,20 @@ void GCodeViewer::render_statistics() const ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.gl_line_strip_calls_count)); +#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + imgui.text(std::string("Multi GL_POINTS calls:")); + ImGui::PopStyleColor(); + ImGui::SameLine(offset); + imgui.text(std::to_string(m_statistics.gl_multi_points_calls_count)); + + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + imgui.text(std::string("Multi GL_LINE_STRIP calls:")); + ImGui::PopStyleColor(); + ImGui::SameLine(offset); + imgui.text(std::to_string(m_statistics.gl_multi_line_strip_calls_count)); +#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION + ImGui::Separator(); ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); @@ -1029,17 +1138,29 @@ void GCodeViewer::render_statistics() const imgui.text(std::to_string(m_statistics.results_size) + " bytes"); ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); - imgui.text(std::string("Vertices:")); + imgui.text(std::string("Vertices CPU:")); ImGui::PopStyleColor(); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.vertices_size) + " bytes"); ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); - imgui.text(std::string("Indices:")); + imgui.text(std::string("Vertices GPU:")); + ImGui::PopStyleColor(); + ImGui::SameLine(offset); + imgui.text(std::to_string(m_statistics.vertices_gpu_size) + " bytes"); + + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + imgui.text(std::string("Indices CPU:")); ImGui::PopStyleColor(); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.indices_size) + " bytes"); + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + imgui.text(std::string("Indices GPU:")); + ImGui::PopStyleColor(); + ImGui::SameLine(offset); + imgui.text(std::to_string(m_statistics.indices_gpu_size) + " bytes"); + imgui.end(); } #endif // ENABLE_GCODE_VIEWER_STATISTICS diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 9688c5c4b8..ec3bfc9a63 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -61,6 +61,16 @@ class GCodeViewer } }; +#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION + // Used to batch the indices needed to render paths + struct RenderPath + { + std::array color; + std::vector sizes; + std::vector offsets; // use size_t because we need the pointer's size (used in the call glMultiDrawElements()) + }; +#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION + // buffer containing indices data and shader for a specific toolpath type struct IBuffer { @@ -69,6 +79,9 @@ class GCodeViewer std::vector data; size_t data_size{ 0 }; std::vector paths; +#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION + std::vector render_paths; +#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION bool visible{ false }; void reset(); @@ -143,9 +156,15 @@ class GCodeViewer long long refresh_time{ 0 }; long long gl_points_calls_count{ 0 }; long long gl_line_strip_calls_count{ 0 }; +#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION + long long gl_multi_points_calls_count{ 0 }; + long long gl_multi_line_strip_calls_count{ 0 }; +#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION long long results_size{ 0 }; long long vertices_size{ 0 }; + long long vertices_gpu_size{ 0 }; long long indices_size{ 0 }; + long long indices_gpu_size{ 0 }; void reset_all() { reset_times(); @@ -161,12 +180,18 @@ class GCodeViewer void reset_opengl() { gl_points_calls_count = 0; gl_line_strip_calls_count = 0; +#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION + gl_multi_points_calls_count = 0; + gl_multi_line_strip_calls_count = 0; +#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION } void reset_sizes() { results_size = 0; vertices_size = 0; + vertices_gpu_size = 0; indices_size = 0; + indices_gpu_size = 0; } }; #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -246,6 +271,9 @@ private: bool init_shaders(); void load_toolpaths(const GCodeProcessor::Result& gcode_result); void load_shells(const Print& print, bool initialized); +#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION + void refresh_render_paths() const; +#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION void render_toolpaths() const; void render_shells() const; void render_legend() const; From d8f6a9179f096f4c495da269c015be34cd5bcfbb Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 28 Apr 2020 15:49:01 +0200 Subject: [PATCH 051/255] GCodeViewer -> Use glMultiDrawElements() in place of glDrawElements() to draw all entities --- src/slic3r/GUI/GCodeViewer.cpp | 92 +++++++++++++++++++++++++++++++++- src/slic3r/GUI/GCodeViewer.hpp | 8 +++ 2 files changed, 99 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 64c027a7b2..4b2784df98 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -661,6 +661,20 @@ void GCodeViewer::render_toolpaths() const { case GCodeProcessor::EMoveType::Tool_change: { +#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION + std::array color = { 1.0f, 1.0f, 1.0f }; + set_color(current_program_id, color); + for (const RenderPath& path : buffer.render_paths) + { + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + +#if ENABLE_GCODE_VIEWER_STATISTICS + ++m_statistics.gl_multi_points_calls_count; +#endif // ENABLE_GCODE_VIEWER_STATISTICS + } +#else std::array color = { 1.0f, 1.0f, 1.0f }; set_color(current_program_id, color); for (const Path& path : buffer.paths) { @@ -675,10 +689,25 @@ void GCodeViewer::render_toolpaths() const ++m_statistics.gl_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } +#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION break; } case GCodeProcessor::EMoveType::Color_change: { +#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION + std::array color = { 1.0f, 0.0f, 0.0f }; + set_color(current_program_id, color); + for (const RenderPath& path : buffer.render_paths) + { + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + +#if ENABLE_GCODE_VIEWER_STATISTICS + ++m_statistics.gl_multi_points_calls_count; +#endif // ENABLE_GCODE_VIEWER_STATISTICS + } +#else std::array color = { 1.0f, 0.0f, 0.0f }; set_color(current_program_id, color); for (const Path& path : buffer.paths) { @@ -693,10 +722,25 @@ void GCodeViewer::render_toolpaths() const ++m_statistics.gl_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } +#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION break; } case GCodeProcessor::EMoveType::Pause_Print: { +#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION + std::array color = { 0.0f, 1.0f, 0.0f }; + set_color(current_program_id, color); + for (const RenderPath& path : buffer.render_paths) + { + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + +#if ENABLE_GCODE_VIEWER_STATISTICS + ++m_statistics.gl_multi_points_calls_count; +#endif // ENABLE_GCODE_VIEWER_STATISTICS + } +#else std::array color = { 0.0f, 1.0f, 0.0f }; set_color(current_program_id, color); for (const Path& path : buffer.paths) { @@ -711,10 +755,25 @@ void GCodeViewer::render_toolpaths() const ++m_statistics.gl_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } +#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION break; } case GCodeProcessor::EMoveType::Custom_GCode: { +#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION + std::array color = { 0.0f, 0.0f, 1.0f }; + set_color(current_program_id, color); + for (const RenderPath& path : buffer.render_paths) + { + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + +#if ENABLE_GCODE_VIEWER_STATISTICS + ++m_statistics.gl_multi_points_calls_count; +#endif // ENABLE_GCODE_VIEWER_STATISTICS + } +#else std::array color = { 0.0f, 0.0f, 1.0f }; set_color(current_program_id, color); for (const Path& path : buffer.paths) { @@ -729,10 +788,25 @@ void GCodeViewer::render_toolpaths() const ++m_statistics.gl_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } +#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION break; } case GCodeProcessor::EMoveType::Retract: { +#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION + std::array color = { 1.0f, 0.0f, 1.0f }; + set_color(current_program_id, color); + for (const RenderPath& path : buffer.render_paths) + { + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + +#if ENABLE_GCODE_VIEWER_STATISTICS + ++m_statistics.gl_multi_points_calls_count; +#endif // ENABLE_GCODE_VIEWER_STATISTICS + } +#else std::array color = { 1.0f, 0.0f, 1.0f }; set_color(current_program_id, color); for (const Path& path : buffer.paths) { @@ -747,10 +821,25 @@ void GCodeViewer::render_toolpaths() const ++m_statistics.gl_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } +#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION break; } case GCodeProcessor::EMoveType::Unretract: { +#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION + std::array color = { 0.0f, 1.0f, 1.0f }; + set_color(current_program_id, color); + for (const RenderPath& path : buffer.render_paths) + { + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + +#if ENABLE_GCODE_VIEWER_STATISTICS + ++m_statistics.gl_multi_points_calls_count; +#endif // ENABLE_GCODE_VIEWER_STATISTICS + } +#else std::array color = { 0.0f, 1.0f, 1.0f }; set_color(current_program_id, color); for (const Path& path : buffer.paths) { @@ -765,6 +854,7 @@ void GCodeViewer::render_toolpaths() const ++m_statistics.gl_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } +#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION break; } case GCodeProcessor::EMoveType::Extrude: @@ -1132,7 +1222,7 @@ void GCodeViewer::render_statistics() const ImGui::Separator(); ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); - imgui.text(std::string("Results:")); + imgui.text(std::string("GCodeProcessor results:")); ImGui::PopStyleColor(); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.results_size) + " bytes"); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index ec3bfc9a63..0f90be5d73 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -262,7 +262,15 @@ public: void set_toolpath_role_visibility_flags(unsigned int flags) { m_extrusions.role_visibility_flags = flags; } unsigned int get_options_visibility_flags() const; void set_options_visibility_from_flags(unsigned int flags); +#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION + void set_layers_z_range(const std::array& layers_z_range) + { + m_layers_z_range = layers_z_range; + refresh_render_paths(); + } +#else void set_layers_z_range(const std::array& layers_z_range) { m_layers_z_range = layers_z_range; } +#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION bool is_legend_enabled() const { return m_legend_enabled; } void enable_legend(bool enable) { m_legend_enabled = enable; } From c9bd0840b3d3ad20e531bd10815b4d8fe4f92814 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 29 Apr 2020 08:24:39 +0200 Subject: [PATCH 052/255] GCodeViewer -> Code cleanup --- src/libslic3r/Technologies.hpp | 1 - src/slic3r/GUI/GCodeViewer.cpp | 175 --------------------------------- src/slic3r/GUI/GCodeViewer.hpp | 18 ---- 3 files changed, 194 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 3f821ddce0..255afc631e 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -59,7 +59,6 @@ // Enable G-Code viewer #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) #define ENABLE_GCODE_VIEWER_DEBUG_OUTPUT (0 && ENABLE_GCODE_VIEWER) -#define ENABLE_GCODE_VIEWER_GL_OPTIMIZATION (1 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 4b2784df98..579ef50a54 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -214,10 +214,8 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: } } -#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION // update buffers' render paths refresh_render_paths(); -#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION #if ENABLE_GCODE_VIEWER_STATISTICS m_statistics.refresh_time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); @@ -533,7 +531,6 @@ void GCodeViewer::load_shells(const Print& print, bool initialized) } } -#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION void GCodeViewer::refresh_render_paths() const { auto extrusion_color = [this](const Path& path) { @@ -589,35 +586,9 @@ void GCodeViewer::refresh_render_paths() const } } } -#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION void GCodeViewer::render_toolpaths() const { -#if !ENABLE_GCODE_VIEWER_GL_OPTIMIZATION - auto extrusion_color = [this](const Path& path) { - std::array color; - switch (m_view_type) - { - case EViewType::FeatureType: { color = Extrusion_Role_Colors[static_cast(path.role)]; break; } - case EViewType::Height: { color = m_extrusions.ranges.height.get_color_at(path.height); break; } - case EViewType::Width: { color = m_extrusions.ranges.width.get_color_at(path.width); break; } - case EViewType::Feedrate: { color = m_extrusions.ranges.feedrate.get_color_at(path.feedrate); break; } - case EViewType::FanSpeed: { color = m_extrusions.ranges.fan_speed.get_color_at(path.fan_speed); break; } - case EViewType::VolumetricRate: { color = m_extrusions.ranges.volumetric_rate.get_color_at(path.volumetric_rate); break; } - case EViewType::Tool: { color = m_tool_colors[path.extruder_id]; break; } - case EViewType::ColorPrint: { color = m_tool_colors[path.cp_color_id]; break; } - default: { color = { 1.0f, 1.0f, 1.0f }; break; } - } - return color; - }; - - auto travel_color = [this](const Path& path) { - return (path.delta_extruder < 0.0f) ? Travel_Colors[2] /* Retract */ : - ((path.delta_extruder > 0.0f) ? Travel_Colors[1] /* Extrude */ : - Travel_Colors[0] /* Move */); - }; -#endif // !ENABLE_GCODE_VIEWER_GL_OPTIMIZATION - auto set_color = [](GLint current_program_id, const std::array& color) { if (current_program_id > 0) { GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1; @@ -661,7 +632,6 @@ void GCodeViewer::render_toolpaths() const { case GCodeProcessor::EMoveType::Tool_change: { -#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION std::array color = { 1.0f, 1.0f, 1.0f }; set_color(current_program_id, color); for (const RenderPath& path : buffer.render_paths) @@ -674,27 +644,10 @@ void GCodeViewer::render_toolpaths() const ++m_statistics.gl_multi_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } -#else - std::array color = { 1.0f, 1.0f, 1.0f }; - set_color(current_program_id, color); - for (const Path& path : buffer.paths) { - if (!is_in_z_range(path)) - continue; - - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last.id - path.first.id + 1), GL_UNSIGNED_INT, (const void*)(path.first.id * sizeof(GLuint)))); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); - -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_points_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - } -#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION break; } case GCodeProcessor::EMoveType::Color_change: { -#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION std::array color = { 1.0f, 0.0f, 0.0f }; set_color(current_program_id, color); for (const RenderPath& path : buffer.render_paths) @@ -707,27 +660,10 @@ void GCodeViewer::render_toolpaths() const ++m_statistics.gl_multi_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } -#else - std::array color = { 1.0f, 0.0f, 0.0f }; - set_color(current_program_id, color); - for (const Path& path : buffer.paths) { - if (!is_in_z_range(path)) - continue; - - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last.id - path.first.id + 1), GL_UNSIGNED_INT, (const void*)(path.first.id * sizeof(GLuint)))); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); - -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_points_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - } -#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION break; } case GCodeProcessor::EMoveType::Pause_Print: { -#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION std::array color = { 0.0f, 1.0f, 0.0f }; set_color(current_program_id, color); for (const RenderPath& path : buffer.render_paths) @@ -740,27 +676,10 @@ void GCodeViewer::render_toolpaths() const ++m_statistics.gl_multi_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } -#else - std::array color = { 0.0f, 1.0f, 0.0f }; - set_color(current_program_id, color); - for (const Path& path : buffer.paths) { - if (!is_in_z_range(path)) - continue; - - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last.id - path.first.id + 1), GL_UNSIGNED_INT, (const void*)(path.first.id * sizeof(GLuint)))); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); - -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_points_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - } -#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION break; } case GCodeProcessor::EMoveType::Custom_GCode: { -#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION std::array color = { 0.0f, 0.0f, 1.0f }; set_color(current_program_id, color); for (const RenderPath& path : buffer.render_paths) @@ -773,27 +692,10 @@ void GCodeViewer::render_toolpaths() const ++m_statistics.gl_multi_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } -#else - std::array color = { 0.0f, 0.0f, 1.0f }; - set_color(current_program_id, color); - for (const Path& path : buffer.paths) { - if (!is_in_z_range(path)) - continue; - - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last.id - path.first.id + 1), GL_UNSIGNED_INT, (const void*)(path.first.id * sizeof(GLuint)))); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); - -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_points_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - } -#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION break; } case GCodeProcessor::EMoveType::Retract: { -#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION std::array color = { 1.0f, 0.0f, 1.0f }; set_color(current_program_id, color); for (const RenderPath& path : buffer.render_paths) @@ -806,27 +708,10 @@ void GCodeViewer::render_toolpaths() const ++m_statistics.gl_multi_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } -#else - std::array color = { 1.0f, 0.0f, 1.0f }; - set_color(current_program_id, color); - for (const Path& path : buffer.paths) { - if (!is_in_z_range(path)) - continue; - - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last.id - path.first.id + 1), GL_UNSIGNED_INT, (const void*)(path.first.id * sizeof(GLuint)))); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); - -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_points_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - } -#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION break; } case GCodeProcessor::EMoveType::Unretract: { -#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION std::array color = { 0.0f, 1.0f, 1.0f }; set_color(current_program_id, color); for (const RenderPath& path : buffer.render_paths) @@ -839,27 +724,10 @@ void GCodeViewer::render_toolpaths() const ++m_statistics.gl_multi_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } -#else - std::array color = { 0.0f, 1.0f, 1.0f }; - set_color(current_program_id, color); - for (const Path& path : buffer.paths) { - if (!is_in_z_range(path)) - continue; - - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last.id - path.first.id + 1), GL_UNSIGNED_INT, (const void*)(path.first.id * sizeof(GLuint)))); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); - -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_points_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - } -#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION break; } case GCodeProcessor::EMoveType::Extrude: { -#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION for (const RenderPath& path : buffer.render_paths) { set_color(current_program_id, path.color); @@ -869,24 +737,10 @@ void GCodeViewer::render_toolpaths() const #endif // ENABLE_GCODE_VIEWER_STATISTICS } -#else - for (const Path& path : buffer.paths) { - if (!is_visible(path) || !is_in_z_range(path)) - continue; - - set_color(current_program_id, extrusion_color(path)); - glsafe(::glDrawElements(GL_LINE_STRIP, GLsizei(path.last.id - path.first.id + 1), GL_UNSIGNED_INT, (const void*)(path.first.id * sizeof(GLuint)))); - -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_line_strip_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - } -#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION break; } case GCodeProcessor::EMoveType::Travel: { -#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION for (const RenderPath& path : buffer.render_paths) { set_color(current_program_id, path.color); @@ -896,19 +750,6 @@ void GCodeViewer::render_toolpaths() const #endif // ENABLE_GCODE_VIEWER_STATISTICS } -#else - for (const Path& path : buffer.paths) { - if (!is_in_z_range(path)) - continue; - - set_color(current_program_id, (m_view_type == EViewType::Feedrate || m_view_type == EViewType::Tool || m_view_type == EViewType::ColorPrint) ? extrusion_color(path) : travel_color(path)); - glsafe(::glDrawElements(GL_LINE_STRIP, GLsizei(path.last.id - path.first.id + 1), GL_UNSIGNED_INT, (const void*)(path.first.id * sizeof(GLuint)))); - -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_line_strip_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - } -#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION break; } } @@ -1021,10 +862,8 @@ void GCodeViewer::render_legend() const if (role < erCount) { m_extrusions.role_visibility_flags = is_visible(role) ? m_extrusions.role_visibility_flags & ~(1 << role) : m_extrusions.role_visibility_flags | (1 << role); -#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION // update buffers' render paths refresh_render_paths(); -#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); wxGetApp().plater()->update_preview_bottom_toolbar(); } @@ -1193,19 +1032,6 @@ void GCodeViewer::render_statistics() const ImGui::Separator(); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); - imgui.text(std::string("GL_POINTS calls:")); - ImGui::PopStyleColor(); - ImGui::SameLine(offset); - imgui.text(std::to_string(m_statistics.gl_points_calls_count)); - - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); - imgui.text(std::string("GL_LINE_STRIP calls:")); - ImGui::PopStyleColor(); - ImGui::SameLine(offset); - imgui.text(std::to_string(m_statistics.gl_line_strip_calls_count)); - -#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); imgui.text(std::string("Multi GL_POINTS calls:")); ImGui::PopStyleColor(); @@ -1217,7 +1043,6 @@ void GCodeViewer::render_statistics() const ImGui::PopStyleColor(); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.gl_multi_line_strip_calls_count)); -#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION ImGui::Separator(); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 0f90be5d73..9af7e7cc48 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -61,7 +61,6 @@ class GCodeViewer } }; -#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION // Used to batch the indices needed to render paths struct RenderPath { @@ -69,7 +68,6 @@ class GCodeViewer std::vector sizes; std::vector offsets; // use size_t because we need the pointer's size (used in the call glMultiDrawElements()) }; -#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION // buffer containing indices data and shader for a specific toolpath type struct IBuffer @@ -79,9 +77,7 @@ class GCodeViewer std::vector data; size_t data_size{ 0 }; std::vector paths; -#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION std::vector render_paths; -#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION bool visible{ false }; void reset(); @@ -154,12 +150,8 @@ class GCodeViewer { long long load_time{ 0 }; long long refresh_time{ 0 }; - long long gl_points_calls_count{ 0 }; - long long gl_line_strip_calls_count{ 0 }; -#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION long long gl_multi_points_calls_count{ 0 }; long long gl_multi_line_strip_calls_count{ 0 }; -#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION long long results_size{ 0 }; long long vertices_size{ 0 }; long long vertices_gpu_size{ 0 }; @@ -178,12 +170,8 @@ class GCodeViewer } void reset_opengl() { - gl_points_calls_count = 0; - gl_line_strip_calls_count = 0; -#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION gl_multi_points_calls_count = 0; gl_multi_line_strip_calls_count = 0; -#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION } void reset_sizes() { @@ -262,15 +250,11 @@ public: void set_toolpath_role_visibility_flags(unsigned int flags) { m_extrusions.role_visibility_flags = flags; } unsigned int get_options_visibility_flags() const; void set_options_visibility_from_flags(unsigned int flags); -#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION void set_layers_z_range(const std::array& layers_z_range) { m_layers_z_range = layers_z_range; refresh_render_paths(); } -#else - void set_layers_z_range(const std::array& layers_z_range) { m_layers_z_range = layers_z_range; } -#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION bool is_legend_enabled() const { return m_legend_enabled; } void enable_legend(bool enable) { m_legend_enabled = enable; } @@ -279,9 +263,7 @@ private: bool init_shaders(); void load_toolpaths(const GCodeProcessor::Result& gcode_result); void load_shells(const Print& print, bool initialized); -#if ENABLE_GCODE_VIEWER_GL_OPTIMIZATION void refresh_render_paths() const; -#endif // ENABLE_GCODE_VIEWER_GL_OPTIMIZATION void render_toolpaths() const; void render_shells() const; void render_legend() const; From cd5d70d5e14561375f29fccc821fcaa55381d37b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 29 Apr 2020 10:18:29 +0200 Subject: [PATCH 053/255] GCodeViewer -> Fixed z slider in initial preview --- src/slic3r/GUI/3DScene.cpp | 3 --- src/slic3r/GUI/3DScene.hpp | 4 ---- src/slic3r/GUI/GLCanvas3D.cpp | 12 +++++++----- src/slic3r/GUI/GLCanvas3D.hpp | 3 ++- src/slic3r/GUI/GUI_Preview.cpp | 12 ++++++++---- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 63cacdd457..cac0910e23 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -340,8 +340,6 @@ BoundingBoxf3 GLVolume::transformed_convex_hull_bounding_box(const Transform3d & bounding_box().transformed(trafo); } - -#if !ENABLE_GCODE_VIEWER void GLVolume::set_range(double min_z, double max_z) { this->qverts_range.first = 0; @@ -376,7 +374,6 @@ void GLVolume::set_range(double min_z, double max_z) } } } -#endif // !ENABLE_GCODE_VIEWER void GLVolume::render() const { diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 28295a35f7..70d6fb016a 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -442,9 +442,7 @@ public: bool empty() const { return this->indexed_vertex_array.empty(); } -#if !ENABLE_GCODE_VIEWER void set_range(double low, double high); -#endif // !ENABLE_GCODE_VIEWER void render() const; #if !ENABLE_SLOPE_RENDERING @@ -562,9 +560,7 @@ public: void clear() { for (auto *v : volumes) delete v; volumes.clear(); } bool empty() const { return volumes.empty(); } -#if !ENABLE_GCODE_VIEWER void set_range(double low, double high) { for (GLVolume *vol : this->volumes) vol->set_range(low, high); } -#endif // !ENABLE_GCODE_VIEWER void set_print_box(float min_x, float min_y, float min_z, float max_x, float max_y, float max_z) { m_print_box_min[0] = min_x; m_print_box_min[1] = min_y; m_print_box_min[2] = min_z; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index f8c0889fd6..6479947175 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -932,11 +932,7 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_items( const GLCanvas3D std::vector> cp_values; cp_values.reserve(custom_gcode_per_print_z.size()); -#if ENABLE_GCODE_VIEWER - const std::vector& print_zs = canvas.get_layers_zs(); -#else std::vector print_zs = canvas.get_current_print_zs(true); -#endif // ENABLE_GCODE_VIEWER for (auto custom_code : custom_gcode_per_print_z) { if (custom_code.gcode != ColorChangeCode) @@ -2327,11 +2323,16 @@ void GLCanvas3D::ensure_on_bed(unsigned int object_idx) #if ENABLE_GCODE_VIEWER -const std::vector& GLCanvas3D::get_layers_zs() const +const std::vector& GLCanvas3D::get_gcode_layers_zs() const { return m_gcode_viewer.get_layers_zs(); } +std::vector GLCanvas3D::get_volumes_print_zs(bool active_only) const +{ + return m_volumes.get_current_print_zs(active_only); +} + void GLCanvas3D::set_gcode_options_visibility_from_flags(unsigned int flags) { m_gcode_viewer.set_options_visibility_from_flags(flags); @@ -2350,6 +2351,7 @@ void GLCanvas3D::set_toolpath_view_type(GCodeViewer::EViewType type) void GLCanvas3D::set_toolpaths_z_range(const std::array& range) { m_gcode_viewer.set_layers_z_range(range); + m_volumes.set_range(range[0] - 1e-6, range[1] + 1e-6); } #else std::vector GLCanvas3D::get_current_print_zs(bool active_only) const diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index a5066d923d..f057ea7d6f 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -648,7 +648,8 @@ public: #if ENABLE_GCODE_VIEWER bool is_gcode_legend_enabled() const { return m_gcode_viewer.is_legend_enabled(); } GCodeViewer::EViewType get_gcode_view_type() const { return m_gcode_viewer.get_view_type(); } - const std::vector& get_layers_zs() const; + const std::vector& get_gcode_layers_zs() const; + std::vector get_volumes_print_zs(bool active_only) const; unsigned int get_gcode_options_visibility_flags() const { return m_gcode_viewer.get_options_visibility_flags(); } void set_gcode_options_visibility_from_flags(unsigned int flags); unsigned int get_toolpath_role_visibility_flags() const { return m_gcode_viewer.get_toolpath_role_visibility_flags(); } diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 72f40bb6b7..7771484f5f 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -1057,6 +1057,10 @@ void Preview::load_print_as_fff(bool keep_z_range) if (IsShown()) { +#if ENABLE_GCODE_VIEWER + std::vector zs; +#endif // ENABLE_GCODE_VIEWER + m_canvas->set_selected_extruder(0); if (gcode_preview_data_valid) { // Load the real G-code preview. @@ -1065,6 +1069,7 @@ void Preview::load_print_as_fff(bool keep_z_range) m_canvas->refresh_gcode_preview(*m_gcode_result, colors); GetSizer()->Show(m_bottom_toolbar_sizer); GetSizer()->Layout(); + zs = m_canvas->get_gcode_layers_zs(); #else m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); #endif // ENABLE_GCODE_VIEWER @@ -1075,14 +1080,13 @@ void Preview::load_print_as_fff(bool keep_z_range) #if ENABLE_GCODE_VIEWER GetSizer()->Hide(m_bottom_toolbar_sizer); GetSizer()->Layout(); + zs = m_canvas->get_volumes_print_zs(true); #endif // ENABLE_GCODE_VIEWER } -#if ENABLE_GCODE_VIEWER - const std::vector& zs = m_canvas->get_layers_zs(); -#else +#if !ENABLE_GCODE_VIEWER show_hide_ui_elements(gcode_preview_data_valid ? "full" : "simple"); std::vector zs = m_canvas->get_current_print_zs(true); -#endif // ENABLE_GCODE_VIEWER +#endif // !ENABLE_GCODE_VIEWER if (zs.empty()) { // all layers filtered out reset_sliders(true); From 9f2f798ea29b8efe00065c4621cd3eb41fe93652 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 29 Apr 2020 13:51:20 +0200 Subject: [PATCH 054/255] GCodeViewer -> Added ironing extrusion role --- src/slic3r/GUI/GCodeViewer.cpp | 1 + src/slic3r/GUI/GUI_Preview.cpp | 73 +++++++++++++++++----------------- 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 579ef50a54..df8e816460 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -127,6 +127,7 @@ const std::vector> GCodeViewer::Extrusion_Role_Colors {{ { 0.69f, 0.19f, 0.16f }, // erInternalInfill { 0.84f, 0.20f, 0.84f }, // erSolidInfill { 1.00f, 0.10f, 0.10f }, // erTopSolidInfill + { 0.00f, 1.00f, 1.00f }, // erIroning { 0.60f, 0.60f, 1.00f }, // erBridgeInfill { 1.00f, 1.00f, 1.00f }, // erGapFill { 0.52f, 0.48f, 0.13f }, // erSkirt diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 7771484f5f..ea7d2dc1bc 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -298,58 +298,59 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view m_double_slider_sizer = new wxBoxSizer(wxHORIZONTAL); create_double_slider(); - m_label_view_type = new wxStaticText(this, wxID_ANY, _(L("View"))); + m_label_view_type = new wxStaticText(this, wxID_ANY, _L("View")); m_choice_view_type = new wxChoice(this, wxID_ANY); - m_choice_view_type->Append(_(L("Feature type"))); - m_choice_view_type->Append(_(L("Height"))); - m_choice_view_type->Append(_(L("Width"))); - m_choice_view_type->Append(_(L("Speed"))); - m_choice_view_type->Append(_(L("Fan speed"))); - m_choice_view_type->Append(_(L("Volumetric flow rate"))); - m_choice_view_type->Append(_(L("Tool"))); - m_choice_view_type->Append(_(L("Color Print"))); + m_choice_view_type->Append(_L("Feature type")); + m_choice_view_type->Append(_L("Height")); + m_choice_view_type->Append(_L("Width")); + m_choice_view_type->Append(_L("Speed")); + m_choice_view_type->Append(_L("Fan speed")); + m_choice_view_type->Append(_L("Volumetric flow rate")); + m_choice_view_type->Append(_L("Tool")); + m_choice_view_type->Append(_L("Color Print")); m_choice_view_type->SetSelection(0); - m_label_show = new wxStaticText(this, wxID_ANY, _(L("Show"))); + m_label_show = new wxStaticText(this, wxID_ANY, _L("Show")); m_combochecklist_features = new wxComboCtrl(); - m_combochecklist_features->Create(this, wxID_ANY, _(L("Feature types")), wxDefaultPosition, wxDefaultSize, wxCB_READONLY); + m_combochecklist_features->Create(this, wxID_ANY, _L("Feature types"), wxDefaultPosition, wxDefaultSize, wxCB_READONLY); std::string feature_items = GUI::into_u8( #if ENABLE_GCODE_VIEWER _L("Unknown") + "|1|" + #endif // ENABLE_GCODE_VIEWER - _(L("Perimeter")) + "|1|" + - _(L("External perimeter")) + "|1|" + - _(L("Overhang perimeter")) + "|1|" + - _(L("Internal infill")) + "|1|" + - _(L("Solid infill")) + "|1|" + - _(L("Top solid infill")) + "|1|" + - _(L("Bridge infill")) + "|1|" + - _(L("Gap fill")) + "|1|" + - _(L("Skirt")) + "|1|" + - _(L("Support material")) + "|1|" + - _(L("Support material interface")) + "|1|" + - _(L("Wipe tower")) + "|1|" + - _(L("Custom")) + "|1" + _L("Perimeter") + "|1|" + + _L("External perimeter") + "|1|" + + _L("Overhang perimeter") + "|1|" + + _L("Internal infill") + "|1|" + + _L("Solid infill") + "|1|" + + _L("Top solid infill") + "|1|" + + _L("Ironing") + "|1|" + + _L("Bridge infill") + "|1|" + + _L("Gap fill") + "|1|" + + _L("Skirt") + "|1|" + + _L("Support material") + "|1|" + + _L("Support material interface") + "|1|" + + _L("Wipe tower") + "|1|" + + _L("Custom") + "|1" ); - Slic3r::GUI::create_combochecklist(m_combochecklist_features, GUI::into_u8(_(L("Feature types"))), feature_items); + Slic3r::GUI::create_combochecklist(m_combochecklist_features, GUI::into_u8(_L("Feature types")), feature_items); #if ENABLE_GCODE_VIEWER m_combochecklist_options = new wxComboCtrl(); - m_combochecklist_options->Create(this, wxID_ANY, _(L("Options")), wxDefaultPosition, wxDefaultSize, wxCB_READONLY); + m_combochecklist_options->Create(this, wxID_ANY, _L("Options"), wxDefaultPosition, wxDefaultSize, wxCB_READONLY); std::string options_items = GUI::into_u8( - _(L("Travel")) + "|0|" + - _(L("Retractions")) + "|0|" + - _(L("Unretractions")) + "|0|" + - _(L("Tool changes")) + "|0|" + - _(L("Color changes")) + "|0|" + - _(L("Pause prints")) + "|0|" + - _(L("Custom GCodes")) + "|0|" + - _(L("Shells")) + "|0|" + - _(L("Legend")) + "|1" + _L("Travel") + "|0|" + + _L("Retractions") + "|0|" + + _L("Unretractions") + "|0|" + + _L("Tool changes") + "|0|" + + _L("Color changes") + "|0|" + + _L("Pause prints") + "|0|" + + _L("Custom GCodes") + "|0|" + + _L("Shells") + "|0|" + + _L("Legend") + "|1" ); - Slic3r::GUI::create_combochecklist(m_combochecklist_options, GUI::into_u8(_(L("Options"))), options_items); + Slic3r::GUI::create_combochecklist(m_combochecklist_options, GUI::into_u8(_L("Options")), options_items); #else m_checkbox_travel = new wxCheckBox(this, wxID_ANY, _(L("Travel"))); m_checkbox_retractions = new wxCheckBox(this, wxID_ANY, _(L("Retractions"))); From c7806dd021ca523a5d0e8354450a2c0d8aee1d92 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 4 May 2020 09:37:06 +0200 Subject: [PATCH 055/255] GCodeViewer -> Fixed visualization of travel paths --- src/slic3r/GUI/GCodeViewer.cpp | 114 ++++++++++++++++++++++++++++----- src/slic3r/GUI/GCodeViewer.hpp | 13 ++-- src/slic3r/GUI/GUI_Preview.cpp | 2 + 3 files changed, 107 insertions(+), 22 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index df8e816460..0c631904aa 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -66,6 +66,30 @@ void GCodeViewer::VBuffer::reset() vertices_count = 0; } +bool GCodeViewer::Path::matches(const GCodeProcessor::MoveVertex& move) const +{ + switch (move.type) + { + case GCodeProcessor::EMoveType::Tool_change: + case GCodeProcessor::EMoveType::Color_change: + case GCodeProcessor::EMoveType::Pause_Print: + case GCodeProcessor::EMoveType::Custom_GCode: + case GCodeProcessor::EMoveType::Retract: + case GCodeProcessor::EMoveType::Unretract: + case GCodeProcessor::EMoveType::Extrude: + { + return type == move.type && role == move.extrusion_role && height == move.height && width == move.width && + feedrate == move.feedrate && fan_speed == move.fan_speed && volumetric_rate == move.volumetric_rate() && + extruder_id == move.extruder_id && cp_color_id == move.cp_color_id; + } + case GCodeProcessor::EMoveType::Travel: + { + return type == move.type && feedrate == move.feedrate && extruder_id == move.extruder_id && cp_color_id == move.cp_color_id; + } + default: { return false; } + } +} + void GCodeViewer::IBuffer::reset() { // release gpu memory @@ -92,7 +116,7 @@ bool GCodeViewer::IBuffer::init_shader(const std::string& vertex_shader_src, con void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move) { - Path::Endpoint endpoint = { static_cast(data.size()), static_cast(move.position[2]) }; + Path::Endpoint endpoint = { static_cast(data.size()), move.position }; paths.push_back({ move.type, move.extrusion_role, endpoint, endpoint, move.delta_extruder, move.height, move.width, move.feedrate, move.fan_speed, move.volumetric_rate(), move.extruder_id, move.cp_color_id }); } @@ -410,10 +434,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) { if (prev.type != curr.type || !buffer.paths.back().matches(curr)) { buffer.add_path(curr); + buffer.paths.back().first.position = prev.position; buffer.data.push_back(static_cast(i - 1)); } - buffer.paths.back().last.id = static_cast(buffer.data.size()); + buffer.paths.back().last = { static_cast(buffer.data.size()), curr.position }; buffer.data.push_back(static_cast(i)); break; } @@ -424,6 +449,13 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) } } +#if ENABLE_GCODE_VIEWER_STATISTICS + for (IBuffer& buffer : m_buffers) + { + m_statistics.paths_size += SLIC3R_STDVEC_MEMSIZE(buffer.paths, Path); + } +#endif // ENABLE_GCODE_VIEWER_STATISTICS + // indices data -> send data to gpu for (IBuffer& buffer : m_buffers) { @@ -445,12 +477,16 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) } // layers zs / roles / extruder ids / cp color ids -> extract from result - for (const GCodeProcessor::MoveVertex& move : gcode_result.moves) { + for (size_t i = 0; i < m_vertices.vertices_count; ++i) + { + const GCodeProcessor::MoveVertex& move = gcode_result.moves[i]; if (move.type == GCodeProcessor::EMoveType::Extrude) m_layers_zs.emplace_back(static_cast(move.position[2])); - m_roles.emplace_back(move.extrusion_role); m_extruder_ids.emplace_back(move.extruder_id); + + if (i > 0) + m_roles.emplace_back(move.extrusion_role); } // layers zs -> replace intervals of layers with similar top positions with their average value. @@ -560,9 +596,13 @@ void GCodeViewer::refresh_render_paths() const for (IBuffer& buffer : m_buffers) { buffer.render_paths = std::vector(); - for (const Path& path : buffer.paths) - { - if (!is_in_z_range(path)) + for (size_t i = 0; i < buffer.paths.size(); ++i) { + const Path& path = buffer.paths[i]; + if (path.type == GCodeProcessor::EMoveType::Travel) { + if (!is_travel_in_z_range(i)) + continue; + } + else if (!is_in_z_range(path)) continue; if (path.type == GCodeProcessor::EMoveType::Extrude && !is_visible(path)) @@ -576,8 +616,7 @@ void GCodeViewer::refresh_render_paths() const } auto it = std::find_if(buffer.render_paths.begin(), buffer.render_paths.end(), [color](const RenderPath& path) { return path.color == color; }); - if (it == buffer.render_paths.end()) - { + if (it == buffer.render_paths.end()) { it = buffer.render_paths.insert(buffer.render_paths.end(), RenderPath()); it->color = color; } @@ -1053,34 +1092,79 @@ void GCodeViewer::render_statistics() const ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.results_size) + " bytes"); + ImGui::Separator(); + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); imgui.text(std::string("Vertices CPU:")); ImGui::PopStyleColor(); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.vertices_size) + " bytes"); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); - imgui.text(std::string("Vertices GPU:")); - ImGui::PopStyleColor(); - ImGui::SameLine(offset); - imgui.text(std::to_string(m_statistics.vertices_gpu_size) + " bytes"); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); imgui.text(std::string("Indices CPU:")); ImGui::PopStyleColor(); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.indices_size) + " bytes"); + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + imgui.text(std::string("Paths CPU:")); + ImGui::PopStyleColor(); + ImGui::SameLine(offset); + imgui.text(std::to_string(m_statistics.paths_size) + " bytes"); + + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + imgui.text(std::string("TOTAL CPU:")); + ImGui::PopStyleColor(); + ImGui::SameLine(offset); + imgui.text(std::to_string(m_statistics.vertices_size + m_statistics.indices_size + m_statistics.paths_size) + " bytes"); + + ImGui::Separator(); + + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + imgui.text(std::string("Vertices GPU:")); + ImGui::PopStyleColor(); + ImGui::SameLine(offset); + imgui.text(std::to_string(m_statistics.vertices_gpu_size) + " bytes"); + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); imgui.text(std::string("Indices GPU:")); ImGui::PopStyleColor(); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.indices_gpu_size) + " bytes"); + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + imgui.text(std::string("TOTAL GPU:")); + ImGui::PopStyleColor(); + ImGui::SameLine(offset); + imgui.text(std::to_string(m_statistics.vertices_gpu_size + m_statistics.indices_gpu_size) + " bytes"); + imgui.end(); } #endif // ENABLE_GCODE_VIEWER_STATISTICS +bool GCodeViewer::is_travel_in_z_range(size_t id) const +{ + const IBuffer& buffer = m_buffers[buffer_id(GCodeProcessor::EMoveType::Travel)]; + if (id >= buffer.paths.size()) + return false; + + Path path = buffer.paths[id]; + int first = static_cast(id); + unsigned int last = static_cast(id); + + // check adjacent paths + while (first > 0 && path.first.position.isApprox(buffer.paths[first - 1].last.position)) { + --first; + path.first = buffer.paths[first].first; + } + while (last < static_cast(buffer.paths.size() - 1) && path.last.position.isApprox(buffer.paths[last + 1].first.position)) { + ++last; + path.last = buffer.paths[last].last; + } + + return is_in_z_range(path); +} + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 9af7e7cc48..aa024a742c 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -38,7 +38,7 @@ class GCodeViewer struct Endpoint { unsigned int id{ 0u }; - double z{ 0.0 }; + Vec3f position{ Vec3f::Zero() }; }; GCodeProcessor::EMoveType type{ GCodeProcessor::EMoveType::Noop }; @@ -54,11 +54,7 @@ class GCodeViewer unsigned char extruder_id{ 0 }; unsigned char cp_color_id{ 0 }; - bool matches(const GCodeProcessor::MoveVertex& move) const { - return type == move.type && role == move.extrusion_role && height == move.height && width == move.width && - feedrate == move.feedrate && fan_speed == move.fan_speed && volumetric_rate == move.volumetric_rate() && - extruder_id == move.extruder_id && cp_color_id == move.cp_color_id; - } + bool matches(const GCodeProcessor::MoveVertex& move) const; }; // Used to batch the indices needed to render paths @@ -157,6 +153,7 @@ class GCodeViewer long long vertices_gpu_size{ 0 }; long long indices_size{ 0 }; long long indices_gpu_size{ 0 }; + long long paths_size{ 0 }; void reset_all() { reset_times(); @@ -180,6 +177,7 @@ class GCodeViewer vertices_gpu_size = 0; indices_size = 0; indices_gpu_size = 0; + paths_size = 0; } }; #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -279,8 +277,9 @@ private: return z > m_layers_z_range[0] - EPSILON && z < m_layers_z_range[1] + EPSILON; }; - return in_z_range(path.first.z) || in_z_range(path.last.z); + return in_z_range(path.first.position[2]) || in_z_range(path.last.position[2]); } + bool is_travel_in_z_range(size_t id) const; }; } // namespace GUI diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index ea7d2dc1bc..22b3d2c253 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -405,6 +405,7 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view bind_event_handlers(); +#if !ENABLE_GCODE_VIEWER // sets colors for gcode preview extrusion roles std::vector extrusion_roles_colors = { "Perimeter", "FFFF66", @@ -422,6 +423,7 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view "Custom", "28CC94" }; m_gcode_preview_data->set_extrusion_paths_colors(extrusion_roles_colors); +#endif // !ENABLE_GCODE_VIEWER return true; } From 170f91b3353d495c9d602fa5f4dce7f94ecde6f5 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 5 May 2020 12:09:11 +0200 Subject: [PATCH 056/255] GCodeViewer -> Prototype for sequential view --- src/slic3r/GUI/GCodeViewer.cpp | 208 +++++++++++++++++++++++++-------- src/slic3r/GUI/GCodeViewer.hpp | 43 +++++-- src/slic3r/GUI/GLCanvas3D.cpp | 3 +- 3 files changed, 197 insertions(+), 57 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 0c631904aa..dc7c0d9731 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -10,6 +10,7 @@ #include "GUI_Utils.hpp" #include "DoubleSlider.hpp" #include "GLCanvas3D.hpp" +#include "GLToolbar.hpp" #include "libslic3r/Model.hpp" #if ENABLE_GCODE_VIEWER_STATISTICS #include @@ -33,10 +34,10 @@ static GCodeProcessor::EMoveType buffer_type(unsigned char id) { return static_cast(static_cast(GCodeProcessor::EMoveType::Retract) + id); } -std::vector> decode_colors(const std::vector& colors) { +std::vector> decode_colors(const std::vector & colors) { static const float INV_255 = 1.0f / 255.0f; - std::vector> output(colors.size(), {0.0f, 0.0f, 0.0f} ); + std::vector> output(colors.size(), { 0.0f, 0.0f, 0.0f }); for (size_t i = 0; i < colors.size(); ++i) { const std::string& color = colors[i]; @@ -102,6 +103,7 @@ void GCodeViewer::IBuffer::reset() data = std::vector(); data_size = 0; paths = std::vector(); + render_paths = std::vector(); } bool GCodeViewer::IBuffer::init_shader(const std::string& vertex_shader_src, const std::string& fragment_shader_src) @@ -114,13 +116,13 @@ bool GCodeViewer::IBuffer::init_shader(const std::string& vertex_shader_src, con return true; } -void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move) +void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move, unsigned int v_id) { - Path::Endpoint endpoint = { static_cast(data.size()), move.position }; + Path::Endpoint endpoint = { static_cast(data.size()), v_id, move.position }; paths.push_back({ move.type, move.extrusion_role, endpoint, endpoint, move.delta_extruder, move.height, move.width, move.feedrate, move.fan_speed, move.volumetric_rate(), move.extruder_id, move.cp_color_id }); } -std::array GCodeViewer::Extrusions::Range::get_color_at(float value) const +GCodeViewer::Color GCodeViewer::Extrusions::Range::get_color_at(float value) const { // Input value scaled to the colors range const float step = step_size(); @@ -136,14 +138,14 @@ std::array GCodeViewer::Extrusions::Range::get_color_at(float value) c const float local_t = std::clamp(global_t - static_cast(color_low_idx), 0.0f, 1.0f); // Interpolate between the low and high colors to find exactly which color the input value should get - std::array ret; + Color ret; for (unsigned int i = 0; i < 3; ++i) { ret[i] = lerp(Range_Colors[color_low_idx][i], Range_Colors[color_high_idx][i], local_t); } return ret; } -const std::vector> GCodeViewer::Extrusion_Role_Colors {{ +const std::vector GCodeViewer::Extrusion_Role_Colors{ { { 0.50f, 0.50f, 0.50f }, // erNone { 1.00f, 1.00f, 0.40f }, // erPerimeter { 1.00f, 0.65f, 0.00f }, // erExternalPerimeter @@ -162,13 +164,13 @@ const std::vector> GCodeViewer::Extrusion_Role_Colors {{ { 0.00f, 0.00f, 0.00f } // erMixed }}; -const std::vector> GCodeViewer::Travel_Colors {{ +const std::vector GCodeViewer::Travel_Colors{ { { 0.0f, 0.0f, 0.5f }, // Move { 0.0f, 0.5f, 0.0f }, // Extrude { 0.5f, 0.0f, 0.0f } // Retract }}; -const std::vector> GCodeViewer::Range_Colors {{ +const std::vector GCodeViewer::Range_Colors{ { { 0.043f, 0.173f, 0.478f }, // bluish { 0.075f, 0.349f, 0.522f }, { 0.110f, 0.533f, 0.569f }, @@ -240,7 +242,7 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: } // update buffers' render paths - refresh_render_paths(); + refresh_render_paths(false); #if ENABLE_GCODE_VIEWER_STATISTICS m_statistics.refresh_time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); @@ -256,7 +258,7 @@ void GCodeViewer::reset() } m_bounding_box = BoundingBoxf3(); - m_tool_colors = std::vector>(); + m_tool_colors = std::vector(); m_extruder_ids = std::vector(); m_extrusions.reset_role_visibility_flags(); m_extrusions.reset_ranges(); @@ -280,6 +282,7 @@ void GCodeViewer::render() const render_toolpaths(); render_shells(); render_legend(); + render_sequential_dlg(); #if ENABLE_GCODE_VIEWER_STATISTICS render_statistics(); #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -425,7 +428,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) case GCodeProcessor::EMoveType::Retract: case GCodeProcessor::EMoveType::Unretract: { - buffer.add_path(curr); + buffer.add_path(curr, static_cast(i)); buffer.data.push_back(static_cast(i)); break; } @@ -433,12 +436,14 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) case GCodeProcessor::EMoveType::Travel: { if (prev.type != curr.type || !buffer.paths.back().matches(curr)) { - buffer.add_path(curr); - buffer.paths.back().first.position = prev.position; + buffer.add_path(curr, static_cast(i)); + Path& last_path = buffer.paths.back(); + last_path.first.position = prev.position; + last_path.first.s_id = static_cast(i - 1); buffer.data.push_back(static_cast(i - 1)); } - buffer.paths.back().last = { static_cast(buffer.data.size()), curr.position }; + buffer.paths.back().last = { static_cast(buffer.data.size()), static_cast(i), curr.position }; buffer.data.push_back(static_cast(i)); break; } @@ -568,10 +573,10 @@ void GCodeViewer::load_shells(const Print& print, bool initialized) } } -void GCodeViewer::refresh_render_paths() const +void GCodeViewer::refresh_render_paths(bool keep_sequential_current) const { auto extrusion_color = [this](const Path& path) { - std::array color; + Color color; switch (m_view_type) { case EViewType::FeatureType: { color = Extrusion_Role_Colors[static_cast(path.role)]; break; } @@ -593,26 +598,86 @@ void GCodeViewer::refresh_render_paths() const Travel_Colors[0] /* Move */); }; + auto is_valid_path = [this](const Path& path, size_t id) { + if (path.type == GCodeProcessor::EMoveType::Travel) { + if (!is_travel_in_z_range(id)) + return false; + } + else if (!is_in_z_range(path)) + return false; + + if (path.type == GCodeProcessor::EMoveType::Extrude && !is_visible(path)) + return false; + + return true; + }; + +#if ENABLE_GCODE_VIEWER_STATISTICS + m_statistics.render_paths_size = 0; +#endif // ENABLE_GCODE_VIEWER_STATISTICS + + m_sequential_view.first = m_vertices.vertices_count; + m_sequential_view.last = 0; + if (!keep_sequential_current) + m_sequential_view.current = m_vertices.vertices_count; + + // first, detect current values for the sequential view + // to be used later to filter the paths + for (IBuffer& buffer : m_buffers) { + if (!buffer.visible) + continue; + + for (size_t i = 0; i < buffer.paths.size(); ++i) { + const Path& path = buffer.paths[i]; + if (!is_valid_path(path, i)) + continue; +// if (path.type == GCodeProcessor::EMoveType::Travel) { +// if (!is_travel_in_z_range(i)) +// continue; +// } +// else if (!is_in_z_range(path)) +// continue; +// +// if (path.type == GCodeProcessor::EMoveType::Extrude && !is_visible(path)) +// continue; + + m_sequential_view.first = std::min(m_sequential_view.first, path.first.s_id); + m_sequential_view.last = std::max(m_sequential_view.last, path.last.s_id); + } + } + + if (keep_sequential_current) + m_sequential_view.clamp_current(); + else + m_sequential_view.current = m_sequential_view.last; for (IBuffer& buffer : m_buffers) { buffer.render_paths = std::vector(); + if (!buffer.visible) + continue; for (size_t i = 0; i < buffer.paths.size(); ++i) { const Path& path = buffer.paths[i]; - if (path.type == GCodeProcessor::EMoveType::Travel) { - if (!is_travel_in_z_range(i)) - continue; - } - else if (!is_in_z_range(path)) + if (!is_valid_path(path, i)) + continue; +// if (path.type == GCodeProcessor::EMoveType::Travel) { +// if (!is_travel_in_z_range(i)) +// continue; +// } +// else if (!is_in_z_range(path)) +// continue; +// +// if (path.type == GCodeProcessor::EMoveType::Extrude && !is_visible(path)) +// continue; + + if ((m_sequential_view.current < path.first.s_id) || (path.last.s_id < m_sequential_view.first)) continue; - if (path.type == GCodeProcessor::EMoveType::Extrude && !is_visible(path)) - continue; - - std::array color = { 0.0f, 0.0f, 0.0f }; + Color color; switch (path.type) { case GCodeProcessor::EMoveType::Extrude: { color = extrusion_color(path); break; } case GCodeProcessor::EMoveType::Travel: { color = (m_view_type == EViewType::Feedrate || m_view_type == EViewType::Tool || m_view_type == EViewType::ColorPrint) ? extrusion_color(path) : travel_color(path); break; } + default: { color = { 0.0f, 0.0f, 0.0f }; break; } } auto it = std::find_if(buffer.render_paths.begin(), buffer.render_paths.end(), [color](const RenderPath& path) { return path.color == color; }); @@ -621,15 +686,25 @@ void GCodeViewer::refresh_render_paths() const it->color = color; } - it->sizes.push_back(path.last.id - path.first.id + 1); - it->offsets.push_back(static_cast(path.first.id * sizeof(unsigned int))); + it->sizes.push_back(std::min(m_sequential_view.current, path.last.s_id) - path.first.s_id + 1); + it->offsets.push_back(static_cast(path.first.i_id * sizeof(unsigned int))); } } + +#if ENABLE_GCODE_VIEWER_STATISTICS + for (const IBuffer& buffer : m_buffers) { + m_statistics.render_paths_size += SLIC3R_STDVEC_MEMSIZE(buffer.render_paths, RenderPath); + for (const RenderPath& path : buffer.render_paths) { + m_statistics.render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.sizes, unsigned int); + m_statistics.render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.offsets, size_t); + } + } +#endif // ENABLE_GCODE_VIEWER_STATISTICS } void GCodeViewer::render_toolpaths() const { - auto set_color = [](GLint current_program_id, const std::array& color) { + auto set_color = [](GLint current_program_id, const Color& color) { if (current_program_id > 0) { GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1; if (color_id >= 0) { @@ -672,7 +747,7 @@ void GCodeViewer::render_toolpaths() const { case GCodeProcessor::EMoveType::Tool_change: { - std::array color = { 1.0f, 1.0f, 1.0f }; + Color color = { 1.0f, 1.0f, 1.0f }; set_color(current_program_id, color); for (const RenderPath& path : buffer.render_paths) { @@ -688,7 +763,7 @@ void GCodeViewer::render_toolpaths() const } case GCodeProcessor::EMoveType::Color_change: { - std::array color = { 1.0f, 0.0f, 0.0f }; + Color color = { 1.0f, 0.0f, 0.0f }; set_color(current_program_id, color); for (const RenderPath& path : buffer.render_paths) { @@ -704,7 +779,7 @@ void GCodeViewer::render_toolpaths() const } case GCodeProcessor::EMoveType::Pause_Print: { - std::array color = { 0.0f, 1.0f, 0.0f }; + Color color = { 0.0f, 1.0f, 0.0f }; set_color(current_program_id, color); for (const RenderPath& path : buffer.render_paths) { @@ -720,7 +795,7 @@ void GCodeViewer::render_toolpaths() const } case GCodeProcessor::EMoveType::Custom_GCode: { - std::array color = { 0.0f, 0.0f, 1.0f }; + Color color = { 0.0f, 0.0f, 1.0f }; set_color(current_program_id, color); for (const RenderPath& path : buffer.render_paths) { @@ -736,7 +811,7 @@ void GCodeViewer::render_toolpaths() const } case GCodeProcessor::EMoveType::Retract: { - std::array color = { 1.0f, 0.0f, 1.0f }; + Color color = { 1.0f, 0.0f, 1.0f }; set_color(current_program_id, color); for (const RenderPath& path : buffer.render_paths) { @@ -752,7 +827,7 @@ void GCodeViewer::render_toolpaths() const } case GCodeProcessor::EMoveType::Unretract: { - std::array color = { 0.0f, 1.0f, 1.0f }; + Color color = { 0.0f, 1.0f, 1.0f }; set_color(current_program_id, color); for (const RenderPath& path : buffer.render_paths) { @@ -827,13 +902,14 @@ void GCodeViewer::render_legend() const ImGuiWrapper& imgui = *wxGetApp().imgui(); - imgui.set_next_window_pos(0, 0, ImGuiCond_Always); + imgui.set_next_window_pos(0.0f, 0.0f, ImGuiCond_Always); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + ImGui::SetNextWindowBgAlpha(0.6f); imgui.begin(std::string("Legend"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); ImDrawList* draw_list = ImGui::GetWindowDrawList(); - auto add_item = [draw_list, &imgui](const std::array& color, const std::string& label, std::function callback = nullptr) { + auto add_item = [draw_list, &imgui](const Color& color, const std::string& label, std::function callback = nullptr) { float icon_size = ImGui::GetTextLineHeight(); ImVec2 pos = ImGui::GetCursorPos(); draw_list->AddRect({ pos.x, pos.y }, { pos.x + icon_size, pos.y + icon_size }, ICON_BORDER_COLOR, 0.0f, 0); @@ -903,7 +979,7 @@ void GCodeViewer::render_legend() const { m_extrusions.role_visibility_flags = is_visible(role) ? m_extrusions.role_visibility_flags & ~(1 << role) : m_extrusions.role_visibility_flags | (1 << role); // update buffers' render paths - refresh_render_paths(); + refresh_render_paths(false); wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); wxGetApp().plater()->update_preview_bottom_toolbar(); } @@ -1044,6 +1120,51 @@ void GCodeViewer::render_legend() const ImGui::PopStyleVar(); } +void GCodeViewer::render_sequential_dlg() const +{ + static const float margin = 125.0f; + + if (m_roles.empty()) + return; + + if (m_sequential_view.last <= m_sequential_view.first) + return; + + ImGuiWrapper& imgui = *wxGetApp().imgui(); + const ImGuiStyle& style = ImGui::GetStyle(); + + const GLToolbar& view_toolbar = wxGetApp().plater()->get_view_toolbar(); + Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size(); + + float left = view_toolbar.get_width(); + float width = static_cast(cnv_size.get_width()) - left; + + ImGui::SetNextWindowBgAlpha(0.5f); + imgui.set_next_window_pos(left, static_cast(cnv_size.get_height()), ImGuiCond_Always, 0.0f, 1.0f); + ImGui::SetNextWindowSize({ width, -1.0f }, ImGuiCond_Always); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + imgui.begin(std::string("Sequential"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); + + std::string low_str = std::to_string(m_sequential_view.first); + ImGui::SetCursorPosX(margin - style.ItemSpacing.x - ImGui::CalcTextSize(low_str.c_str()).x); + ImGui::AlignTextToFramePadding(); + imgui.text(low_str); + ImGui::SameLine(margin); + ImGui::PushItemWidth(-margin); + int index = static_cast(m_sequential_view.current); + if (ImGui::SliderInt("##slider int", &index, static_cast(m_sequential_view.first), static_cast(m_sequential_view.last))) + { + m_sequential_view.current = static_cast(index); + refresh_render_paths(true); + } + ImGui::PopItemWidth(); + ImGui::SameLine(); + imgui.text(std::to_string(m_sequential_view.last)); + + imgui.end(); + ImGui::PopStyleVar(); +} + #if ENABLE_GCODE_VIEWER_STATISTICS void GCodeViewer::render_statistics() const { @@ -1055,6 +1176,7 @@ void GCodeViewer::render_statistics() const ImGuiWrapper& imgui = *wxGetApp().imgui(); + imgui.set_next_window_pos(0.5f * wxGetApp().plater()->get_current_canvas3D()->get_canvas_size().get_width(), 0.0f, ImGuiCond_Once, 0.5f, 0.0f); imgui.begin(std::string("Statistics"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindow()); @@ -1113,10 +1235,10 @@ void GCodeViewer::render_statistics() const imgui.text(std::to_string(m_statistics.paths_size) + " bytes"); ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); - imgui.text(std::string("TOTAL CPU:")); + imgui.text(std::string("Render paths CPU:")); ImGui::PopStyleColor(); ImGui::SameLine(offset); - imgui.text(std::to_string(m_statistics.vertices_size + m_statistics.indices_size + m_statistics.paths_size) + " bytes"); + imgui.text(std::to_string(m_statistics.render_paths_size) + " bytes"); ImGui::Separator(); @@ -1132,12 +1254,6 @@ void GCodeViewer::render_statistics() const ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.indices_gpu_size) + " bytes"); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); - imgui.text(std::string("TOTAL GPU:")); - ImGui::PopStyleColor(); - ImGui::SameLine(offset); - imgui.text(std::to_string(m_statistics.vertices_gpu_size + m_statistics.indices_gpu_size) + " bytes"); - imgui.end(); } #endif // ENABLE_GCODE_VIEWER_STATISTICS diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index aa024a742c..5e4ea53964 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -14,9 +14,10 @@ namespace GUI { class GCodeViewer { - static const std::vector> Extrusion_Role_Colors; - static const std::vector> Travel_Colors; - static const std::vector> Range_Colors; + using Color = std::array; + static const std::vector Extrusion_Role_Colors; + static const std::vector Travel_Colors; + static const std::vector Range_Colors; // buffer containing vertices data struct VBuffer @@ -37,7 +38,10 @@ class GCodeViewer { struct Endpoint { - unsigned int id{ 0u }; + // index into the ibo + unsigned int i_id{ 0u }; + // sequential id + unsigned int s_id{ 0u }; Vec3f position{ Vec3f::Zero() }; }; @@ -55,12 +59,14 @@ class GCodeViewer unsigned char cp_color_id{ 0 }; bool matches(const GCodeProcessor::MoveVertex& move) const; + + unsigned int size() const { return last.i_id - first.i_id + 1; } }; // Used to batch the indices needed to render paths struct RenderPath { - std::array color; + Color color; std::vector sizes; std::vector offsets; // use size_t because we need the pointer's size (used in the call glMultiDrawElements()) }; @@ -78,9 +84,10 @@ class GCodeViewer void reset(); bool init_shader(const std::string& vertex_shader_src, const std::string& fragment_shader_src); - void add_path(const GCodeProcessor::MoveVertex& move); + void add_path(const GCodeProcessor::MoveVertex& move, unsigned int s_id); }; + struct Shells { GLVolumeCollection volumes; @@ -102,7 +109,7 @@ class GCodeViewer void reset() { min = FLT_MAX; max = -FLT_MAX; } float step_size() const { return (max - min) / (static_cast(Range_Colors.size()) - 1.0f); } - std::array get_color_at(float value) const; + Color get_color_at(float value) const; }; struct Ranges @@ -141,6 +148,15 @@ class GCodeViewer void reset_ranges() { ranges.reset(); } }; + struct SequentialView + { + unsigned int first{ 0 }; + unsigned int last{ 0 }; + unsigned int current{ 0 }; + + void clamp_current() { current = std::clamp(current, first, last); } + }; + #if ENABLE_GCODE_VIEWER_STATISTICS struct Statistics { @@ -154,6 +170,7 @@ class GCodeViewer long long indices_size{ 0 }; long long indices_gpu_size{ 0 }; long long paths_size{ 0 }; + long long render_paths_size{ 0 }; void reset_all() { reset_times(); @@ -178,6 +195,7 @@ class GCodeViewer indices_size = 0; indices_gpu_size = 0; paths_size = 0; + render_paths_size = 0; } }; #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -201,12 +219,13 @@ private: VBuffer m_vertices; mutable std::vector m_buffers{ static_cast(GCodeProcessor::EMoveType::Extrude) }; BoundingBoxf3 m_bounding_box; - std::vector> m_tool_colors; + std::vector m_tool_colors; std::vector m_layers_zs; std::array m_layers_z_range; std::vector m_roles; std::vector m_extruder_ids; mutable Extrusions m_extrusions; + mutable SequentialView m_sequential_view; Shells m_shells; EViewType m_view_type{ EViewType::FeatureType }; bool m_legend_enabled{ true }; @@ -231,6 +250,8 @@ public: void reset(); void render() const; + bool has_data() const { return !m_roles.empty(); } + const BoundingBoxf3& get_bounding_box() const { return m_bounding_box; } const std::vector& get_layers_zs() const { return m_layers_zs; }; @@ -250,8 +271,9 @@ public: void set_options_visibility_from_flags(unsigned int flags); void set_layers_z_range(const std::array& layers_z_range) { + bool keep_sequential_current = layers_z_range[1] <= m_layers_z_range[1]; m_layers_z_range = layers_z_range; - refresh_render_paths(); + refresh_render_paths(keep_sequential_current); } bool is_legend_enabled() const { return m_legend_enabled; } @@ -261,10 +283,11 @@ private: bool init_shaders(); void load_toolpaths(const GCodeProcessor::Result& gcode_result); void load_shells(const Print& print, bool initialized); - void refresh_render_paths() const; + void refresh_render_paths(bool keep_sequential_current) const; void render_toolpaths() const; void render_shells() const; void render_legend() const; + void render_sequential_dlg() const; #if ENABLE_GCODE_VIEWER_STATISTICS void render_statistics() const; #endif // ENABLE_GCODE_VIEWER_STATISTICS diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 6881e86fd5..875e4fd525 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2363,8 +2363,9 @@ void GLCanvas3D::set_toolpath_view_type(GCodeViewer::EViewType type) void GLCanvas3D::set_toolpaths_z_range(const std::array& range) { - m_gcode_viewer.set_layers_z_range(range); m_volumes.set_range(range[0] - 1e-6, range[1] + 1e-6); + if (m_gcode_viewer.has_data()) + m_gcode_viewer.set_layers_z_range(range); } #else std::vector GLCanvas3D::get_current_print_zs(bool active_only) const From a84c4347872eb009d88296e053e930975973b91e Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 5 May 2020 13:57:51 +0200 Subject: [PATCH 057/255] GCodeViewer -> Refactoring/Optimization --- src/slic3r/GUI/GCodeViewer.cpp | 125 ++++++++++++++------------------- src/slic3r/GUI/GCodeViewer.hpp | 10 ++- src/slic3r/GUI/GUI_Preview.cpp | 1 + 3 files changed, 59 insertions(+), 77 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index dc7c0d9731..3323e784cd 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -385,12 +385,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) return; // vertex data / bounding box -> extract from result - std::vector vertices_data; - for (const GCodeProcessor::MoveVertex& move : gcode_result.moves) { - for (int j = 0; j < 3; ++j) { - vertices_data.insert(vertices_data.end(), move.position[j]); - m_bounding_box.merge(move.position.cast()); - } + std::vector vertices_data(m_vertices.vertices_count * 3); + for (size_t i = 0; i < m_vertices.vertices_count; ++i) { + const GCodeProcessor::MoveVertex& move = gcode_result.moves[i]; + m_bounding_box.merge(move.position.cast()); + ::memcpy(static_cast(&vertices_data[i * 3]), static_cast(move.position.data()), 3 * sizeof(float)); } #if ENABLE_GCODE_VIEWER_STATISTICS @@ -575,6 +574,10 @@ void GCodeViewer::load_shells(const Print& print, bool initialized) void GCodeViewer::refresh_render_paths(bool keep_sequential_current) const { +#if ENABLE_GCODE_VIEWER_STATISTICS + auto start_time = std::chrono::high_resolution_clock::now(); +#endif // ENABLE_GCODE_VIEWER_STATISTICS + auto extrusion_color = [this](const Path& path) { Color color; switch (m_view_type) @@ -598,20 +601,6 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current) const Travel_Colors[0] /* Move */); }; - auto is_valid_path = [this](const Path& path, size_t id) { - if (path.type == GCodeProcessor::EMoveType::Travel) { - if (!is_travel_in_z_range(id)) - return false; - } - else if (!is_in_z_range(path)) - return false; - - if (path.type == GCodeProcessor::EMoveType::Extrude && !is_visible(path)) - return false; - - return true; - }; - #if ENABLE_GCODE_VIEWER_STATISTICS m_statistics.render_paths_size = 0; #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -621,74 +610,60 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current) const if (!keep_sequential_current) m_sequential_view.current = m_vertices.vertices_count; - // first, detect current values for the sequential view - // to be used later to filter the paths + // first pass: collect visible paths and update sequential view data + std::vector> paths; for (IBuffer& buffer : m_buffers) { + // reset render paths + buffer.render_paths = std::vector(); + if (!buffer.visible) continue; for (size_t i = 0; i < buffer.paths.size(); ++i) { const Path& path = buffer.paths[i]; - if (!is_valid_path(path, i)) + if (path.type == GCodeProcessor::EMoveType::Travel) { + if (!is_travel_in_z_range(i)) + continue; + } + else if (!is_in_z_range(path)) continue; -// if (path.type == GCodeProcessor::EMoveType::Travel) { -// if (!is_travel_in_z_range(i)) -// continue; -// } -// else if (!is_in_z_range(path)) -// continue; -// -// if (path.type == GCodeProcessor::EMoveType::Extrude && !is_visible(path)) -// continue; + + if (path.type == GCodeProcessor::EMoveType::Extrude && !is_visible(path)) + continue; + + // store valid path + paths.push_back({ &buffer, i }); m_sequential_view.first = std::min(m_sequential_view.first, path.first.s_id); m_sequential_view.last = std::max(m_sequential_view.last, path.last.s_id); } } - if (keep_sequential_current) - m_sequential_view.clamp_current(); - else - m_sequential_view.current = m_sequential_view.last; + // update current sequential position + m_sequential_view.current = keep_sequential_current ? std::clamp(m_sequential_view.current, m_sequential_view.first, m_sequential_view.last) : m_sequential_view.last; - for (IBuffer& buffer : m_buffers) { - buffer.render_paths = std::vector(); - if (!buffer.visible) + // second pass: filter paths by sequential data + for (auto&& [buffer, id] : paths) { + const Path& path = buffer->paths[id]; + if ((m_sequential_view.current < path.first.s_id) || (path.last.s_id < m_sequential_view.first)) continue; - for (size_t i = 0; i < buffer.paths.size(); ++i) { - const Path& path = buffer.paths[i]; - if (!is_valid_path(path, i)) - continue; -// if (path.type == GCodeProcessor::EMoveType::Travel) { -// if (!is_travel_in_z_range(i)) -// continue; -// } -// else if (!is_in_z_range(path)) -// continue; -// -// if (path.type == GCodeProcessor::EMoveType::Extrude && !is_visible(path)) -// continue; - if ((m_sequential_view.current < path.first.s_id) || (path.last.s_id < m_sequential_view.first)) - continue; - - Color color; - switch (path.type) - { - case GCodeProcessor::EMoveType::Extrude: { color = extrusion_color(path); break; } - case GCodeProcessor::EMoveType::Travel: { color = (m_view_type == EViewType::Feedrate || m_view_type == EViewType::Tool || m_view_type == EViewType::ColorPrint) ? extrusion_color(path) : travel_color(path); break; } - default: { color = { 0.0f, 0.0f, 0.0f }; break; } - } - - auto it = std::find_if(buffer.render_paths.begin(), buffer.render_paths.end(), [color](const RenderPath& path) { return path.color == color; }); - if (it == buffer.render_paths.end()) { - it = buffer.render_paths.insert(buffer.render_paths.end(), RenderPath()); - it->color = color; - } - - it->sizes.push_back(std::min(m_sequential_view.current, path.last.s_id) - path.first.s_id + 1); - it->offsets.push_back(static_cast(path.first.i_id * sizeof(unsigned int))); + Color color; + switch (path.type) + { + case GCodeProcessor::EMoveType::Extrude: { color = extrusion_color(path); break; } + case GCodeProcessor::EMoveType::Travel: { color = (m_view_type == EViewType::Feedrate || m_view_type == EViewType::Tool || m_view_type == EViewType::ColorPrint) ? extrusion_color(path) : travel_color(path); break; } + default: { color = { 0.0f, 0.0f, 0.0f }; break; } } + + auto it = std::find_if(buffer->render_paths.begin(), buffer->render_paths.end(), [color](const RenderPath& path) { return path.color == color; }); + if (it == buffer->render_paths.end()) { + it = buffer->render_paths.insert(buffer->render_paths.end(), RenderPath()); + it->color = color; + } + + it->sizes.push_back(std::min(m_sequential_view.current, path.last.s_id) - path.first.s_id + 1); + it->offsets.push_back(static_cast(path.first.i_id * sizeof(unsigned int))); } #if ENABLE_GCODE_VIEWER_STATISTICS @@ -699,6 +674,8 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current) const m_statistics.render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.offsets, size_t); } } + + m_statistics.refresh_paths_time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); #endif // ENABLE_GCODE_VIEWER_STATISTICS } @@ -1192,6 +1169,12 @@ void GCodeViewer::render_statistics() const ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.refresh_time) + "ms"); + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + imgui.text(std::string("Resfresh paths time:")); + ImGui::PopStyleColor(); + ImGui::SameLine(offset); + imgui.text(std::to_string(m_statistics.refresh_paths_time) + "ms"); + ImGui::Separator(); ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 5e4ea53964..3e73cb5d68 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -38,9 +38,9 @@ class GCodeViewer { struct Endpoint { - // index into the ibo + // index into the buffer indices ibo unsigned int i_id{ 0u }; - // sequential id + // sequential id (same as index into the vertices vbo) unsigned int s_id{ 0u }; Vec3f position{ Vec3f::Zero() }; }; @@ -59,8 +59,6 @@ class GCodeViewer unsigned char cp_color_id{ 0 }; bool matches(const GCodeProcessor::MoveVertex& move) const; - - unsigned int size() const { return last.i_id - first.i_id + 1; } }; // Used to batch the indices needed to render paths @@ -153,8 +151,6 @@ class GCodeViewer unsigned int first{ 0 }; unsigned int last{ 0 }; unsigned int current{ 0 }; - - void clamp_current() { current = std::clamp(current, first, last); } }; #if ENABLE_GCODE_VIEWER_STATISTICS @@ -162,6 +158,7 @@ class GCodeViewer { long long load_time{ 0 }; long long refresh_time{ 0 }; + long long refresh_paths_time{ 0 }; long long gl_multi_points_calls_count{ 0 }; long long gl_multi_line_strip_calls_count{ 0 }; long long results_size{ 0 }; @@ -181,6 +178,7 @@ class GCodeViewer void reset_times() { load_time = 0; refresh_time = 0; + refresh_paths_time = 0; } void reset_opengl() { diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index ce79a4bcd4..b4cbe44616 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -368,6 +368,7 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view #if ENABLE_GCODE_VIEWER m_bottom_toolbar_sizer = new wxBoxSizer(wxHORIZONTAL); + m_bottom_toolbar_sizer->AddSpacer(10); m_bottom_toolbar_sizer->Add(m_label_view_type, 0, wxALIGN_CENTER_VERTICAL, 5); m_bottom_toolbar_sizer->Add(m_choice_view_type, 0, wxEXPAND | wxALL, 5); m_bottom_toolbar_sizer->AddSpacer(10); From 1c4ffa9b16eb85bfed2e6fadf68c21937bf68ac8 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 5 May 2020 16:29:07 +0200 Subject: [PATCH 058/255] GCodeViewer -> Added buttons for forward/backward movements of 1, 10 and 100 moves to sequential view bar --- src/slic3r/GUI/GCodeViewer.cpp | 67 ++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 12 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 3323e784cd..44fe361c21 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1099,7 +1099,13 @@ void GCodeViewer::render_legend() const void GCodeViewer::render_sequential_dlg() const { - static const float margin = 125.0f; + static const float MARGIN = 125.0f; + static const float BUTTON_W = 50.0f; + + auto apply_button_action = [this](unsigned int value) { + m_sequential_view.current = std::clamp(value, m_sequential_view.first, m_sequential_view.last); + refresh_render_paths(true); + }; if (m_roles.empty()) return; @@ -1110,10 +1116,9 @@ void GCodeViewer::render_sequential_dlg() const ImGuiWrapper& imgui = *wxGetApp().imgui(); const ImGuiStyle& style = ImGui::GetStyle(); - const GLToolbar& view_toolbar = wxGetApp().plater()->get_view_toolbar(); Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size(); - float left = view_toolbar.get_width(); + float left = wxGetApp().plater()->get_view_toolbar().get_width(); float width = static_cast(cnv_size.get_width()) - left; ImGui::SetNextWindowBgAlpha(0.5f); @@ -1122,21 +1127,59 @@ void GCodeViewer::render_sequential_dlg() const ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); imgui.begin(std::string("Sequential"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); - std::string low_str = std::to_string(m_sequential_view.first); - ImGui::SetCursorPosX(margin - style.ItemSpacing.x - ImGui::CalcTextSize(low_str.c_str()).x); + ImGui::SetCursorPosX(MARGIN); + imgui.disabled_begin(m_sequential_view.first == m_sequential_view.current); + if (ImGui::Button("< 1", { BUTTON_W, 0.0f })) + apply_button_action(m_sequential_view.current - 1); + imgui.disabled_end(); + + ImGui::SameLine(); + imgui.disabled_begin(m_sequential_view.current - m_sequential_view.first < 10); + if (ImGui::Button("< 10", { BUTTON_W, 0.0f })) + apply_button_action(m_sequential_view.current - 10); + imgui.disabled_end(); + + ImGui::SameLine(); + imgui.disabled_begin(m_sequential_view.current - m_sequential_view.first < 100); + if (ImGui::Button("< 100", { BUTTON_W, 0.0f })) + apply_button_action(m_sequential_view.current - 100); + imgui.disabled_end(); + + ImGui::SameLine(width - MARGIN - 3 * BUTTON_W - 2 * style.ItemSpacing.x - style.WindowPadding.x); + imgui.disabled_begin(m_sequential_view.last - m_sequential_view.current < 100); + if (ImGui::Button("> 100", { BUTTON_W, 0.0f })) + apply_button_action(m_sequential_view.current + 100); + imgui.disabled_end(); + + ImGui::SameLine(); + imgui.disabled_begin(m_sequential_view.last - m_sequential_view.current < 10); + if (ImGui::Button("> 10", { BUTTON_W, 0.0f })) + apply_button_action(m_sequential_view.current + 10); + imgui.disabled_end(); + + ImGui::SameLine(); + imgui.disabled_begin(m_sequential_view.last == m_sequential_view.current); + if (ImGui::Button("> 1", { BUTTON_W, 0.0f })) + apply_button_action(m_sequential_view.current + 1); + imgui.disabled_end(); + + int index = 1 + static_cast(m_sequential_view.current); + int i_min = 1 + static_cast(m_sequential_view.first); + int i_max = 1 + static_cast(m_sequential_view.last); + + std::string low_str = std::to_string(i_min); + ImGui::SetCursorPosX(MARGIN - style.ItemSpacing.x - ImGui::CalcTextSize(low_str.c_str()).x); ImGui::AlignTextToFramePadding(); imgui.text(low_str); - ImGui::SameLine(margin); - ImGui::PushItemWidth(-margin); - int index = static_cast(m_sequential_view.current); - if (ImGui::SliderInt("##slider int", &index, static_cast(m_sequential_view.first), static_cast(m_sequential_view.last))) - { - m_sequential_view.current = static_cast(index); + ImGui::SameLine(MARGIN); + ImGui::PushItemWidth(-MARGIN); + if (ImGui::SliderInt("##slider int", &index, i_min, i_max)) { + m_sequential_view.current = static_cast(index - 1); refresh_render_paths(true); } ImGui::PopItemWidth(); ImGui::SameLine(); - imgui.text(std::to_string(m_sequential_view.last)); + imgui.text(std::to_string(i_max)); imgui.end(); ImGui::PopStyleVar(); From 82b75112bd0be3b9e5eccea447605369a6f12033 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 6 May 2020 11:18:37 +0200 Subject: [PATCH 059/255] GCodeViewer -> Sequential view marker wip + refactoring --- src/slic3r/GUI/GCodeViewer.cpp | 71 +++++++++++++++++++++++----------- src/slic3r/GUI/GCodeViewer.hpp | 27 ++++++++++--- 2 files changed, 70 insertions(+), 28 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 44fe361c21..d4cd840884 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -100,8 +100,7 @@ void GCodeViewer::IBuffer::reset() } // release cpu memory - data = std::vector(); - data_size = 0; + indices_count = 0; paths = std::vector(); render_paths = std::vector(); } @@ -116,9 +115,9 @@ bool GCodeViewer::IBuffer::init_shader(const std::string& vertex_shader_src, con return true; } -void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move, unsigned int v_id) +void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move, unsigned int i_id, unsigned int s_id) { - Path::Endpoint endpoint = { static_cast(data.size()), v_id, move.position }; + Path::Endpoint endpoint = { i_id, s_id, move.position }; paths.push_back({ move.type, move.extrusion_role, endpoint, endpoint, move.delta_extruder, move.height, move.width, move.feedrate, move.fan_speed, move.volumetric_rate(), move.extruder_id, move.cp_color_id }); } @@ -145,6 +144,21 @@ GCodeViewer::Color GCodeViewer::Extrusions::Range::get_color_at(float value) con return ret; } +void GCodeViewer::SequentialView::Marker::init() +{ + if (m_initialized) + return; + +} + +void GCodeViewer::SequentialView::Marker::render() const +{ + if (!m_initialized) + return; + + +} + const std::vector GCodeViewer::Extrusion_Role_Colors{ { { 0.50f, 0.50f, 0.50f }, // erNone { 1.00f, 1.00f, 0.40f }, // erPerimeter @@ -280,9 +294,11 @@ void GCodeViewer::render() const glsafe(::glEnable(GL_DEPTH_TEST)); render_toolpaths(); + if (m_sequential_view.marker.visible) + m_sequential_view.marker.render(); render_shells(); render_legend(); - render_sequential_dlg(); + render_sequential_bar(); #if ENABLE_GCODE_VIEWER_STATISTICS render_statistics(); #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -403,10 +419,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) glsafe(::glBufferData(GL_ARRAY_BUFFER, vertices_data.size() * sizeof(float), vertices_data.data(), GL_STATIC_DRAW)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - // vertex data -> free ram + // vertex data -> no more needed, free ram vertices_data = std::vector(); // indices data -> extract from result + std::vector> indices(m_buffers.size()); for (size_t i = 0; i < m_vertices.vertices_count; ++i) { // skip first vertex @@ -416,7 +433,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) const GCodeProcessor::MoveVertex& prev = gcode_result.moves[i - 1]; const GCodeProcessor::MoveVertex& curr = gcode_result.moves[i]; - IBuffer& buffer = m_buffers[buffer_id(curr.type)]; + unsigned char id = buffer_id(curr.type); + IBuffer& buffer = m_buffers[id]; + std::vector& buffer_indices = indices[id]; switch (curr.type) { @@ -427,23 +446,23 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) case GCodeProcessor::EMoveType::Retract: case GCodeProcessor::EMoveType::Unretract: { - buffer.add_path(curr, static_cast(i)); - buffer.data.push_back(static_cast(i)); + buffer.add_path(curr, static_cast(buffer_indices.size()), static_cast(i)); + buffer_indices.push_back(static_cast(i)); break; } case GCodeProcessor::EMoveType::Extrude: case GCodeProcessor::EMoveType::Travel: { if (prev.type != curr.type || !buffer.paths.back().matches(curr)) { - buffer.add_path(curr, static_cast(i)); + buffer.add_path(curr, static_cast(buffer_indices.size()), static_cast(i)); Path& last_path = buffer.paths.back(); last_path.first.position = prev.position; last_path.first.s_id = static_cast(i - 1); - buffer.data.push_back(static_cast(i - 1)); + buffer_indices.push_back(static_cast(i - 1)); } - buffer.paths.back().last = { static_cast(buffer.data.size()), static_cast(i), curr.position }; - buffer.data.push_back(static_cast(i)); + buffer.paths.back().last = { static_cast(buffer_indices.size()), static_cast(i), curr.position }; + buffer_indices.push_back(static_cast(i)); break; } default: @@ -461,22 +480,21 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) #endif // ENABLE_GCODE_VIEWER_STATISTICS // indices data -> send data to gpu - for (IBuffer& buffer : m_buffers) + for (size_t i = 0; i < m_buffers.size(); ++i) { - buffer.data_size = buffer.data.size(); + IBuffer& buffer = m_buffers[i]; + std::vector& buffer_indices = indices[i]; + buffer.indices_count = buffer_indices.size(); #if ENABLE_GCODE_VIEWER_STATISTICS - m_statistics.indices_size += SLIC3R_STDVEC_MEMSIZE(buffer.data, unsigned int); - m_statistics.indices_gpu_size += buffer.data_size * sizeof(unsigned int); + m_statistics.indices_size += SLIC3R_STDVEC_MEMSIZE(buffer_indices, unsigned int); + m_statistics.indices_gpu_size += buffer.indices_count * sizeof(unsigned int); #endif // ENABLE_GCODE_VIEWER_STATISTICS - if (buffer.data_size > 0) { + if (buffer.indices_count > 0) { glsafe(::glGenBuffers(1, &buffer.ibo_id)); glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.ibo_id)); - glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, buffer.data_size * sizeof(unsigned int), buffer.data.data(), GL_STATIC_DRAW)); + glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, buffer.indices_count * sizeof(unsigned int), buffer_indices.data(), GL_STATIC_DRAW)); glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - - // indices data -> free ram - buffer.data = std::vector(); } } @@ -641,6 +659,10 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current) const // update current sequential position m_sequential_view.current = keep_sequential_current ? std::clamp(m_sequential_view.current, m_sequential_view.first, m_sequential_view.last) : m_sequential_view.last; + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vertices.vbo_id)); + size_t v_size = VBuffer::vertex_size_bytes(); + glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, static_cast(m_sequential_view.current * v_size), static_cast(v_size), static_cast(m_sequential_view.current_position.data()))); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); // second pass: filter paths by sequential data for (auto&& [buffer, id] : paths) { @@ -1097,7 +1119,7 @@ void GCodeViewer::render_legend() const ImGui::PopStyleVar(); } -void GCodeViewer::render_sequential_dlg() const +void GCodeViewer::render_sequential_bar() const { static const float MARGIN = 125.0f; static const float BUTTON_W = 50.0f; @@ -1181,6 +1203,9 @@ void GCodeViewer::render_sequential_dlg() const ImGui::SameLine(); imgui.text(std::to_string(i_max)); + ImGui::Separator(); + ImGui::Checkbox(I18N::translate_utf8(L("Show marker")).c_str(), &m_sequential_view.marker.visible); + imgui.end(); ImGui::PopStyleVar(); } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 3e73cb5d68..5354ae067f 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -74,18 +74,17 @@ class GCodeViewer { unsigned int ibo_id{ 0 }; Shader shader; - std::vector data; - size_t data_size{ 0 }; + size_t indices_count{ 0 }; std::vector paths; std::vector render_paths; bool visible{ false }; void reset(); bool init_shader(const std::string& vertex_shader_src, const std::string& fragment_shader_src); - void add_path(const GCodeProcessor::MoveVertex& move, unsigned int s_id); + void add_path(const GCodeProcessor::MoveVertex& move, unsigned int i_id, unsigned int s_id); }; - + // helper to render shells struct Shells { GLVolumeCollection volumes; @@ -148,9 +147,26 @@ class GCodeViewer struct SequentialView { + struct Marker + { + private: + bool m_initialized{ false }; + + public: + unsigned int vbo_id{ 0 }; + unsigned int ibo_id{ 0 }; + bool visible{ false }; + Shader shader; + + void init(); + void render() const; + }; + unsigned int first{ 0 }; unsigned int last{ 0 }; unsigned int current{ 0 }; + Vec3f current_position{ Vec3f::Zero() }; + Marker marker; }; #if ENABLE_GCODE_VIEWER_STATISTICS @@ -237,6 +253,7 @@ public: bool init() { set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Extrude, true); + m_sequential_view.marker.init(); return init_shaders(); } @@ -285,7 +302,7 @@ private: void render_toolpaths() const; void render_shells() const; void render_legend() const; - void render_sequential_dlg() const; + void render_sequential_bar() const; #if ENABLE_GCODE_VIEWER_STATISTICS void render_statistics() const; #endif // ENABLE_GCODE_VIEWER_STATISTICS From c29f0a4849a8ec10bbbb35bec72256565417e554 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 6 May 2020 15:17:53 +0200 Subject: [PATCH 060/255] GCodeViewer -> Increased size of wxCheckListBoxComboPopup --- src/slic3r/GUI/wxExtensions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 55468cde7b..7dadffb5b4 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -214,7 +214,7 @@ wxSize wxCheckListBoxComboPopup::GetAdjustedSize(int minWidth, int prefHeight, i max_width = std::max(max_width, 60 + GetTextExtent(GetString(i)).x); } size.SetWidth(max_width); - size.SetHeight(count * GetTextExtent(GetString(0)).y); + size.SetHeight(4 + count * (2 + GetTextExtent(GetString(0)).y)); } else size.SetHeight(DefaultHeight); From 5c6a56ca29d0faf38cf1f01e12d5da175cd1857e Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 7 May 2020 10:49:12 +0200 Subject: [PATCH 061/255] GCodeAnalyzer and GCodePreviewData removed from tech ENABLE_GCODE_VIEWER --- src/libslic3r/CustomGCode.cpp | 12 +- src/libslic3r/GCode.cpp | 128 +++++++++++++------- src/libslic3r/GCode.hpp | 37 +++++- src/libslic3r/GCode/Analyzer.cpp | 42 +------ src/libslic3r/GCode/Analyzer.hpp | 9 +- src/libslic3r/GCode/PreviewData.cpp | 4 + src/libslic3r/GCode/PreviewData.hpp | 4 + src/libslic3r/GCode/WipeTower.cpp | 25 ++-- src/libslic3r/Model.cpp | 2 + src/libslic3r/Print.cpp | 8 +- src/libslic3r/Print.hpp | 2 +- src/libslic3r/Technologies.hpp | 1 - src/slic3r/GUI/3DScene.cpp | 4 + src/slic3r/GUI/BackgroundSlicingProcess.cpp | 8 +- src/slic3r/GUI/BackgroundSlicingProcess.hpp | 17 +-- src/slic3r/GUI/DoubleSlider.cpp | 8 ++ src/slic3r/GUI/GCodeViewer.cpp | 5 +- src/slic3r/GUI/GLCanvas3D.cpp | 116 ++++++++++++++---- src/slic3r/GUI/GLCanvas3D.hpp | 2 + src/slic3r/GUI/GUI_Preview.cpp | 19 ++- src/slic3r/GUI/GUI_Preview.hpp | 4 +- src/slic3r/GUI/Plater.cpp | 10 +- 22 files changed, 311 insertions(+), 156 deletions(-) diff --git a/src/libslic3r/CustomGCode.cpp b/src/libslic3r/CustomGCode.cpp index 824bcdd93c..72c5c20de9 100644 --- a/src/libslic3r/CustomGCode.cpp +++ b/src/libslic3r/CustomGCode.cpp @@ -1,6 +1,10 @@ #include "CustomGCode.hpp" #include "Config.hpp" +#if ENABLE_GCODE_VIEWER +#include "GCode.hpp" +#else #include "GCode/PreviewData.hpp" +#endif // ENABLE_GCODE_VIEWER #include "GCodeWriter.hpp" namespace Slic3r { @@ -17,8 +21,12 @@ extern void update_custom_gcode_per_print_z_from_config(Info& info, DynamicPrint return; if (info.gcodes.empty() && ! colorprint_heights->values.empty()) { // Convert the old colorprint_heighs only if there is no equivalent data in a new format. - const std::vector& colors = GCodePreviewData::ColorPrintColors(); - const auto& colorprint_values = colorprint_heights->values; +#if ENABLE_GCODE_VIEWER + const std::vector& colors = ColorPrintColors::get(); +#else + const std::vector& colors = GCodePreviewData::ColorPrintColors(); +#endif // ENABLE_GCODE_VIEWER + const auto& colorprint_values = colorprint_heights->values; info.gcodes.clear(); info.gcodes.reserve(colorprint_values.size()); int i = 0; diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 10636082bb..584d1a1e3e 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -572,6 +572,10 @@ std::string WipeTowerIntegration::finalize(GCode &gcodegen) return gcode; } +#if ENABLE_GCODE_VIEWER +const std::vector ColorPrintColors::Colors = { "#C0392B", "#E67E22", "#F1C40F", "#27AE60", "#1ABC9C", "#2980B9", "#9B59B6" }; +#endif // ENABLE_GCODE_VIEWER + #define EXTRUDER_CONFIG(OPT) m_config.OPT.get_at(m_writer.extruder()->id()) // Collect pairs of object_layer + support_layer sorted by print_z. @@ -699,7 +703,7 @@ std::vector>> GCode::collec } #if ENABLE_GCODE_VIEWER -void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_data, GCodeProcessor::Result* result, ThumbnailsGeneratorCallback thumbnail_cb) +void GCode::do_export(Print* print, const char* path, GCodeProcessor::Result* result, ThumbnailsGeneratorCallback thumbnail_cb) #else void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_data, ThumbnailsGeneratorCallback thumbnail_cb) #endif // ENABLE_GCODE_VIEWER @@ -724,7 +728,9 @@ void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_ if (file == nullptr) throw std::runtime_error(std::string("G-code export to ") + path + " failed.\nCannot open the file for writing.\n"); +#if !ENABLE_GCODE_VIEWER m_enable_analyzer = preview_data != nullptr; +#endif // !ENABLE_GCODE_VIEWER try { m_placeholder_parser_failed_templates.clear(); @@ -778,16 +784,14 @@ void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_ m_silent_time_estimator.reset(); } +#if !ENABLE_GCODE_VIEWER // starts analyzer calculations if (m_enable_analyzer) { -#if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT - m_analyzer.close_debug_output_file(); -#endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT - BOOST_LOG_TRIVIAL(debug) << "Preparing G-code preview data" << log_memory_info(); m_analyzer.calc_gcode_preview_data(*preview_data, [print]() { print->throw_if_canceled(); }); m_analyzer.reset(); } +#endif // !ENABLE_GCODE_VIEWER if (rename_file(path_tmp, path)) throw std::runtime_error( @@ -877,7 +881,14 @@ namespace DoExport { } } - static void init_gcode_analyzer(const PrintConfig &config, GCodeAnalyzer &analyzer) +#if ENABLE_GCODE_VIEWER + static void init_gcode_processor(const PrintConfig& config, GCodeProcessor& processor) + { + processor.reset(); + processor.apply_config(config); + } +#else + static void init_gcode_analyzer(const PrintConfig &config, GCodeAnalyzer &analyzer) { // resets analyzer analyzer.reset(); @@ -901,17 +912,6 @@ namespace DoExport { // tell analyzer about the gcode flavor analyzer.set_gcode_flavor(config.gcode_flavor); - -#if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT - analyzer.open_debug_output_file(); -#endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT - } - -#if ENABLE_GCODE_VIEWER - static void init_gcode_processor(const PrintConfig& config, GCodeProcessor& processor) - { - processor.reset(); - processor.apply_config(config); } #endif // ENABLE_GCODE_VIEWER @@ -1145,15 +1145,22 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu DoExport::init_time_estimators(print.config(), // modifies the following: m_normal_time_estimator, m_silent_time_estimator, m_silent_time_estimator_enabled); - DoExport::init_gcode_analyzer(print.config(), m_analyzer); #if ENABLE_GCODE_VIEWER DoExport::init_gcode_processor(print.config(), m_processor); +#else + DoExport::init_gcode_analyzer(print.config(), m_analyzer); #endif // ENABLE_GCODE_VIEWER // resets analyzer's tracking data +#if ENABLE_GCODE_VIEWER + m_last_mm3_per_mm = 0.0f; + m_last_width = 0.0f; + m_last_height = 0.0f; +#else m_last_mm3_per_mm = GCodeAnalyzer::Default_mm3_per_mm; m_last_width = GCodeAnalyzer::Default_Width; m_last_height = GCodeAnalyzer::Default_Height; +#endif // ENABLE_GCODE_VIEWER // How many times will be change_layer() called? // change_layer() in turn increments the progress bar status. @@ -1333,13 +1340,13 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu // Set extruder(s) temperature before and after start G-code. this->_print_first_layer_extruder_temperatures(file, print, start_gcode, initial_extruder_id, false); - if (m_enable_analyzer) - // adds tag for analyzer - _write_format(file, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), erCustom); - #if ENABLE_GCODE_VIEWER // adds tag for processor _write_format(file, ";%s%d\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), erCustom); +#else + if (m_enable_analyzer) + // adds tag for analyzer + _write_format(file, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), erCustom); #endif // ENABLE_GCODE_VIEWER // Write the custom start G-code @@ -1491,13 +1498,13 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu _write(file, this->retract()); _write(file, m_writer.set_fan(false)); - if (m_enable_analyzer) - // adds tag for analyzer - _write_format(file, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), erCustom); - #if ENABLE_GCODE_VIEWER // adds tag for processor _write_format(file, ";%s%d\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), erCustom); +#else + if (m_enable_analyzer) + // adds tag for analyzer + _write_format(file, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), erCustom); #endif // ENABLE_GCODE_VIEWER // Process filament-specific gcode in extruder order. @@ -1821,11 +1828,12 @@ namespace ProcessLayer { assert(m600_extruder_before_layer >= 0); // Color Change or Tool Change as Color Change. - // add tag for analyzer - gcode += "; " + GCodeAnalyzer::Color_Change_Tag + ",T" + std::to_string(m600_extruder_before_layer) + "\n"; #if ENABLE_GCODE_VIEWER // add tag for processor gcode += "; " + GCodeProcessor::Color_Change_Tag + ",T" + std::to_string(m600_extruder_before_layer) + "\n"; +#else + // add tag for analyzer + gcode += "; " + GCodeAnalyzer::Color_Change_Tag + ",T" + std::to_string(m600_extruder_before_layer) + "\n"; #endif // ENABLE_GCODE_VIEWER // add tag for time estimator gcode += "; " + GCodeTimeEstimator::Color_Change_Tag + "\n"; @@ -1846,11 +1854,12 @@ namespace ProcessLayer { if (custom_code == PausePrintCode) // Pause print { - // add tag for analyzer - gcode += "; " + GCodeAnalyzer::Pause_Print_Tag + "\n"; #if ENABLE_GCODE_VIEWER // add tag for processor gcode += "; " + GCodeProcessor::Pause_Print_Tag + "\n"; +#else + // add tag for analyzer + gcode += "; " + GCodeAnalyzer::Pause_Print_Tag + "\n"; #endif // ENABLE_GCODE_VIEWER //! FIXME_in_fw show message during print pause if (!pause_print_msg.empty()) @@ -1860,11 +1869,12 @@ namespace ProcessLayer } else // custom Gcode { - // add tag for analyzer - gcode += "; " + GCodeAnalyzer::Custom_Code_Tag + "\n"; #if ENABLE_GCODE_VIEWER // add tag for processor gcode += "; " + GCodeProcessor::Custom_Code_Tag + "\n"; +#else + // add tag for analyzer + gcode += "; " + GCodeAnalyzer::Custom_Code_Tag + "\n"; #endif // ENABLE_GCODE_VIEWER // add tag for time estimator //gcode += "; " + GCodeTimeEstimator::Custom_Code_Tag + "\n"; @@ -2218,9 +2228,15 @@ void GCode::process_layer( m_wipe_tower->tool_change(*this, extruder_id, extruder_id == layer_tools.extruders.back()) : this->set_extruder(extruder_id, print_z); +#if ENABLE_GCODE_VIEWER + // let analyzer tag generator aware of a role type change + if (layer_tools.has_wipe_tower && m_wipe_tower) + m_last_processor_extrusion_role = erWipeTower; +#else // let analyzer tag generator aware of a role type change if (m_enable_analyzer && layer_tools.has_wipe_tower && m_wipe_tower) m_last_analyzer_extrusion_role = erWipeTower; +#endif // ENABLE_GCODE_VIEWER if (auto loops_it = skirt_loops_per_extruder.find(extruder_id); loops_it != skirt_loops_per_extruder.end()) { const std::pair loops = loops_it->second; @@ -2324,11 +2340,13 @@ void GCode::process_layer( if (m_cooling_buffer) gcode = m_cooling_buffer->process_layer(gcode, layer.id()); +#if !ENABLE_GCODE_VIEWER // add tag for analyzer if (gcode.find(GCodeAnalyzer::Pause_Print_Tag) != gcode.npos) gcode += "\n; " + GCodeAnalyzer::End_Pause_Print_Or_Custom_Code_Tag + "\n"; else if (gcode.find(GCodeAnalyzer::Custom_Code_Tag) != gcode.npos) gcode += "\n; " + GCodeAnalyzer::End_Pause_Print_Or_Custom_Code_Tag + "\n"; +#endif // !ENABLE_GCODE_VIEWER #ifdef HAS_PRESSURE_EQUALIZER // Apply pressure equalization if enabled; @@ -2342,9 +2360,11 @@ void GCode::process_layer( BOOST_LOG_TRIVIAL(trace) << "Exported layer " << layer.id() << " print_z " << print_z << ", time estimator memory: " << format_memsize_MB(m_normal_time_estimator.memory_used() + (m_silent_time_estimator_enabled ? m_silent_time_estimator.memory_used() : 0)) << - ", analyzer memory: " << +#if !ENABLE_GCODE_VIEWER + ", analyzer memory: " << format_memsize_MB(m_analyzer.memory_used()) << - log_memory_info(); +#endif // !ENABLE_GCODE_VIEWER + log_memory_info(); } void GCode::apply_print_config(const PrintConfig &print_config) @@ -2984,8 +3004,12 @@ std::string GCode::extrude_support(const ExtrusionEntityCollection &support_fill void GCode::_write(FILE* file, const char *what) { if (what != nullptr) { +#if ENABLE_GCODE_VIEWER + const char* gcode = what; +#else // apply analyzer, if enabled const char* gcode = m_enable_analyzer ? m_analyzer.process_gcode(what).c_str() : what; +#endif // !ENABLE_GCODE_VIEWER // writes string to file fwrite(gcode, 1, ::strlen(gcode), file); @@ -3132,57 +3156,73 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } // adds analyzer tags and updates analyzer's tracking data +#if !ENABLE_GCODE_VIEWER if (m_enable_analyzer) { +#endif // !ENABLE_GCODE_VIEWER // PrusaMultiMaterial::Writer may generate GCodeAnalyzer::Height_Tag and GCodeAnalyzer::Width_Tag lines without updating m_last_height and m_last_width // so, if the last role was erWipeTower we force export of GCodeAnalyzer::Height_Tag and GCodeAnalyzer::Width_Tag lines +#if ENABLE_GCODE_VIEWER + bool last_was_wipe_tower = (m_last_processor_extrusion_role == erWipeTower); +#else bool last_was_wipe_tower = (m_last_analyzer_extrusion_role == erWipeTower); +#endif // ENABLE_GCODE_VIEWER char buf[64]; +#if ENABLE_GCODE_VIEWER + if (path.role() != m_last_processor_extrusion_role) + { + m_last_processor_extrusion_role = path.role(); + sprintf(buf, ";%s%d\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), int(m_last_processor_extrusion_role)); + gcode += buf; + } +#else if (path.role() != m_last_analyzer_extrusion_role) { m_last_analyzer_extrusion_role = path.role(); sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), int(m_last_analyzer_extrusion_role)); -#if ENABLE_GCODE_VIEWER - gcode += buf; - sprintf(buf, ";%s%d\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), int(m_last_analyzer_extrusion_role)); -#endif // ENABLE_GCODE_VIEWER gcode += buf; } +#endif // ENABLE_GCODE_VIEWER if (last_was_wipe_tower || (m_last_mm3_per_mm != path.mm3_per_mm)) { m_last_mm3_per_mm = path.mm3_per_mm; - sprintf(buf, ";%s%f\n", GCodeAnalyzer::Mm3_Per_Mm_Tag.c_str(), m_last_mm3_per_mm); - gcode += buf; #if ENABLE_GCODE_VIEWER sprintf(buf, ";%s%f\n", GCodeProcessor::Mm3_Per_Mm_Tag.c_str(), m_last_mm3_per_mm); gcode += buf; +#else + sprintf(buf, ";%s%f\n", GCodeAnalyzer::Mm3_Per_Mm_Tag.c_str(), m_last_mm3_per_mm); + gcode += buf; #endif // ENABLE_GCODE_VIEWER } if (last_was_wipe_tower || (m_last_width != path.width)) { m_last_width = path.width; - sprintf(buf, ";%s%f\n", GCodeAnalyzer::Width_Tag.c_str(), m_last_width); - gcode += buf; #if ENABLE_GCODE_VIEWER sprintf(buf, ";%s%f\n", GCodeProcessor::Width_Tag.c_str(), m_last_width); gcode += buf; +#else + sprintf(buf, ";%s%f\n", GCodeAnalyzer::Width_Tag.c_str(), m_last_width); + gcode += buf; #endif // ENABLE_GCODE_VIEWER } if (last_was_wipe_tower || (m_last_height != path.height)) { m_last_height = path.height; - sprintf(buf, ";%s%f\n", GCodeAnalyzer::Height_Tag.c_str(), m_last_height); - gcode += buf; #if ENABLE_GCODE_VIEWER sprintf(buf, ";%s%f\n", GCodeProcessor::Height_Tag.c_str(), m_last_height); gcode += buf; +#else + sprintf(buf, ";%s%f\n", GCodeAnalyzer::Height_Tag.c_str(), m_last_height); + gcode += buf; #endif // ENABLE_GCODE_VIEWER } +#if !ENABLE_GCODE_VIEWER } +#endif // !ENABLE_GCODE_VIEWER std::string comment; if (m_enable_cooling_markers) { diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index f6668ad3d6..546c425755 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -16,10 +16,11 @@ #include "GCode/WipeTower.hpp" #if ENABLE_GCODE_VIEWER #include "GCode/GCodeProcessor.hpp" +#else +#include "GCode/Analyzer.hpp" #endif // ENABLE_GCODE_VIEWER #include "GCodeTimeEstimator.hpp" #include "EdgeGrid.hpp" -#include "GCode/Analyzer.hpp" #include "GCode/ThumbnailData.hpp" #include @@ -33,7 +34,9 @@ namespace Slic3r { // Forward declarations. class GCode; +#if !ENABLE_GCODE_VIEWER class GCodePreviewData; +#endif // !ENABLE_GCODE_VIEWER class AvoidCrossingPerimeters { public: @@ -138,6 +141,15 @@ private: double m_last_wipe_tower_print_z = 0.f; }; +#if ENABLE_GCODE_VIEWER +class ColorPrintColors +{ + static const std::vector Colors; +public: + static const std::vector& get() { return Colors; } +}; +#endif // ENABLE_GCODE_VIEWER + class GCode { public: GCode() : @@ -145,17 +157,27 @@ public: m_enable_loop_clipping(true), m_enable_cooling_markers(false), m_enable_extrusion_role_markers(false), +#if ENABLE_GCODE_VIEWER + m_last_processor_extrusion_role(erNone), +#else m_enable_analyzer(false), m_last_analyzer_extrusion_role(erNone), +#endif // ENABLE_GCODE_VIEWER m_layer_count(0), m_layer_index(-1), m_layer(nullptr), m_volumetric_speed(0), m_last_pos_defined(false), m_last_extrusion_role(erNone), +#if ENABLE_GCODE_VIEWER + m_last_mm3_per_mm(0.0f), + m_last_width(0.0f), + m_last_height(0.0f), +#else m_last_mm3_per_mm(GCodeAnalyzer::Default_mm3_per_mm), m_last_width(GCodeAnalyzer::Default_Width), m_last_height(GCodeAnalyzer::Default_Height), +#endif // ENABLE_GCODE_VIEWER m_brim_done(false), m_second_layer_things_done(false), m_normal_time_estimator(GCodeTimeEstimator::Normal), @@ -168,7 +190,7 @@ public: // throws std::runtime_exception on error, // throws CanceledException through print->throw_if_canceled(). #if ENABLE_GCODE_VIEWER - void do_export(Print* print, const char* path, GCodePreviewData* preview_data = nullptr, GCodeProcessor::Result* result = nullptr, ThumbnailsGeneratorCallback thumbnail_cb = nullptr); + void do_export(Print* print, const char* path, GCodeProcessor::Result* result = nullptr, ThumbnailsGeneratorCallback thumbnail_cb = nullptr); #else void do_export(Print* print, const char* path, GCodePreviewData* preview_data = nullptr, ThumbnailsGeneratorCallback thumbnail_cb = nullptr); #endif // ENABLE_GCODE_VIEWER @@ -331,11 +353,16 @@ private: // Markers for the Pressure Equalizer to recognize the extrusion type. // The Pressure Equalizer removes the markers from the final G-code. bool m_enable_extrusion_role_markers; +#if ENABLE_GCODE_VIEWER + // Keeps track of the last extrusion role passed to the processor + ExtrusionRole m_last_processor_extrusion_role; +#else // Enableds the G-code Analyzer. // Extended markers will be added during G-code generation. // The G-code Analyzer will remove these comments from the final G-code. bool m_enable_analyzer; ExtrusionRole m_last_analyzer_extrusion_role; +#endif // ENABLE_GCODE_VIEWER // How many times will change_layer() be called? // change_layer() will update the progress bar. unsigned int m_layer_count; @@ -377,12 +404,12 @@ private: GCodeTimeEstimator m_silent_time_estimator; bool m_silent_time_estimator_enabled; - // Analyzer - GCodeAnalyzer m_analyzer; - #if ENABLE_GCODE_VIEWER // Processor GCodeProcessor m_processor; +#else + // Analyzer + GCodeAnalyzer m_analyzer; #endif // ENABLE_GCODE_VIEWER // Write a string into a file. diff --git a/src/libslic3r/GCode/Analyzer.cpp b/src/libslic3r/GCode/Analyzer.cpp index 974176dbd7..d022b37983 100644 --- a/src/libslic3r/GCode/Analyzer.cpp +++ b/src/libslic3r/GCode/Analyzer.cpp @@ -8,19 +8,11 @@ #include "Print.hpp" #include -#if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT -#include -#endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT #include "Analyzer.hpp" #include "PreviewData.hpp" -#if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT -#include - -// don't worry, this is just temporary -static boost::nowide::ofstream g_debug_output; -#endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT +#if !ENABLE_GCODE_VIEWER static const std::string AXIS_STR = "XYZE"; static const float MMMIN_TO_MMSEC = 1.0f / 60.0f; @@ -184,19 +176,6 @@ bool GCodeAnalyzer::is_valid_extrusion_role(ExtrusionRole role) return ((erPerimeter <= role) && (role < erMixed)); } -#if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT -void GCodeAnalyzer::open_debug_output_file() -{ - boost::filesystem::path path("d:/analyzer.output"); - g_debug_output.open(path.string()); -} - -void GCodeAnalyzer::close_debug_output_file() -{ - g_debug_output.close(); -} -#endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT - void GCodeAnalyzer::_process_gcode_line(GCodeReader&, const GCodeReader::GCodeLine& line) { // processes 'special' comments contained in line @@ -945,23 +924,6 @@ void GCodeAnalyzer::_store_move(GCodeAnalyzer::GCodeMove::EType type) Vec3f start_position = _get_start_position() + extruder_offset; Vec3f end_position = _get_end_position() + extruder_offset; it->second.emplace_back(type, _get_extrusion_role(), extruder_id, _get_mm3_per_mm(), _get_width(), _get_height(), _get_feedrate(), start_position, end_position, _get_delta_extrusion(), _get_fan_speed(), _get_cp_color_id()); - -#if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT - if (g_debug_output.good()) - { - g_debug_output << std::to_string(static_cast(type)); - g_debug_output << ", " << std::to_string(static_cast(_get_extrusion_role())); - g_debug_output << ", " << Slic3r::to_string(static_cast(end_position.cast())); - g_debug_output << ", " << std::to_string(extruder_id); - g_debug_output << ", " << std::to_string(_get_cp_color_id()); - g_debug_output << ", " << std::to_string(_get_feedrate()); - g_debug_output << ", " << std::to_string(_get_width()); - g_debug_output << ", " << std::to_string(_get_height()); - g_debug_output << ", " << std::to_string(_get_mm3_per_mm()); - g_debug_output << ", " << std::to_string(_get_fan_speed()); - g_debug_output << "\n"; - } -#endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT } bool GCodeAnalyzer::_is_valid_extrusion_role(int value) const @@ -1231,3 +1193,5 @@ size_t GCodeAnalyzer::memory_used() const } } // namespace Slic3r + +#endif // !ENABLE_GCODE_VIEWER diff --git a/src/libslic3r/GCode/Analyzer.hpp b/src/libslic3r/GCode/Analyzer.hpp index 9d16ab4944..37d9072592 100644 --- a/src/libslic3r/GCode/Analyzer.hpp +++ b/src/libslic3r/GCode/Analyzer.hpp @@ -1,6 +1,8 @@ #ifndef slic3r_GCode_Analyzer_hpp_ #define slic3r_GCode_Analyzer_hpp_ +#if !ENABLE_GCODE_VIEWER + #include "../libslic3r.h" #include "../PrintConfig.hpp" #include "../ExtrusionEntity.hpp" @@ -147,11 +149,6 @@ public: static bool is_valid_extrusion_role(ExtrusionRole role); -#if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT - void open_debug_output_file(); - void close_debug_output_file(); -#endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT - private: // Processes the given gcode line void _process_gcode_line(GCodeReader& reader, const GCodeReader::GCodeLine& line); @@ -307,4 +304,6 @@ private: } // namespace Slic3r +#endif // !ENABLE_GCODE_VIEWER + #endif /* slic3r_GCode_Analyzer_hpp_ */ diff --git a/src/libslic3r/GCode/PreviewData.cpp b/src/libslic3r/GCode/PreviewData.cpp index 3aae15748d..58b15e9a46 100644 --- a/src/libslic3r/GCode/PreviewData.cpp +++ b/src/libslic3r/GCode/PreviewData.cpp @@ -5,6 +5,8 @@ #include +#if !ENABLE_GCODE_VIEWER + //! macro used to mark string used at localization, #define L(s) (s) @@ -515,3 +517,5 @@ Color operator * (float f, const Color& color) } } // namespace Slic3r + +#endif // !ENABLE_GCODE_VIEWER diff --git a/src/libslic3r/GCode/PreviewData.hpp b/src/libslic3r/GCode/PreviewData.hpp index c0f768088e..930c1659e3 100644 --- a/src/libslic3r/GCode/PreviewData.hpp +++ b/src/libslic3r/GCode/PreviewData.hpp @@ -1,6 +1,8 @@ #ifndef slic3r_GCode_PreviewData_hpp_ #define slic3r_GCode_PreviewData_hpp_ +#if !ENABLE_GCODE_VIEWER + #include "../libslic3r.h" #include "../ExtrusionEntity.hpp" #include "../Point.hpp" @@ -391,4 +393,6 @@ public: } // namespace Slic3r +#endif // !ENABLE_GCODE_VIEWER + #endif /* slic3r_GCode_PreviewData_hpp_ */ diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index d5d060f773..3b5c2a1599 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -21,9 +21,10 @@ TODO LIST #include #include -#include "Analyzer.hpp" #if ENABLE_GCODE_VIEWER #include "GCodeProcessor.hpp" +#else +#include "Analyzer.hpp" #endif // ENABLE_GCODE_VIEWER #include "BoundingBox.hpp" @@ -56,16 +57,16 @@ public: { // adds tag for analyzer: char buf[64]; - sprintf(buf, ";%s%f\n", GCodeAnalyzer::Height_Tag.c_str(), m_layer_height); // don't rely on GCodeAnalyzer knowing the layer height - it knows nothing at priming - m_gcode += buf; #if ENABLE_GCODE_VIEWER sprintf(buf, ";%s%f\n", GCodeProcessor::Height_Tag.c_str(), m_layer_height); // don't rely on GCodeAnalyzer knowing the layer height - it knows nothing at priming - m_gcode += buf; +#else + sprintf(buf, ";%s%f\n", GCodeAnalyzer::Height_Tag.c_str(), m_layer_height); // don't rely on GCodeAnalyzer knowing the layer height - it knows nothing at priming #endif // ENABLE_GCODE_VIEWER - sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), erWipeTower); -#if ENABLE_GCODE_VIEWER m_gcode += buf; +#if ENABLE_GCODE_VIEWER sprintf(buf, ";%s%d\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), erWipeTower); +#else + sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), erWipeTower); #endif // ENABLE_GCODE_VIEWER m_gcode += buf; change_analyzer_line_width(line_width); @@ -74,12 +75,12 @@ public: WipeTowerWriter& change_analyzer_line_width(float line_width) { // adds tag for analyzer: char buf[64]; - sprintf(buf, ";%s%f\n", GCodeAnalyzer::Width_Tag.c_str(), line_width); - m_gcode += buf; #if ENABLE_GCODE_VIEWER sprintf(buf, ";%s%f\n", GCodeProcessor::Width_Tag.c_str(), line_width); - m_gcode += buf; +#else + sprintf(buf, ";%s%f\n", GCodeAnalyzer::Width_Tag.c_str(), line_width); #endif // ENABLE_GCODE_VIEWER + m_gcode += buf; return *this; } @@ -88,12 +89,12 @@ public: float mm3_per_mm = (len == 0.f ? 0.f : area * e / len); // adds tag for analyzer: char buf[64]; - sprintf(buf, ";%s%f\n", GCodeAnalyzer::Mm3_Per_Mm_Tag.c_str(), mm3_per_mm); - m_gcode += buf; #if ENABLE_GCODE_VIEWER sprintf(buf, ";%s%f\n", GCodeProcessor::Mm3_Per_Mm_Tag.c_str(), mm3_per_mm); - m_gcode += buf; +#else + sprintf(buf, ";%s%f\n", GCodeAnalyzer::Mm3_Per_Mm_Tag.c_str(), mm3_per_mm); #endif // ENABLE_GCODE_VIEWER + m_gcode += buf; return *this; } diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 98f595d91e..90c9d03571 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -20,7 +20,9 @@ #include "SVG.hpp" #include #include "GCodeWriter.hpp" +#if !ENABLE_GCODE_VIEWER #include "GCode/PreviewData.hpp" +#endif // !ENABLE_GCODE_VIEWER namespace Slic3r { diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 6bc0494127..0ffb5472c6 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1628,7 +1628,7 @@ void Print::process() // write error into the G-code, cannot execute post-processing scripts). // It is up to the caller to show an error message. #if ENABLE_GCODE_VIEWER -std::string Print::export_gcode(const std::string& path_template, GCodePreviewData* preview_data, GCodeProcessor::Result* result, ThumbnailsGeneratorCallback thumbnail_cb) +std::string Print::export_gcode(const std::string& path_template, GCodeProcessor::Result* result, ThumbnailsGeneratorCallback thumbnail_cb) #else std::string Print::export_gcode(const std::string& path_template, GCodePreviewData* preview_data, ThumbnailsGeneratorCallback thumbnail_cb) #endif // ENABLE_GCODE_VIEWER @@ -1637,7 +1637,11 @@ std::string Print::export_gcode(const std::string& path_template, GCodePreviewDa // The following call may die if the output_filename_format template substitution fails. std::string path = this->output_filepath(path_template); std::string message; +#if ENABLE_GCODE_VIEWER + if (!path.empty() && result == nullptr) { +#else if (! path.empty() && preview_data == nullptr) { +#endif // ENABLE_GCODE_VIEWER // Only show the path if preview_data is not set -> running from command line. message = L("Exporting G-code"); message += " to "; @@ -1649,7 +1653,7 @@ std::string Print::export_gcode(const std::string& path_template, GCodePreviewDa // The following line may die for multiple reasons. GCode gcode; #if ENABLE_GCODE_VIEWER - gcode.do_export(this, path.c_str(), preview_data, result, thumbnail_cb); + gcode.do_export(this, path.c_str(), result, thumbnail_cb); #else gcode.do_export(this, path.c_str(), preview_data, thumbnail_cb); #endif // ENABLE_GCODE_VIEWER diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 9ae0f13945..c358cd9184 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -372,7 +372,7 @@ public: // Exports G-code into a file name based on the path_template, returns the file path of the generated G-code file. // If preview_data is not null, the preview_data is filled in for the G-code visualization (not used by the command line Slic3r). #if ENABLE_GCODE_VIEWER - std::string export_gcode(const std::string& path_template, GCodePreviewData* preview_data, GCodeProcessor::Result* result, ThumbnailsGeneratorCallback thumbnail_cb = nullptr); + std::string export_gcode(const std::string& path_template, GCodeProcessor::Result* result, ThumbnailsGeneratorCallback thumbnail_cb = nullptr); #else std::string export_gcode(const std::string& path_template, GCodePreviewData* preview_data, ThumbnailsGeneratorCallback thumbnail_cb = nullptr); #endif // ENABLE_GCODE_VIEWER diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index a648bb244b..c22e504dff 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -55,7 +55,6 @@ // Enable G-Code viewer #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) -#define ENABLE_GCODE_VIEWER_DEBUG_OUTPUT (0 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index ca2f0389da..6aaf0b500e 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -5,11 +5,15 @@ #include "libslic3r/ExtrusionEntity.hpp" #include "libslic3r/ExtrusionEntityCollection.hpp" #include "libslic3r/Geometry.hpp" +#if !ENABLE_GCODE_VIEWER #include "libslic3r/GCode/PreviewData.hpp" +#endif // !ENABLE_GCODE_VIEWER #include "libslic3r/Print.hpp" #include "libslic3r/SLAPrint.hpp" #include "libslic3r/Slicing.hpp" +#if !ENABLE_GCODE_VIEWER #include "libslic3r/GCode/Analyzer.hpp" +#endif // !ENABLE_GCODE_VIEWER #include "slic3r/GUI/BitmapCache.hpp" #include "libslic3r/Format/STL.hpp" #include "libslic3r/Utils.hpp" diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index c8c344caaf..32b7b83653 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -18,7 +18,9 @@ #include "libslic3r/SLAPrint.hpp" #include "libslic3r/Utils.hpp" #include "libslic3r/GCode/PostProcessor.hpp" +#if !ENABLE_GCODE_VIEWER #include "libslic3r/GCode/PreviewData.hpp" +#endif // !ENABLE_GCODE_VIEWER #include "libslic3r/Format/SL1.hpp" #include "libslic3r/libslic3r.h" @@ -89,7 +91,7 @@ void BackgroundSlicingProcess::process_fff() m_print->process(); wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, new wxCommandEvent(m_event_slicing_completed_id)); #if ENABLE_GCODE_VIEWER - m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data, m_gcode_result, m_thumbnail_cb); + m_fff_print->export_gcode(m_temp_output_path, m_gcode_result, m_thumbnail_cb); #else m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data, m_thumbnail_cb); #endif // ENABLE_GCODE_VIEWER @@ -385,9 +387,7 @@ Print::ApplyStatus BackgroundSlicingProcess::apply(const Model &model, const Dyn // Some FFF status was invalidated, and the G-code was not exported yet. // Let the G-code preview UI know that the final G-code preview is not valid. // In addition, this early memory deallocation reduces memory footprint. - if (m_gcode_preview_data != nullptr) - m_gcode_preview_data->reset(); - else if (m_gcode_result != nullptr) + if (m_gcode_result != nullptr) m_gcode_result->reset(); } #else diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.hpp b/src/slic3r/GUI/BackgroundSlicingProcess.hpp index d3fca88fc4..91ebc1372c 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.hpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.hpp @@ -50,10 +50,11 @@ public: void set_fff_print(Print *print) { m_fff_print = print; } void set_sla_print(SLAPrint *print) { m_sla_print = print; m_sla_print->set_printer(&m_sla_archive); } - void set_gcode_preview_data(GCodePreviewData *gpd) { m_gcode_preview_data = gpd; } - void set_thumbnail_cb(ThumbnailsGeneratorCallback cb) { m_thumbnail_cb = cb; } + void set_thumbnail_cb(ThumbnailsGeneratorCallback cb) { m_thumbnail_cb = cb; } #if ENABLE_GCODE_VIEWER void set_gcode_result(GCodeProcessor::Result* result) { m_gcode_result = result; } +#else + void set_gcode_preview_data(GCodePreviewData* gpd) { m_gcode_preview_data = gpd; } #endif // ENABLE_GCODE_VIEWER // The following wxCommandEvent will be sent to the UI thread / Plater window, when the slicing is finished @@ -156,15 +157,17 @@ private: // Non-owned pointers to Print instances. Print *m_fff_print = nullptr; SLAPrint *m_sla_print = nullptr; +#if ENABLE_GCODE_VIEWER + // Data structure, to which the G-code export writes its annotations. + GCodeProcessor::Result *m_gcode_result = nullptr; +#else // Data structure, to which the G-code export writes its annotations. GCodePreviewData *m_gcode_preview_data = nullptr; - // Callback function, used to write thumbnails into gcode. +#endif // ENABLE_GCODE_VIEWER + // Callback function, used to write thumbnails into gcode. ThumbnailsGeneratorCallback m_thumbnail_cb = nullptr; SL1Archive m_sla_archive; -#if ENABLE_GCODE_VIEWER - GCodeProcessor::Result* m_gcode_result = nullptr; -#endif // ENABLE_GCODE_VIEWER - // Temporary G-code, there is one defined for the BackgroundSlicingProcess, differentiated from the other processes by a process ID. + // Temporary G-code, there is one defined for the BackgroundSlicingProcess, differentiated from the other processes by a process ID. std::string m_temp_output_path; // Output path provided by the user. The output path may be set even if the slicing is running, // but once set, it cannot be re-set. diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index 4c4c1aa8dd..0a89333714 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -1,5 +1,9 @@ #include "wxExtensions.hpp" +#if ENABLE_GCODE_VIEWER +#include "libslic3r/GCode.hpp" +#else #include "libslic3r/GCode/PreviewData.hpp" +#endif // ENABLE_GCODE_VIEWER #include "GUI.hpp" #include "GUI_App.hpp" #include "I18N.hpp" @@ -1945,7 +1949,11 @@ std::string TickCodeInfo::get_color_for_tick(TickCode tick, const std::string& c { if (mode == t_mode::SingleExtruder && code == ColorChangeCode && m_use_default_colors) { +#if ENABLE_GCODE_VIEWER + const std::vector& colors = ColorPrintColors::get(); +#else const std::vector& colors = GCodePreviewData::ColorPrintColors(); +#endif // ENABLE_GCODE_VIEWER if (ticks.empty()) return colors[0]; m_default_color_idx++; diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index d4cd840884..0893a7d465 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -167,7 +167,7 @@ const std::vector GCodeViewer::Extrusion_Role_Colors{ { { 0.69f, 0.19f, 0.16f }, // erInternalInfill { 0.84f, 0.20f, 0.84f }, // erSolidInfill { 1.00f, 0.10f, 0.10f }, // erTopSolidInfill - { 0.00f, 1.00f, 1.00f }, // erIroning + { 1.00f, 0.55f, 0.41f }, // erIroning { 0.60f, 0.60f, 1.00f }, // erBridgeInfill { 1.00f, 1.00f, 1.00f }, // erGapFill { 0.52f, 0.48f, 0.13f }, // erSkirt @@ -404,7 +404,8 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) std::vector vertices_data(m_vertices.vertices_count * 3); for (size_t i = 0; i < m_vertices.vertices_count; ++i) { const GCodeProcessor::MoveVertex& move = gcode_result.moves[i]; - m_bounding_box.merge(move.position.cast()); + if (move.type == GCodeProcessor::EMoveType::Extrude) + m_bounding_box.merge(move.position.cast()); ::memcpy(static_cast(&vertices_data[i * 3]), static_cast(move.position.data()), 3 * sizeof(float)); } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 8859a07463..8be8f8b378 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -5,7 +5,9 @@ #include "polypartition.h" #include "libslic3r/ClipperUtils.hpp" #include "libslic3r/PrintConfig.hpp" +#if !ENABLE_GCODE_VIEWER #include "libslic3r/GCode/PreviewData.hpp" +#endif // !ENABLE_GCODE_VIEWER #include "libslic3r/GCode/ThumbnailData.hpp" #include "libslic3r/Geometry.hpp" #include "libslic3r/ExtrusionEntity.hpp" @@ -56,10 +58,6 @@ #include #include -#if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT -#include -#endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT - #include #include #include @@ -2747,22 +2745,8 @@ static void load_gcode_retractions(const GCodePreviewData::Retraction& retractio #if ENABLE_GCODE_VIEWER void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result) { -#if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT - static unsigned int last_result_id = 0; - if (last_result_id != gcode_result.id) - { - last_result_id = gcode_result.id; - boost::filesystem::path path("d:/processor.output"); - boost::nowide::ofstream out; - out.open(path.string()); - for (const GCodeProcessor::MoveVertex& v : gcode_result.moves) - { - out << v.to_string() << "\n"; - } - out.close(); - } -#endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT m_gcode_viewer.load(gcode_result, *this->fff_print(), m_initialized); + _show_warning_texture_if_needed(WarningTexture::ToolpathOutside); } void GLCanvas3D::refresh_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors) @@ -2771,9 +2755,7 @@ void GLCanvas3D::refresh_gcode_preview(const GCodeProcessor::Result& gcode_resul set_as_dirty(); request_extra_frame(); } -#endif // ENABLE_GCODE_VIEWER - -#if !ENABLE_GCODE_VIEWER +#else void GLCanvas3D::load_gcode_preview(const GCodePreviewData& preview_data, const std::vector& str_tool_colors) { const Print *print = this->fff_print(); @@ -2842,7 +2824,7 @@ void GLCanvas3D::load_gcode_preview(const GCodePreviewData& preview_data, const _generate_legend_texture(preview_data, tool_colors); } } -#endif // !ENABLE_GCODE_VIEWER +#endif // ENABLE_GCODE_VIEWER void GLCanvas3D::load_sla_preview() { @@ -3144,7 +3126,24 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) } #endif // ENABLE_RENDER_PICKING_PASS case 'Z': +#if ENABLE_GCODE_VIEWER + case 'z': + { + if (!m_selection.is_empty()) + zoom_to_selection(); + else + { + if (!m_volumes.empty()) + zoom_to_volumes(); + else + _zoom_to_box(m_gcode_viewer.get_bounding_box()); + } + + break; + } +#else case 'z': { m_selection.is_empty() ? zoom_to_volumes() : zoom_to_selection(); break; } +#endif // ENABLE_GCODE_VIEWER default: { evt.Skip(); break; } } } @@ -5467,8 +5466,39 @@ void GLCanvas3D::_rectangular_selection_picking_pass() const _update_volumes_hover_state(); } +#if ENABLE_GCODE_VIEWER +static BoundingBoxf3 print_volume(const DynamicPrintConfig& config) +{ + // tolerance to avoid false detection at bed edges + const double tolerance_x = 0.05; + const double tolerance_y = 0.05; + + BoundingBoxf3 ret; + const ConfigOptionPoints* opt = dynamic_cast(config.option("bed_shape")); + if (opt != nullptr) + { + BoundingBox bed_box_2D = get_extents(Polygon::new_scale(opt->values)); + ret = BoundingBoxf3(Vec3d(unscale(bed_box_2D.min(0)) - tolerance_x, unscale(bed_box_2D.min(1)) - tolerance_y, 0.0), Vec3d(unscale(bed_box_2D.max(0)) + tolerance_x, unscale(bed_box_2D.max(1)) + tolerance_y, config.opt_float("max_print_height"))); + // Allow the objects to protrude below the print bed + ret.min(2) = -1e10; + } + return ret; +} +#endif // ENABLE_GCODE_VIEWER + void GLCanvas3D::_render_background() const { +#if ENABLE_GCODE_VIEWER + bool use_error_color = m_dynamic_background_enabled; + if (!m_volumes.empty()) + use_error_color &= _is_any_volume_outside(); + else + { + BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3(); + use_error_color &= (test_volume.radius() > 0.0) ? !test_volume.contains(m_gcode_viewer.get_bounding_box()) : false; + } +#endif // ENABLE_GCODE_VIEWER + glsafe(::glPushMatrix()); glsafe(::glLoadIdentity()); glsafe(::glMatrixMode(GL_PROJECTION)); @@ -5479,7 +5509,11 @@ void GLCanvas3D::_render_background() const glsafe(::glDisable(GL_DEPTH_TEST)); ::glBegin(GL_QUADS); +#if ENABLE_GCODE_VIEWER + if (use_error_color) +#else if (m_dynamic_background_enabled && _is_any_volume_outside()) +#endif // ENABLE_GCODE_VIEWER ::glColor3fv(ERROR_BG_DARK_COLOR); else ::glColor3fv(DEFAULT_BG_DARK_COLOR); @@ -5487,8 +5521,12 @@ void GLCanvas3D::_render_background() const ::glVertex2f(-1.0f, -1.0f); ::glVertex2f(1.0f, -1.0f); +#if ENABLE_GCODE_VIEWER + if (use_error_color) +#else if (m_dynamic_background_enabled && _is_any_volume_outside()) - ::glColor3fv(ERROR_BG_LIGHT_COLOR); +#endif // ENABLE_GCODE_VIEWER +::glColor3fv(ERROR_BG_LIGHT_COLOR); else ::glColor3fv(DEFAULT_BG_LIGHT_COLOR); @@ -6991,6 +7029,7 @@ void GLCanvas3D::_load_sla_shells() update_volumes_colors_by_extruder(); } +#if !ENABLE_GCODE_VIEWER void GLCanvas3D::_update_gcode_volumes_visibility(const GCodePreviewData& preview_data) { unsigned int size = (unsigned int)m_gcode_preview_volume_index.first_volumes.size(); @@ -7048,9 +7087,13 @@ void GLCanvas3D::_update_gcode_volumes_visibility(const GCodePreviewData& previe } } } +#endif // !ENABLE_GCODE_VIEWER void GLCanvas3D::_update_toolpath_volumes_outside_state() { +#if ENABLE_GCODE_VIEWER + BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3(); +#else // tolerance to avoid false detection at bed edges static const double tolerance_x = 0.05; static const double tolerance_y = 0.05; @@ -7067,15 +7110,23 @@ void GLCanvas3D::_update_toolpath_volumes_outside_state() print_volume.min(2) = -1e10; } } +#endif // ENABLE_GCODE_VIEWER for (GLVolume* volume : m_volumes.volumes) { +#if ENABLE_GCODE_VIEWER + volume->is_outside = ((test_volume.radius() > 0.0) && volume->is_extrusion_path) ? !test_volume.contains(volume->bounding_box()) : false; +#else volume->is_outside = ((print_volume.radius() > 0.0) && volume->is_extrusion_path) ? !print_volume.contains(volume->bounding_box()) : false; +#endif // ENABLE_GCODE_VIEWER } } void GLCanvas3D::_update_sla_shells_outside_state() { +#if ENABLE_GCODE_VIEWER + BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3(); +#else // tolerance to avoid false detection at bed edges static const double tolerance_x = 0.05; static const double tolerance_y = 0.05; @@ -7092,17 +7143,34 @@ void GLCanvas3D::_update_sla_shells_outside_state() print_volume.min(2) = -1e10; } } +#endif // ENABLE_GCODE_VIEWER for (GLVolume* volume : m_volumes.volumes) { +#if ENABLE_GCODE_VIEWER + volume->is_outside = ((test_volume.radius() > 0.0) && volume->shader_outside_printer_detection_enabled) ? !test_volume.contains(volume->transformed_convex_hull_bounding_box()) : false; +#else volume->is_outside = ((print_volume.radius() > 0.0) && volume->shader_outside_printer_detection_enabled) ? !print_volume.contains(volume->transformed_convex_hull_bounding_box()) : false; +#endif // ENABLE_GCODE_VIEWER } } void GLCanvas3D::_show_warning_texture_if_needed(WarningTexture::Warning warning) { _set_current(); +#if ENABLE_GCODE_VIEWER + bool show = false; + if (!m_volumes.empty()) + show = _is_any_volume_outside(); + else + { + BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3(); + show = (test_volume.radius() > 0.0) ? !test_volume.contains(m_gcode_viewer.get_bounding_box()) : false; + } + _set_warning_texture(warning, show); +#else _set_warning_texture(warning, _is_any_volume_outside()); +#endif // ENABLE_GCODE_VIEWER } std::vector GLCanvas3D::_parse_colors(const std::vector& colors) diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index ed034bd28c..5684901f3d 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -846,8 +846,10 @@ private: #endif // !ENABLE_GCODE_VIEWER // Load SLA objects and support structures for objects, for which the slaposSliceSupports step has been finished. void _load_sla_shells(); +#if !ENABLE_GCODE_VIEWER // sets gcode geometry visibility according to user selection void _update_gcode_volumes_visibility(const GCodePreviewData& preview_data); +#endif // !ENABLE_GCODE_VIEWER void _update_toolpath_volumes_outside_state(); void _update_sla_shells_outside_state(); void _show_warning_texture_if_needed(WarningTexture::Warning warning); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 05d6071099..4f47c2d18f 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -1,5 +1,7 @@ #include "libslic3r/libslic3r.h" +#if !ENABLE_GCODE_VIEWER #include "libslic3r/GCode/PreviewData.hpp" +#endif // !ENABLE_GCODE_VIEWER #include "GUI_Preview.hpp" #include "GUI_App.hpp" #include "GUI.hpp" @@ -172,8 +174,8 @@ void View3D::render() #if ENABLE_GCODE_VIEWER Preview::Preview( - wxWindow * parent, Model * model, DynamicPrintConfig * config, - BackgroundSlicingProcess * process, GCodePreviewData * gcode_preview_data, GCodeProcessor::Result * gcode_result, std::function schedule_background_process_func) + wxWindow* parent, Model* model, DynamicPrintConfig* config, + BackgroundSlicingProcess* process, GCodeProcessor::Result* gcode_result, std::function schedule_background_process_func) #else Preview::Preview( wxWindow* parent, Model* model, DynamicPrintConfig* config, @@ -200,9 +202,10 @@ Preview::Preview( #endif // ENABLE_GCODE_VIEWER , m_config(config) , m_process(process) - , m_gcode_preview_data(gcode_preview_data) #if ENABLE_GCODE_VIEWER , m_gcode_result(gcode_result) +#else + , m_gcode_preview_data(gcode_preview_data) #endif // ENABLE_GCODE_VIEWER , m_number_extruders(1) , m_preferred_color_mode("feature") @@ -401,8 +404,13 @@ void Preview::set_number_extruders(unsigned int number_extruders) int tool_idx = m_choice_view_type->FindString(_(L("Tool"))); int type = (number_extruders > 1) ? tool_idx /* color by a tool number */ : 0; // color by a feature type m_choice_view_type->SetSelection(type); +#if ENABLE_GCODE_VIEWER + if ((0 <= type) && (type < static_cast(GCodeViewer::EViewType::Count))) + m_canvas->set_gcode_view_preview_type(static_cast(type)); +#else if ((0 <= type) && (type < (int)GCodePreviewData::Extrusion::Num_View_Types)) m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)type; +#endif // ENABLE_GCODE_VIEWER m_preferred_color_mode = (type == tool_idx) ? "tool_or_feature" : "feature"; } @@ -679,8 +687,13 @@ void Preview::update_view_type(bool slice_completed) int type = m_choice_view_type->FindString(choice); if (m_choice_view_type->GetSelection() != type) { m_choice_view_type->SetSelection(type); +#if ENABLE_GCODE_VIEWER + if ((0 <= type) && (type < static_cast(GCodeViewer::EViewType::Count))) + m_canvas->set_gcode_view_preview_type(static_cast(type)); +#else if (0 <= type && type < (int)GCodePreviewData::Extrusion::Num_View_Types) m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)type; +#endif // ENABLE_GCODE_VIEWER m_preferred_color_mode = "feature"; } } diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 90943de006..a11a474ccf 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -124,8 +124,8 @@ class Preview : public wxPanel public: #if ENABLE_GCODE_VIEWER -Preview(wxWindow * parent, Model * model, DynamicPrintConfig * config, - BackgroundSlicingProcess * process, GCodePreviewData * gcode_preview_data, GCodeProcessor::Result * gcode_result, std::function schedule_background_process = []() {}); +Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process, + GCodeProcessor::Result* gcode_result, std::function schedule_background_process = []() {}); #else Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function schedule_background_process = []() {}); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 7d6497731c..c4a43fbb00 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -33,7 +33,9 @@ #include "libslic3r/Format/STL.hpp" #include "libslic3r/Format/AMF.hpp" #include "libslic3r/Format/3mf.hpp" +#if !ENABLE_GCODE_VIEWER #include "libslic3r/GCode/PreviewData.hpp" +#endif // !ENABLE_GCODE_VIEWER #include "libslic3r/GCode/ThumbnailData.hpp" #include "libslic3r/Model.hpp" #include "libslic3r/SLA/Hollowing.hpp" @@ -1528,9 +1530,10 @@ struct Plater::priv Slic3r::SLAPrint sla_print; Slic3r::Model model; PrinterTechnology printer_technology = ptFFF; - Slic3r::GCodePreviewData gcode_preview_data; #if ENABLE_GCODE_VIEWER Slic3r::GCodeProcessor::Result gcode_result; +#else + Slic3r::GCodePreviewData gcode_preview_data; #endif // ENABLE_GCODE_VIEWER // GUI elements @@ -1840,9 +1843,10 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) background_process.set_fff_print(&fff_print); background_process.set_sla_print(&sla_print); - background_process.set_gcode_preview_data(&gcode_preview_data); #if ENABLE_GCODE_VIEWER background_process.set_gcode_result(&gcode_result); +#else + background_process.set_gcode_preview_data(&gcode_preview_data); #endif // ENABLE_GCODE_VIEWER background_process.set_thumbnail_cb([this](ThumbnailsList& thumbnails, const Vec2ds& sizes, bool printable_only, bool parts_only, bool show_bed, bool transparent_background) { @@ -1868,7 +1872,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) view3D = new View3D(q, &model, config, &background_process); #if ENABLE_GCODE_VIEWER - preview = new Preview(q, &model, config, &background_process, &gcode_preview_data, &gcode_result, [this]() { schedule_background_process(); }); + preview = new Preview(q, &model, config, &background_process, &gcode_result, [this]() { schedule_background_process(); }); #else preview = new Preview(q, &model, config, &background_process, &gcode_preview_data, [this]() { schedule_background_process(); }); #endif // ENABLE_GCODE_VIEWER From 27b9f856077009be98fad60920ea31d335dabd25 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 7 May 2020 11:24:36 +0200 Subject: [PATCH 062/255] Fixed build when tech ENABLE_GCODE_VIEWER is disabled + fixed perl code --- src/slic3r/GUI/DoubleSlider.cpp | 2 +- src/slic3r/GUI/GLCanvas3D.hpp | 1 - xs/src/perlglue.cpp | 4 +- xs/xsp/GCode.xsp | 66 +++++++++++++++++---------------- xs/xsp/Print.xsp | 2 +- xs/xsp/my.map | 8 ++-- xs/xsp/typemap.xspt | 8 ++-- 7 files changed, 50 insertions(+), 41 deletions(-) diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index 0a89333714..3475f50246 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -1950,7 +1950,7 @@ std::string TickCodeInfo::get_color_for_tick(TickCode tick, const std::string& c if (mode == t_mode::SingleExtruder && code == ColorChangeCode && m_use_default_colors) { #if ENABLE_GCODE_VIEWER - const std::vector& colors = ColorPrintColors::get(); + const std::vector& colors = Slic3r::ColorPrintColors::get(); #else const std::vector& colors = GCodePreviewData::ColorPrintColors(); #endif // ENABLE_GCODE_VIEWER diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index cc43e7d145..294dbabe17 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -640,7 +640,6 @@ public: void set_toolpaths_z_range(const std::array& range); #else std::vector get_current_print_zs(bool active_only) const; - void set_toolpaths_range(double low, double high); #endif // ENABLE_GCODE_VIEWER void set_toolpaths_range(double low, double high); diff --git a/xs/src/perlglue.cpp b/xs/src/perlglue.cpp index c3cd7e6165..64cf9378fc 100644 --- a/xs/src/perlglue.cpp +++ b/xs/src/perlglue.cpp @@ -15,7 +15,9 @@ REGISTER_CLASS(Filler, "Filler"); REGISTER_CLASS(Flow, "Flow"); REGISTER_CLASS(CoolingBuffer, "GCode::CoolingBuffer"); REGISTER_CLASS(GCode, "GCode"); -REGISTER_CLASS(GCodePreviewData, "GCode::PreviewData"); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//REGISTER_CLASS(GCodePreviewData, "GCode::PreviewData"); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // REGISTER_CLASS(GCodeSender, "GCode::Sender"); REGISTER_CLASS(Layer, "Layer"); REGISTER_CLASS(SupportLayer, "Layer::Support"); diff --git a/xs/xsp/GCode.xsp b/xs/xsp/GCode.xsp index 9e04edd4c6..5799cafdbd 100644 --- a/xs/xsp/GCode.xsp +++ b/xs/xsp/GCode.xsp @@ -26,14 +26,16 @@ croak("%s\n", e.what()); } %}; - void do_export_w_preview(Print *print, const char *path, GCodePreviewData *preview_data) - %code%{ - try { - THIS->do_export(print, path, preview_data); - } catch (std::exception& e) { - croak("%s\n", e.what()); - } - %}; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// void do_export_w_preview(Print *print, const char *path, GCodePreviewData *preview_data) +// %code%{ +// try { +// THIS->do_export(print, path, preview_data); +// } catch (std::exception& e) { +// croak("%s\n", e.what()); +// } +// %}; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Ref origin() %code{% RETVAL = &(THIS->origin()); %}; @@ -60,26 +62,28 @@ %code{% RETVAL = const_cast(static_cast(static_cast(&THIS->config()))); %}; }; -%name{Slic3r::GCode::PreviewData} class GCodePreviewData { - GCodePreviewData(); - ~GCodePreviewData(); - void reset(); - bool empty() const; - void set_type(int type) - %code%{ - if ((0 <= type) && (type < GCodePreviewData::Extrusion::Num_View_Types)) - THIS->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)type; - %}; - int type() %code%{ RETVAL = (int)THIS->extrusion.view_type; %}; - void set_extrusion_flags(int flags) - %code%{ THIS->extrusion.role_flags = (unsigned int)flags; %}; - void set_travel_visible(bool visible) - %code%{ THIS->travel.is_visible = visible; %}; - void set_retractions_visible(bool visible) - %code%{ THIS->retraction.is_visible = visible; %}; - void set_unretractions_visible(bool visible) - %code%{ THIS->unretraction.is_visible = visible; %}; - void set_shells_visible(bool visible) - %code%{ THIS->shell.is_visible = visible; %}; - void set_extrusion_paths_colors(std::vector colors); -}; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//%name{Slic3r::GCode::PreviewData} class GCodePreviewData { +// GCodePreviewData(); +// ~GCodePreviewData(); +// void reset(); +// bool empty() const; +// void set_type(int type) +// %code%{ +// if ((0 <= type) && (type < GCodePreviewData::Extrusion::Num_View_Types)) +// THIS->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)type; +// %}; +// int type() %code%{ RETVAL = (int)THIS->extrusion.view_type; %}; +// void set_extrusion_flags(int flags) +// %code%{ THIS->extrusion.role_flags = (unsigned int)flags; %}; +// void set_travel_visible(bool visible) +// %code%{ THIS->travel.is_visible = visible; %}; +// void set_retractions_visible(bool visible) +// %code%{ THIS->retraction.is_visible = visible; %}; +// void set_unretractions_visible(bool visible) +// %code%{ THIS->unretraction.is_visible = visible; %}; +// void set_shells_visible(bool visible) +// %code%{ THIS->shell.is_visible = visible; %}; +// void set_extrusion_paths_colors(std::vector colors); +//}; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ diff --git a/xs/xsp/Print.xsp b/xs/xsp/Print.xsp index 160fd3e60c..0952513ca3 100644 --- a/xs/xsp/Print.xsp +++ b/xs/xsp/Print.xsp @@ -164,7 +164,7 @@ _constant() void export_gcode(char *path_template) %code%{ try { - THIS->export_gcode(path_template, nullptr, nullptr); + THIS->export_gcode(path_template, nullptr); } catch (std::exception& e) { croak("%s\n", e.what()); } diff --git a/xs/xsp/my.map b/xs/xsp/my.map index fd50d29751..44b9eaa893 100644 --- a/xs/xsp/my.map +++ b/xs/xsp/my.map @@ -191,9 +191,11 @@ GCode* O_OBJECT_SLIC3R Ref O_OBJECT_SLIC3R_T Clone O_OBJECT_SLIC3R_T -GCodePreviewData* O_OBJECT_SLIC3R -Ref O_OBJECT_SLIC3R_T -Clone O_OBJECT_SLIC3R_T +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//GCodePreviewData* O_OBJECT_SLIC3R +//Ref O_OBJECT_SLIC3R_T +//Clone O_OBJECT_SLIC3R_T +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ MotionPlanner* O_OBJECT_SLIC3R Ref O_OBJECT_SLIC3R_T diff --git a/xs/xsp/typemap.xspt b/xs/xsp/typemap.xspt index 7e277703b8..5ee142029b 100644 --- a/xs/xsp/typemap.xspt +++ b/xs/xsp/typemap.xspt @@ -155,9 +155,11 @@ %typemap{Ref}{simple}; %typemap{Clone}{simple}; -%typemap{GCodePreviewData*}; -%typemap{Ref}{simple}; -%typemap{Clone}{simple}; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//%typemap{GCodePreviewData*}; +//%typemap{Ref}{simple}; +//%typemap{Clone}{simple}; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ %typemap{Points}; %typemap{Pointfs}; From 277b340481617936f4c5c4ca82f3e8ca8e268826 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 7 May 2020 12:03:17 +0200 Subject: [PATCH 063/255] Attempt to fix build on OsX --- src/slic3r/GUI/DoubleSlider.cpp | 5 ++++- xs/src/perlglue.cpp | 2 -- xs/xsp/GCode.xsp | 4 ---- xs/xsp/my.map | 2 -- xs/xsp/typemap.xspt | 2 -- 5 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index 3475f50246..f0940fbfdb 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -1,3 +1,6 @@ +#if ENABLE_GCODE_VIEWER +#include "libslic3r/libslic3r.h" +#endif // ENABLE_GCODE_VIEWER #include "wxExtensions.hpp" #if ENABLE_GCODE_VIEWER #include "libslic3r/GCode.hpp" @@ -1950,7 +1953,7 @@ std::string TickCodeInfo::get_color_for_tick(TickCode tick, const std::string& c if (mode == t_mode::SingleExtruder && code == ColorChangeCode && m_use_default_colors) { #if ENABLE_GCODE_VIEWER - const std::vector& colors = Slic3r::ColorPrintColors::get(); + const std::vector& colors = ColorPrintColors::get(); #else const std::vector& colors = GCodePreviewData::ColorPrintColors(); #endif // ENABLE_GCODE_VIEWER diff --git a/xs/src/perlglue.cpp b/xs/src/perlglue.cpp index 64cf9378fc..47961c6231 100644 --- a/xs/src/perlglue.cpp +++ b/xs/src/perlglue.cpp @@ -15,9 +15,7 @@ REGISTER_CLASS(Filler, "Filler"); REGISTER_CLASS(Flow, "Flow"); REGISTER_CLASS(CoolingBuffer, "GCode::CoolingBuffer"); REGISTER_CLASS(GCode, "GCode"); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ //REGISTER_CLASS(GCodePreviewData, "GCode::PreviewData"); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // REGISTER_CLASS(GCodeSender, "GCode::Sender"); REGISTER_CLASS(Layer, "Layer"); REGISTER_CLASS(SupportLayer, "Layer::Support"); diff --git a/xs/xsp/GCode.xsp b/xs/xsp/GCode.xsp index 5799cafdbd..1536c874b5 100644 --- a/xs/xsp/GCode.xsp +++ b/xs/xsp/GCode.xsp @@ -26,7 +26,6 @@ croak("%s\n", e.what()); } %}; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // void do_export_w_preview(Print *print, const char *path, GCodePreviewData *preview_data) // %code%{ // try { @@ -35,7 +34,6 @@ // croak("%s\n", e.what()); // } // %}; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Ref origin() %code{% RETVAL = &(THIS->origin()); %}; @@ -62,7 +60,6 @@ %code{% RETVAL = const_cast(static_cast(static_cast(&THIS->config()))); %}; }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ //%name{Slic3r::GCode::PreviewData} class GCodePreviewData { // GCodePreviewData(); // ~GCodePreviewData(); @@ -86,4 +83,3 @@ // %code%{ THIS->shell.is_visible = visible; %}; // void set_extrusion_paths_colors(std::vector colors); //}; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ diff --git a/xs/xsp/my.map b/xs/xsp/my.map index 44b9eaa893..7e51b237c0 100644 --- a/xs/xsp/my.map +++ b/xs/xsp/my.map @@ -191,11 +191,9 @@ GCode* O_OBJECT_SLIC3R Ref O_OBJECT_SLIC3R_T Clone O_OBJECT_SLIC3R_T -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ //GCodePreviewData* O_OBJECT_SLIC3R //Ref O_OBJECT_SLIC3R_T //Clone O_OBJECT_SLIC3R_T -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ MotionPlanner* O_OBJECT_SLIC3R Ref O_OBJECT_SLIC3R_T diff --git a/xs/xsp/typemap.xspt b/xs/xsp/typemap.xspt index 5ee142029b..385b50f1aa 100644 --- a/xs/xsp/typemap.xspt +++ b/xs/xsp/typemap.xspt @@ -155,11 +155,9 @@ %typemap{Ref}{simple}; %typemap{Clone}{simple}; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ //%typemap{GCodePreviewData*}; //%typemap{Ref}{simple}; //%typemap{Clone}{simple}; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ %typemap{Points}; %typemap{Pointfs}; From 383d7f2d73066c1efdca893897b999f2d013fd06 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 7 May 2020 13:07:56 +0200 Subject: [PATCH 064/255] 2nd attempt to fix build on OsX --- src/slic3r/GUI/DoubleSlider.cpp | 5 ++--- src/slic3r/GUI/DoubleSlider.hpp | 2 ++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index f0940fbfdb..4732ff2613 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -1,10 +1,9 @@ -#if ENABLE_GCODE_VIEWER #include "libslic3r/libslic3r.h" -#endif // ENABLE_GCODE_VIEWER -#include "wxExtensions.hpp" #if ENABLE_GCODE_VIEWER +#include "DoubleSlider.hpp" #include "libslic3r/GCode.hpp" #else +#include "wxExtensions.hpp" #include "libslic3r/GCode/PreviewData.hpp" #endif // ENABLE_GCODE_VIEWER #include "GUI.hpp" diff --git a/src/slic3r/GUI/DoubleSlider.hpp b/src/slic3r/GUI/DoubleSlider.hpp index bf8f54d6c9..36bff17e94 100644 --- a/src/slic3r/GUI/DoubleSlider.hpp +++ b/src/slic3r/GUI/DoubleSlider.hpp @@ -4,7 +4,9 @@ #include "libslic3r/CustomGCode.hpp" #include "wxExtensions.hpp" +#if !ENABLE_GCODE_VIEWER #include +#endif // !ENABLE_GCODE_VIEWER #include #include #include From c02a77d94215348eb89f4143269a8cd59160c1ca Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 11 May 2020 13:09:26 +0200 Subject: [PATCH 065/255] GCodeViewer -> Prototype for tool marker --- resources/shaders/gouraud_light.fs | 11 ++ resources/shaders/gouraud_light.vs | 38 ++++++ src/slic3r/GUI/GCodeViewer.cpp | 201 ++++++++++++++++++++++++----- src/slic3r/GUI/GCodeViewer.hpp | 33 +++-- src/slic3r/GUI/GUI_Preview.cpp | 3 +- 5 files changed, 244 insertions(+), 42 deletions(-) create mode 100644 resources/shaders/gouraud_light.fs create mode 100644 resources/shaders/gouraud_light.vs diff --git a/resources/shaders/gouraud_light.fs b/resources/shaders/gouraud_light.fs new file mode 100644 index 0000000000..1a58abc852 --- /dev/null +++ b/resources/shaders/gouraud_light.fs @@ -0,0 +1,11 @@ +#version 110 + +uniform vec4 uniform_color; + +// x = tainted, y = specular; +varying vec2 intensity; + +void main() +{ + gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color.rgb * intensity.x, uniform_color.a); +} diff --git a/resources/shaders/gouraud_light.vs b/resources/shaders/gouraud_light.vs new file mode 100644 index 0000000000..d4f71938a9 --- /dev/null +++ b/resources/shaders/gouraud_light.vs @@ -0,0 +1,38 @@ +#version 110 + +#define INTENSITY_CORRECTION 0.6 + +// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) +const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); +#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SHININESS 20.0 + +// normalized values for (1./1.43, 0.2/1.43, 1./1.43) +const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074); +#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) + +#define INTENSITY_AMBIENT 0.3 + +// x = tainted, y = specular; +varying vec2 intensity; + +void main() +{ + // First transform the normal into camera space and normalize the result. + vec3 normal = normalize(gl_NormalMatrix * gl_Normal); + + // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. + // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. + float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0); + + intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; + vec3 position = (gl_ModelViewMatrix * gl_Vertex).xyz; + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); + + // Perform the same lighting calculation for the 2nd light source (no specular applied). + NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + + gl_Position = ftransform(); +} diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 0893a7d465..269780d950 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -3,6 +3,8 @@ #if ENABLE_GCODE_VIEWER #include "libslic3r/Print.hpp" +#include "libslic3r/TriangleMesh.hpp" +#include "libslic3r/Geometry.hpp" #include "GUI_App.hpp" #include "PresetBundle.hpp" #include "Camera.hpp" @@ -146,20 +148,160 @@ GCodeViewer::Color GCodeViewer::Extrusions::Range::get_color_at(float value) con void GCodeViewer::SequentialView::Marker::init() { - if (m_initialized) - return; + Pointf3s vertices; + std::vector triangles; + // arrow tip + vertices.emplace_back(0.0, 0.0, 0.0); + vertices.emplace_back(0.5, -0.5, 1.0); + vertices.emplace_back(0.5, 0.5, 1.0); + vertices.emplace_back(-0.5, 0.5, 1.0); + vertices.emplace_back(-0.5, -0.5, 1.0); + + triangles.emplace_back(0, 1, 4); + triangles.emplace_back(0, 2, 1); + triangles.emplace_back(0, 3, 2); + triangles.emplace_back(0, 4, 3); + triangles.emplace_back(1, 2, 4); + triangles.emplace_back(2, 3, 4); + + // arrow stem + vertices.emplace_back(0.25, -0.25, 1.0); + vertices.emplace_back(0.25, 0.25, 1.0); + vertices.emplace_back(-0.25, 0.25, 1.0); + vertices.emplace_back(-0.25, -0.25, 1.0); + vertices.emplace_back(0.25, -0.25, 3.0); + vertices.emplace_back(0.25, 0.25, 3.0); + vertices.emplace_back(-0.25, 0.25, 3.0); + vertices.emplace_back(-0.25, -0.25, 3.0); + + triangles.emplace_back(5, 9, 8); + triangles.emplace_back(8, 9, 12); + triangles.emplace_back(6, 10, 5); + triangles.emplace_back(5, 10, 9); + triangles.emplace_back(7, 11, 6); + triangles.emplace_back(6, 11, 10); + triangles.emplace_back(8, 12, 7); + triangles.emplace_back(7, 12, 11); + triangles.emplace_back(9, 10, 12); + triangles.emplace_back(12, 10, 11); + + TriangleMesh mesh(vertices, triangles); + mesh.require_shared_vertices(); + + init_from_mesh(mesh); +} + +bool GCodeViewer::SequentialView::Marker::init_from_mesh(const TriangleMesh& mesh) +{ + auto get_normal = [](const std::array& triangle) { + return (triangle[1] - triangle[0]).cross(triangle[2] - triangle[0]).normalized(); + }; + + reset(); + + // vertex data -> load from mesh + std::vector vertices(6 * mesh.its.vertices.size()); + for (size_t i = 0; i < mesh.its.vertices.size(); ++i) { + ::memcpy(static_cast(&vertices[i * 6]), static_cast(mesh.its.vertices[i].data()), 3 * sizeof(float)); + } + + // indices/normals data -> load from mesh + std::vector indices(3 * mesh.its.indices.size()); + for (size_t i = 0; i < mesh.its.indices.size(); ++i) { + const stl_triangle_vertex_indices& triangle = mesh.its.indices[i]; + for (size_t j = 0; j < 3; ++j) { + indices[i * 3 + j] = static_cast(triangle[j]); + } + Vec3f normal = get_normal({ mesh.its.vertices[triangle[0]], mesh.its.vertices[triangle[1]], mesh.its.vertices[triangle[2]] }); + ::memcpy(static_cast(&vertices[3 + static_cast(triangle[0]) * 6]), static_cast(normal.data()), 3 * sizeof(float)); + ::memcpy(static_cast(&vertices[3 + static_cast(triangle[1]) * 6]), static_cast(normal.data()), 3 * sizeof(float)); + ::memcpy(static_cast(&vertices[3 + static_cast(triangle[2]) * 6]), static_cast(normal.data()), 3 * sizeof(float)); + } + + m_indices_count = static_cast(indices.size()); + + // vertex data -> send to gpu + glsafe(::glGenBuffers(1, &m_vbo_id)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id)); + glsafe(::glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + + // indices data -> send to gpu + glsafe(::glGenBuffers(1, &m_ibo_id)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo_id)); + glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + + return init_shader(); } void GCodeViewer::SequentialView::Marker::render() const { - if (!m_initialized) + if (!m_visible || !m_shader.is_initialized()) return; + glsafe(::glEnable(GL_BLEND)); + glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); + m_shader.start_using(); + GLint color_id = ::glGetUniformLocation(m_shader.get_shader_program_id(), "uniform_color"); + if (color_id >= 0) + glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)m_color.data())); + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id)); + glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)0)); + glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)))); + + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); + + glsafe(::glPushMatrix()); + glsafe(::glMultMatrixf(m_world_transform.data())); + + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo_id)); + glsafe(::glDrawElements(GL_TRIANGLES, static_cast(m_indices_count), GL_UNSIGNED_INT, (const void*)0)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + + glsafe(::glPopMatrix()); + + glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + + m_shader.stop_using(); + + glsafe(::glDisable(GL_BLEND)); } -const std::vector GCodeViewer::Extrusion_Role_Colors{ { +void GCodeViewer::SequentialView::Marker::reset() +{ + // release gpu memory + if (m_ibo_id > 0) { + glsafe(::glDeleteBuffers(1, &m_ibo_id)); + m_ibo_id = 0; + } + + if (m_vbo_id > 0) { + glsafe(::glDeleteBuffers(1, &m_vbo_id)); + m_vbo_id = 0; + } + + m_indices_count = 0; +} + +bool GCodeViewer::SequentialView::Marker::init_shader() +{ + if (!m_shader.init("gouraud_light.vs", "gouraud_light.fs")) { + BOOST_LOG_TRIVIAL(error) << "Unable to initialize gouraud_light shader: please, check that the files gouraud_light.vs and gouraud_light.fs are available"; + return false; + } + + return true; +} + +const std::vector GCodeViewer::Extrusion_Role_Colors {{ { 0.50f, 0.50f, 0.50f }, // erNone { 1.00f, 1.00f, 0.40f }, // erPerimeter { 1.00f, 0.65f, 0.00f }, // erExternalPerimeter @@ -178,13 +320,13 @@ const std::vector GCodeViewer::Extrusion_Role_Colors{ { { 0.00f, 0.00f, 0.00f } // erMixed }}; -const std::vector GCodeViewer::Travel_Colors{ { +const std::vector GCodeViewer::Travel_Colors {{ { 0.0f, 0.0f, 0.5f }, // Move { 0.0f, 0.5f, 0.0f }, // Extrude { 0.5f, 0.0f, 0.0f } // Retract }}; -const std::vector GCodeViewer::Range_Colors{ { +const std::vector GCodeViewer::Range_Colors {{ { 0.043f, 0.173f, 0.478f }, // bluish { 0.075f, 0.349f, 0.522f }, { 0.110f, 0.533f, 0.569f }, @@ -292,10 +434,13 @@ void GCodeViewer::render() const m_statistics.reset_opengl(); #endif // ENABLE_GCODE_VIEWER_STATISTICS + if (m_roles.empty()) + return; + glsafe(::glEnable(GL_DEPTH_TEST)); render_toolpaths(); - if (m_sequential_view.marker.visible) - m_sequential_view.marker.render(); + m_sequential_view.marker.set_world_transform(Geometry::assemble_transform(m_sequential_view.current_position.cast() + 0.5 * Vec3d::UnitZ(), { 0.0, 0.0, 0.0 }, { 4.0, 4.0, 4.0 }, { 1.0, 1.0, 1.0 }).cast()); + m_sequential_view.marker.render(); render_shells(); render_legend(); render_sequential_bar(); @@ -332,7 +477,8 @@ unsigned int GCodeViewer::get_options_visibility_flags() const flags = set_flag(flags, 5, is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Pause_Print)); flags = set_flag(flags, 6, is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Custom_GCode)); flags = set_flag(flags, 7, m_shells.visible); - flags = set_flag(flags, 8, is_legend_enabled()); + flags = set_flag(flags, 8, m_sequential_view.marker.is_visible()); + flags = set_flag(flags, 9, is_legend_enabled()); return flags; } @@ -350,7 +496,8 @@ void GCodeViewer::set_options_visibility_from_flags(unsigned int flags) set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Pause_Print, is_flag_set(5)); set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Custom_GCode, is_flag_set(6)); m_shells.visible = is_flag_set(7); - enable_legend(is_flag_set(8)); + m_sequential_view.marker.set_visible(is_flag_set(8)); + enable_legend(is_flag_set(9)); } bool GCodeViewer::init_shaders() @@ -706,7 +853,7 @@ void GCodeViewer::render_toolpaths() const { auto set_color = [](GLint current_program_id, const Color& color) { if (current_program_id > 0) { - GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1; + GLint color_id = ::glGetUniformLocation(current_program_id, "uniform_color"); if (color_id >= 0) { glsafe(::glUniform3fv(color_id, 1, (const GLfloat*)color.data())); return; @@ -737,10 +884,7 @@ void GCodeViewer::render_toolpaths() const GCodeProcessor::EMoveType type = buffer_type(i); buffer.shader.start_using(); - - GLint current_program_id; - glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id)); - + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.ibo_id)); switch (type) @@ -748,7 +892,7 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Tool_change: { Color color = { 1.0f, 1.0f, 1.0f }; - set_color(current_program_id, color); + set_color(static_cast(buffer.shader.get_shader_program_id()), color); for (const RenderPath& path : buffer.render_paths) { glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); @@ -764,7 +908,7 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Color_change: { Color color = { 1.0f, 0.0f, 0.0f }; - set_color(current_program_id, color); + set_color(static_cast(buffer.shader.get_shader_program_id()), color); for (const RenderPath& path : buffer.render_paths) { glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); @@ -780,7 +924,7 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Pause_Print: { Color color = { 0.0f, 1.0f, 0.0f }; - set_color(current_program_id, color); + set_color(static_cast(buffer.shader.get_shader_program_id()), color); for (const RenderPath& path : buffer.render_paths) { glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); @@ -796,7 +940,7 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Custom_GCode: { Color color = { 0.0f, 0.0f, 1.0f }; - set_color(current_program_id, color); + set_color(static_cast(buffer.shader.get_shader_program_id()), color); for (const RenderPath& path : buffer.render_paths) { glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); @@ -812,7 +956,7 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Retract: { Color color = { 1.0f, 0.0f, 1.0f }; - set_color(current_program_id, color); + set_color(static_cast(buffer.shader.get_shader_program_id()), color); for (const RenderPath& path : buffer.render_paths) { glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); @@ -828,7 +972,7 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Unretract: { Color color = { 0.0f, 1.0f, 1.0f }; - set_color(current_program_id, color); + set_color(static_cast(buffer.shader.get_shader_program_id()), color); for (const RenderPath& path : buffer.render_paths) { glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); @@ -845,7 +989,7 @@ void GCodeViewer::render_toolpaths() const { for (const RenderPath& path : buffer.render_paths) { - set_color(current_program_id, path.color); + set_color(static_cast(buffer.shader.get_shader_program_id()), path.color); glsafe(::glMultiDrawElements(GL_LINE_STRIP, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_line_strip_calls_count; @@ -858,7 +1002,7 @@ void GCodeViewer::render_toolpaths() const { for (const RenderPath& path : buffer.render_paths) { - set_color(current_program_id, path.color); + set_color(static_cast(buffer.shader.get_shader_program_id()), path.color); glsafe(::glMultiDrawElements(GL_LINE_STRIP, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_line_strip_calls_count; @@ -897,7 +1041,7 @@ void GCodeViewer::render_legend() const static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); static const ImU32 ICON_BORDER_COLOR = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); - if (!m_legend_enabled || m_roles.empty()) + if (!m_legend_enabled) return; ImGuiWrapper& imgui = *wxGetApp().imgui(); @@ -1130,9 +1274,6 @@ void GCodeViewer::render_sequential_bar() const refresh_render_paths(true); }; - if (m_roles.empty()) - return; - if (m_sequential_view.last <= m_sequential_view.first) return; @@ -1204,9 +1345,6 @@ void GCodeViewer::render_sequential_bar() const ImGui::SameLine(); imgui.text(std::to_string(i_max)); - ImGui::Separator(); - ImGui::Checkbox(I18N::translate_utf8(L("Show marker")).c_str(), &m_sequential_view.marker.visible); - imgui.end(); ImGui::PopStyleVar(); } @@ -1217,9 +1355,6 @@ void GCodeViewer::render_statistics() const static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); static const float offset = 250.0f; - if (m_roles.empty()) - return; - ImGuiWrapper& imgui = *wxGetApp().imgui(); imgui.set_next_window_pos(0.5f * wxGetApp().plater()->get_current_canvas3D()->get_canvas_size().get_width(), 0.0f, ImGuiCond_Once, 0.5f, 0.0f); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 5354ae067f..d34e8ee4bd 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -9,7 +9,10 @@ #include namespace Slic3r { + class Print; +class TriangleMesh; + namespace GUI { class GCodeViewer @@ -73,8 +76,8 @@ class GCodeViewer struct IBuffer { unsigned int ibo_id{ 0 }; - Shader shader; size_t indices_count{ 0 }; + Shader shader; std::vector paths; std::vector render_paths; bool visible{ false }; @@ -147,19 +150,33 @@ class GCodeViewer struct SequentialView { - struct Marker + class Marker { - private: - bool m_initialized{ false }; + unsigned int m_vbo_id{ 0 }; + unsigned int m_ibo_id{ 0 }; + size_t m_indices_count{ 0 }; + Transform3f m_world_transform; + std::array m_color{ 1.0f, 1.0f, 1.0f, 1.0f }; + bool m_visible{ false }; + Shader m_shader; public: - unsigned int vbo_id{ 0 }; - unsigned int ibo_id{ 0 }; - bool visible{ false }; - Shader shader; + ~Marker() { reset(); } void init(); + bool init_from_mesh(const TriangleMesh& mesh); + + void set_world_transform(const Transform3f& transform) { m_world_transform = transform; } + + void set_color(const std::array& color) { m_color = color; } + + bool is_visible() const { return m_visible; } + void set_visible(bool visible) { m_visible = visible; } void render() const; + void reset(); + + private: + bool init_shader(); }; unsigned int first{ 0 }; diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 4f47c2d18f..fc97796749 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -298,8 +298,9 @@ bool Preview::init(wxWindow* parent, Model* model) _L("Pause prints") + "|0|" + _L("Custom GCodes") + "|0|" + _L("Shells") + "|0|" + + _L("Tool marker") + "|1|" + _L("Legend") + "|1" - ); +); Slic3r::GUI::create_combochecklist(m_combochecklist_options, GUI::into_u8(_L("Options")), options_items); #else m_checkbox_travel = new wxCheckBox(this, wxID_ANY, _(L("Travel"))); From 769cca4b25410a2cdaf43af032ff301e443bbe43 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 11 May 2020 16:26:35 +0200 Subject: [PATCH 066/255] GCodeViewer -> Enhanced tool marker + refactoring (added new base class for OpenGL models) --- src/slic3r/CMakeLists.txt | 2 + src/slic3r/GUI/GCodeViewer.cpp | 129 +------------------ src/slic3r/GUI/GCodeViewer.hpp | 13 +- src/slic3r/GUI/GLModel.cpp | 229 +++++++++++++++++++++++++++++++++ src/slic3r/GUI/GLModel.hpp | 46 +++++++ 5 files changed, 286 insertions(+), 133 deletions(-) create mode 100644 src/slic3r/GUI/GLModel.cpp create mode 100644 src/slic3r/GUI/GLModel.hpp diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index fefc12ba87..b085fad456 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -55,6 +55,8 @@ set(SLIC3R_GUI_SOURCES GUI/Gizmos/GLGizmoHollow.hpp GUI/GLSelectionRectangle.cpp GUI/GLSelectionRectangle.hpp + GUI/GLModel.hpp + GUI/GLModel.cpp GUI/GLTexture.hpp GUI/GLTexture.cpp GUI/GLToolbar.hpp diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 269780d950..ad3985c625 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -3,7 +3,6 @@ #if ENABLE_GCODE_VIEWER #include "libslic3r/Print.hpp" -#include "libslic3r/TriangleMesh.hpp" #include "libslic3r/Geometry.hpp" #include "GUI_App.hpp" #include "PresetBundle.hpp" @@ -148,92 +147,8 @@ GCodeViewer::Color GCodeViewer::Extrusions::Range::get_color_at(float value) con void GCodeViewer::SequentialView::Marker::init() { - Pointf3s vertices; - std::vector triangles; - - // arrow tip - vertices.emplace_back(0.0, 0.0, 0.0); - vertices.emplace_back(0.5, -0.5, 1.0); - vertices.emplace_back(0.5, 0.5, 1.0); - vertices.emplace_back(-0.5, 0.5, 1.0); - vertices.emplace_back(-0.5, -0.5, 1.0); - - triangles.emplace_back(0, 1, 4); - triangles.emplace_back(0, 2, 1); - triangles.emplace_back(0, 3, 2); - triangles.emplace_back(0, 4, 3); - triangles.emplace_back(1, 2, 4); - triangles.emplace_back(2, 3, 4); - - // arrow stem - vertices.emplace_back(0.25, -0.25, 1.0); - vertices.emplace_back(0.25, 0.25, 1.0); - vertices.emplace_back(-0.25, 0.25, 1.0); - vertices.emplace_back(-0.25, -0.25, 1.0); - vertices.emplace_back(0.25, -0.25, 3.0); - vertices.emplace_back(0.25, 0.25, 3.0); - vertices.emplace_back(-0.25, 0.25, 3.0); - vertices.emplace_back(-0.25, -0.25, 3.0); - - triangles.emplace_back(5, 9, 8); - triangles.emplace_back(8, 9, 12); - triangles.emplace_back(6, 10, 5); - triangles.emplace_back(5, 10, 9); - triangles.emplace_back(7, 11, 6); - triangles.emplace_back(6, 11, 10); - triangles.emplace_back(8, 12, 7); - triangles.emplace_back(7, 12, 11); - triangles.emplace_back(9, 10, 12); - triangles.emplace_back(12, 10, 11); - - TriangleMesh mesh(vertices, triangles); - mesh.require_shared_vertices(); - - init_from_mesh(mesh); -} - -bool GCodeViewer::SequentialView::Marker::init_from_mesh(const TriangleMesh& mesh) -{ - auto get_normal = [](const std::array& triangle) { - return (triangle[1] - triangle[0]).cross(triangle[2] - triangle[0]).normalized(); - }; - - reset(); - - // vertex data -> load from mesh - std::vector vertices(6 * mesh.its.vertices.size()); - for (size_t i = 0; i < mesh.its.vertices.size(); ++i) { - ::memcpy(static_cast(&vertices[i * 6]), static_cast(mesh.its.vertices[i].data()), 3 * sizeof(float)); - } - - // indices/normals data -> load from mesh - std::vector indices(3 * mesh.its.indices.size()); - for (size_t i = 0; i < mesh.its.indices.size(); ++i) { - const stl_triangle_vertex_indices& triangle = mesh.its.indices[i]; - for (size_t j = 0; j < 3; ++j) { - indices[i * 3 + j] = static_cast(triangle[j]); - } - Vec3f normal = get_normal({ mesh.its.vertices[triangle[0]], mesh.its.vertices[triangle[1]], mesh.its.vertices[triangle[2]] }); - ::memcpy(static_cast(&vertices[3 + static_cast(triangle[0]) * 6]), static_cast(normal.data()), 3 * sizeof(float)); - ::memcpy(static_cast(&vertices[3 + static_cast(triangle[1]) * 6]), static_cast(normal.data()), 3 * sizeof(float)); - ::memcpy(static_cast(&vertices[3 + static_cast(triangle[2]) * 6]), static_cast(normal.data()), 3 * sizeof(float)); - } - - m_indices_count = static_cast(indices.size()); - - // vertex data -> send to gpu - glsafe(::glGenBuffers(1, &m_vbo_id)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id)); - glsafe(::glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - - // indices data -> send to gpu - glsafe(::glGenBuffers(1, &m_ibo_id)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo_id)); - glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - - return init_shader(); + m_model.init_from(stilized_arrow(16, 0.5f, 1.0f, 0.25f, 2.0f)); + init_shader(); } void GCodeViewer::SequentialView::Marker::render() const @@ -249,56 +164,22 @@ void GCodeViewer::SequentialView::Marker::render() const if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)m_color.data())); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id)); - glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)0)); - glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)))); - - glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); - glsafe(::glPushMatrix()); glsafe(::glMultMatrixf(m_world_transform.data())); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo_id)); - glsafe(::glDrawElements(GL_TRIANGLES, static_cast(m_indices_count), GL_UNSIGNED_INT, (const void*)0)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + m_model.render(); glsafe(::glPopMatrix()); - glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); - - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - m_shader.stop_using(); glsafe(::glDisable(GL_BLEND)); } -void GCodeViewer::SequentialView::Marker::reset() +void GCodeViewer::SequentialView::Marker::init_shader() { - // release gpu memory - if (m_ibo_id > 0) { - glsafe(::glDeleteBuffers(1, &m_ibo_id)); - m_ibo_id = 0; - } - - if (m_vbo_id > 0) { - glsafe(::glDeleteBuffers(1, &m_vbo_id)); - m_vbo_id = 0; - } - - m_indices_count = 0; -} - -bool GCodeViewer::SequentialView::Marker::init_shader() -{ - if (!m_shader.init("gouraud_light.vs", "gouraud_light.fs")) { + if (!m_shader.init("gouraud_light.vs", "gouraud_light.fs")) BOOST_LOG_TRIVIAL(error) << "Unable to initialize gouraud_light shader: please, check that the files gouraud_light.vs and gouraud_light.fs are available"; - return false; - } - - return true; } const std::vector GCodeViewer::Extrusion_Role_Colors {{ diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index d34e8ee4bd..44f23b2852 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -5,6 +5,7 @@ #include "GLShader.hpp" #include "3DScene.hpp" #include "libslic3r/GCode/GCodeProcessor.hpp" +#include "GLModel.hpp" #include @@ -152,31 +153,25 @@ class GCodeViewer { class Marker { - unsigned int m_vbo_id{ 0 }; - unsigned int m_ibo_id{ 0 }; - size_t m_indices_count{ 0 }; + GL_Model m_model; Transform3f m_world_transform; std::array m_color{ 1.0f, 1.0f, 1.0f, 1.0f }; bool m_visible{ false }; Shader m_shader; public: - ~Marker() { reset(); } - void init(); - bool init_from_mesh(const TriangleMesh& mesh); void set_world_transform(const Transform3f& transform) { m_world_transform = transform; } - void set_color(const std::array& color) { m_color = color; } bool is_visible() const { return m_visible; } void set_visible(bool visible) { m_visible = visible; } + void render() const; - void reset(); private: - bool init_shader(); + void init_shader(); }; unsigned int first{ 0 }; diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp new file mode 100644 index 0000000000..336c699371 --- /dev/null +++ b/src/slic3r/GUI/GLModel.cpp @@ -0,0 +1,229 @@ +#include "libslic3r/libslic3r.h" +#include "GLModel.hpp" + +#include "3DScene.hpp" +#include "libslic3r/TriangleMesh.hpp" + +#include + +namespace Slic3r { +namespace GUI { + +bool GL_Model::init_from(const GLModelInitializationData& data) +{ + assert(!data.positions.empty() && !data.triangles.empty()); + assert(data.positions.size() == data.normals.size()); + + reset(); + + // vertices/normals data + std::vector vertices(6 * data.positions.size()); + for (size_t i = 0; i < data.positions.size(); ++i) { + ::memcpy(static_cast(&vertices[i * 6]), static_cast(data.positions[i].data()), 3 * sizeof(float)); + ::memcpy(static_cast(&vertices[3 + i * 6]), static_cast(data.normals[i].data()), 3 * sizeof(float)); + } + + // indices data + std::vector indices(3 * data.triangles.size()); + for (size_t i = 0; i < data.triangles.size(); ++i) { + for (size_t j = 0; j < 3; ++j) { + indices[i * 3 + j] = static_cast(data.triangles[i][j]); + } + } + + m_indices_count = static_cast(indices.size()); + + send_to_gpu(vertices, indices); + + return true; +} + +bool GL_Model::init_from(const TriangleMesh& mesh) +{ + auto get_normal = [](const std::array& triangle) { + return (triangle[1] - triangle[0]).cross(triangle[2] - triangle[0]).normalized(); + }; + + reset(); + + assert(!mesh.its.vertices.empty() && !mesh.its.indices.empty()); // call require_shared_vertices() before to pass the mesh to this method + + // vertices data -> load from mesh + std::vector vertices(6 * mesh.its.vertices.size()); + for (size_t i = 0; i < mesh.its.vertices.size(); ++i) { + ::memcpy(static_cast(&vertices[i * 6]), static_cast(mesh.its.vertices[i].data()), 3 * sizeof(float)); + } + + // indices/normals data -> load from mesh + std::vector indices(3 * mesh.its.indices.size()); + for (size_t i = 0; i < mesh.its.indices.size(); ++i) { + const stl_triangle_vertex_indices& triangle = mesh.its.indices[i]; + for (size_t j = 0; j < 3; ++j) { + indices[i * 3 + j] = static_cast(triangle[j]); + } + Vec3f normal = get_normal({ mesh.its.vertices[triangle[0]], mesh.its.vertices[triangle[1]], mesh.its.vertices[triangle[2]] }); + ::memcpy(static_cast(&vertices[3 + static_cast(triangle[0]) * 6]), static_cast(normal.data()), 3 * sizeof(float)); + ::memcpy(static_cast(&vertices[3 + static_cast(triangle[1]) * 6]), static_cast(normal.data()), 3 * sizeof(float)); + ::memcpy(static_cast(&vertices[3 + static_cast(triangle[2]) * 6]), static_cast(normal.data()), 3 * sizeof(float)); + } + + m_indices_count = static_cast(indices.size()); + + send_to_gpu(vertices, indices); + + return true; +} + +void GL_Model::reset() +{ + // release gpu memory + if (m_ibo_id > 0) { + glsafe(::glDeleteBuffers(1, &m_ibo_id)); + m_ibo_id = 0; + } + + if (m_vbo_id > 0) { + glsafe(::glDeleteBuffers(1, &m_vbo_id)); + m_vbo_id = 0; + } + + m_indices_count = 0; +} + +void GL_Model::render() const +{ + if (m_vbo_id == 0 || m_ibo_id == 0) + return; + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id)); + glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)0)); + glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)))); + + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); + + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo_id)); + glsafe(::glDrawElements(GL_TRIANGLES, static_cast(m_indices_count), GL_UNSIGNED_INT, (const void*)0)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + + glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); +} + +void GL_Model::send_to_gpu(const std::vector& vertices, const std::vector& indices) +{ + // vertex data -> send to gpu + glsafe(::glGenBuffers(1, &m_vbo_id)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id)); + glsafe(::glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + + // indices data -> send to gpu + glsafe(::glGenBuffers(1, &m_ibo_id)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo_id)); + glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); +} + +GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float tip_height, float stem_radius, float stem_height) +{ + GLModelInitializationData data; + + float angle_step = 2.0f * M_PI / static_cast(resolution); + std::vector cosines(resolution); + std::vector sines(resolution); + + for (int i = 0; i < resolution; ++i) + { + float angle = angle_step * static_cast(i); + cosines[i] = ::cos(angle); + sines[i] = -::sin(angle); + } + + // tip vertices/normals + data.positions.emplace_back(0.0f, 0.0f, 0.0f); + data.normals.emplace_back(-Vec3f::UnitZ()); + for (int i = 0; i < resolution; ++i) + { + data.positions.emplace_back(tip_radius * sines[i], tip_radius * cosines[i], tip_height); + data.normals.emplace_back(sines[i], cosines[i], 0.0f); + } + + // tip triangles + for (int i = 0; i < resolution; ++i) + { + int v3 = (i < resolution - 1) ? i + 2 : 1; + data.triangles.emplace_back(0, v3, i + 1); + } + + // tip cap outer perimeter vertices + for (int i = 0; i < resolution; ++i) + { + data.positions.emplace_back(tip_radius * sines[i], tip_radius * cosines[i], tip_height); + data.normals.emplace_back(Vec3f::UnitZ()); + } + + // tip cap inner perimeter vertices + for (int i = 0; i < resolution; ++i) + { + data.positions.emplace_back(stem_radius * sines[i], stem_radius * cosines[i], tip_height); + data.normals.emplace_back(Vec3f::UnitZ()); + } + + // tip cap triangles + for (int i = 0; i < resolution; ++i) + { + int v2 = (i < resolution - 1) ? i + resolution + 2 : resolution + 1; + int v3 = (i < resolution - 1) ? i + 2 * resolution + 2 : 2 * resolution + 1; + data.triangles.emplace_back(i + resolution + 1, v2, v3); + data.triangles.emplace_back(i + resolution + 1, v3, i + 2 * resolution + 1); + } + + // stem bottom vertices + for (int i = 0; i < resolution; ++i) + { + data.positions.emplace_back(stem_radius * sines[i], stem_radius * cosines[i], tip_height); + data.normals.emplace_back(sines[i], cosines[i], 0.0f); + } + + float total_height = tip_height + stem_height; + + // stem top vertices + for (int i = 0; i < resolution; ++i) + { + data.positions.emplace_back(stem_radius * sines[i], stem_radius * cosines[i], total_height); + data.normals.emplace_back(sines[i], cosines[i], 0.0f); + } + + // stem triangles + for (int i = 0; i < resolution; ++i) + { + int v2 = (i < resolution - 1) ? i + 3 * resolution + 2 : 3 * resolution + 1; + int v3 = (i < resolution - 1) ? i + 4 * resolution + 2 : 4 * resolution + 1; + data.triangles.emplace_back(i + 3 * resolution + 1, v2, v3); + data.triangles.emplace_back(i + 3 * resolution + 1, v3, i + 4 * resolution + 1); + } + + // stem cap vertices + data.positions.emplace_back(0.0f, 0.0f, total_height); + data.normals.emplace_back(Vec3f::UnitZ()); + for (int i = 0; i < resolution; ++i) + { + data.positions.emplace_back(stem_radius * sines[i], stem_radius * cosines[i], total_height); + data.normals.emplace_back(Vec3f::UnitZ()); + } + + // stem cap triangles + for (int i = 0; i < resolution; ++i) + { + int v3 = (i < resolution - 1) ? i + 5 * resolution + 3 : 5 * resolution + 2; + data.triangles.emplace_back(5 * resolution + 1, i + 5 * resolution + 2, v3); + } + + return data; +} + +} // namespace GUI +} // namespace Slic3r diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp new file mode 100644 index 0000000000..f294531abb --- /dev/null +++ b/src/slic3r/GUI/GLModel.hpp @@ -0,0 +1,46 @@ +#ifndef slic3r_GLModel_hpp_ +#define slic3r_GLModel_hpp_ + +namespace Slic3r { + +class TriangleMesh; + +namespace GUI { + + struct GLModelInitializationData + { + std::vector positions; + std::vector normals; + std::vector triangles; + }; + + class GL_Model + { + unsigned int m_vbo_id{ 0 }; + unsigned int m_ibo_id{ 0 }; + size_t m_indices_count{ 0 }; + + public: + virtual ~GL_Model() { reset(); } + + bool init_from(const GLModelInitializationData& data); + bool init_from(const TriangleMesh& mesh); + void reset(); + void render() const; + + private: + void send_to_gpu(const std::vector& vertices, const std::vector& indices); + }; + + + // create an arrow with cylindrical stem and conical tip, with the given dimensions and resolution + // the arrow tip is at 0,0,0 + // the arrow has its axis of symmetry along the Z axis and is pointing downward + GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float tip_height, + float stem_radius, float stem_height); + +} // namespace GUI +} // namespace Slic3r + +#endif // slic3r_GLModel_hpp_ + From b2f8f2bca6a3b2907870743180af05130a0352fc Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 11 May 2020 16:37:04 +0200 Subject: [PATCH 067/255] Added missing includes --- src/slic3r/GUI/GLModel.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index f294531abb..18e8bafbdd 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -1,6 +1,9 @@ #ifndef slic3r_GLModel_hpp_ #define slic3r_GLModel_hpp_ +#include "libslic3r/Point.hpp" +#include + namespace Slic3r { class TriangleMesh; From 8d5cea82f4e2035663812547d65a5bb1a63ea73a Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 12 May 2020 11:33:50 +0200 Subject: [PATCH 068/255] Tech ENABLE_GCODE_VIEWER -> Bed axes rendered using the new OpenGL model class --- src/slic3r/GUI/3DBed.cpp | 74 +++++++++++++++++++++++++++++++++- src/slic3r/GUI/3DBed.hpp | 33 +++++++++++++++ src/slic3r/GUI/GCodeViewer.cpp | 6 ++- src/slic3r/GUI/GCodeViewer.hpp | 2 + src/slic3r/GUI/GLModel.cpp | 63 ++++++++++++++++------------- src/slic3r/GUI/GLModel.hpp | 13 ++++-- 6 files changed, 154 insertions(+), 37 deletions(-) diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 6c070ca99a..4ef8679603 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -5,15 +5,24 @@ #include "libslic3r/Polygon.hpp" #include "libslic3r/ClipperUtils.hpp" #include "libslic3r/BoundingBox.hpp" +#if ENABLE_GCODE_VIEWER +#include "libslic3r/Geometry.hpp" +#endif // ENABLE_GCODE_VIEWER #include "GUI_App.hpp" #include "PresetBundle.hpp" #include "GLCanvas3D.hpp" +#if ENABLE_GCODE_VIEWER +#include "3DScene.hpp" +#endif // ENABLE_GCODE_VIEWER #include #include #include +#if ENABLE_GCODE_VIEWER +#include +#endif // ENABLE_GCODE_VIEWER static const float GROUND_Z = -0.02f; @@ -119,13 +128,25 @@ const float* GeometryBuffer::get_vertices_data() const return (m_vertices.size() > 0) ? (const float*)m_vertices.data() : nullptr; } +#if ENABLE_GCODE_VIEWER +const float Bed3D::Axes::DefaultStemRadius = 0.5f; +const float Bed3D::Axes::DefaultStemLength = 25.0f; +const float Bed3D::Axes::DefaultTipRadius = 2.5f * Bed3D::Axes::DefaultStemRadius; +const float Bed3D::Axes::DefaultTipLength = 5.0f; +#else const double Bed3D::Axes::Radius = 0.5; const double Bed3D::Axes::ArrowBaseRadius = 2.5 * Bed3D::Axes::Radius; const double Bed3D::Axes::ArrowLength = 5.0; +#endif // ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER +void Bed3D::Axes::set_stem_length(float length) +{ + m_stem_length = length; + m_arrow.reset(); +} +#else Bed3D::Axes::Axes() -: origin(Vec3d::Zero()) -, length(25.0 * Vec3d::Ones()) { m_quadric = ::gluNewQuadric(); if (m_quadric != nullptr) @@ -137,9 +158,46 @@ Bed3D::Axes::~Axes() if (m_quadric != nullptr) ::gluDeleteQuadric(m_quadric); } +#endif // ENABLE_GCODE_VIEWER void Bed3D::Axes::render() const { +#if ENABLE_GCODE_VIEWER + auto render_axis = [this](const Transform3f& transform, GLint color_id, const std::array& color) { + if (color_id >= 0) + glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)color.data())); + + glsafe(::glPushMatrix()); + glsafe(::glMultMatrixf(transform.data())); + m_arrow.render(); + glsafe(::glPopMatrix()); + }; + + m_arrow.init_from(stilized_arrow(16, DefaultTipRadius, DefaultTipLength, DefaultStemRadius, m_stem_length)); + if (!m_shader.init("gouraud_light.vs", "gouraud_light.fs")) + BOOST_LOG_TRIVIAL(error) << "Unable to initialize gouraud_light shader: please, check that the files gouraud_light.vs and gouraud_light.fs are available"; + + if (!m_shader.is_initialized()) + return; + + glsafe(::glEnable(GL_DEPTH_TEST)); + + m_shader.start_using(); + GLint color_id = ::glGetUniformLocation(m_shader.get_shader_program_id(), "uniform_color"); + + // x axis + render_axis(Geometry::assemble_transform(m_origin, { 0.0, 0.5 * M_PI, 0.0f }).cast(), color_id, { 0.75f, 0.0f, 0.0f, 1.0f }); + + // y axis + render_axis(Geometry::assemble_transform(m_origin, { -0.5 * M_PI, 0.0, 0.0f }).cast(), color_id, { 0.0f, 0.75f, 0.0f, 1.0f }); + + // z axis + render_axis(Geometry::assemble_transform(m_origin).cast(), color_id, { 0.0f, 0.0f, 0.75f, 1.0f }); + + m_shader.stop_using(); + + glsafe(::glDisable(GL_DEPTH_TEST)); +#else if (m_quadric == nullptr) return; @@ -171,8 +229,10 @@ void Bed3D::Axes::render() const glsafe(::glDisable(GL_LIGHTING)); glsafe(::glDisable(GL_DEPTH_TEST)); +#endif // !ENABLE_GCODE_VIEWER } +#if !ENABLE_GCODE_VIEWER void Bed3D::Axes::render_axis(double length) const { ::gluQuadricOrientation(m_quadric, GLU_OUTSIDE); @@ -185,6 +245,7 @@ void Bed3D::Axes::render_axis(double length) const ::gluQuadricOrientation(m_quadric, GLU_INSIDE); ::gluDisk(m_quadric, 0.0, ArrowBaseRadius, 32, 1); } +#endif // !ENABLE_GCODE_VIEWER Bed3D::Bed3D() : m_type(Custom) @@ -242,8 +303,13 @@ bool Bed3D::set_shape(const Pointfs& shape, const std::string& custom_texture, c m_model.reset(); // Set the origin and size for rendering the coordinate system axes. +#if ENABLE_GCODE_VIEWER + m_axes.set_origin({ 0.0, 0.0, static_cast(GROUND_Z) }); + m_axes.set_stem_length(0.1f * static_cast(m_bounding_box.max_size())); +#else m_axes.origin = Vec3d(0.0, 0.0, (double)GROUND_Z); m_axes.length = 0.1 * m_bounding_box.max_size() * Vec3d::Ones(); +#endif // ENABLE_GCODE_VIEWER // Let the calee to update the UI. return true; @@ -290,7 +356,11 @@ void Bed3D::calc_bounding_boxes() const m_extended_bounding_box = m_bounding_box; // extend to contain axes +#if ENABLE_GCODE_VIEWER + m_extended_bounding_box.merge(m_axes.get_total_length() * Vec3d::Ones()); +#else m_extended_bounding_box.merge(m_axes.length + Axes::ArrowLength * Vec3d::Ones()); +#endif // ENABLE_GCODE_VIEWER // extend to contain model, if any if (!m_model.get_filename().empty()) diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp index abdfca1fe0..440468233c 100644 --- a/src/slic3r/GUI/3DBed.hpp +++ b/src/slic3r/GUI/3DBed.hpp @@ -4,11 +4,16 @@ #include "GLTexture.hpp" #include "3DScene.hpp" #include "GLShader.hpp" +#if ENABLE_GCODE_VIEWER +#include "GLModel.hpp" +#endif // ENABLE_GCODE_VIEWER #include +#if !ENABLE_GCODE_VIEWER class GLUquadric; typedef class GLUquadric GLUquadricObj; +#endif // !ENABLE_GCODE_VIEWER namespace Slic3r { namespace GUI { @@ -45,22 +50,50 @@ public: class Bed3D { +#if ENABLE_GCODE_VIEWER + class Axes + { + static const float DefaultStemRadius; + static const float DefaultStemLength; + static const float DefaultTipRadius; + static const float DefaultTipLength; +#else struct Axes { static const double Radius; static const double ArrowBaseRadius; static const double ArrowLength; +#endif // ENABLE_GCODE_VIEWER + +#if ENABLE_GCODE_VIEWER + Vec3d m_origin{ Vec3d::Zero() }; + float m_stem_length{ DefaultStemLength }; + mutable GL_Model m_arrow; + mutable Shader m_shader; + + public: +#else Vec3d origin; Vec3d length; GLUquadricObj* m_quadric; +#endif // ENABLE_GCODE_VIEWER +#if !ENABLE_GCODE_VIEWER Axes(); ~Axes(); +#endif // !ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER + void set_origin(const Vec3d& origin) { m_origin = origin; } + void set_stem_length(float length); + float get_total_length() const { return m_stem_length + DefaultTipLength; } +#endif // ENABLE_GCODE_VIEWER void render() const; +#if !ENABLE_GCODE_VIEWER private: void render_axis(double length) const; +#endif // !ENABLE_GCODE_VIEWER }; public: diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index ad3985c625..525a2fd5a1 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -147,7 +147,7 @@ GCodeViewer::Color GCodeViewer::Extrusions::Range::get_color_at(float value) con void GCodeViewer::SequentialView::Marker::init() { - m_model.init_from(stilized_arrow(16, 0.5f, 1.0f, 0.25f, 2.0f)); + m_model.init_from(stilized_arrow(16, 2.0f, 4.0f, 1.0f, 8.0f)); init_shader(); } @@ -320,7 +320,7 @@ void GCodeViewer::render() const glsafe(::glEnable(GL_DEPTH_TEST)); render_toolpaths(); - m_sequential_view.marker.set_world_transform(Geometry::assemble_transform(m_sequential_view.current_position.cast() + 0.5 * Vec3d::UnitZ(), { 0.0, 0.0, 0.0 }, { 4.0, 4.0, 4.0 }, { 1.0, 1.0, 1.0 }).cast()); + m_sequential_view.marker.set_world_transform(Geometry::assemble_transform(m_sequential_view.current_position.cast() + (0.5 + 12.0) * Vec3d::UnitZ(), { M_PI, 0.0, 0.0 }).cast()); m_sequential_view.marker.render(); render_shells(); render_legend(); @@ -437,6 +437,8 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) ::memcpy(static_cast(&vertices_data[i * 3]), static_cast(move.position.data()), 3 * sizeof(float)); } + m_bounding_box.merge(m_bounding_box.max + m_sequential_view.marker.get_bounding_box().max[2] * Vec3d::UnitZ()); + #if ENABLE_GCODE_VIEWER_STATISTICS m_statistics.vertices_size = SLIC3R_STDVEC_MEMSIZE(vertices_data, float); m_statistics.vertices_gpu_size = vertices_data.size() * sizeof(float); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 44f23b2852..6f3ca47dba 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -162,6 +162,8 @@ class GCodeViewer public: void init(); + const BoundingBoxf3& get_bounding_box() const { return m_model.get_bounding_box(); } + void set_world_transform(const Transform3f& transform) { m_world_transform = transform; } void set_color(const std::array& color) { m_color = color; } diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index 336c699371..4b2ce4e9e9 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -9,12 +9,14 @@ namespace Slic3r { namespace GUI { -bool GL_Model::init_from(const GLModelInitializationData& data) +void GL_Model::init_from(const GLModelInitializationData& data) { + assert(!data.positions.empty() && !data.triangles.empty()); assert(data.positions.size() == data.normals.size()); - reset(); + if (m_vbo_id > 0) // call reset() if you want to reuse this model + return; // vertices/normals data std::vector vertices(6 * data.positions.size()); @@ -32,19 +34,22 @@ bool GL_Model::init_from(const GLModelInitializationData& data) } m_indices_count = static_cast(indices.size()); + m_bounding_box = BoundingBoxf3(); + for (size_t i = 0; i < data.positions.size(); ++i) { + m_bounding_box.merge(data.positions[i].cast()); + } send_to_gpu(vertices, indices); - - return true; } -bool GL_Model::init_from(const TriangleMesh& mesh) +void GL_Model::init_from(const TriangleMesh& mesh) { auto get_normal = [](const std::array& triangle) { return (triangle[1] - triangle[0]).cross(triangle[2] - triangle[0]).normalized(); }; - reset(); + if (m_vbo_id > 0) // call reset() if you want to reuse this model + return; assert(!mesh.its.vertices.empty() && !mesh.its.indices.empty()); // call require_shared_vertices() before to pass the mesh to this method @@ -68,10 +73,9 @@ bool GL_Model::init_from(const TriangleMesh& mesh) } m_indices_count = static_cast(indices.size()); + m_bounding_box = mesh.bounding_box(); send_to_gpu(vertices, indices); - - return true; } void GL_Model::reset() @@ -88,6 +92,7 @@ void GL_Model::reset() } m_indices_count = 0; + m_bounding_box = BoundingBoxf3(); } void GL_Model::render() const @@ -142,12 +147,14 @@ GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float sines[i] = -::sin(angle); } + float total_height = tip_height + stem_height; + // tip vertices/normals - data.positions.emplace_back(0.0f, 0.0f, 0.0f); - data.normals.emplace_back(-Vec3f::UnitZ()); + data.positions.emplace_back(0.0f, 0.0f, total_height); + data.normals.emplace_back(Vec3f::UnitZ()); for (int i = 0; i < resolution; ++i) { - data.positions.emplace_back(tip_radius * sines[i], tip_radius * cosines[i], tip_height); + data.positions.emplace_back(tip_radius * sines[i], tip_radius * cosines[i], stem_height); data.normals.emplace_back(sines[i], cosines[i], 0.0f); } @@ -155,21 +162,21 @@ GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float for (int i = 0; i < resolution; ++i) { int v3 = (i < resolution - 1) ? i + 2 : 1; - data.triangles.emplace_back(0, v3, i + 1); + data.triangles.emplace_back(0, i + 1, v3); } // tip cap outer perimeter vertices for (int i = 0; i < resolution; ++i) { - data.positions.emplace_back(tip_radius * sines[i], tip_radius * cosines[i], tip_height); - data.normals.emplace_back(Vec3f::UnitZ()); + data.positions.emplace_back(tip_radius * sines[i], tip_radius * cosines[i], stem_height); + data.normals.emplace_back(-Vec3f::UnitZ()); } // tip cap inner perimeter vertices for (int i = 0; i < resolution; ++i) { - data.positions.emplace_back(stem_radius * sines[i], stem_radius * cosines[i], tip_height); - data.normals.emplace_back(Vec3f::UnitZ()); + data.positions.emplace_back(stem_radius * sines[i], stem_radius * cosines[i], stem_height); + data.normals.emplace_back(-Vec3f::UnitZ()); } // tip cap triangles @@ -177,23 +184,21 @@ GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float { int v2 = (i < resolution - 1) ? i + resolution + 2 : resolution + 1; int v3 = (i < resolution - 1) ? i + 2 * resolution + 2 : 2 * resolution + 1; - data.triangles.emplace_back(i + resolution + 1, v2, v3); - data.triangles.emplace_back(i + resolution + 1, v3, i + 2 * resolution + 1); + data.triangles.emplace_back(i + resolution + 1, v3, v2); + data.triangles.emplace_back(i + resolution + 1, i + 2 * resolution + 1, v3); } // stem bottom vertices for (int i = 0; i < resolution; ++i) { - data.positions.emplace_back(stem_radius * sines[i], stem_radius * cosines[i], tip_height); + data.positions.emplace_back(stem_radius * sines[i], stem_radius * cosines[i], stem_height); data.normals.emplace_back(sines[i], cosines[i], 0.0f); } - float total_height = tip_height + stem_height; - // stem top vertices for (int i = 0; i < resolution; ++i) { - data.positions.emplace_back(stem_radius * sines[i], stem_radius * cosines[i], total_height); + data.positions.emplace_back(stem_radius * sines[i], stem_radius * cosines[i], 0.0f); data.normals.emplace_back(sines[i], cosines[i], 0.0f); } @@ -202,24 +207,24 @@ GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float { int v2 = (i < resolution - 1) ? i + 3 * resolution + 2 : 3 * resolution + 1; int v3 = (i < resolution - 1) ? i + 4 * resolution + 2 : 4 * resolution + 1; - data.triangles.emplace_back(i + 3 * resolution + 1, v2, v3); - data.triangles.emplace_back(i + 3 * resolution + 1, v3, i + 4 * resolution + 1); + data.triangles.emplace_back(i + 3 * resolution + 1, v3, v2); + data.triangles.emplace_back(i + 3 * resolution + 1, i + 4 * resolution + 1, v3); } // stem cap vertices - data.positions.emplace_back(0.0f, 0.0f, total_height); - data.normals.emplace_back(Vec3f::UnitZ()); + data.positions.emplace_back(0.0f, 0.0f, 0.0f); + data.normals.emplace_back(-Vec3f::UnitZ()); for (int i = 0; i < resolution; ++i) { - data.positions.emplace_back(stem_radius * sines[i], stem_radius * cosines[i], total_height); - data.normals.emplace_back(Vec3f::UnitZ()); + data.positions.emplace_back(stem_radius* sines[i], stem_radius* cosines[i], 0.0f); + data.normals.emplace_back(-Vec3f::UnitZ()); } // stem cap triangles for (int i = 0; i < resolution; ++i) { int v3 = (i < resolution - 1) ? i + 5 * resolution + 3 : 5 * resolution + 2; - data.triangles.emplace_back(5 * resolution + 1, i + 5 * resolution + 2, v3); + data.triangles.emplace_back(5 * resolution + 1, v3, i + 5 * resolution + 2); } return data; diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index 18e8bafbdd..7b135ada6b 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -2,6 +2,7 @@ #define slic3r_GLModel_hpp_ #include "libslic3r/Point.hpp" +#include "libslic3r/BoundingBox.hpp" #include namespace Slic3r { @@ -23,22 +24,26 @@ namespace GUI { unsigned int m_ibo_id{ 0 }; size_t m_indices_count{ 0 }; + BoundingBoxf3 m_bounding_box; + public: virtual ~GL_Model() { reset(); } - bool init_from(const GLModelInitializationData& data); - bool init_from(const TriangleMesh& mesh); + void init_from(const GLModelInitializationData& data); + void init_from(const TriangleMesh& mesh); void reset(); void render() const; + const BoundingBoxf3& get_bounding_box() const { return m_bounding_box; } + private: void send_to_gpu(const std::vector& vertices, const std::vector& indices); }; // create an arrow with cylindrical stem and conical tip, with the given dimensions and resolution - // the arrow tip is at 0,0,0 - // the arrow has its axis of symmetry along the Z axis and is pointing downward + // the origin of the arrow is in the center of the stem cap + // the arrow has its axis of symmetry along the Z axis and is pointing upward GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float tip_height, float stem_radius, float stem_height); From 58258df113249505ebe872bd1608fb08b6051884 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 12 May 2020 16:15:43 +0200 Subject: [PATCH 069/255] Tech ENABLE_GCODE_VIEWER -> Selection curved arrows rendered using the new OpenGL model class --- src/slic3r/GUI/3DScene.cpp | 2 + src/slic3r/GUI/3DScene.hpp | 2 + src/slic3r/GUI/GLModel.cpp | 184 +++++++++++++++++++++++++++++++---- src/slic3r/GUI/GLModel.hpp | 5 + src/slic3r/GUI/Selection.cpp | 54 +++++++++- src/slic3r/GUI/Selection.hpp | 9 ++ 6 files changed, 236 insertions(+), 20 deletions(-) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 6aaf0b500e..ef5e22c823 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -2002,6 +2002,7 @@ bool GLArrow::on_init() return true; } +#if !ENABLE_GCODE_VIEWER GLCurvedArrow::GLCurvedArrow(unsigned int resolution) : GLModel() , m_resolution(resolution) @@ -2115,6 +2116,7 @@ bool GLCurvedArrow::on_init() m_volume.indexed_vertex_array.finalize_geometry(true); return true; } +#endif // !ENABLE_GCODE_VIEWER bool GLBed::on_init_from_file(const std::string& filename) { diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 07c5cd53e3..d6ee72bdc1 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -648,6 +648,7 @@ protected: bool on_init() override; }; +#if !ENABLE_GCODE_VIEWER class GLCurvedArrow : public GLModel { unsigned int m_resolution; @@ -658,6 +659,7 @@ public: protected: bool on_init() override; }; +#endif // !ENABLE_GCODE_VIEWER class GLBed : public GLModel { diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index 4b2ce4e9e9..6590da1409 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -11,7 +11,6 @@ namespace GUI { void GL_Model::init_from(const GLModelInitializationData& data) { - assert(!data.positions.empty() && !data.triangles.empty()); assert(data.positions.size() == data.normals.size()); @@ -134,9 +133,16 @@ void GL_Model::send_to_gpu(const std::vector& vertices, const std::vector GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float tip_height, float stem_radius, float stem_height) { + auto append_vertex = [](GLModelInitializationData& data, const Vec3f& position, const Vec3f& normal) { + data.positions.emplace_back(position); + data.normals.emplace_back(normal); + }; + + resolution = std::max(4, resolution); + GLModelInitializationData data; - float angle_step = 2.0f * M_PI / static_cast(resolution); + const float angle_step = 2.0f * M_PI / static_cast(resolution); std::vector cosines(resolution); std::vector sines(resolution); @@ -147,15 +153,13 @@ GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float sines[i] = -::sin(angle); } - float total_height = tip_height + stem_height; + const float total_height = tip_height + stem_height; // tip vertices/normals - data.positions.emplace_back(0.0f, 0.0f, total_height); - data.normals.emplace_back(Vec3f::UnitZ()); + append_vertex(data, { 0.0f, 0.0f, total_height }, Vec3f::UnitZ()); for (int i = 0; i < resolution; ++i) { - data.positions.emplace_back(tip_radius * sines[i], tip_radius * cosines[i], stem_height); - data.normals.emplace_back(sines[i], cosines[i], 0.0f); + append_vertex(data, { tip_radius * sines[i], tip_radius * cosines[i], stem_height }, { sines[i], cosines[i], 0.0f }); } // tip triangles @@ -168,15 +172,13 @@ GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float // tip cap outer perimeter vertices for (int i = 0; i < resolution; ++i) { - data.positions.emplace_back(tip_radius * sines[i], tip_radius * cosines[i], stem_height); - data.normals.emplace_back(-Vec3f::UnitZ()); + append_vertex(data, { tip_radius * sines[i], tip_radius * cosines[i], stem_height }, -Vec3f::UnitZ()); } // tip cap inner perimeter vertices for (int i = 0; i < resolution; ++i) { - data.positions.emplace_back(stem_radius * sines[i], stem_radius * cosines[i], stem_height); - data.normals.emplace_back(-Vec3f::UnitZ()); + append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], stem_height }, -Vec3f::UnitZ()); } // tip cap triangles @@ -191,15 +193,13 @@ GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float // stem bottom vertices for (int i = 0; i < resolution; ++i) { - data.positions.emplace_back(stem_radius * sines[i], stem_radius * cosines[i], stem_height); - data.normals.emplace_back(sines[i], cosines[i], 0.0f); + append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], stem_height }, { sines[i], cosines[i], 0.0f }); } // stem top vertices for (int i = 0; i < resolution; ++i) { - data.positions.emplace_back(stem_radius * sines[i], stem_radius * cosines[i], 0.0f); - data.normals.emplace_back(sines[i], cosines[i], 0.0f); + append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], 0.0f }, { sines[i], cosines[i], 0.0f }); } // stem triangles @@ -212,12 +212,10 @@ GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float } // stem cap vertices - data.positions.emplace_back(0.0f, 0.0f, 0.0f); - data.normals.emplace_back(-Vec3f::UnitZ()); + append_vertex(data, Vec3f::Zero(), -Vec3f::UnitZ()); for (int i = 0; i < resolution; ++i) { - data.positions.emplace_back(stem_radius* sines[i], stem_radius* cosines[i], 0.0f); - data.normals.emplace_back(-Vec3f::UnitZ()); + append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], 0.0f }, -Vec3f::UnitZ()); } // stem cap triangles @@ -230,5 +228,153 @@ GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float return data; } +GLModelInitializationData circular_arrow(int resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness) +{ + auto append_vertex = [](GLModelInitializationData& data, const Vec3f& position, const Vec3f& normal) { + data.positions.emplace_back(position); + data.normals.emplace_back(normal); + }; + + resolution = std::max(2, resolution); + + GLModelInitializationData data; + + const float half_thickness = 0.5f * thickness; + const float half_stem_width = 0.5f * stem_width; + const float half_tip_width = 0.5f * tip_width; + + const float outer_radius = radius + half_stem_width; + const float inner_radius = radius - half_stem_width; + const float step_angle = 0.5f * PI / static_cast(resolution); + + // tip + // top face vertices + append_vertex(data, { 0.0f, outer_radius, half_thickness }, Vec3f::UnitZ()); + append_vertex(data, { 0.0f, radius + half_tip_width, half_thickness }, Vec3f::UnitZ()); + append_vertex(data, { -tip_height, radius, half_thickness }, Vec3f::UnitZ()); + append_vertex(data, { 0.0f, radius - half_tip_width, half_thickness }, Vec3f::UnitZ()); + append_vertex(data, { 0.0f, inner_radius, half_thickness }, Vec3f::UnitZ()); + + // top face triangles + data.triangles.emplace_back(0, 1, 2); + data.triangles.emplace_back(0, 2, 4); + data.triangles.emplace_back(4, 2, 3); + + // bottom face vertices + append_vertex(data, { 0.0f, outer_radius, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(data, { 0.0f, radius + half_tip_width, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(data, { -tip_height, radius, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(data, { 0.0f, radius - half_tip_width, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(data, { 0.0f, inner_radius, -half_thickness }, -Vec3f::UnitZ()); + + // bottom face triangles + data.triangles.emplace_back(5, 7, 6); + data.triangles.emplace_back(5, 9, 7); + data.triangles.emplace_back(9, 8, 7); + + // side faces vertices + append_vertex(data, { 0.0f, outer_radius, half_thickness }, Vec3f::UnitX()); + append_vertex(data, { 0.0f, radius + half_tip_width, half_thickness }, Vec3f::UnitY()); + append_vertex(data, { -tip_height, radius, half_thickness }, -Vec3f::UnitX()); + append_vertex(data, { 0.0f, radius - half_tip_width, half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { 0.0f, inner_radius, half_thickness }, Vec3f::UnitX()); + + append_vertex(data, { 0.0f, outer_radius, -half_thickness }, Vec3f::UnitX()); + append_vertex(data, { 0.0f, radius + half_tip_width, -half_thickness }, Vec3f::UnitY()); + append_vertex(data, { -tip_height, radius, -half_thickness }, -Vec3f::UnitX()); + append_vertex(data, { 0.0f, radius - half_tip_width, -half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { 0.0f, inner_radius, -half_thickness }, Vec3f::UnitX()); + + // side faces triangles + for (int i = 0; i < 4; ++i) + { + data.triangles.emplace_back(15 + i, 11 + i, 10 + i); + data.triangles.emplace_back(15 + i, 16 + i, 11 + i); + } + + // stem + // top face vertices + for (int i = 0; i <= resolution; ++i) + { + float angle = static_cast(i) * step_angle; + append_vertex(data, { inner_radius * ::sin(angle), inner_radius * ::cos(angle), half_thickness }, Vec3f::UnitZ()); + } + + for (int i = 0; i <= resolution; ++i) + { + float angle = static_cast(i) * step_angle; + append_vertex(data, { outer_radius * ::sin(angle), outer_radius * ::cos(angle), half_thickness }, Vec3f::UnitZ()); + } + + // top face triangles + for (int i = 0; i < resolution; ++i) + { + data.triangles.emplace_back(20 + i, 21 + i, 21 + resolution + i); + data.triangles.emplace_back(21 + i, 22 + resolution + i, 21 + resolution + i); + } + + // bottom face vertices + for (int i = 0; i <= resolution; ++i) + { + float angle = static_cast(i) * step_angle; + append_vertex(data, { inner_radius * ::sin(angle), inner_radius * ::cos(angle), -half_thickness }, -Vec3f::UnitZ()); + } + + for (int i = 0; i <= resolution; ++i) + { + float angle = static_cast(i) * step_angle; + append_vertex(data, { outer_radius * ::sin(angle), outer_radius * ::cos(angle), -half_thickness }, -Vec3f::UnitZ()); + } + + // bottom face triangles + for (int i = 0; i < resolution; ++i) + { + data.triangles.emplace_back(22 + 2 * resolution + i, 23 + 3 * resolution + i, 23 + 2 * resolution + i); + data.triangles.emplace_back(23 + 2 * resolution + i, 23 + 3 * resolution + i, 24 + 3 * resolution + i); + } + + // side faces vertices + for (int i = 0; i <= resolution; ++i) + { + float angle = static_cast(i) * step_angle; + float c = ::cos(angle); + float s = ::sin(angle); + append_vertex(data, { inner_radius * s, inner_radius * c, half_thickness }, { -s, -c, 0.0f}); + } + + for (int i = resolution; i >= 0; --i) + { + float angle = static_cast(i) * step_angle; + float c = ::cos(angle); + float s = ::sin(angle); + append_vertex(data, { outer_radius * s, outer_radius * c, half_thickness }, { s, c, 0.0f }); + } + + for (int i = 0; i <= resolution; ++i) + { + float angle = static_cast(i) * step_angle; + float c = ::cos(angle); + float s = ::sin(angle); + append_vertex(data, { inner_radius * s, inner_radius * c, -half_thickness }, { -s, -c, 0.0f }); + } + + for (int i = resolution; i >= 0; --i) + { + float angle = static_cast(i) * step_angle; + float c = ::cos(angle); + float s = ::sin(angle); + append_vertex(data, { outer_radius * s, outer_radius * c, -half_thickness }, { s, c, 0.0f }); + } + + // side faces triangles + for (int i = 0; i < 2 * resolution + 1; ++i) + { + data.triangles.emplace_back(20 + 6 * (resolution + 1) + i, 21 + 6 * (resolution + 1) + i, 21 + 4 * (resolution + 1) + i); + data.triangles.emplace_back(20 + 6 * (resolution + 1) + i, 21 + 4 * (resolution + 1) + i, 20 + 4 * (resolution + 1) + i); + } + + return data; +} + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index 7b135ada6b..c55931ef10 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -47,6 +47,11 @@ namespace GUI { GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float tip_height, float stem_radius, float stem_height); + // create an arrow whose stem is a quarter of circle, with the given dimensions and resolution + // the origin of the arrow is in the center of the circle + // the arrow is contained in the 1st quadrant and is pointing counterclockwise + GLModelInitializationData circular_arrow(int resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness); + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 87f8b60ede..62a046a251 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -13,6 +13,9 @@ #include #include +#if ENABLE_GCODE_VIEWER +#include +#endif // ENABLE_GCODE_VIEWER static const float UNIFORM_SCALE_COLOR[3] = { 1.0f, 0.38f, 0.0f }; @@ -76,7 +79,9 @@ Selection::Selection() , m_mode(Instance) , m_type(Empty) , m_valid(false) +#if !ENABLE_GCODE_VIEWER , m_curved_arrow(16) +#endif // !ENABLE_GCODE_VIEWER , m_scale_factor(1.0f) { this->set_bounding_boxes_dirty(); @@ -109,10 +114,21 @@ bool Selection::init() m_arrow.set_scale(5.0 * Vec3d::Ones()); +#if ENABLE_GCODE_VIEWER + m_curved_arrow.init_from(circular_arrow(16, 10.0f, 5.0f, 10.0f, 5.0f, 1.0f)); + + if (!m_arrows_shader.init("gouraud_light.vs", "gouraud_light.fs")) + { + BOOST_LOG_TRIVIAL(error) << "Unable to initialize gouraud_light shader: please, check that the files gouraud_light.vs and gouraud_light.fs are available"; + return false; + } +#else if (!m_curved_arrow.init()) return false; m_curved_arrow.set_scale(5.0 * Vec3d::Ones()); +#endif //ENABLE_GCODE_VIEWER + return true; } @@ -1927,6 +1943,40 @@ void Selection::render_sidebar_position_hints(const std::string& sidebar_field) void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) const { +#if ENABLE_GCODE_VIEWER + if (!m_arrows_shader.is_initialized()) + return; + + m_arrows_shader.start_using(); + GLint color_id = ::glGetUniformLocation(m_arrows_shader.get_shader_program_id(), "uniform_color"); + + if (boost::ends_with(sidebar_field, "x")) + { + if (color_id >= 0) + glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[0])); + + glsafe(::glRotated(90.0, 0.0, 1.0, 0.0)); + render_sidebar_rotation_hint(X); + } + else if (boost::ends_with(sidebar_field, "y")) + { + if (color_id >= 0) + glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[1])); + + glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0)); + render_sidebar_rotation_hint(Y); + } + else if (boost::ends_with(sidebar_field, "z")) + { + if (color_id >= 0) + glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[2])); + + render_sidebar_rotation_hint(Z); + } + + m_arrows_shader.stop_using(); + +#else if (boost::ends_with(sidebar_field, "x")) { glsafe(::glRotated(90.0, 0.0, 1.0, 0.0)); @@ -1939,6 +1989,7 @@ void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) } else if (boost::ends_with(sidebar_field, "z")) render_sidebar_rotation_hint(Z); +#endif // ENABLE_GCODE_VIEWER } void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) const @@ -2054,9 +2105,10 @@ void Selection::render_sidebar_position_hint(Axis axis) const void Selection::render_sidebar_rotation_hint(Axis axis) const { +#if !ENABLE_GCODE_VIEWER m_curved_arrow.set_color(AXES_COLOR[axis], 3); +#endif // !ENABLE_GCODE_VIEWER m_curved_arrow.render(); - glsafe(::glRotated(180.0, 0.0, 0.0, 1.0)); m_curved_arrow.render(); } diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index c27b4cc29d..321cb70e04 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -4,6 +4,10 @@ #include #include "libslic3r/Geometry.hpp" #include "3DScene.hpp" +#if ENABLE_GCODE_VIEWER +#include "GLModel.hpp" +#include "GLShader.hpp" +#endif // ENABLE_GCODE_VIEWER #if ENABLE_RENDER_SELECTION_CENTER class GLUquadric; @@ -201,7 +205,12 @@ private: GLUquadricObj* m_quadric; #endif // ENABLE_RENDER_SELECTION_CENTER mutable GLArrow m_arrow; +#if ENABLE_GCODE_VIEWER + GL_Model m_curved_arrow; + Shader m_arrows_shader; +#else mutable GLCurvedArrow m_curved_arrow; +#endif // ENABLE_GCODE_VIEWER mutable float m_scale_factor; From b59fc1e57d7e6f66cb580196c984f5d18cec7027 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 13 May 2020 09:07:06 +0200 Subject: [PATCH 070/255] Tech ENABLE_GCODE_VIEWER -> Selection straight arrows rendered using the new OpenGL model class --- src/slic3r/GUI/GLCanvas3D.cpp | 4 ++ src/slic3r/GUI/GLModel.cpp | 97 ++++++++++++++++++++++++++++++++++ src/slic3r/GUI/GLModel.hpp | 7 ++- src/slic3r/GUI/Selection.cpp | 98 ++++++++++++++++++++++++++++++----- src/slic3r/GUI/Selection.hpp | 11 +++- 5 files changed, 203 insertions(+), 14 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ba8d3b1ba6..1cbfac4e48 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -5976,7 +5976,11 @@ void GLCanvas3D::_render_sla_slices() const void GLCanvas3D::_render_selection_sidebar_hints() const { +#if ENABLE_GCODE_VIEWER + m_selection.render_sidebar_hints(m_sidebar_field); +#else m_selection.render_sidebar_hints(m_sidebar_field, m_shader); +#endif // ENABLE_GCODE_VIEWER } void GLCanvas3D::_update_volumes_hover_state() const diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index 6590da1409..ee98ce678a 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -376,5 +376,102 @@ GLModelInitializationData circular_arrow(int resolution, float radius, float tip return data; } +GLModelInitializationData straight_arrow(float tip_width, float tip_height, float stem_width, float stem_height, float thickness) +{ + auto append_vertex = [](GLModelInitializationData& data, const Vec3f& position, const Vec3f& normal) { + data.positions.emplace_back(position); + data.normals.emplace_back(normal); + }; + + GLModelInitializationData data; + + const float half_thickness = 0.5f * thickness; + const float half_stem_width = 0.5f * stem_width; + const float half_tip_width = 0.5f * tip_width; + const float total_height = tip_height + stem_height; + + // top face vertices + append_vertex(data, { half_stem_width, 0.0, half_thickness }, Vec3f::UnitZ()); + append_vertex(data, { half_stem_width, stem_height, half_thickness }, Vec3f::UnitZ()); + append_vertex(data, { half_tip_width, stem_height, half_thickness }, Vec3f::UnitZ()); + append_vertex(data, { 0.0, total_height, half_thickness }, Vec3f::UnitZ()); + append_vertex(data, { -half_tip_width, stem_height, half_thickness }, Vec3f::UnitZ()); + append_vertex(data, { -half_stem_width, stem_height, half_thickness }, Vec3f::UnitZ()); + append_vertex(data, { -half_stem_width, 0.0, half_thickness }, Vec3f::UnitZ()); + + // top face triangles + data.triangles.emplace_back(0, 1, 6); + data.triangles.emplace_back(6, 1, 5); + data.triangles.emplace_back(4, 5, 3); + data.triangles.emplace_back(5, 1, 3); + data.triangles.emplace_back(1, 2, 3); + + // bottom face vertices + append_vertex(data, { half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(data, { half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(data, { half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(data, { 0.0, total_height, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(data, { -half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(data, { -half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(data, { -half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitZ()); + + // bottom face triangles + data.triangles.emplace_back(7, 13, 8); + data.triangles.emplace_back(13, 12, 8); + data.triangles.emplace_back(12, 11, 10); + data.triangles.emplace_back(8, 12, 10); + data.triangles.emplace_back(9, 8, 10); + + // side faces vertices + append_vertex(data, { half_stem_width, 0.0, -half_thickness }, Vec3f::UnitX()); + append_vertex(data, { half_stem_width, stem_height, -half_thickness }, Vec3f::UnitX()); + append_vertex(data, { half_stem_width, 0.0, half_thickness }, Vec3f::UnitX()); + append_vertex(data, { half_stem_width, stem_height, half_thickness }, Vec3f::UnitX()); + + append_vertex(data, { half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { half_stem_width, stem_height, half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { half_tip_width, stem_height, half_thickness }, -Vec3f::UnitY()); + + Vec3f normal(tip_height, half_tip_width, 0.0f); + normal.normalize(); + append_vertex(data, { half_tip_width, stem_height, -half_thickness }, normal); + append_vertex(data, { 0.0, total_height, -half_thickness }, normal); + append_vertex(data, { half_tip_width, stem_height, half_thickness }, normal); + append_vertex(data, { 0.0, total_height, half_thickness }, normal); + + normal = Vec3f(-tip_height, half_tip_width, 0.0f); + normal.normalize(); + append_vertex(data, { 0.0, total_height, -half_thickness }, normal); + append_vertex(data, { -half_tip_width, stem_height, -half_thickness }, normal); + append_vertex(data, { 0.0, total_height, half_thickness }, normal); + append_vertex(data, { -half_tip_width, stem_height, half_thickness }, normal); + + append_vertex(data, { -half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { -half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { -half_tip_width, stem_height, half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { -half_stem_width, stem_height, half_thickness }, -Vec3f::UnitY()); + + append_vertex(data, { -half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitX()); + append_vertex(data, { -half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitX()); + append_vertex(data, { -half_stem_width, stem_height, half_thickness }, -Vec3f::UnitX()); + append_vertex(data, { -half_stem_width, 0.0, half_thickness }, -Vec3f::UnitX()); + + append_vertex(data, { -half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { -half_stem_width, 0.0, half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { half_stem_width, 0.0, half_thickness }, -Vec3f::UnitY()); + + // side face triangles + for (int i = 0; i < 7; ++i) + { + int ii = i * 4; + data.triangles.emplace_back(14 + ii, 15 + ii, 17 + ii); + data.triangles.emplace_back(14 + ii, 17 + ii, 16 + ii); + } + + return data; +} + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index c55931ef10..a11073b191 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -49,9 +49,14 @@ namespace GUI { // create an arrow whose stem is a quarter of circle, with the given dimensions and resolution // the origin of the arrow is in the center of the circle - // the arrow is contained in the 1st quadrant and is pointing counterclockwise + // the arrow is contained in the 1st quadrant of the XY plane and is pointing counterclockwise GLModelInitializationData circular_arrow(int resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness); + // create an arrow with the given dimensions + // the origin of the arrow is in the center of the stem cap + // the arrow is contained in XY plane and has its main axis along the Y axis + GLModelInitializationData straight_arrow(float tip_width, float tip_height, float stem_width, float stem_height, float thickness); + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 62a046a251..3bab06b4d5 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -109,12 +109,8 @@ void Selection::set_volumes(GLVolumePtrs* volumes) // Init shall be called from the OpenGL render function, so that the OpenGL context is initialized! bool Selection::init() { - if (!m_arrow.init()) - return false; - - m_arrow.set_scale(5.0 * Vec3d::Ones()); - #if ENABLE_GCODE_VIEWER + m_arrow.init_from(straight_arrow(10.0f, 5.0f, 5.0f, 10.0f, 1.0f)); m_curved_arrow.init_from(circular_arrow(16, 10.0f, 5.0f, 10.0f, 5.0f, 1.0f)); if (!m_arrows_shader.init("gouraud_light.vs", "gouraud_light.fs")) @@ -123,6 +119,11 @@ bool Selection::init() return false; } #else + if (!m_arrow.init()) + return false; + + m_arrow.set_scale(5.0 * Vec3d::Ones()); + if (!m_curved_arrow.init()) return false; @@ -1243,16 +1244,28 @@ void Selection::render_center(bool gizmo_is_dragging) const } #endif // ENABLE_RENDER_SELECTION_CENTER +#if ENABLE_GCODE_VIEWER +void Selection::render_sidebar_hints(const std::string& sidebar_field) const +#else void Selection::render_sidebar_hints(const std::string& sidebar_field, const Shader& shader) const +#endif // ENABLE_GCODE_VIEWER { if (sidebar_field.empty()) return; if (!boost::starts_with(sidebar_field, "layer")) { +#if ENABLE_GCODE_VIEWER + if (!m_arrows_shader.is_initialized()) + return; + + m_arrows_shader.start_using(); + glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); +#else shader.start_using(); glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); glsafe(::glEnable(GL_LIGHTING)); +#endif // ENABLE_GCODE_VIEWER } glsafe(::glEnable(GL_DEPTH_TEST)); @@ -1323,8 +1336,12 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field, const Sha if (!boost::starts_with(sidebar_field, "layer")) { +#if ENABLE_GCODE_VIEWER + m_arrows_shader.stop_using(); +#else glsafe(::glDisable(GL_LIGHTING)); shader.stop_using(); +#endif // ENABLE_GCODE_VIEWER } } @@ -1927,6 +1944,33 @@ void Selection::render_bounding_box(const BoundingBoxf3& box, float* color) cons void Selection::render_sidebar_position_hints(const std::string& sidebar_field) const { +#if ENABLE_GCODE_VIEWER + GLint color_id = ::glGetUniformLocation(m_arrows_shader.get_shader_program_id(), "uniform_color"); + + if (boost::ends_with(sidebar_field, "x")) + { + if (color_id >= 0) + glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[0])); + + glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0)); + m_arrow.render(); + } + else if (boost::ends_with(sidebar_field, "y")) + { + if (color_id >= 0) + glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[1])); + + m_arrow.render(); + } + else if (boost::ends_with(sidebar_field, "z")) + { + if (color_id >= 0) + glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[2])); + + glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); + m_arrow.render(); + } +#else if (boost::ends_with(sidebar_field, "x")) { glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0)); @@ -1939,15 +1983,12 @@ void Selection::render_sidebar_position_hints(const std::string& sidebar_field) glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); render_sidebar_position_hint(Z); } +#endif // ENABLE_GCODE_VIEWER } void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) const { #if ENABLE_GCODE_VIEWER - if (!m_arrows_shader.is_initialized()) - return; - - m_arrows_shader.start_using(); GLint color_id = ::glGetUniformLocation(m_arrows_shader.get_shader_program_id(), "uniform_color"); if (boost::ends_with(sidebar_field, "x")) @@ -1973,9 +2014,6 @@ void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) render_sidebar_rotation_hint(Z); } - - m_arrows_shader.stop_using(); - #else if (boost::ends_with(sidebar_field, "x")) { @@ -1996,6 +2034,7 @@ void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) con { bool uniform_scale = requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling(); +#if ENABLE_GCODE_VIEWER if (boost::ends_with(sidebar_field, "x") || uniform_scale) { glsafe(::glPushMatrix()); @@ -2018,6 +2057,30 @@ void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) con render_sidebar_scale_hint(Z); glsafe(::glPopMatrix()); } +#else + if (boost::ends_with(sidebar_field, "x") || uniform_scale) + { + glsafe(::glPushMatrix()); + glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0)); + render_sidebar_scale_hint(X); + glsafe(::glPopMatrix()); + } + + if (boost::ends_with(sidebar_field, "y") || uniform_scale) + { + glsafe(::glPushMatrix()); + render_sidebar_scale_hint(Y); + glsafe(::glPopMatrix()); + } + + if (boost::ends_with(sidebar_field, "z") || uniform_scale) + { + glsafe(::glPushMatrix()); + glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); + render_sidebar_scale_hint(Z); + glsafe(::glPopMatrix()); + } +#endif // ENABLE_GCODE_VIEWER } void Selection::render_sidebar_size_hints(const std::string& sidebar_field) const @@ -2097,11 +2160,13 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) co glsafe(::glDisable(GL_BLEND)); } +#if !ENABLE_GCODE_VIEWER void Selection::render_sidebar_position_hint(Axis axis) const { m_arrow.set_color(AXES_COLOR[axis], 3); m_arrow.render(); } +#endif // !ENABLE_GCODE_VIEWER void Selection::render_sidebar_rotation_hint(Axis axis) const { @@ -2115,7 +2180,14 @@ void Selection::render_sidebar_rotation_hint(Axis axis) const void Selection::render_sidebar_scale_hint(Axis axis) const { +#if ENABLE_GCODE_VIEWER + GLint color_id = ::glGetUniformLocation(m_arrows_shader.get_shader_program_id(), "uniform_color"); + + if (color_id >= 0) + glsafe(::glUniform4fv(color_id, 1, (requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling()) ? (const GLfloat*)UNIFORM_SCALE_COLOR : (const GLfloat*)AXES_COLOR[axis])); +#else m_arrow.set_color(((requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling()) ? UNIFORM_SCALE_COLOR : AXES_COLOR[axis]), 3); +#endif // ENABLE_GCODE_VIEWER glsafe(::glTranslated(0.0, 5.0, 0.0)); m_arrow.render(); @@ -2125,9 +2197,11 @@ void Selection::render_sidebar_scale_hint(Axis axis) const m_arrow.render(); } +#if !ENABLE_GCODE_VIEWER void Selection::render_sidebar_size_hint(Axis axis, double length) const { } +#endif // !ENABLE_GCODE_VIEWER #ifndef NDEBUG static bool is_rotation_xy_synchronized(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to) diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 321cb70e04..53caf11060 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -204,11 +204,12 @@ private: #if ENABLE_RENDER_SELECTION_CENTER GLUquadricObj* m_quadric; #endif // ENABLE_RENDER_SELECTION_CENTER - mutable GLArrow m_arrow; #if ENABLE_GCODE_VIEWER + GL_Model m_arrow; GL_Model m_curved_arrow; Shader m_arrows_shader; #else + mutable GLArrow m_arrow; mutable GLCurvedArrow m_curved_arrow; #endif // ENABLE_GCODE_VIEWER @@ -325,7 +326,11 @@ public: #if ENABLE_RENDER_SELECTION_CENTER void render_center(bool gizmo_is_dragging) const; #endif // ENABLE_RENDER_SELECTION_CENTER +#if ENABLE_GCODE_VIEWER + void render_sidebar_hints(const std::string& sidebar_field) const; +#else void render_sidebar_hints(const std::string& sidebar_field, const Shader& shader) const; +#endif // ENABLE_GCODE_VIEWER bool requires_local_axes() const; @@ -368,10 +373,14 @@ private: void render_sidebar_scale_hints(const std::string& sidebar_field) const; void render_sidebar_size_hints(const std::string& sidebar_field) const; void render_sidebar_layers_hints(const std::string& sidebar_field) const; +#if !ENABLE_GCODE_VIEWER void render_sidebar_position_hint(Axis axis) const; +#endif // !ENABLE_GCODE_VIEWER void render_sidebar_rotation_hint(Axis axis) const; void render_sidebar_scale_hint(Axis axis) const; +#if !ENABLE_GCODE_VIEWER void render_sidebar_size_hint(Axis axis, double length) const; +#endif // !ENABLE_GCODE_VIEWER public: enum SyncRotationType { From 800a6c5e574ca9b35b4a1128860cb9b12d38ac13 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 13 May 2020 11:48:29 +0200 Subject: [PATCH 071/255] Tech ENABLE_GCODE_VIEWER -> Fixed normals in curved arrows model --- src/slic3r/GUI/GLModel.cpp | 105 ++++++++++++++++++++++++------------- 1 file changed, 68 insertions(+), 37 deletions(-) diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index ee98ce678a..e5b6cbdcb6 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -273,23 +273,36 @@ GLModelInitializationData circular_arrow(int resolution, float radius, float tip data.triangles.emplace_back(9, 8, 7); // side faces vertices + append_vertex(data, { 0.0f, outer_radius, -half_thickness }, Vec3f::UnitX()); + append_vertex(data, { 0.0f, radius + half_tip_width, -half_thickness }, Vec3f::UnitX()); append_vertex(data, { 0.0f, outer_radius, half_thickness }, Vec3f::UnitX()); - append_vertex(data, { 0.0f, radius + half_tip_width, half_thickness }, Vec3f::UnitY()); - append_vertex(data, { -tip_height, radius, half_thickness }, -Vec3f::UnitX()); - append_vertex(data, { 0.0f, radius - half_tip_width, half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { 0.0f, radius + half_tip_width, half_thickness }, Vec3f::UnitX()); + + Vec3f normal(-half_tip_width, tip_height, 0.0f); + normal.normalize(); + append_vertex(data, { 0.0f, radius + half_tip_width, -half_thickness }, normal); + append_vertex(data, { -tip_height, radius, -half_thickness }, normal); + append_vertex(data, { 0.0f, radius + half_tip_width, half_thickness }, normal); + append_vertex(data, { -tip_height, radius, half_thickness }, normal); + + normal = Vec3f(-half_tip_width, -tip_height, 0.0f); + normal.normalize(); + append_vertex(data, { -tip_height, radius, -half_thickness }, normal); + append_vertex(data, { 0.0f, radius - half_tip_width, -half_thickness }, normal); + append_vertex(data, { -tip_height, radius, half_thickness }, normal); + append_vertex(data, { 0.0f, radius - half_tip_width, half_thickness }, normal); + + append_vertex(data, { 0.0f, radius - half_tip_width, -half_thickness }, Vec3f::UnitX()); + append_vertex(data, { 0.0f, inner_radius, -half_thickness }, Vec3f::UnitX()); + append_vertex(data, { 0.0f, radius - half_tip_width, half_thickness }, Vec3f::UnitX()); append_vertex(data, { 0.0f, inner_radius, half_thickness }, Vec3f::UnitX()); - append_vertex(data, { 0.0f, outer_radius, -half_thickness }, Vec3f::UnitX()); - append_vertex(data, { 0.0f, radius + half_tip_width, -half_thickness }, Vec3f::UnitY()); - append_vertex(data, { -tip_height, radius, -half_thickness }, -Vec3f::UnitX()); - append_vertex(data, { 0.0f, radius - half_tip_width, -half_thickness }, -Vec3f::UnitY()); - append_vertex(data, { 0.0f, inner_radius, -half_thickness }, Vec3f::UnitX()); - - // side faces triangles + // side face triangles for (int i = 0; i < 4; ++i) { - data.triangles.emplace_back(15 + i, 11 + i, 10 + i); - data.triangles.emplace_back(15 + i, 16 + i, 11 + i); + int ii = i * 4; + data.triangles.emplace_back(10 + ii, 11 + ii, 13 + ii); + data.triangles.emplace_back(10 + ii, 13 + ii, 12 + ii); } // stem @@ -309,8 +322,8 @@ GLModelInitializationData circular_arrow(int resolution, float radius, float tip // top face triangles for (int i = 0; i < resolution; ++i) { - data.triangles.emplace_back(20 + i, 21 + i, 21 + resolution + i); - data.triangles.emplace_back(21 + i, 22 + resolution + i, 21 + resolution + i); + data.triangles.emplace_back(26 + i, 27 + i, 27 + resolution + i); + data.triangles.emplace_back(27 + i, 28 + resolution + i, 27 + resolution + i); } // bottom face vertices @@ -329,27 +342,11 @@ GLModelInitializationData circular_arrow(int resolution, float radius, float tip // bottom face triangles for (int i = 0; i < resolution; ++i) { - data.triangles.emplace_back(22 + 2 * resolution + i, 23 + 3 * resolution + i, 23 + 2 * resolution + i); - data.triangles.emplace_back(23 + 2 * resolution + i, 23 + 3 * resolution + i, 24 + 3 * resolution + i); - } - - // side faces vertices - for (int i = 0; i <= resolution; ++i) - { - float angle = static_cast(i) * step_angle; - float c = ::cos(angle); - float s = ::sin(angle); - append_vertex(data, { inner_radius * s, inner_radius * c, half_thickness }, { -s, -c, 0.0f}); - } - - for (int i = resolution; i >= 0; --i) - { - float angle = static_cast(i) * step_angle; - float c = ::cos(angle); - float s = ::sin(angle); - append_vertex(data, { outer_radius * s, outer_radius * c, half_thickness }, { s, c, 0.0f }); + data.triangles.emplace_back(28 + 2 * resolution + i, 29 + 3 * resolution + i, 29 + 2 * resolution + i); + data.triangles.emplace_back(29 + 2 * resolution + i, 29 + 3 * resolution + i, 30 + 3 * resolution + i); } + // side faces vertices and triangles for (int i = 0; i <= resolution; ++i) { float angle = static_cast(i) * step_angle; @@ -358,6 +355,31 @@ GLModelInitializationData circular_arrow(int resolution, float radius, float tip append_vertex(data, { inner_radius * s, inner_radius * c, -half_thickness }, { -s, -c, 0.0f }); } + for (int i = 0; i <= resolution; ++i) + { + float angle = static_cast(i) * step_angle; + float c = ::cos(angle); + float s = ::sin(angle); + append_vertex(data, { inner_radius * s, inner_radius * c, half_thickness }, { -s, -c, 0.0f }); + } + + int first_id = 26 + 4 * (resolution + 1); + for (int i = 0; i < resolution; ++i) + { + int ii = first_id + i; + data.triangles.emplace_back(ii, ii + 1, ii + resolution + 2); + data.triangles.emplace_back(ii, ii + resolution + 2, ii + resolution + 1); + } + + append_vertex(data, { inner_radius, 0.0f, -half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { outer_radius, 0.0f, -half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { inner_radius, 0.0f, half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { outer_radius, 0.0f, half_thickness }, -Vec3f::UnitY()); + + first_id = 26 + 6 * (resolution + 1); + data.triangles.emplace_back(first_id, first_id + 1, first_id + 3); + data.triangles.emplace_back(first_id, first_id + 3, first_id + 2); + for (int i = resolution; i >= 0; --i) { float angle = static_cast(i) * step_angle; @@ -366,11 +388,20 @@ GLModelInitializationData circular_arrow(int resolution, float radius, float tip append_vertex(data, { outer_radius * s, outer_radius * c, -half_thickness }, { s, c, 0.0f }); } - // side faces triangles - for (int i = 0; i < 2 * resolution + 1; ++i) + for (int i = resolution; i >= 0; --i) { - data.triangles.emplace_back(20 + 6 * (resolution + 1) + i, 21 + 6 * (resolution + 1) + i, 21 + 4 * (resolution + 1) + i); - data.triangles.emplace_back(20 + 6 * (resolution + 1) + i, 21 + 4 * (resolution + 1) + i, 20 + 4 * (resolution + 1) + i); + float angle = static_cast(i) * step_angle; + float c = ::cos(angle); + float s = ::sin(angle); + append_vertex(data, { outer_radius * s, outer_radius * c, +half_thickness }, { s, c, 0.0f }); + } + + first_id = 30 + 6 * (resolution + 1); + for (int i = 0; i < resolution; ++i) + { + int ii = first_id + i; + data.triangles.emplace_back(ii, ii + 1, ii + resolution + 2); + data.triangles.emplace_back(ii, ii + resolution + 2, ii + resolution + 1); } return data; From cd2e4002ed2b432ecd898db99d3306aa319bd94f Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 13 May 2020 11:59:48 +0200 Subject: [PATCH 072/255] Tech ENABLE_GCODE_VIEWER -> Removed obsolete class GLArrow --- src/slic3r/GUI/3DScene.cpp | 7 ++++++- src/slic3r/GUI/3DScene.hpp | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index ef5e22c823..dc5376553f 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -1944,6 +1944,9 @@ void GLModel::render() const glsafe(::glDisable(GL_BLEND)); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool GLArrow::on_init() { Pointf3s vertices; @@ -2002,7 +2005,9 @@ bool GLArrow::on_init() return true; } -#if !ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//#if !ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GLCurvedArrow::GLCurvedArrow(unsigned int resolution) : GLModel() , m_resolution(resolution) diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index d6ee72bdc1..d357fba6cf 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -642,13 +642,18 @@ protected: virtual bool on_init_from_file(const std::string& filename) { return false; } }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ class GLArrow : public GLModel { protected: bool on_init() override; }; -#if !ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//#if !ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ class GLCurvedArrow : public GLModel { unsigned int m_resolution; From 32529b66ac1945e406f4b7f4b795ee388a418e75 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 13 May 2020 13:55:00 +0200 Subject: [PATCH 073/255] Tech ENABLE_GCODE_VIEWER -> Small refactoring --- src/slic3r/GUI/3DScene.cpp | 5 ---- src/slic3r/GUI/3DScene.hpp | 5 ---- src/slic3r/GUI/GCodeViewer.cpp | 42 +++++++++++++++++----------------- 3 files changed, 21 insertions(+), 31 deletions(-) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index dc5376553f..29a4b84a30 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -1944,9 +1944,7 @@ void GLModel::render() const glsafe(::glDisable(GL_BLEND)); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool GLArrow::on_init() { Pointf3s vertices; @@ -2005,9 +2003,6 @@ bool GLArrow::on_init() return true; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -//#if !ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GLCurvedArrow::GLCurvedArrow(unsigned int resolution) : GLModel() , m_resolution(resolution) diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index d357fba6cf..86072754d7 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -642,18 +642,13 @@ protected: virtual bool on_init_from_file(const std::string& filename) { return false; } }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ class GLArrow : public GLModel { protected: bool on_init() override; }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -//#if !ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ class GLCurvedArrow : public GLModel { unsigned int m_resolution; diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 525a2fd5a1..aa188cae3f 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -978,14 +978,14 @@ void GCodeViewer::render_legend() const ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); switch (m_view_type) { - case EViewType::FeatureType: { imgui.text(I18N::translate_utf8(L("Feature type"))); break; } - case EViewType::Height: { imgui.text(I18N::translate_utf8(L("Height (mm)"))); break; } - case EViewType::Width: { imgui.text(I18N::translate_utf8(L("Width (mm)"))); break; } - case EViewType::Feedrate: { imgui.text(I18N::translate_utf8(L("Speed (mm/s)"))); break; } - case EViewType::FanSpeed: { imgui.text(I18N::translate_utf8(L("Fan Speed (%%)"))); break; } - case EViewType::VolumetricRate: { imgui.text(I18N::translate_utf8(L("Volumetric flow rate (mm³/s)"))); break; } - case EViewType::Tool: { imgui.text(I18N::translate_utf8(L("Tool"))); break; } - case EViewType::ColorPrint: { imgui.text(I18N::translate_utf8(L("Color Print"))); break; } + case EViewType::FeatureType: { imgui.text(_u8L("Feature type")); break; } + case EViewType::Height: { imgui.text(_u8L("Height (mm)")); break; } + case EViewType::Width: { imgui.text(_u8L("Width (mm)")); break; } + case EViewType::Feedrate: { imgui.text(_u8L("Speed (mm/s)")); break; } + case EViewType::FanSpeed: { imgui.text(_u8L("Fan Speed (%%)")); break; } + case EViewType::VolumetricRate: { imgui.text(_u8L("Volumetric flow rate (mm³/s)")); break; } + case EViewType::Tool: { imgui.text(_u8L("Tool")); break; } + case EViewType::ColorPrint: { imgui.text(_u8L("Color Print")); break; } default: { break; } } ImGui::PopStyleColor(); @@ -1001,7 +1001,7 @@ void GCodeViewer::render_legend() const if (!visible) ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.3333f); - add_item(Extrusion_Role_Colors[static_cast(role)], I18N::translate_utf8(ExtrusionEntity::role_to_string(role)), [this, role]() { + add_item(Extrusion_Role_Colors[static_cast(role)], _u8L(ExtrusionEntity::role_to_string(role)), [this, role]() { if (role < erCount) { m_extrusions.role_visibility_flags = is_visible(role) ? m_extrusions.role_visibility_flags & ~(1 << role) : m_extrusions.role_visibility_flags | (1 << role); @@ -1031,7 +1031,7 @@ void GCodeViewer::render_legend() const if (it == m_extruder_ids.end()) continue; - add_item(m_tool_colors[i], (boost::format(I18N::translate_utf8(L("Extruder %d"))) % (i + 1)).str()); + add_item(m_tool_colors[i], (boost::format(_u8L("Extruder %d")) % (i + 1)).str()); } break; } @@ -1042,7 +1042,7 @@ void GCodeViewer::render_legend() const if (extruders_count == 1) { // single extruder use case if (custom_gcode_per_print_z.empty()) // no data to show - add_item(m_tool_colors.front(), I18N::translate_utf8(L("Default print color"))); + add_item(m_tool_colors.front(), _u8L("Default print color")); else { std::vector> cp_values; cp_values.reserve(custom_gcode_per_print_z.size()); @@ -1066,7 +1066,7 @@ void GCodeViewer::render_legend() const const int items_cnt = static_cast(cp_values.size()); if (items_cnt == 0) { // There is no one color change, but there are some pause print or custom Gcode - add_item(m_tool_colors.front(), I18N::translate_utf8(L("Default print color"))); + add_item(m_tool_colors.front(), _u8L("Default print color")); } else { for (int i = items_cnt; i >= 0; --i) { @@ -1074,14 +1074,14 @@ void GCodeViewer::render_legend() const std::string id_str = " (" + std::to_string(i + 1) + ")"; if (i == 0) { - add_item(m_tool_colors[i], (boost::format(I18N::translate_utf8(L("up to %.2f mm"))) % cp_values.front().first).str() + id_str); + add_item(m_tool_colors[i], (boost::format(_u8L("up to %.2f mm")) % cp_values.front().first).str() + id_str); break; } else if (i == items_cnt) { - add_item(m_tool_colors[i], (boost::format(I18N::translate_utf8(L("above %.2f mm"))) % cp_values[i - 1].second).str() + id_str); + add_item(m_tool_colors[i], (boost::format(_u8L("above %.2f mm")) % cp_values[i - 1].second).str() + id_str); continue; } - add_item(m_tool_colors[i], (boost::format(I18N::translate_utf8(L("%.2f - %.2f mm"))) % cp_values[i - 1].second % cp_values[i].first).str() + id_str); + add_item(m_tool_colors[i], (boost::format(_u8L("%.2f - %.2f mm")) % cp_values[i - 1].second% cp_values[i].first).str() + id_str); } } } @@ -1090,7 +1090,7 @@ void GCodeViewer::render_legend() const { // extruders for (unsigned int i = 0; i < (unsigned int)extruders_count; ++i) { - add_item(m_tool_colors[i], (boost::format(I18N::translate_utf8(L("Extruder %d"))) % (i + 1)).str()); + add_item(m_tool_colors[i], (boost::format(_u8L("Extruder %d")) % (i + 1)).str()); } // color changes @@ -1102,7 +1102,7 @@ void GCodeViewer::render_legend() const std::string id_str = " (" + std::to_string(color_change_idx--) + ")"; add_item(m_tool_colors[last_color_id--], - (boost::format(I18N::translate_utf8(L("Color change for Extruder %d at %.2f mm"))) % custom_gcode_per_print_z[i].extruder % custom_gcode_per_print_z[i].print_z).str() + id_str); + (boost::format(_u8L("Color change for Extruder %d at %.2f mm")) % custom_gcode_per_print_z[i].extruder % custom_gcode_per_print_z[i].print_z).str() + id_str); } } } @@ -1129,14 +1129,14 @@ void GCodeViewer::render_legend() const ImGui::Spacing(); ImGui::Spacing(); ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); - imgui.text(I18N::translate_utf8(L("Travel"))); + imgui.text(_u8L("Travel")); ImGui::PopStyleColor(); ImGui::Separator(); // items - add_item(Travel_Colors[0], I18N::translate_utf8(L("Movement"))); - add_item(Travel_Colors[1], I18N::translate_utf8(L("Extrusion"))); - add_item(Travel_Colors[2], I18N::translate_utf8(L("Retraction"))); + add_item(Travel_Colors[0], _u8L("Movement")); + add_item(Travel_Colors[1], _u8L("Extrusion")); + add_item(Travel_Colors[2], _u8L("Retraction")); break; } From 5be901547e1c9cd641681f3c40c8aeabdbbe7332 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 15 May 2020 09:22:51 +0200 Subject: [PATCH 074/255] GCodeViewer -> Imgui slider for sequential view replaced by DoubleSlider::Control (wip) --- src/libslic3r/Print.hpp | 2 + src/libslic3r/Technologies.hpp | 1 + src/slic3r/GUI/BackgroundSlicingProcess.hpp | 2 + src/slic3r/GUI/DoubleSlider.cpp | 76 ++++-- src/slic3r/GUI/DoubleSlider.hpp | 8 +- src/slic3r/GUI/GCodeViewer.cpp | 14 + src/slic3r/GUI/GCodeViewer.hpp | 49 ++++ src/slic3r/GUI/GLCanvas3D.hpp | 6 + src/slic3r/GUI/GUI_Preview.cpp | 285 ++++++++++++++++++-- src/slic3r/GUI/GUI_Preview.hpp | 48 +++- src/slic3r/GUI/Plater.cpp | 21 ++ src/slic3r/GUI/Plater.hpp | 3 + 12 files changed, 463 insertions(+), 52 deletions(-) diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index c358cd9184..36ba68c45e 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -24,7 +24,9 @@ class Print; class PrintObject; class ModelObject; class GCode; +#if !ENABLE_GCODE_VIEWER class GCodePreviewData; +#endif // !ENABLE_GCODE_VIEWER enum class SlicingMode : uint32_t; // Print step IDs for keeping track of the print state. diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index c22e504dff..8ce01a3530 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -55,6 +55,7 @@ // Enable G-Code viewer #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) +#define ENABLE_GCODE_USE_WXWIDGETS_SLIDER (1 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.hpp b/src/slic3r/GUI/BackgroundSlicingProcess.hpp index 91ebc1372c..22a99951ff 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.hpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.hpp @@ -17,7 +17,9 @@ namespace Slic3r { class DynamicPrintConfig; +#if !ENABLE_GCODE_VIEWER class GCodePreviewData; +#endif // !ENABLE_GCODE_VIEWER class Model; class SLAPrint; class SL1Archive; diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index 4732ff2613..021d73882e 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -20,7 +20,9 @@ #include #include #include +#if !ENABLE_GCODE_USE_WXWIDGETS_SLIDER #include +#endif // !ENABLE_GCODE_USE_WXWIDGETS_SLIDER #include #include @@ -408,22 +410,22 @@ void Control::render() // draw line draw_scroll_line(dc, lower_pos, higher_pos); - //draw color print ticks + // draw color print ticks draw_ticks(dc); // draw both sliders draw_thumbs(dc, lower_pos, higher_pos); - //draw lock/unlock + // draw lock/unlock draw_one_layer_icon(dc); - //draw revert bitmap (if it's shown) + // draw revert bitmap (if it's shown) draw_revert_icon(dc); - //draw cog bitmap (if it's shown) + // draw cog bitmap (if it's shown) draw_cog_icon(dc); - //draw mouse position + // draw mouse position draw_tick_on_mouse_position(dc); } @@ -535,10 +537,21 @@ wxString Control::get_label(int tick) const if (value >= m_values.size()) return "ErrVal"; - const wxString str = m_values.empty() ? - wxNumberFormatter::ToString(m_label_koef*value, 2, wxNumberFormatter::Style_None) : - wxNumberFormatter::ToString(m_values[value], 2, wxNumberFormatter::Style_None); - return format_wxstr("%1%\n(%2%)", str, m_values.empty() ? value : value+1); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + if (m_draw_mode == dmSequentialGCodeView) + return wxString::Format("%d", static_cast(m_values[value])); + else { + const wxString str = m_values.empty() ? + wxString::Format("%.*f", 2, m_label_koef * value) : + wxString::Format("%.*f", 2, m_values[value]); + return format_wxstr("%1%\n(%2%)", str, m_values.empty() ? value : value + 1); + } +#else + const wxString str = m_values.empty() ? + wxNumberFormatter::ToString(m_label_koef * value, 2, wxNumberFormatter::Style_None) : + wxNumberFormatter::ToString(m_values[value], 2, wxNumberFormatter::Style_None); + return format_wxstr("%1%\n(%2%)", str, m_values.empty() ? value : value + 1); +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER } void Control::draw_tick_text(wxDC& dc, const wxPoint& pos, int tick, bool right_side/*=true*/) const @@ -779,6 +792,11 @@ void Control::draw_colored_band(wxDC& dc) void Control::draw_one_layer_icon(wxDC& dc) { +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + if (m_draw_mode == dmSequentialGCodeView) + return; +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER + const wxBitmap& icon = m_is_one_layer ? m_focus == fiOneLayerIcon ? m_bmp_one_layer_lock_off.bmp() : m_bmp_one_layer_lock_on.bmp() : m_focus == fiOneLayerIcon ? m_bmp_one_layer_unlock_off.bmp() : m_bmp_one_layer_unlock_on.bmp(); @@ -1284,7 +1302,11 @@ void Control::OnWheel(wxMouseEvent& event) ssLower : ssHigher; } +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + move_current_thumb((m_draw_mode == dmSequentialGCodeView) ? event.GetWheelRotation() < 0 : event.GetWheelRotation() > 0); +#else move_current_thumb(event.GetWheelRotation() > 0); +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER } void Control::OnKeyDown(wxKeyEvent &event) @@ -1306,20 +1328,34 @@ void Control::OnKeyDown(wxKeyEvent &event) UseDefaultColors(false); else if (is_horizontal()) { - if (key == WXK_LEFT || key == WXK_RIGHT) - move_current_thumb(key == WXK_LEFT); - else if (key == WXK_UP || key == WXK_DOWN) { - m_selection = key == WXK_UP ? ssHigher : ssLower; - Refresh(); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + if (m_is_focused) + { +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER + if (key == WXK_LEFT || key == WXK_RIGHT) + move_current_thumb(key == WXK_LEFT); + else if (key == WXK_UP || key == WXK_DOWN) { + m_selection = key == WXK_UP ? ssHigher : ssLower; + Refresh(); + } +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + } +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER } - } else { - if (key == WXK_LEFT || key == WXK_RIGHT) { - m_selection = key == WXK_LEFT ? ssHigher : ssLower; - Refresh(); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + if (m_is_focused) + { +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER + if (key == WXK_LEFT || key == WXK_RIGHT) { + m_selection = key == WXK_LEFT ? ssHigher : ssLower; + Refresh(); + } + else if (key == WXK_UP || key == WXK_DOWN) + move_current_thumb(key == WXK_UP); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER } - else if (key == WXK_UP || key == WXK_DOWN) - move_current_thumb(key == WXK_UP); +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER } event.Skip(); // !Needed to have EVT_CHAR generated as well diff --git a/src/slic3r/GUI/DoubleSlider.hpp b/src/slic3r/GUI/DoubleSlider.hpp index 36bff17e94..a17fb2b6fa 100644 --- a/src/slic3r/GUI/DoubleSlider.hpp +++ b/src/slic3r/GUI/DoubleSlider.hpp @@ -73,6 +73,9 @@ enum DrawMode dmRegular, dmSlaPrint, dmSequentialFffPrint, +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + dmSequentialGCodeView, +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER }; using t_mode = CustomGCode::Mode; @@ -211,6 +214,9 @@ public: void SetTicksValues(const Slic3r::CustomGCode::Info &custom_gcode_per_print_z); void SetDrawMode(bool is_sla_print, bool is_sequential_print); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + void SetDrawMode(DrawMode mode) { m_draw_mode = mode; } +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER void SetManipulationMode(t_mode mode) { m_mode = mode; } t_mode GetManipulationMode() const { return m_mode; } @@ -223,7 +229,7 @@ public: bool is_higher_at_max() const { return m_higher_value == m_max_value; } bool is_full_span() const { return this->is_lower_at_min() && this->is_higher_at_max(); } - void OnPaint(wxPaintEvent& ) { render();} + void OnPaint(wxPaintEvent& ) { render(); } void OnLeftDown(wxMouseEvent& event); void OnMotion(wxMouseEvent& event); void OnLeftUp(wxMouseEvent& event); diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index aa188cae3f..acf1da4c71 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -324,7 +324,9 @@ void GCodeViewer::render() const m_sequential_view.marker.render(); render_shells(); render_legend(); +#if !ENABLE_GCODE_USE_WXWIDGETS_SLIDER render_sequential_bar(); +#endif // !ENABLE_GCODE_USE_WXWIDGETS_SLIDER #if ENABLE_GCODE_VIEWER_STATISTICS render_statistics(); #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -381,6 +383,16 @@ void GCodeViewer::set_options_visibility_from_flags(unsigned int flags) enable_legend(is_flag_set(9)); } +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER +void GCodeViewer::set_layers_z_range(const std::array& layers_z_range) +{ + bool keep_sequential_current = layers_z_range[1] <= m_layers_z_range[1]; + m_layers_z_range = layers_z_range; + refresh_render_paths(keep_sequential_current); + wxGetApp().plater()->update_preview_horz_slider(); +} +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER + bool GCodeViewer::init_shaders() { unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); @@ -1147,6 +1159,7 @@ void GCodeViewer::render_legend() const ImGui::PopStyleVar(); } +#if !ENABLE_GCODE_USE_WXWIDGETS_SLIDER void GCodeViewer::render_sequential_bar() const { static const float MARGIN = 125.0f; @@ -1231,6 +1244,7 @@ void GCodeViewer::render_sequential_bar() const imgui.end(); ImGui::PopStyleVar(); } +#endif // !ENABLE_GCODE_USE_WXWIDGETS_SLIDER #if ENABLE_GCODE_VIEWER_STATISTICS void GCodeViewer::render_statistics() const diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 6f3ca47dba..a4ac3358d2 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -149,6 +149,7 @@ class GCodeViewer void reset_ranges() { ranges.reset(); } }; +#if !ENABLE_GCODE_USE_WXWIDGETS_SLIDER struct SequentialView { class Marker @@ -182,6 +183,7 @@ class GCodeViewer Vec3f current_position{ Vec3f::Zero() }; Marker marker; }; +#endif // !ENABLE_GCODE_USE_WXWIDGETS_SLIDER #if ENABLE_GCODE_VIEWER_STATISTICS struct Statistics @@ -229,6 +231,42 @@ class GCodeViewer #endif // ENABLE_GCODE_VIEWER_STATISTICS public: +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + struct SequentialView + { + class Marker + { + GL_Model m_model; + Transform3f m_world_transform; + std::array m_color{ 1.0f, 1.0f, 1.0f, 1.0f }; + bool m_visible{ false }; + Shader m_shader; + + public: + void init(); + + const BoundingBoxf3& get_bounding_box() const { return m_model.get_bounding_box(); } + + void set_world_transform(const Transform3f& transform) { m_world_transform = transform; } + void set_color(const std::array& color) { m_color = color; } + + bool is_visible() const { return m_visible; } + void set_visible(bool visible) { m_visible = visible; } + + void render() const; + + private: + void init_shader(); + }; + + unsigned int first{ 0 }; + unsigned int last{ 0 }; + unsigned int current{ 0 }; + Vec3f current_position{ Vec3f::Zero() }; + Marker marker; + }; +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER + enum class EViewType : unsigned char { FeatureType, @@ -284,6 +322,11 @@ public: const BoundingBoxf3& get_bounding_box() const { return m_bounding_box; } const std::vector& get_layers_zs() const { return m_layers_zs; }; +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + const SequentialView& get_sequential_view() const { return m_sequential_view; } + void update_sequential_view_current(unsigned int low, unsigned int high) { m_sequential_view.current = high; refresh_render_paths(true); } +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER + EViewType get_view_type() const { return m_view_type; } void set_view_type(EViewType type) { if (type == EViewType::Count) @@ -298,12 +341,16 @@ public: void set_toolpath_role_visibility_flags(unsigned int flags) { m_extrusions.role_visibility_flags = flags; } unsigned int get_options_visibility_flags() const; void set_options_visibility_from_flags(unsigned int flags); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + void set_layers_z_range(const std::array& layers_z_range); +#else void set_layers_z_range(const std::array& layers_z_range) { bool keep_sequential_current = layers_z_range[1] <= m_layers_z_range[1]; m_layers_z_range = layers_z_range; refresh_render_paths(keep_sequential_current); } +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER bool is_legend_enabled() const { return m_legend_enabled; } void enable_legend(bool enable) { m_legend_enabled = enable; } @@ -316,7 +363,9 @@ private: void render_toolpaths() const; void render_shells() const; void render_legend() const; +#if !ENABLE_GCODE_USE_WXWIDGETS_SLIDER void render_sequential_bar() const; +#endif // !ENABLE_GCODE_USE_WXWIDGETS_SLIDER #if ENABLE_GCODE_VIEWER_STATISTICS void render_statistics() const; #endif // ENABLE_GCODE_VIEWER_STATISTICS diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 3e7296e139..d4df60ad2a 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -42,7 +42,9 @@ namespace Slic3r { class Bed3D; struct Camera; class BackgroundSlicingProcess; +#if !ENABLE_GCODE_VIEWER class GCodePreviewData; +#endif // !ENABLE_GCODE_VIEWER struct ThumbnailData; struct SlicingParameters; enum LayerHeightEditActionType : unsigned int; @@ -551,6 +553,10 @@ public: #if ENABLE_GCODE_VIEWER void reset_gcode_toolpaths() { m_gcode_viewer.reset(); } +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + const GCodeViewer::SequentialView& get_gcode_sequential_view() const { return m_gcode_viewer.get_sequential_view(); } + void update_gcode_sequential_view_current(unsigned int low, unsigned int high) { m_gcode_viewer.update_sequential_view_current(low, high); } +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER #endif // ENABLE_GCODE_VIEWER void toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index fc97796749..9547e0bf89 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -210,7 +210,9 @@ Preview::Preview( , m_number_extruders(1) , m_preferred_color_mode("feature") , m_loaded(false) +#if !ENABLE_GCODE_VIEWER , m_enabled(false) +#endif // !ENABLE_GCODE_VIEWER , m_schedule_background_process(schedule_background_process_func) #ifdef __linux__ , m_volumes_cleanup_required(false) @@ -245,8 +247,12 @@ bool Preview::init(wxWindow* parent, Model* model) m_canvas->enable_dynamic_background(true); m_canvas->enable_collapse_toolbar(true); +#if ENABLE_GCODE_VIEWER + m_double_slider_sizer = create_vert_slider_sizer(); +#else m_double_slider_sizer = new wxBoxSizer(wxHORIZONTAL); create_double_slider(); +#endif // ENABLE_GCODE_VIEWER m_label_view_type = new wxStaticText(this, wxID_ANY, _L("View")); @@ -315,15 +321,25 @@ bool Preview::init(wxWindow* parent, Model* model) top_sizer->Add(m_canvas_widget, 1, wxALL | wxEXPAND, 0); top_sizer->Add(m_double_slider_sizer, 0, wxEXPAND, 0); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + m_horz_slider = new DoubleSlider::Control(this, wxID_ANY, 0, 0, 0, 100, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL); + m_horz_slider->SetDrawMode(DoubleSlider::dmSequentialGCodeView); + m_horz_slider->Bind(wxEVT_SCROLL_CHANGED, &Preview::on_horz_slider_scroll_changed, this); +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER + #if ENABLE_GCODE_VIEWER m_bottom_toolbar_sizer = new wxBoxSizer(wxHORIZONTAL); m_bottom_toolbar_sizer->AddSpacer(10); - m_bottom_toolbar_sizer->Add(m_label_view_type, 0, wxALIGN_CENTER_VERTICAL, 5); - m_bottom_toolbar_sizer->Add(m_choice_view_type, 0, wxEXPAND | wxALL, 5); + m_bottom_toolbar_sizer->Add(m_label_view_type, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5); + m_bottom_toolbar_sizer->Add(m_choice_view_type, 0, wxALIGN_CENTER_VERTICAL, 5); m_bottom_toolbar_sizer->AddSpacer(10); - m_bottom_toolbar_sizer->Add(m_label_show, 0, wxALIGN_CENTER_VERTICAL, 5); - m_bottom_toolbar_sizer->Add(m_combochecklist_options, 0, wxEXPAND | wxALL, 5); - m_bottom_toolbar_sizer->Add(m_combochecklist_features, 0, wxEXPAND | wxALL, 5); + m_bottom_toolbar_sizer->Add(m_label_show, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5); + m_bottom_toolbar_sizer->Add(m_combochecklist_options, 0, wxALIGN_CENTER_VERTICAL, 5); + m_bottom_toolbar_sizer->Add(m_combochecklist_features, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 5); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + m_bottom_toolbar_sizer->AddSpacer(10); + m_bottom_toolbar_sizer->Add(m_horz_slider, 1, wxALL | wxEXPAND, 5); +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER #else wxBoxSizer* bottom_sizer = new wxBoxSizer(wxHORIZONTAL); bottom_sizer->Add(m_label_view_type, 0, wxALIGN_CENTER_VERTICAL, 5); @@ -417,10 +433,12 @@ void Preview::set_number_extruders(unsigned int number_extruders) } } +#if !ENABLE_GCODE_VIEWER void Preview::set_enabled(bool enabled) { m_enabled = enabled; } +#endif // !ENABLE_GCODE_VIEWER void Preview::bed_shape_changed() { @@ -498,7 +516,14 @@ void Preview::refresh_print() void Preview::msw_rescale() { // rescale slider +#if ENABLE_GCODE_VIEWER + if (m_vert_slider != nullptr) m_vert_slider->msw_rescale(); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + if (m_horz_slider != nullptr) m_horz_slider->msw_rescale(); +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#else if (m_slider) m_slider->msw_rescale(); +#endif // ENABLE_GCODE_VIEWER // rescale warning legend on the canvas get_canvas3d()->msw_rescale(); @@ -509,14 +534,22 @@ void Preview::msw_rescale() void Preview::move_double_slider(wxKeyEvent& evt) { - if (m_slider) +#if ENABLE_GCODE_VIEWER + if (m_vert_slider != nullptr) m_vert_slider->OnKeyDown(evt); +#else + if (m_slider) m_slider->OnKeyDown(evt); +#endif // ENABLE_GCODE_VIEWER } void Preview::edit_double_slider(wxKeyEvent& evt) { - if (m_slider) +#if ENABLE_GCODE_VIEWER + if (m_vert_slider != nullptr) m_vert_slider->OnChar(evt); +#else + if (m_slider) m_slider->OnChar(evt); +#endif // ENABLE_GCODE_VIEWER } void Preview::bind_event_handlers() @@ -580,25 +613,35 @@ void Preview::show_hide_ui_elements(const std::string& what) } #endif // !ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER +void Preview::hide_vert_slider() +{ + m_double_slider_sizer->Hide((size_t)0); + Layout(); +} +#else void Preview::reset_sliders(bool reset_all) { m_enabled = false; -// reset_double_slider(); + // reset_double_slider(); if (reset_all) m_double_slider_sizer->Hide((size_t)0); else m_double_slider_sizer->GetItem(size_t(0))->GetSizer()->Hide(1); } +#endif // ENABLE_GCODE_VIEWER +#if !ENABLE_GCODE_VIEWER void Preview::update_sliders(const std::vector& layers_z, bool keep_z_range) { m_enabled = true; - update_double_slider(layers_z, keep_z_range); + m_double_slider_sizer->Show((size_t)0); Layout(); } +#endif // !ENABLE_GCODE_VIEWER void Preview::on_size(wxSizeEvent& evt) { @@ -705,32 +748,68 @@ void Preview::update_bottom_toolbar() combochecklist_set_flags(m_combochecklist_features, m_canvas->get_toolpath_role_visibility_flags()); combochecklist_set_flags(m_combochecklist_options, m_canvas->get_gcode_options_visibility_flags()); - m_bottom_toolbar_sizer->Show(m_combochecklist_features, + m_bottom_toolbar_sizer->Show(m_combochecklist_features, !m_canvas->is_gcode_legend_enabled() || m_canvas->get_gcode_view_type() != GCodeViewer::EViewType::FeatureType); m_bottom_toolbar_sizer->Layout(); + Refresh(); } #endif // ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER +wxBoxSizer* Preview::create_vert_slider_sizer() +{ + wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL); + m_vert_slider = new DoubleSlider::Control(this, wxID_ANY, 0, 0, 0, 100); + + m_vert_slider->SetDrawMode(wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA, + wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_bool("complete_objects")); + + sizer->Add(m_vert_slider, 0, wxEXPAND, 0); + + // sizer, m_canvas_widget + m_canvas_widget->Bind(wxEVT_KEY_DOWN, &Preview::update_vert_slider_from_canvas, this); + m_canvas_widget->Bind(wxEVT_KEY_UP, [this](wxKeyEvent& event) { + if (event.GetKeyCode() == WXK_SHIFT) + m_vert_slider->UseDefaultColors(true); + event.Skip(); + }); + + m_vert_slider->Bind(wxEVT_SCROLL_CHANGED, &Preview::on_vert_slider_scroll_changed, this); + + Bind(DoubleSlider::wxCUSTOMEVT_TICKSCHANGED, [this](wxEvent&) { + Model& model = wxGetApp().plater()->model(); + model.custom_gcode_per_print_z = m_vert_slider->GetTicksValues(); + m_schedule_background_process(); + + update_view_type(false); + + reload_print(); + }); + + return sizer; +} +#else void Preview::create_double_slider() { m_slider = new DoubleSlider::Control(this, wxID_ANY, 0, 0, 0, 100); + bool sla_print_technology = wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA; bool sequential_print = wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_bool("complete_objects"); m_slider->SetDrawMode(sla_print_technology, sequential_print); m_double_slider_sizer->Add(m_slider, 0, wxEXPAND, 0); + // sizer, m_canvas_widget m_canvas_widget->Bind(wxEVT_KEY_DOWN, &Preview::update_double_slider_from_canvas, this); m_canvas_widget->Bind(wxEVT_KEY_UP, [this](wxKeyEvent& event) { if (event.GetKeyCode() == WXK_SHIFT) m_slider->UseDefaultColors(true); event.Skip(); - }); + }); m_slider->Bind(wxEVT_SCROLL_CHANGED, &Preview::on_sliders_scroll_changed, this); - Bind(DoubleSlider::wxCUSTOMEVT_TICKSCHANGED, [this](wxEvent&) { Model& model = wxGetApp().plater()->model(); model.custom_gcode_per_print_z = m_slider->GetTicksValues(); @@ -739,8 +818,9 @@ void Preview::create_double_slider() update_view_type(false); reload_print(); - }); + }); } +#endif // ENABLE_GCODE_VIEWER // Find an index of a value in a sorted vector, which is in . // Returns -1 if there is no such member. @@ -769,8 +849,13 @@ static int find_close_layer_idx(const std::vector& zs, double &z, double return -1; } +#if ENABLE_GCODE_VIEWER +void Preview::check_vert_slider_values(std::vector& ticks_from_model, + const std::vector& layers_z) +#else void Preview::check_slider_values(std::vector& ticks_from_model, const std::vector& layers_z) +#endif // ENABLE_GCODE_VIEWER { // All ticks that would end up outside the slider range should be erased. // TODO: this should be placed into more appropriate part of code, @@ -787,12 +872,68 @@ void Preview::check_slider_values(std::vector& ticks_from_mod m_schedule_background_process(); } -void Preview::update_double_slider(const std::vector& layers_z, bool keep_z_range) +#if ENABLE_GCODE_VIEWER +void Preview::update_vert_slider(const std::vector& layers_z, bool keep_z_range) +{ + // Save the initial slider span. + double z_low = m_vert_slider->GetLowerValueD(); + double z_high = m_vert_slider->GetHigherValueD(); + bool was_empty = m_vert_slider->GetMaxValue() == 0; + + bool force_sliders_full_range = was_empty; + if (!keep_z_range) + { + bool span_changed = layers_z.empty() || std::abs(layers_z.back() - m_vert_slider->GetMaxValueD()) > DoubleSlider::epsilon()/*1e-6*/; + force_sliders_full_range |= span_changed; +} + bool snap_to_min = force_sliders_full_range || m_vert_slider->is_lower_at_min(); + bool snap_to_max = force_sliders_full_range || m_vert_slider->is_higher_at_max(); + + // Detect and set manipulation mode for double slider + update_vert_slider_mode(); + + CustomGCode::Info& ticks_info_from_model = wxGetApp().plater()->model().custom_gcode_per_print_z; + check_vert_slider_values(ticks_info_from_model.gcodes, layers_z); + + m_vert_slider->SetSliderValues(layers_z); + assert(m_vert_slider->GetMinValue() == 0); + m_vert_slider->SetMaxValue(layers_z.empty() ? 0 : layers_z.size() - 1); + + int idx_low = 0; + int idx_high = m_vert_slider->GetMaxValue(); + if (!layers_z.empty()) { + if (!snap_to_min) { + int idx_new = find_close_layer_idx(layers_z, z_low, DoubleSlider::epsilon()/*1e-6*/); + if (idx_new != -1) + idx_low = idx_new; + } + if (!snap_to_max) { + int idx_new = find_close_layer_idx(layers_z, z_high, DoubleSlider::epsilon()/*1e-6*/); + if (idx_new != -1) + idx_high = idx_new; + } + } + m_vert_slider->SetSelectionSpan(idx_low, idx_high); + + m_vert_slider->SetTicksValues(ticks_info_from_model); + + bool sla_print_technology = wxGetApp().plater()->printer_technology() == ptSLA; + bool sequential_print = wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_bool("complete_objects"); + m_vert_slider->SetDrawMode(sla_print_technology, sequential_print); + + m_vert_slider->SetExtruderColors(wxGetApp().plater()->get_extruder_colors_from_plater_config()); + + m_double_slider_sizer->Show((size_t)0); + Layout(); +} +#else +void Preview::update_double_slider(const std::vector & layers_z, bool keep_z_range) { // Save the initial slider span. double z_low = m_slider->GetLowerValueD(); double z_high = m_slider->GetHigherValueD(); bool was_empty = m_slider->GetMaxValue() == 0; + bool force_sliders_full_range = was_empty; if (!keep_z_range) { @@ -800,27 +941,27 @@ void Preview::update_double_slider(const std::vector& layers_z, bool kee force_sliders_full_range |= span_changed; } bool snap_to_min = force_sliders_full_range || m_slider->is_lower_at_min(); - bool snap_to_max = force_sliders_full_range || m_slider->is_higher_at_max(); + bool snap_to_max = force_sliders_full_range || m_slider->is_higher_at_max(); // Detect and set manipulation mode for double slider update_double_slider_mode(); - CustomGCode::Info &ticks_info_from_model = wxGetApp().plater()->model().custom_gcode_per_print_z; + CustomGCode::Info& ticks_info_from_model = wxGetApp().plater()->model().custom_gcode_per_print_z; check_slider_values(ticks_info_from_model.gcodes, layers_z); m_slider->SetSliderValues(layers_z); assert(m_slider->GetMinValue() == 0); m_slider->SetMaxValue(layers_z.empty() ? 0 : layers_z.size() - 1); - int idx_low = 0; + int idx_low = 0; int idx_high = m_slider->GetMaxValue(); - if (! layers_z.empty()) { - if (! snap_to_min) { + if (!layers_z.empty()) { + if (!snap_to_min) { int idx_new = find_close_layer_idx(layers_z, z_low, DoubleSlider::epsilon()/*1e-6*/); if (idx_new != -1) idx_low = idx_new; } - if (! snap_to_max) { + if (!snap_to_max) { int idx_new = find_close_layer_idx(layers_z, z_high, DoubleSlider::epsilon()/*1e-6*/); if (idx_new != -1) idx_high = idx_new; @@ -836,8 +977,13 @@ void Preview::update_double_slider(const std::vector& layers_z, bool kee m_slider->SetExtruderColors(wxGetApp().plater()->get_extruder_colors_from_plater_config()); } +#endif // ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER +void Preview::update_vert_slider_mode() +#else void Preview::update_double_slider_mode() +#endif // ENABLE_GCODE_VIEWER { // true -> single-extruder printer profile OR // multi-extruder printer profile , but whole model is printed by only one extruder @@ -886,16 +1032,68 @@ void Preview::update_double_slider_mode() } } +#if ENABLE_GCODE_VIEWER + m_vert_slider->SetModeAndOnlyExtruder(one_extruder_printed_model, only_extruder); +#else m_slider->SetModeAndOnlyExtruder(one_extruder_printed_model, only_extruder); +#endif // ENABLE_GCODE_VIEWER } +#if ENABLE_GCODE_VIEWER +void Preview::reset_vert_slider() +{ + m_vert_slider->SetHigherValue(0); + m_vert_slider->SetLowerValue(0); +} +#else void Preview::reset_double_slider() { m_slider->SetHigherValue(0); m_slider->SetLowerValue(0); } +#endif // ENABLE_GCODE_VIEWER -void Preview::update_double_slider_from_canvas(wxKeyEvent& event) +#if ENABLE_GCODE_VIEWER +void Preview::update_vert_slider_from_canvas(wxKeyEvent& event) +{ + if (event.HasModifiers()) { + event.Skip(); + return; + } + + const auto key = event.GetKeyCode(); + + if (key == 'U' || key == 'D') { + const int new_pos = key == 'U' ? m_vert_slider->GetHigherValue() + 1 : m_vert_slider->GetHigherValue() - 1; + m_vert_slider->SetHigherValue(new_pos); + if (event.ShiftDown() || m_vert_slider->is_one_layer()) m_vert_slider->SetLowerValue(m_vert_slider->GetHigherValue()); + } + else if (key == 'S') + m_vert_slider->ChangeOneLayerLock(); + else if (key == WXK_SHIFT) + m_vert_slider->UseDefaultColors(false); + else + event.Skip(); +} + +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER +void Preview::update_horz_slider() +{ + const GCodeViewer::SequentialView& view = m_canvas->get_gcode_sequential_view(); + std::vector values(view.last - view.first + 1); + unsigned int count = 0; + for (unsigned int i = view.first; i <= view.last; ++i) + { + values[count++] = static_cast(i + 1); + } + + m_horz_slider->SetSliderValues(values); + m_horz_slider->SetMaxValue(view.last - view.first); + m_horz_slider->SetSelectionSpan(0, view.current); +} +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#else +void Preview::update_double_slider_from_canvas(wxKeyEvent & event) { if (event.HasModifiers()) { event.Skip(); @@ -909,13 +1107,11 @@ void Preview::update_double_slider_from_canvas(wxKeyEvent& event) m_slider->SetHigherValue(new_pos); if (event.ShiftDown() || m_slider->is_one_layer()) m_slider->SetLowerValue(m_slider->GetHigherValue()); } -#if !ENABLE_GCODE_VIEWER else if (key == 'L') { m_checkbox_legend->SetValue(!m_checkbox_legend->GetValue()); auto evt = wxCommandEvent(); on_checkbox_legend(evt); } -#endif // !ENABLE_GCODE_VIEWER else if (key == 'S') m_slider->ChangeOneLayerLock(); else if (key == WXK_SHIFT) @@ -923,6 +1119,7 @@ void Preview::update_double_slider_from_canvas(wxKeyEvent& event) else event.Skip(); } +#endif // ENABLE_GCODE_VIEWER void Preview::load_print_as_fff(bool keep_z_range) { @@ -951,10 +1148,12 @@ void Preview::load_print_as_fff(bool keep_z_range) if (! has_layers) { +#if ENABLE_GCODE_VIEWER + hide_vert_slider(); +#else reset_sliders(true); -#if !ENABLE_GCODE_VIEWER m_canvas->reset_legend_texture(); -#endif // !ENABLE_GCODE_VIEWER +#endif // ENABLE_GCODE_VIEWER m_canvas_widget->Refresh(); return; } @@ -1046,10 +1245,18 @@ void Preview::load_print_as_fff(bool keep_z_range) #endif // !ENABLE_GCODE_VIEWER if (zs.empty()) { // all layers filtered out +#if ENABLE_GCODE_VIEWER + hide_vert_slider(); +#else reset_sliders(true); +#endif // ENABLE_GCODE_VIEWER m_canvas_widget->Refresh(); } else +#if ENABLE_GCODE_VIEWER + update_vert_slider(zs, keep_z_range); +#else update_sliders(zs, keep_z_range); +#endif // ENABLE_GCODE_VIEWER } } @@ -1077,7 +1284,11 @@ void Preview::load_print_as_sla() n_layers = (unsigned int)zs.size(); if (n_layers == 0) { +#if ENABLE_GCODE_VIEWER + hide_vert_slider(); +#else reset_sliders(true); +#endif // ENABLE_GCODE_VIEWER m_canvas_widget->Refresh(); } @@ -1092,13 +1303,21 @@ void Preview::load_print_as_sla() #endif // ENABLE_GCODE_VIEWER if (n_layers > 0) +#if ENABLE_GCODE_VIEWER + update_vert_slider(zs); +#else update_sliders(zs); +#endif // ENABLE_GCODE_VIEWER m_loaded = true; } } +#if ENABLE_GCODE_VIEWER +void Preview::on_vert_slider_scroll_changed(wxCommandEvent& event) +#else void Preview::on_sliders_scroll_changed(wxCommandEvent& event) +#endif // ENABLE_GCODE_VIEWER { if (IsShown()) { @@ -1106,7 +1325,7 @@ void Preview::on_sliders_scroll_changed(wxCommandEvent& event) if (tech == ptFFF) { #if ENABLE_GCODE_VIEWER - m_canvas->set_toolpaths_z_range({ m_slider->GetLowerValueD(), m_slider->GetHigherValueD() }); + m_canvas->set_toolpaths_z_range({ m_vert_slider->GetLowerValueD(), m_vert_slider->GetHigherValueD() }); m_canvas->set_as_dirty(); #else m_canvas->set_toolpaths_range(m_slider->GetLowerValueD() - 1e-6, m_slider->GetHigherValueD() + 1e-6); @@ -1116,13 +1335,27 @@ void Preview::on_sliders_scroll_changed(wxCommandEvent& event) } else if (tech == ptSLA) { +#if ENABLE_GCODE_VIEWER + m_canvas->set_clipping_plane(0, ClippingPlane(Vec3d::UnitZ(), -m_vert_slider->GetLowerValueD())); + m_canvas->set_clipping_plane(1, ClippingPlane(-Vec3d::UnitZ(), m_vert_slider->GetHigherValueD())); + m_canvas->set_use_clipping_planes(m_vert_slider->GetHigherValue() != 0); +#else m_canvas->set_clipping_plane(0, ClippingPlane(Vec3d::UnitZ(), -m_slider->GetLowerValueD())); m_canvas->set_clipping_plane(1, ClippingPlane(-Vec3d::UnitZ(), m_slider->GetHigherValueD())); m_canvas->set_use_clipping_planes(m_slider->GetHigherValue() != 0); +#endif // ENABLE_GCODE_VIEWER m_canvas->render(); } } } +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER +void Preview::on_horz_slider_scroll_changed(wxCommandEvent& event) +{ + m_canvas->update_gcode_sequential_view_current(static_cast(m_horz_slider->GetLowerValueD()), static_cast(m_horz_slider->GetHigherValueD())); + m_canvas->render(); +} +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index a11a474ccf..4df48a153e 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -24,7 +24,9 @@ namespace Slic3r { class DynamicPrintConfig; class Print; class BackgroundSlicingProcess; +#if !ENABLE_GCODE_VIEWER class GCodePreviewData; +#endif // !ENABLE_GCODE_VIEWER class Model; namespace DoubleSlider { @@ -100,9 +102,10 @@ class Preview : public wxPanel DynamicPrintConfig* m_config; BackgroundSlicingProcess* m_process; - GCodePreviewData* m_gcode_preview_data; #if ENABLE_GCODE_VIEWER GCodeProcessor::Result* m_gcode_result; +#else + GCodePreviewData* m_gcode_preview_data; #endif // ENABLE_GCODE_VIEWER #ifdef __linux__ @@ -118,9 +121,18 @@ class Preview : public wxPanel std::string m_preferred_color_mode; bool m_loaded; +#if !ENABLE_GCODE_VIEWER bool m_enabled; +#endif // !ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER + DoubleSlider::Control* m_vert_slider{ nullptr }; +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + DoubleSlider::Control* m_horz_slider{ nullptr }; +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#else DoubleSlider::Control* m_slider {nullptr}; +#endif // ENABLE_GCODE_VIEWER public: #if ENABLE_GCODE_VIEWER @@ -138,7 +150,9 @@ Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config, void set_as_dirty(); void set_number_extruders(unsigned int number_extruders); +#if !ENABLE_GCODE_VIEWER void set_enabled(bool enabled); +#endif // !ENABLE_GCODE_VIEWER void bed_shape_changed(); void select_view(const std::string& direction); void set_drop_target(wxDropTarget* target); @@ -157,6 +171,9 @@ Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config, #if ENABLE_GCODE_VIEWER void update_bottom_toolbar(); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + void update_horz_slider(); +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER #endif // ENABLE_GCODE_VIEWER private: @@ -165,12 +182,14 @@ private: void bind_event_handlers(); void unbind_event_handlers(); -#if !ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER + void hide_vert_slider(); +#else void show_hide_ui_elements(const std::string& what); -#endif // !ENABLE_GCODE_VIEWER void reset_sliders(bool reset_all); void update_sliders(const std::vector& layers_z, bool keep_z_range = false); +#endif // ENABLE_GCODE_VIEWER void on_size(wxSizeEvent& evt); void on_choice_view_type(wxCommandEvent& evt); @@ -185,20 +204,39 @@ private: void on_checkbox_legend(wxCommandEvent& evt); #endif // ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER + // Create/Update/Reset double slider on 3dPreview + wxBoxSizer* create_vert_slider_sizer(); + void check_vert_slider_values(std::vector& ticks_from_model, + const std::vector& layers_z); + void reset_vert_slider(); + void update_vert_slider(const std::vector& layers_z, bool keep_z_range = false); + void update_vert_slider_mode(); + // update vertical DoubleSlider after keyDown in canvas + void update_vert_slider_from_canvas(wxKeyEvent& event); +#else // Create/Update/Reset double slider on 3dPreview void create_double_slider(); - void check_slider_values(std::vector &ticks_from_model, - const std::vector &layers_z); + void check_slider_values(std::vector& ticks_from_model, + const std::vector& layers_z); void reset_double_slider(); void update_double_slider(const std::vector& layers_z, bool keep_z_range = false); void update_double_slider_mode(); // update DoubleSlider after keyDown in canvas void update_double_slider_from_canvas(wxKeyEvent& event); +#endif // ENABLE_GCODE_VIEWER void load_print_as_fff(bool keep_z_range = false); void load_print_as_sla(); +#if ENABLE_GCODE_VIEWER + void on_vert_slider_scroll_changed(wxCommandEvent& event); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + void on_horz_slider_scroll_changed(wxCommandEvent& event); +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#else void on_sliders_scroll_changed(wxCommandEvent& event); +#endif // ENABLE_GCODE_VIEWER }; } // namespace GUI diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 8d505f2b65..4243b6ee84 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1641,6 +1641,9 @@ struct Plater::priv bool init_view_toolbar(); #if ENABLE_GCODE_VIEWER void update_preview_bottom_toolbar(); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + void update_preview_horz_slider(); +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER #endif // ENABLE_GCODE_VIEWER void reset_all_gizmos(); @@ -2591,8 +2594,10 @@ void Plater::priv::deselect_all() void Plater::priv::remove(size_t obj_idx) { +#if !ENABLE_GCODE_VIEWER // Prevent toolpaths preview from rendering while we modify the Print object preview->set_enabled(false); +#endif // !ENABLE_GCODE_VIEWER if (view3D->is_layers_editing_enabled()) view3D->enable_layers_editing(false); @@ -2622,8 +2627,10 @@ void Plater::priv::reset() set_project_filename(wxEmptyString); +#if !ENABLE_GCODE_VIEWER // Prevent toolpaths preview from rendering while we modify the Print object preview->set_enabled(false); +#endif // !ENABLE_GCODE_VIEWER if (view3D->is_layers_editing_enabled()) view3D->enable_layers_editing(false); @@ -3867,6 +3874,13 @@ void Plater::priv::update_preview_bottom_toolbar() { preview->update_bottom_toolbar(); } + +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER +void Plater::priv::update_preview_horz_slider() +{ + preview->update_horz_slider(); +} +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER #endif // ENABLE_GCODE_VIEWER bool Plater::priv::can_set_instance_to_object() const @@ -5463,6 +5477,13 @@ void Plater::update_preview_bottom_toolbar() { p->update_preview_bottom_toolbar(); } + +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER +void Plater::update_preview_horz_slider() +{ + p->update_preview_horz_slider(); +} +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER #endif // ENABLE_GCODE_VIEWER const Mouse3DController& Plater::get_mouse3d_controller() const diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 7a08c04efe..82c8bbe076 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -320,6 +320,9 @@ public: #if ENABLE_GCODE_VIEWER void update_preview_bottom_toolbar(); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + void update_preview_horz_slider(); +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER #endif // ENABLE_GCODE_VIEWER const Mouse3DController& get_mouse3d_controller() const; From a68eefbe4abc366dc5c80b315503b05fc321df64 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 15 May 2020 12:25:38 +0200 Subject: [PATCH 075/255] Tech ENABLE_GCODE_VIEWER -> Refactoring and code cleanup --- src/libslic3r/Technologies.hpp | 1 - src/slic3r/GUI/DoubleSlider.cpp | 32 +++--- src/slic3r/GUI/DoubleSlider.hpp | 8 +- src/slic3r/GUI/GCodeViewer.cpp | 94 +---------------- src/slic3r/GUI/GCodeViewer.hpp | 52 ---------- src/slic3r/GUI/GLCanvas3D.cpp | 8 ++ src/slic3r/GUI/GLCanvas3D.hpp | 6 +- src/slic3r/GUI/GUI_Preview.cpp | 175 ++++++++++++++++---------------- src/slic3r/GUI/GUI_Preview.hpp | 39 +++---- src/slic3r/GUI/Plater.cpp | 21 ++-- src/slic3r/GUI/Plater.hpp | 4 +- 11 files changed, 152 insertions(+), 288 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 8ce01a3530..c22e504dff 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -55,7 +55,6 @@ // Enable G-Code viewer #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) -#define ENABLE_GCODE_USE_WXWIDGETS_SLIDER (1 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index 021d73882e..597b9ad607 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -20,9 +20,9 @@ #include #include #include -#if !ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#if !ENABLE_GCODE_VIEWER #include -#endif // !ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#endif // !ENABLE_GCODE_VIEWER #include #include @@ -537,7 +537,7 @@ wxString Control::get_label(int tick) const if (value >= m_values.size()) return "ErrVal"; -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#if ENABLE_GCODE_VIEWER if (m_draw_mode == dmSequentialGCodeView) return wxString::Format("%d", static_cast(m_values[value])); else { @@ -551,7 +551,7 @@ wxString Control::get_label(int tick) const wxNumberFormatter::ToString(m_label_koef * value, 2, wxNumberFormatter::Style_None) : wxNumberFormatter::ToString(m_values[value], 2, wxNumberFormatter::Style_None); return format_wxstr("%1%\n(%2%)", str, m_values.empty() ? value : value + 1); -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#endif // ENABLE_GCODE_VIEWER } void Control::draw_tick_text(wxDC& dc, const wxPoint& pos, int tick, bool right_side/*=true*/) const @@ -792,10 +792,10 @@ void Control::draw_colored_band(wxDC& dc) void Control::draw_one_layer_icon(wxDC& dc) { -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#if ENABLE_GCODE_VIEWER if (m_draw_mode == dmSequentialGCodeView) return; -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#endif // ENABLE_GCODE_VIEWER const wxBitmap& icon = m_is_one_layer ? m_focus == fiOneLayerIcon ? m_bmp_one_layer_lock_off.bmp() : m_bmp_one_layer_lock_on.bmp() : @@ -1302,11 +1302,11 @@ void Control::OnWheel(wxMouseEvent& event) ssLower : ssHigher; } -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#if ENABLE_GCODE_VIEWER move_current_thumb((m_draw_mode == dmSequentialGCodeView) ? event.GetWheelRotation() < 0 : event.GetWheelRotation() > 0); #else move_current_thumb(event.GetWheelRotation() > 0); -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#endif // ENABLE_GCODE_VIEWER } void Control::OnKeyDown(wxKeyEvent &event) @@ -1328,34 +1328,34 @@ void Control::OnKeyDown(wxKeyEvent &event) UseDefaultColors(false); else if (is_horizontal()) { -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#if ENABLE_GCODE_VIEWER if (m_is_focused) { -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#endif // ENABLE_GCODE_VIEWER if (key == WXK_LEFT || key == WXK_RIGHT) move_current_thumb(key == WXK_LEFT); else if (key == WXK_UP || key == WXK_DOWN) { m_selection = key == WXK_UP ? ssHigher : ssLower; Refresh(); } -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#if ENABLE_GCODE_VIEWER } -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#endif // ENABLE_GCODE_VIEWER } else { -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#if ENABLE_GCODE_VIEWER if (m_is_focused) { -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#endif // ENABLE_GCODE_VIEWER if (key == WXK_LEFT || key == WXK_RIGHT) { m_selection = key == WXK_LEFT ? ssHigher : ssLower; Refresh(); } else if (key == WXK_UP || key == WXK_DOWN) move_current_thumb(key == WXK_UP); -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#if ENABLE_GCODE_VIEWER } -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#endif // ENABLE_GCODE_VIEWER } event.Skip(); // !Needed to have EVT_CHAR generated as well diff --git a/src/slic3r/GUI/DoubleSlider.hpp b/src/slic3r/GUI/DoubleSlider.hpp index a17fb2b6fa..fea1ba172e 100644 --- a/src/slic3r/GUI/DoubleSlider.hpp +++ b/src/slic3r/GUI/DoubleSlider.hpp @@ -73,9 +73,9 @@ enum DrawMode dmRegular, dmSlaPrint, dmSequentialFffPrint, -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#if ENABLE_GCODE_VIEWER dmSequentialGCodeView, -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#endif // ENABLE_GCODE_VIEWER }; using t_mode = CustomGCode::Mode; @@ -214,9 +214,9 @@ public: void SetTicksValues(const Slic3r::CustomGCode::Info &custom_gcode_per_print_z); void SetDrawMode(bool is_sla_print, bool is_sequential_print); -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#if ENABLE_GCODE_VIEWER void SetDrawMode(DrawMode mode) { m_draw_mode = mode; } -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#endif // ENABLE_GCODE_VIEWER void SetManipulationMode(t_mode mode) { m_mode = mode; } t_mode GetManipulationMode() const { return m_mode; } diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index acf1da4c71..c4bc391d18 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -324,9 +324,6 @@ void GCodeViewer::render() const m_sequential_view.marker.render(); render_shells(); render_legend(); -#if !ENABLE_GCODE_USE_WXWIDGETS_SLIDER - render_sequential_bar(); -#endif // !ENABLE_GCODE_USE_WXWIDGETS_SLIDER #if ENABLE_GCODE_VIEWER_STATISTICS render_statistics(); #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -383,15 +380,13 @@ void GCodeViewer::set_options_visibility_from_flags(unsigned int flags) enable_legend(is_flag_set(9)); } -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER void GCodeViewer::set_layers_z_range(const std::array& layers_z_range) { bool keep_sequential_current = layers_z_range[1] <= m_layers_z_range[1]; m_layers_z_range = layers_z_range; refresh_render_paths(keep_sequential_current); - wxGetApp().plater()->update_preview_horz_slider(); + wxGetApp().plater()->update_preview_moves_slider(); } -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER bool GCodeViewer::init_shaders() { @@ -1159,93 +1154,6 @@ void GCodeViewer::render_legend() const ImGui::PopStyleVar(); } -#if !ENABLE_GCODE_USE_WXWIDGETS_SLIDER -void GCodeViewer::render_sequential_bar() const -{ - static const float MARGIN = 125.0f; - static const float BUTTON_W = 50.0f; - - auto apply_button_action = [this](unsigned int value) { - m_sequential_view.current = std::clamp(value, m_sequential_view.first, m_sequential_view.last); - refresh_render_paths(true); - }; - - if (m_sequential_view.last <= m_sequential_view.first) - return; - - ImGuiWrapper& imgui = *wxGetApp().imgui(); - const ImGuiStyle& style = ImGui::GetStyle(); - - Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size(); - - float left = wxGetApp().plater()->get_view_toolbar().get_width(); - float width = static_cast(cnv_size.get_width()) - left; - - ImGui::SetNextWindowBgAlpha(0.5f); - imgui.set_next_window_pos(left, static_cast(cnv_size.get_height()), ImGuiCond_Always, 0.0f, 1.0f); - ImGui::SetNextWindowSize({ width, -1.0f }, ImGuiCond_Always); - ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); - imgui.begin(std::string("Sequential"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); - - ImGui::SetCursorPosX(MARGIN); - imgui.disabled_begin(m_sequential_view.first == m_sequential_view.current); - if (ImGui::Button("< 1", { BUTTON_W, 0.0f })) - apply_button_action(m_sequential_view.current - 1); - imgui.disabled_end(); - - ImGui::SameLine(); - imgui.disabled_begin(m_sequential_view.current - m_sequential_view.first < 10); - if (ImGui::Button("< 10", { BUTTON_W, 0.0f })) - apply_button_action(m_sequential_view.current - 10); - imgui.disabled_end(); - - ImGui::SameLine(); - imgui.disabled_begin(m_sequential_view.current - m_sequential_view.first < 100); - if (ImGui::Button("< 100", { BUTTON_W, 0.0f })) - apply_button_action(m_sequential_view.current - 100); - imgui.disabled_end(); - - ImGui::SameLine(width - MARGIN - 3 * BUTTON_W - 2 * style.ItemSpacing.x - style.WindowPadding.x); - imgui.disabled_begin(m_sequential_view.last - m_sequential_view.current < 100); - if (ImGui::Button("> 100", { BUTTON_W, 0.0f })) - apply_button_action(m_sequential_view.current + 100); - imgui.disabled_end(); - - ImGui::SameLine(); - imgui.disabled_begin(m_sequential_view.last - m_sequential_view.current < 10); - if (ImGui::Button("> 10", { BUTTON_W, 0.0f })) - apply_button_action(m_sequential_view.current + 10); - imgui.disabled_end(); - - ImGui::SameLine(); - imgui.disabled_begin(m_sequential_view.last == m_sequential_view.current); - if (ImGui::Button("> 1", { BUTTON_W, 0.0f })) - apply_button_action(m_sequential_view.current + 1); - imgui.disabled_end(); - - int index = 1 + static_cast(m_sequential_view.current); - int i_min = 1 + static_cast(m_sequential_view.first); - int i_max = 1 + static_cast(m_sequential_view.last); - - std::string low_str = std::to_string(i_min); - ImGui::SetCursorPosX(MARGIN - style.ItemSpacing.x - ImGui::CalcTextSize(low_str.c_str()).x); - ImGui::AlignTextToFramePadding(); - imgui.text(low_str); - ImGui::SameLine(MARGIN); - ImGui::PushItemWidth(-MARGIN); - if (ImGui::SliderInt("##slider int", &index, i_min, i_max)) { - m_sequential_view.current = static_cast(index - 1); - refresh_render_paths(true); - } - ImGui::PopItemWidth(); - ImGui::SameLine(); - imgui.text(std::to_string(i_max)); - - imgui.end(); - ImGui::PopStyleVar(); -} -#endif // !ENABLE_GCODE_USE_WXWIDGETS_SLIDER - #if ENABLE_GCODE_VIEWER_STATISTICS void GCodeViewer::render_statistics() const { diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index a4ac3358d2..e53bcb0c62 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -149,42 +149,6 @@ class GCodeViewer void reset_ranges() { ranges.reset(); } }; -#if !ENABLE_GCODE_USE_WXWIDGETS_SLIDER - struct SequentialView - { - class Marker - { - GL_Model m_model; - Transform3f m_world_transform; - std::array m_color{ 1.0f, 1.0f, 1.0f, 1.0f }; - bool m_visible{ false }; - Shader m_shader; - - public: - void init(); - - const BoundingBoxf3& get_bounding_box() const { return m_model.get_bounding_box(); } - - void set_world_transform(const Transform3f& transform) { m_world_transform = transform; } - void set_color(const std::array& color) { m_color = color; } - - bool is_visible() const { return m_visible; } - void set_visible(bool visible) { m_visible = visible; } - - void render() const; - - private: - void init_shader(); - }; - - unsigned int first{ 0 }; - unsigned int last{ 0 }; - unsigned int current{ 0 }; - Vec3f current_position{ Vec3f::Zero() }; - Marker marker; - }; -#endif // !ENABLE_GCODE_USE_WXWIDGETS_SLIDER - #if ENABLE_GCODE_VIEWER_STATISTICS struct Statistics { @@ -231,7 +195,6 @@ class GCodeViewer #endif // ENABLE_GCODE_VIEWER_STATISTICS public: -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER struct SequentialView { class Marker @@ -265,7 +228,6 @@ public: Vec3f current_position{ Vec3f::Zero() }; Marker marker; }; -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER enum class EViewType : unsigned char { @@ -322,10 +284,8 @@ public: const BoundingBoxf3& get_bounding_box() const { return m_bounding_box; } const std::vector& get_layers_zs() const { return m_layers_zs; }; -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER const SequentialView& get_sequential_view() const { return m_sequential_view; } void update_sequential_view_current(unsigned int low, unsigned int high) { m_sequential_view.current = high; refresh_render_paths(true); } -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER EViewType get_view_type() const { return m_view_type; } void set_view_type(EViewType type) { @@ -341,16 +301,7 @@ public: void set_toolpath_role_visibility_flags(unsigned int flags) { m_extrusions.role_visibility_flags = flags; } unsigned int get_options_visibility_flags() const; void set_options_visibility_from_flags(unsigned int flags); -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER void set_layers_z_range(const std::array& layers_z_range); -#else - void set_layers_z_range(const std::array& layers_z_range) - { - bool keep_sequential_current = layers_z_range[1] <= m_layers_z_range[1]; - m_layers_z_range = layers_z_range; - refresh_render_paths(keep_sequential_current); - } -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER bool is_legend_enabled() const { return m_legend_enabled; } void enable_legend(bool enable) { m_legend_enabled = enable; } @@ -363,9 +314,6 @@ private: void render_toolpaths() const; void render_shells() const; void render_legend() const; -#if !ENABLE_GCODE_USE_WXWIDGETS_SLIDER - void render_sequential_bar() const; -#endif // !ENABLE_GCODE_USE_WXWIDGETS_SLIDER #if ENABLE_GCODE_VIEWER_STATISTICS void render_statistics() const; #endif // ENABLE_GCODE_VIEWER_STATISTICS diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 073a9cd35e..7629bc969b 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1523,7 +1523,11 @@ wxDEFINE_EVENT(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_UPDATE_BED_SHAPE, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_TAB, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_RESETGIZMOS, SimpleEvent); +#if ENABLE_GCODE_VIEWER +wxDEFINE_EVENT(EVT_GLCANVAS_MOVE_LAYERS_SLIDER, wxKeyEvent); +#else wxDEFINE_EVENT(EVT_GLCANVAS_MOVE_DOUBLE_SLIDER, wxKeyEvent); +#endif // ENABLE_GCODE_VIEWER wxDEFINE_EVENT(EVT_GLCANVAS_EDIT_COLOR_CHANGE, wxKeyEvent); wxDEFINE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent); @@ -3405,7 +3409,11 @@ void GLCanvas3D::on_key(wxKeyEvent& evt) keyCode == WXK_DOWN) { if (dynamic_cast(m_canvas->GetParent()) != nullptr) +#if ENABLE_GCODE_VIEWER + post_event(wxKeyEvent(EVT_GLCANVAS_MOVE_LAYERS_SLIDER, evt)); +#else post_event(wxKeyEvent(EVT_GLCANVAS_MOVE_DOUBLE_SLIDER, evt)); +#endif // ENABLE_GCODE_VIEWER } } } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index d4df60ad2a..43d37607c5 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -107,7 +107,11 @@ wxDECLARE_EVENT(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_UPDATE_BED_SHAPE, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_TAB, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_RESETGIZMOS, SimpleEvent); +#if ENABLE_GCODE_VIEWER +wxDECLARE_EVENT(EVT_GLCANVAS_MOVE_LAYERS_SLIDER, wxKeyEvent); +#else wxDECLARE_EVENT(EVT_GLCANVAS_MOVE_DOUBLE_SLIDER, wxKeyEvent); +#endif // ENABLE_GCODE_VIEWER wxDECLARE_EVENT(EVT_GLCANVAS_EDIT_COLOR_CHANGE, wxKeyEvent); wxDECLARE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent); @@ -553,10 +557,8 @@ public: #if ENABLE_GCODE_VIEWER void reset_gcode_toolpaths() { m_gcode_viewer.reset(); } -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER const GCodeViewer::SequentialView& get_gcode_sequential_view() const { return m_gcode_viewer.get_sequential_view(); } void update_gcode_sequential_view_current(unsigned int low, unsigned int high) { m_gcode_viewer.update_sequential_view_current(low, high); } -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER #endif // ENABLE_GCODE_VIEWER void toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 9547e0bf89..714ed3c9ef 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -183,9 +183,11 @@ Preview::Preview( #endif // ENABLE_GCODE_VIEWER : m_canvas_widget(nullptr) , m_canvas(nullptr) - , m_double_slider_sizer(nullptr) #if ENABLE_GCODE_VIEWER , m_bottom_toolbar_sizer(nullptr) + , m_layers_slider_sizer(nullptr) +#else + , m_double_slider_sizer(nullptr) #endif // ENABLE_GCODE_VIEWER , m_label_view_type(nullptr) , m_choice_view_type(nullptr) @@ -248,7 +250,7 @@ bool Preview::init(wxWindow* parent, Model* model) m_canvas->enable_collapse_toolbar(true); #if ENABLE_GCODE_VIEWER - m_double_slider_sizer = create_vert_slider_sizer(); + m_layers_slider_sizer = create_layers_slider_sizer(); #else m_double_slider_sizer = new wxBoxSizer(wxHORIZONTAL); create_double_slider(); @@ -319,15 +321,17 @@ bool Preview::init(wxWindow* parent, Model* model) wxBoxSizer* top_sizer = new wxBoxSizer(wxHORIZONTAL); top_sizer->Add(m_canvas_widget, 1, wxALL | wxEXPAND, 0); +#if ENABLE_GCODE_VIEWER + top_sizer->Add(m_layers_slider_sizer, 0, wxEXPAND, 0); +#else top_sizer->Add(m_double_slider_sizer, 0, wxEXPAND, 0); - -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER - m_horz_slider = new DoubleSlider::Control(this, wxID_ANY, 0, 0, 0, 100, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL); - m_horz_slider->SetDrawMode(DoubleSlider::dmSequentialGCodeView); - m_horz_slider->Bind(wxEVT_SCROLL_CHANGED, &Preview::on_horz_slider_scroll_changed, this); -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#endif // ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER + m_moves_slider = new DoubleSlider::Control(this, wxID_ANY, 0, 0, 0, 100, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL); + m_moves_slider->SetDrawMode(DoubleSlider::dmSequentialGCodeView); + m_moves_slider->Bind(wxEVT_SCROLL_CHANGED, &Preview::on_moves_slider_scroll_changed, this); + m_bottom_toolbar_sizer = new wxBoxSizer(wxHORIZONTAL); m_bottom_toolbar_sizer->AddSpacer(10); m_bottom_toolbar_sizer->Add(m_label_view_type, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5); @@ -336,10 +340,8 @@ bool Preview::init(wxWindow* parent, Model* model) m_bottom_toolbar_sizer->Add(m_label_show, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5); m_bottom_toolbar_sizer->Add(m_combochecklist_options, 0, wxALIGN_CENTER_VERTICAL, 5); m_bottom_toolbar_sizer->Add(m_combochecklist_features, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 5); -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER m_bottom_toolbar_sizer->AddSpacer(10); - m_bottom_toolbar_sizer->Add(m_horz_slider, 1, wxALL | wxEXPAND, 5); -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER + m_bottom_toolbar_sizer->Add(m_moves_slider, 1, wxALL | wxEXPAND, 5); #else wxBoxSizer* bottom_sizer = new wxBoxSizer(wxHORIZONTAL); bottom_sizer->Add(m_label_view_type, 0, wxALIGN_CENTER_VERTICAL, 5); @@ -517,10 +519,8 @@ void Preview::msw_rescale() { // rescale slider #if ENABLE_GCODE_VIEWER - if (m_vert_slider != nullptr) m_vert_slider->msw_rescale(); -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER - if (m_horz_slider != nullptr) m_horz_slider->msw_rescale(); -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER + if (m_layers_slider != nullptr) m_layers_slider->msw_rescale(); + if (m_moves_slider != nullptr) m_moves_slider->msw_rescale(); #else if (m_slider) m_slider->msw_rescale(); #endif // ENABLE_GCODE_VIEWER @@ -532,25 +532,31 @@ void Preview::msw_rescale() refresh_print(); } +#if ENABLE_GCODE_VIEWER +void Preview::move_layers_slider(wxKeyEvent& evt) +{ + if (m_layers_slider != nullptr) m_layers_slider->OnKeyDown(evt); +} +#else void Preview::move_double_slider(wxKeyEvent& evt) { -#if ENABLE_GCODE_VIEWER - if (m_vert_slider != nullptr) m_vert_slider->OnKeyDown(evt); -#else if (m_slider) m_slider->OnKeyDown(evt); -#endif // ENABLE_GCODE_VIEWER } +#endif // ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER +void Preview::edit_layers_slider(wxKeyEvent& evt) +{ + if (m_layers_slider != nullptr) m_layers_slider->OnChar(evt); +} +#else void Preview::edit_double_slider(wxKeyEvent& evt) { -#if ENABLE_GCODE_VIEWER - if (m_vert_slider != nullptr) m_vert_slider->OnChar(evt); -#else if (m_slider) m_slider->OnChar(evt); -#endif // ENABLE_GCODE_VIEWER } +#endif // ENABLE_GCODE_VIEWER void Preview::bind_event_handlers() { @@ -614,9 +620,9 @@ void Preview::show_hide_ui_elements(const std::string& what) #endif // !ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER -void Preview::hide_vert_slider() +void Preview::hide_layers_slider() { - m_double_slider_sizer->Hide((size_t)0); + m_layers_slider_sizer->Hide((size_t)0); Layout(); } #else @@ -756,29 +762,29 @@ void Preview::update_bottom_toolbar() #endif // ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER -wxBoxSizer* Preview::create_vert_slider_sizer() +wxBoxSizer* Preview::create_layers_slider_sizer() { wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL); - m_vert_slider = new DoubleSlider::Control(this, wxID_ANY, 0, 0, 0, 100); + m_layers_slider = new DoubleSlider::Control(this, wxID_ANY, 0, 0, 0, 100); - m_vert_slider->SetDrawMode(wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA, + m_layers_slider->SetDrawMode(wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA, wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_bool("complete_objects")); - sizer->Add(m_vert_slider, 0, wxEXPAND, 0); + sizer->Add(m_layers_slider, 0, wxEXPAND, 0); // sizer, m_canvas_widget - m_canvas_widget->Bind(wxEVT_KEY_DOWN, &Preview::update_vert_slider_from_canvas, this); + m_canvas_widget->Bind(wxEVT_KEY_DOWN, &Preview::update_layers_slider_from_canvas, this); m_canvas_widget->Bind(wxEVT_KEY_UP, [this](wxKeyEvent& event) { if (event.GetKeyCode() == WXK_SHIFT) - m_vert_slider->UseDefaultColors(true); + m_layers_slider->UseDefaultColors(true); event.Skip(); }); - m_vert_slider->Bind(wxEVT_SCROLL_CHANGED, &Preview::on_vert_slider_scroll_changed, this); + m_layers_slider->Bind(wxEVT_SCROLL_CHANGED, &Preview::on_layers_slider_scroll_changed, this); Bind(DoubleSlider::wxCUSTOMEVT_TICKSCHANGED, [this](wxEvent&) { Model& model = wxGetApp().plater()->model(); - model.custom_gcode_per_print_z = m_vert_slider->GetTicksValues(); + model.custom_gcode_per_print_z = m_layers_slider->GetTicksValues(); m_schedule_background_process(); update_view_type(false); @@ -850,8 +856,7 @@ static int find_close_layer_idx(const std::vector& zs, double &z, double } #if ENABLE_GCODE_VIEWER -void Preview::check_vert_slider_values(std::vector& ticks_from_model, - const std::vector& layers_z) +void Preview::check_layers_slider_values(std::vector& ticks_from_model, const std::vector& layers_z) #else void Preview::check_slider_values(std::vector& ticks_from_model, const std::vector& layers_z) @@ -873,34 +878,34 @@ void Preview::check_slider_values(std::vector& ticks_from_mod } #if ENABLE_GCODE_VIEWER -void Preview::update_vert_slider(const std::vector& layers_z, bool keep_z_range) +void Preview::update_layers_slider(const std::vector& layers_z, bool keep_z_range) { // Save the initial slider span. - double z_low = m_vert_slider->GetLowerValueD(); - double z_high = m_vert_slider->GetHigherValueD(); - bool was_empty = m_vert_slider->GetMaxValue() == 0; + double z_low = m_layers_slider->GetLowerValueD(); + double z_high = m_layers_slider->GetHigherValueD(); + bool was_empty = m_layers_slider->GetMaxValue() == 0; bool force_sliders_full_range = was_empty; if (!keep_z_range) { - bool span_changed = layers_z.empty() || std::abs(layers_z.back() - m_vert_slider->GetMaxValueD()) > DoubleSlider::epsilon()/*1e-6*/; + bool span_changed = layers_z.empty() || std::abs(layers_z.back() - m_layers_slider->GetMaxValueD()) > DoubleSlider::epsilon()/*1e-6*/; force_sliders_full_range |= span_changed; -} - bool snap_to_min = force_sliders_full_range || m_vert_slider->is_lower_at_min(); - bool snap_to_max = force_sliders_full_range || m_vert_slider->is_higher_at_max(); + } + bool snap_to_min = force_sliders_full_range || m_layers_slider->is_lower_at_min(); + bool snap_to_max = force_sliders_full_range || m_layers_slider->is_higher_at_max(); // Detect and set manipulation mode for double slider - update_vert_slider_mode(); + update_layers_slider_mode(); CustomGCode::Info& ticks_info_from_model = wxGetApp().plater()->model().custom_gcode_per_print_z; - check_vert_slider_values(ticks_info_from_model.gcodes, layers_z); + check_layers_slider_values(ticks_info_from_model.gcodes, layers_z); - m_vert_slider->SetSliderValues(layers_z); - assert(m_vert_slider->GetMinValue() == 0); - m_vert_slider->SetMaxValue(layers_z.empty() ? 0 : layers_z.size() - 1); + m_layers_slider->SetSliderValues(layers_z); + assert(m_layers_slider->GetMinValue() == 0); + m_layers_slider->SetMaxValue(layers_z.empty() ? 0 : layers_z.size() - 1); int idx_low = 0; - int idx_high = m_vert_slider->GetMaxValue(); + int idx_high = m_layers_slider->GetMaxValue(); if (!layers_z.empty()) { if (!snap_to_min) { int idx_new = find_close_layer_idx(layers_z, z_low, DoubleSlider::epsilon()/*1e-6*/); @@ -913,17 +918,15 @@ void Preview::update_vert_slider(const std::vector& layers_z, bool keep_ idx_high = idx_new; } } - m_vert_slider->SetSelectionSpan(idx_low, idx_high); - - m_vert_slider->SetTicksValues(ticks_info_from_model); + m_layers_slider->SetSelectionSpan(idx_low, idx_high); + m_layers_slider->SetTicksValues(ticks_info_from_model); bool sla_print_technology = wxGetApp().plater()->printer_technology() == ptSLA; bool sequential_print = wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_bool("complete_objects"); - m_vert_slider->SetDrawMode(sla_print_technology, sequential_print); + m_layers_slider->SetDrawMode(sla_print_technology, sequential_print); + m_layers_slider->SetExtruderColors(wxGetApp().plater()->get_extruder_colors_from_plater_config()); - m_vert_slider->SetExtruderColors(wxGetApp().plater()->get_extruder_colors_from_plater_config()); - - m_double_slider_sizer->Show((size_t)0); + m_layers_slider_sizer->Show((size_t)0); Layout(); } #else @@ -980,7 +983,7 @@ void Preview::update_double_slider(const std::vector & layers_z, bool ke #endif // ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER -void Preview::update_vert_slider_mode() +void Preview::update_layers_slider_mode() #else void Preview::update_double_slider_mode() #endif // ENABLE_GCODE_VIEWER @@ -1033,17 +1036,17 @@ void Preview::update_double_slider_mode() } #if ENABLE_GCODE_VIEWER - m_vert_slider->SetModeAndOnlyExtruder(one_extruder_printed_model, only_extruder); + m_layers_slider->SetModeAndOnlyExtruder(one_extruder_printed_model, only_extruder); #else m_slider->SetModeAndOnlyExtruder(one_extruder_printed_model, only_extruder); #endif // ENABLE_GCODE_VIEWER } #if ENABLE_GCODE_VIEWER -void Preview::reset_vert_slider() +void Preview::reset_layers_slider() { - m_vert_slider->SetHigherValue(0); - m_vert_slider->SetLowerValue(0); + m_layers_slider->SetHigherValue(0); + m_layers_slider->SetLowerValue(0); } #else void Preview::reset_double_slider() @@ -1054,7 +1057,7 @@ void Preview::reset_double_slider() #endif // ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER -void Preview::update_vert_slider_from_canvas(wxKeyEvent& event) +void Preview::update_layers_slider_from_canvas(wxKeyEvent& event) { if (event.HasModifiers()) { event.Skip(); @@ -1064,20 +1067,19 @@ void Preview::update_vert_slider_from_canvas(wxKeyEvent& event) const auto key = event.GetKeyCode(); if (key == 'U' || key == 'D') { - const int new_pos = key == 'U' ? m_vert_slider->GetHigherValue() + 1 : m_vert_slider->GetHigherValue() - 1; - m_vert_slider->SetHigherValue(new_pos); - if (event.ShiftDown() || m_vert_slider->is_one_layer()) m_vert_slider->SetLowerValue(m_vert_slider->GetHigherValue()); + const int new_pos = key == 'U' ? m_layers_slider->GetHigherValue() + 1 : m_layers_slider->GetHigherValue() - 1; + m_layers_slider->SetHigherValue(new_pos); + if (event.ShiftDown() || m_layers_slider->is_one_layer()) m_layers_slider->SetLowerValue(m_layers_slider->GetHigherValue()); } else if (key == 'S') - m_vert_slider->ChangeOneLayerLock(); + m_layers_slider->ChangeOneLayerLock(); else if (key == WXK_SHIFT) - m_vert_slider->UseDefaultColors(false); + m_layers_slider->UseDefaultColors(false); else event.Skip(); } -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER -void Preview::update_horz_slider() +void Preview::update_moves_slider() { const GCodeViewer::SequentialView& view = m_canvas->get_gcode_sequential_view(); std::vector values(view.last - view.first + 1); @@ -1087,11 +1089,10 @@ void Preview::update_horz_slider() values[count++] = static_cast(i + 1); } - m_horz_slider->SetSliderValues(values); - m_horz_slider->SetMaxValue(view.last - view.first); - m_horz_slider->SetSelectionSpan(0, view.current); + m_moves_slider->SetSliderValues(values); + m_moves_slider->SetMaxValue(view.last - view.first); + m_moves_slider->SetSelectionSpan(0, view.current); } -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER #else void Preview::update_double_slider_from_canvas(wxKeyEvent & event) { @@ -1149,7 +1150,7 @@ void Preview::load_print_as_fff(bool keep_z_range) if (! has_layers) { #if ENABLE_GCODE_VIEWER - hide_vert_slider(); + hide_layers_slider(); #else reset_sliders(true); m_canvas->reset_legend_texture(); @@ -1246,14 +1247,14 @@ void Preview::load_print_as_fff(bool keep_z_range) if (zs.empty()) { // all layers filtered out #if ENABLE_GCODE_VIEWER - hide_vert_slider(); + hide_layers_slider(); #else reset_sliders(true); #endif // ENABLE_GCODE_VIEWER m_canvas_widget->Refresh(); } else #if ENABLE_GCODE_VIEWER - update_vert_slider(zs, keep_z_range); + update_layers_slider(zs, keep_z_range); #else update_sliders(zs, keep_z_range); #endif // ENABLE_GCODE_VIEWER @@ -1285,7 +1286,7 @@ void Preview::load_print_as_sla() if (n_layers == 0) { #if ENABLE_GCODE_VIEWER - hide_vert_slider(); + hide_layers_slider(); #else reset_sliders(true); #endif // ENABLE_GCODE_VIEWER @@ -1304,7 +1305,7 @@ void Preview::load_print_as_sla() if (n_layers > 0) #if ENABLE_GCODE_VIEWER - update_vert_slider(zs); + update_layers_slider(zs); #else update_sliders(zs); #endif // ENABLE_GCODE_VIEWER @@ -1314,7 +1315,7 @@ void Preview::load_print_as_sla() } #if ENABLE_GCODE_VIEWER -void Preview::on_vert_slider_scroll_changed(wxCommandEvent& event) +void Preview::on_layers_slider_scroll_changed(wxCommandEvent& event) #else void Preview::on_sliders_scroll_changed(wxCommandEvent& event) #endif // ENABLE_GCODE_VIEWER @@ -1325,7 +1326,7 @@ void Preview::on_sliders_scroll_changed(wxCommandEvent& event) if (tech == ptFFF) { #if ENABLE_GCODE_VIEWER - m_canvas->set_toolpaths_z_range({ m_vert_slider->GetLowerValueD(), m_vert_slider->GetHigherValueD() }); + m_canvas->set_toolpaths_z_range({ m_layers_slider->GetLowerValueD(), m_layers_slider->GetHigherValueD() }); m_canvas->set_as_dirty(); #else m_canvas->set_toolpaths_range(m_slider->GetLowerValueD() - 1e-6, m_slider->GetHigherValueD() + 1e-6); @@ -1336,9 +1337,9 @@ void Preview::on_sliders_scroll_changed(wxCommandEvent& event) else if (tech == ptSLA) { #if ENABLE_GCODE_VIEWER - m_canvas->set_clipping_plane(0, ClippingPlane(Vec3d::UnitZ(), -m_vert_slider->GetLowerValueD())); - m_canvas->set_clipping_plane(1, ClippingPlane(-Vec3d::UnitZ(), m_vert_slider->GetHigherValueD())); - m_canvas->set_use_clipping_planes(m_vert_slider->GetHigherValue() != 0); + m_canvas->set_clipping_plane(0, ClippingPlane(Vec3d::UnitZ(), -m_layers_slider->GetLowerValueD())); + m_canvas->set_clipping_plane(1, ClippingPlane(-Vec3d::UnitZ(), m_layers_slider->GetHigherValueD())); + m_canvas->set_use_clipping_planes(m_layers_slider->GetHigherValue() != 0); #else m_canvas->set_clipping_plane(0, ClippingPlane(Vec3d::UnitZ(), -m_slider->GetLowerValueD())); m_canvas->set_clipping_plane(1, ClippingPlane(-Vec3d::UnitZ(), m_slider->GetHigherValueD())); @@ -1349,13 +1350,13 @@ void Preview::on_sliders_scroll_changed(wxCommandEvent& event) } } -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER -void Preview::on_horz_slider_scroll_changed(wxCommandEvent& event) +#if ENABLE_GCODE_VIEWER +void Preview::on_moves_slider_scroll_changed(wxCommandEvent& event) { - m_canvas->update_gcode_sequential_view_current(static_cast(m_horz_slider->GetLowerValueD()), static_cast(m_horz_slider->GetHigherValueD())); + m_canvas->update_gcode_sequential_view_current(static_cast(m_moves_slider->GetLowerValueD()), static_cast(m_moves_slider->GetHigherValueD())); m_canvas->render(); } -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#endif // ENABLE_GCODE_VIEWER } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 4df48a153e..3f0d4b4e68 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -82,9 +82,11 @@ class Preview : public wxPanel { wxGLCanvas* m_canvas_widget; GLCanvas3D* m_canvas; - wxBoxSizer* m_double_slider_sizer; #if ENABLE_GCODE_VIEWER + wxBoxSizer* m_layers_slider_sizer; wxBoxSizer* m_bottom_toolbar_sizer; +#else + wxBoxSizer* m_double_slider_sizer; #endif // ENABLE_GCODE_VIEWER wxStaticText* m_label_view_type; wxChoice* m_choice_view_type; @@ -126,10 +128,8 @@ class Preview : public wxPanel #endif // !ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER - DoubleSlider::Control* m_vert_slider{ nullptr }; -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER - DoubleSlider::Control* m_horz_slider{ nullptr }; -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER + DoubleSlider::Control* m_layers_slider{ nullptr }; + DoubleSlider::Control* m_moves_slider{ nullptr }; #else DoubleSlider::Control* m_slider {nullptr}; #endif // ENABLE_GCODE_VIEWER @@ -162,8 +162,13 @@ Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config, void refresh_print(); void msw_rescale(); +#if ENABLE_GCODE_VIEWER + void move_layers_slider(wxKeyEvent& evt); + void edit_layers_slider(wxKeyEvent& evt); +#else void move_double_slider(wxKeyEvent& evt); void edit_double_slider(wxKeyEvent& evt); +#endif // ENABLE_GCODE_VIEWER void update_view_type(bool slice_completed); @@ -171,9 +176,7 @@ Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config, #if ENABLE_GCODE_VIEWER void update_bottom_toolbar(); -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER - void update_horz_slider(); -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER + void update_moves_slider(); #endif // ENABLE_GCODE_VIEWER private: @@ -183,7 +186,7 @@ private: void unbind_event_handlers(); #if ENABLE_GCODE_VIEWER - void hide_vert_slider(); + void hide_layers_slider(); #else void show_hide_ui_elements(const std::string& what); @@ -206,14 +209,14 @@ private: #if ENABLE_GCODE_VIEWER // Create/Update/Reset double slider on 3dPreview - wxBoxSizer* create_vert_slider_sizer(); - void check_vert_slider_values(std::vector& ticks_from_model, + wxBoxSizer* create_layers_slider_sizer(); + void check_layers_slider_values(std::vector& ticks_from_model, const std::vector& layers_z); - void reset_vert_slider(); - void update_vert_slider(const std::vector& layers_z, bool keep_z_range = false); - void update_vert_slider_mode(); + void reset_layers_slider(); + void update_layers_slider(const std::vector& layers_z, bool keep_z_range = false); + void update_layers_slider_mode(); // update vertical DoubleSlider after keyDown in canvas - void update_vert_slider_from_canvas(wxKeyEvent& event); + void update_layers_slider_from_canvas(wxKeyEvent& event); #else // Create/Update/Reset double slider on 3dPreview void create_double_slider(); @@ -230,10 +233,8 @@ private: void load_print_as_sla(); #if ENABLE_GCODE_VIEWER - void on_vert_slider_scroll_changed(wxCommandEvent& event); -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER - void on_horz_slider_scroll_changed(wxCommandEvent& event); -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER + void on_layers_slider_scroll_changed(wxCommandEvent& event); + void on_moves_slider_scroll_changed(wxCommandEvent& event); #else void on_sliders_scroll_changed(wxCommandEvent& event); #endif // ENABLE_GCODE_VIEWER diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index be5b5b3ab4..35455fa9c0 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1642,9 +1642,7 @@ struct Plater::priv bool init_view_toolbar(); #if ENABLE_GCODE_VIEWER void update_preview_bottom_toolbar(); -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER - void update_preview_horz_slider(); -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER + void update_preview_moves_slider(); #endif // ENABLE_GCODE_VIEWER void reset_all_gizmos(); @@ -1975,8 +1973,13 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) config->option("bed_custom_model")->value); }); preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_TAB, [this](SimpleEvent&) { select_next_view_3D(); }); +#if ENABLE_GCODE_VIEWER + preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_MOVE_LAYERS_SLIDER, [this](wxKeyEvent& evt) { preview->move_layers_slider(evt); }); + preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_EDIT_COLOR_CHANGE, [this](wxKeyEvent& evt) { preview->edit_layers_slider(evt); }); +#else preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_MOVE_DOUBLE_SLIDER, [this](wxKeyEvent& evt) { preview->move_double_slider(evt); }); preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_EDIT_COLOR_CHANGE, [this](wxKeyEvent& evt) { preview->edit_double_slider(evt); }); +#endif // ENABLE_GCODE_VIEWER q->Bind(EVT_SLICING_COMPLETED, &priv::on_slicing_completed, this); q->Bind(EVT_PROCESS_COMPLETED, &priv::on_process_completed, this); @@ -3879,12 +3882,10 @@ void Plater::priv::update_preview_bottom_toolbar() preview->update_bottom_toolbar(); } -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER -void Plater::priv::update_preview_horz_slider() +void Plater::priv::update_preview_moves_slider() { - preview->update_horz_slider(); + preview->update_moves_slider(); } -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER #endif // ENABLE_GCODE_VIEWER bool Plater::priv::can_set_instance_to_object() const @@ -5482,12 +5483,10 @@ void Plater::update_preview_bottom_toolbar() p->update_preview_bottom_toolbar(); } -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER -void Plater::update_preview_horz_slider() +void Plater::update_preview_moves_slider() { - p->update_preview_horz_slider(); + p->update_preview_moves_slider(); } -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER #endif // ENABLE_GCODE_VIEWER const Mouse3DController& Plater::get_mouse3d_controller() const diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 82c8bbe076..21eba8ad13 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -320,9 +320,7 @@ public: #if ENABLE_GCODE_VIEWER void update_preview_bottom_toolbar(); -#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER - void update_preview_horz_slider(); -#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER + void update_preview_moves_slider(); #endif // ENABLE_GCODE_VIEWER const Mouse3DController& get_mouse3d_controller() const; From 2b536137d2830847b42732b294f37698a4484519 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 15 May 2020 17:57:47 +0200 Subject: [PATCH 076/255] Tech ENABLE_GCODE_VIEWER -> Adapting DoubleSlider::Control for sequential view --- src/slic3r/GUI/DoubleSlider.cpp | 75 ++++++++++++++++++++++++++++++--- src/slic3r/GUI/DoubleSlider.hpp | 4 ++ src/slic3r/GUI/GLCanvas3D.hpp | 2 +- 3 files changed, 73 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index 597b9ad607..a6c9a5c772 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -838,8 +838,20 @@ void Control::draw_cog_icon(wxDC& dc) get_size(&width, &height); wxCoord x_draw, y_draw; - is_horizontal() ? x_draw = width-2 : x_draw = width - m_cog_icon_dim - 2; - is_horizontal() ? y_draw = height - m_cog_icon_dim - 2 : y_draw = height-2; +#if ENABLE_GCODE_VIEWER + if (m_draw_mode == dmSequentialGCodeView) + { + is_horizontal() ? x_draw = width - 2 : x_draw = 0.5 * width - 0.5 * m_cog_icon_dim; + is_horizontal() ? y_draw = 0.5 * height - 0.5 * m_cog_icon_dim : y_draw = height - 2; + } + else + { +#endif // ENABLE_GCODE_VIEWER + is_horizontal() ? x_draw = width - 2 : x_draw = width - m_cog_icon_dim - 2; + is_horizontal() ? y_draw = height - m_cog_icon_dim - 2 : y_draw = height - 2; +#if ENABLE_GCODE_VIEWER + } +#endif // ENABLE_GCODE_VIEWER dc.DrawBitmap(m_bmp_cog.bmp(), x_draw, y_draw); @@ -977,10 +989,19 @@ wxString Control::get_tooltip(int tick/*=-1*/) if (m_focus == fiRevertIcon) return _(L("Discard all custom changes")); if (m_focus == fiCogIcon) - return m_mode == t_mode::MultiAsSingle ? - GUI::from_u8((boost::format(_utf8(L("Jump to height %s or " - "Set extruder sequence for the entire print"))) % " (Shift + G)\n").str()) : - _(L("Jump to height")) + " (Shift + G)"; +#if ENABLE_GCODE_VIEWER + { + if (m_draw_mode == dmSequentialGCodeView) + return _L("Jump to move") + " (Shift + G)"; + else +#endif // ENABLE_GCODE_VIEWER + return m_mode == t_mode::MultiAsSingle ? + GUI::from_u8((boost::format(_utf8(L("Jump to height %s or " + "Set extruder sequence for the entire print"))) % " (Shift + G)\n").str()) : + _(L("Jump to height")) + " (Shift + G)"; +#if ENABLE_GCODE_VIEWER + } +#endif // ENABLE_GCODE_VIEWER if (m_focus == fiColorBand) return m_mode != t_mode::SingleExtruder ? "" : _(L("Edit current color - Right click the colored slider segment")); @@ -1230,7 +1251,11 @@ void Control::OnLeftUp(wxMouseEvent& event) if (m_mode == t_mode::MultiAsSingle && m_draw_mode == dmRegular) show_cog_icon_context_menu(); else +#if ENABLE_GCODE_VIEWER + jump_to_value(); +#else jump_to_print_z(); +#endif // ENABLE_GCODE_VIEWER break; case maOneLayerIconClick: switch_one_layer_mode(); @@ -1385,7 +1410,11 @@ void Control::OnChar(wxKeyEvent& event) m_ticks.suppress_minus(false); } if (key == 'G') +#if ENABLE_GCODE_VIEWER + jump_to_value(); +#else jump_to_print_z(); +#endif // ENABLE_GCODE_VIEWER } void Control::OnRightDown(wxMouseEvent& event) @@ -1571,7 +1600,11 @@ void Control::show_cog_icon_context_menu() wxMenu menu; append_menu_item(&menu, wxID_ANY, _(L("Jump to height")) + " (Shift+G)", "", - [this](wxCommandEvent&) { jump_to_print_z(); }, "", &menu); +#if ENABLE_GCODE_VIEWER + [this](wxCommandEvent&) { jump_to_value(); }, "", & menu); +#else + [this](wxCommandEvent&) { jump_to_print_z(); }, "", &menu); +#endif // ENABLE_GCODE_VIEWER append_menu_item(&menu, wxID_ANY, _(L("Set extruder sequence for the entire print")), "", [this](wxCommandEvent&) { edit_extruder_sequence(); }, "", &menu); @@ -1689,11 +1722,21 @@ static std::string get_pause_print_msg(const std::string& msg_in, double height) return into_u8(dlg.GetValue()); } +#if ENABLE_GCODE_VIEWER +static double get_value_to_jump(double active_value, double min_z, double max_z, DrawMode mode) +#else static double get_print_z_to_jump(double active_print_z, double min_z, double max_z) +#endif // ENABLE_GCODE_VIEWER { +#if ENABLE_GCODE_VIEWER + wxString msg_text = (mode == dmSequentialGCodeView) ? _L("Enter the move you want to jump to") + ":" : _L("Enter the height you want to jump to") + ":"; + wxString msg_header = (mode == dmSequentialGCodeView) ? _L("Jump to move") : _L("Jump to height"); + wxString msg_in = GUI::double_to_string(active_value); +#else wxString msg_text = _(L("Enter the height you want to jump to")) + ":"; wxString msg_header = _(L("Jump to height")); wxString msg_in = GUI::double_to_string(active_print_z); +#endif // ENABLE_GCODE_VIEWER // get custom gcode wxTextEntryDialog dlg(nullptr, msg_text, msg_header, msg_in, wxTextEntryDialogStyle); @@ -1902,6 +1945,23 @@ void Control::edit_extruder_sequence() post_ticks_changed_event(ToolChangeCode); } +#if ENABLE_GCODE_VIEWER +void Control::jump_to_value() +{ + double value = get_value_to_jump(m_values[m_selection == ssLower ? m_lower_value : m_higher_value], + m_values[m_min_value], m_values[m_max_value], m_draw_mode); + if (value < 0.0) + return; + + auto it = std::lower_bound(m_values.begin(), m_values.end(), value - epsilon()); + int tick_value = it - m_values.begin(); + + if (m_selection == ssLower) + SetLowerValue(tick_value); + else + SetHigherValue(tick_value); +} +#else void Control::jump_to_print_z() { double print_z = get_print_z_to_jump(m_values[m_selection == ssLower ? m_lower_value : m_higher_value], @@ -1917,6 +1977,7 @@ void Control::jump_to_print_z() else SetHigherValue(tick_value); } +#endif // ENABLE_GCODE_VIEWER void Control::post_ticks_changed_event(const std::string& gcode /*= ""*/) { diff --git a/src/slic3r/GUI/DoubleSlider.hpp b/src/slic3r/GUI/DoubleSlider.hpp index fea1ba172e..71949f7f3e 100644 --- a/src/slic3r/GUI/DoubleSlider.hpp +++ b/src/slic3r/GUI/DoubleSlider.hpp @@ -253,7 +253,11 @@ public: void discard_all_thicks(); void move_current_thumb_to_pos(wxPoint pos); void edit_extruder_sequence(); +#if ENABLE_GCODE_VIEWER + void jump_to_value(); +#else void jump_to_print_z(); +#endif // ENABLE_GCODE_VIEWER void show_add_context_menu(); void show_edit_context_menu(); void show_cog_icon_context_menu(); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 43d37607c5..2c059c648f 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -558,7 +558,7 @@ public: #if ENABLE_GCODE_VIEWER void reset_gcode_toolpaths() { m_gcode_viewer.reset(); } const GCodeViewer::SequentialView& get_gcode_sequential_view() const { return m_gcode_viewer.get_sequential_view(); } - void update_gcode_sequential_view_current(unsigned int low, unsigned int high) { m_gcode_viewer.update_sequential_view_current(low, high); } + void update_gcode_sequential_view_current(unsigned int first, unsigned int last) { m_gcode_viewer.update_sequential_view_current(first, last); } #endif // ENABLE_GCODE_VIEWER void toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1); From 163fbec8c84f6d314bd79a54a4741e050d52b3f3 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 18 May 2020 13:24:07 +0200 Subject: [PATCH 077/255] GCodeViewer -> Completed implementation of slider for sequential view --- src/slic3r/GUI/GCodeViewer.cpp | 81 +++++++++++++++++--------------- src/slic3r/GUI/GCodeViewer.hpp | 20 ++++++-- src/slic3r/GUI/GUI_Preview.cpp | 84 ++++++++++++++++++++++++---------- src/slic3r/GUI/GUI_Preview.hpp | 15 ++++++ 4 files changed, 136 insertions(+), 64 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index c4bc391d18..dcb320766a 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -12,6 +12,7 @@ #include "DoubleSlider.hpp" #include "GLCanvas3D.hpp" #include "GLToolbar.hpp" +#include "GUI_Preview.hpp" #include "libslic3r/Model.hpp" #if ENABLE_GCODE_VIEWER_STATISTICS #include @@ -279,7 +280,7 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: } // update buffers' render paths - refresh_render_paths(false); + refresh_render_paths(false, false); #if ENABLE_GCODE_VIEWER_STATISTICS m_statistics.refresh_time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); @@ -349,16 +350,16 @@ unsigned int GCodeViewer::get_options_visibility_flags() const }; unsigned int flags = 0; - flags = set_flag(flags, 0, is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Travel)); - flags = set_flag(flags, 1, is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Retract)); - flags = set_flag(flags, 2, is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Unretract)); - flags = set_flag(flags, 3, is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Tool_change)); - flags = set_flag(flags, 4, is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Color_change)); - flags = set_flag(flags, 5, is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Pause_Print)); - flags = set_flag(flags, 6, is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Custom_GCode)); - flags = set_flag(flags, 7, m_shells.visible); - flags = set_flag(flags, 8, m_sequential_view.marker.is_visible()); - flags = set_flag(flags, 9, is_legend_enabled()); + flags = set_flag(flags, static_cast(Preview::OptionType::Travel), is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Travel)); + flags = set_flag(flags, static_cast(Preview::OptionType::Retractions), is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Retract)); + flags = set_flag(flags, static_cast(Preview::OptionType::Unretractions), is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Unretract)); + flags = set_flag(flags, static_cast(Preview::OptionType::ToolChanges), is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Tool_change)); + flags = set_flag(flags, static_cast(Preview::OptionType::ColorChanges), is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Color_change)); + flags = set_flag(flags, static_cast(Preview::OptionType::PausePrints), is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Pause_Print)); + flags = set_flag(flags, static_cast(Preview::OptionType::CustomGCodes), is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Custom_GCode)); + flags = set_flag(flags, static_cast(Preview::OptionType::Shells), m_shells.visible); + flags = set_flag(flags, static_cast(Preview::OptionType::ToolMarker), m_sequential_view.marker.is_visible()); + flags = set_flag(flags, static_cast(Preview::OptionType::Legend), is_legend_enabled()); return flags; } @@ -368,23 +369,24 @@ void GCodeViewer::set_options_visibility_from_flags(unsigned int flags) return (flags & (1 << flag)) != 0; }; - set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Travel, is_flag_set(0)); - set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Retract, is_flag_set(1)); - set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Unretract, is_flag_set(2)); - set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Tool_change, is_flag_set(3)); - set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Color_change, is_flag_set(4)); - set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Pause_Print, is_flag_set(5)); - set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Custom_GCode, is_flag_set(6)); - m_shells.visible = is_flag_set(7); - m_sequential_view.marker.set_visible(is_flag_set(8)); - enable_legend(is_flag_set(9)); + set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Travel, is_flag_set(static_cast(Preview::OptionType::Travel))); + set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Retract, is_flag_set(static_cast(Preview::OptionType::Retractions))); + set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Unretract, is_flag_set(static_cast(Preview::OptionType::Unretractions))); + set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Tool_change, is_flag_set(static_cast(Preview::OptionType::ToolChanges))); + set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Color_change, is_flag_set(static_cast(Preview::OptionType::ColorChanges))); + set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Pause_Print, is_flag_set(static_cast(Preview::OptionType::PausePrints))); + set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Custom_GCode, is_flag_set(static_cast(Preview::OptionType::CustomGCodes))); + m_shells.visible = is_flag_set(static_cast(Preview::OptionType::Shells)); + m_sequential_view.marker.set_visible(is_flag_set(static_cast(Preview::OptionType::ToolMarker))); + enable_legend(is_flag_set(static_cast(Preview::OptionType::Legend))); } void GCodeViewer::set_layers_z_range(const std::array& layers_z_range) { - bool keep_sequential_current = layers_z_range[1] <= m_layers_z_range[1]; + bool keep_sequential_current_first = layers_z_range[0] >= m_layers_z_range[0]; + bool keep_sequential_current_last = layers_z_range[1] <= m_layers_z_range[1]; m_layers_z_range = layers_z_range; - refresh_render_paths(keep_sequential_current); + refresh_render_paths(keep_sequential_current_first, keep_sequential_current_last); wxGetApp().plater()->update_preview_moves_slider(); } @@ -628,7 +630,7 @@ void GCodeViewer::load_shells(const Print& print, bool initialized) } } -void GCodeViewer::refresh_render_paths(bool keep_sequential_current) const +void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const { #if ENABLE_GCODE_VIEWER_STATISTICS auto start_time = std::chrono::high_resolution_clock::now(); @@ -661,10 +663,12 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current) const m_statistics.render_paths_size = 0; #endif // ENABLE_GCODE_VIEWER_STATISTICS - m_sequential_view.first = m_vertices.vertices_count; - m_sequential_view.last = 0; - if (!keep_sequential_current) - m_sequential_view.current = m_vertices.vertices_count; + m_sequential_view.endpoints.first = m_vertices.vertices_count; + m_sequential_view.endpoints.last = 0; + if (!keep_sequential_current_first) + m_sequential_view.current.first = 0; + if (!keep_sequential_current_last) + m_sequential_view.current.last = m_vertices.vertices_count; // first pass: collect visible paths and update sequential view data std::vector> paths; @@ -690,22 +694,23 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current) const // store valid path paths.push_back({ &buffer, i }); - m_sequential_view.first = std::min(m_sequential_view.first, path.first.s_id); - m_sequential_view.last = std::max(m_sequential_view.last, path.last.s_id); + m_sequential_view.endpoints.first = std::min(m_sequential_view.endpoints.first, path.first.s_id); + m_sequential_view.endpoints.last = std::max(m_sequential_view.endpoints.last, path.last.s_id); } } // update current sequential position - m_sequential_view.current = keep_sequential_current ? std::clamp(m_sequential_view.current, m_sequential_view.first, m_sequential_view.last) : m_sequential_view.last; + m_sequential_view.current.first = keep_sequential_current_first ? std::clamp(m_sequential_view.current.first, m_sequential_view.endpoints.first, m_sequential_view.endpoints.last) : m_sequential_view.endpoints.first; + m_sequential_view.current.last = keep_sequential_current_last ? std::clamp(m_sequential_view.current.last, m_sequential_view.endpoints.first, m_sequential_view.endpoints.last) : m_sequential_view.endpoints.last; glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vertices.vbo_id)); size_t v_size = VBuffer::vertex_size_bytes(); - glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, static_cast(m_sequential_view.current * v_size), static_cast(v_size), static_cast(m_sequential_view.current_position.data()))); + glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, static_cast(m_sequential_view.current.last * v_size), static_cast(v_size), static_cast(m_sequential_view.current_position.data()))); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); // second pass: filter paths by sequential data for (auto&& [buffer, id] : paths) { const Path& path = buffer->paths[id]; - if ((m_sequential_view.current < path.first.s_id) || (path.last.s_id < m_sequential_view.first)) + if ((m_sequential_view.current.last <= path.first.s_id) || (path.last.s_id <= m_sequential_view.current.first)) continue; Color color; @@ -722,8 +727,12 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current) const it->color = color; } - it->sizes.push_back(std::min(m_sequential_view.current, path.last.s_id) - path.first.s_id + 1); - it->offsets.push_back(static_cast(path.first.i_id * sizeof(unsigned int))); + it->sizes.push_back(std::min(m_sequential_view.current.last, path.last.s_id) - std::max(m_sequential_view.current.first, path.first.s_id) + 1); + unsigned int delta_1st = 0; + if ((path.first.s_id < m_sequential_view.current.first) && (m_sequential_view.current.first <= path.last.s_id)) + delta_1st = m_sequential_view.current.first - path.first.s_id; + + it->offsets.push_back(static_cast((path.first.i_id + delta_1st) * sizeof(unsigned int))); } #if ENABLE_GCODE_VIEWER_STATISTICS @@ -1013,7 +1022,7 @@ void GCodeViewer::render_legend() const { m_extrusions.role_visibility_flags = is_visible(role) ? m_extrusions.role_visibility_flags & ~(1 << role) : m_extrusions.role_visibility_flags | (1 << role); // update buffers' render paths - refresh_render_paths(false); + refresh_render_paths(false, false); wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); wxGetApp().plater()->update_preview_bottom_toolbar(); } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index e53bcb0c62..688f1266b5 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -222,9 +222,14 @@ public: void init_shader(); }; - unsigned int first{ 0 }; - unsigned int last{ 0 }; - unsigned int current{ 0 }; + struct Endpoints + { + unsigned int first{ 0 }; + unsigned int last{ 0 }; + }; + + Endpoints endpoints; + Endpoints current; Vec3f current_position{ Vec3f::Zero() }; Marker marker; }; @@ -285,7 +290,12 @@ public: const std::vector& get_layers_zs() const { return m_layers_zs; }; const SequentialView& get_sequential_view() const { return m_sequential_view; } - void update_sequential_view_current(unsigned int low, unsigned int high) { m_sequential_view.current = high; refresh_render_paths(true); } + void update_sequential_view_current(unsigned int first, unsigned int last) + { + m_sequential_view.current.first = first; + m_sequential_view.current.last = last; + refresh_render_paths(true, true); + } EViewType get_view_type() const { return m_view_type; } void set_view_type(EViewType type) { @@ -310,7 +320,7 @@ private: bool init_shaders(); void load_toolpaths(const GCodeProcessor::Result& gcode_result); void load_shells(const Print& print, bool initialized); - void refresh_render_paths(bool keep_sequential_current) const; + void refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const; void render_toolpaths() const; void render_shells() const; void render_legend() const; diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 714ed3c9ef..65e1e50589 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -298,17 +298,17 @@ bool Preview::init(wxWindow* parent, Model* model) m_combochecklist_options = new wxComboCtrl(); m_combochecklist_options->Create(this, wxID_ANY, _L("Options"), wxDefaultPosition, wxDefaultSize, wxCB_READONLY); std::string options_items = GUI::into_u8( - _L("Travel") + "|0|" + - _L("Retractions") + "|0|" + - _L("Unretractions") + "|0|" + - _L("Tool changes") + "|0|" + - _L("Color changes") + "|0|" + - _L("Pause prints") + "|0|" + - _L("Custom GCodes") + "|0|" + - _L("Shells") + "|0|" + - _L("Tool marker") + "|1|" + - _L("Legend") + "|1" -); + get_option_type_string(OptionType::Travel) + "|0|" + + get_option_type_string(OptionType::Retractions) + "|0|" + + get_option_type_string(OptionType::Unretractions) + "|0|" + + get_option_type_string(OptionType::ToolChanges) + "|0|" + + get_option_type_string(OptionType::ColorChanges) + "|0|" + + get_option_type_string(OptionType::PausePrints) + "|0|" + + get_option_type_string(OptionType::CustomGCodes) + "|0|" + + get_option_type_string(OptionType::Shells) + "|0|" + + get_option_type_string(OptionType::ToolMarker) + "|0|" + + get_option_type_string(OptionType::Legend) + "|1" + ); Slic3r::GUI::create_combochecklist(m_combochecklist_options, GUI::into_u8(_L("Options")), options_items); #else m_checkbox_travel = new wxCheckBox(this, wxID_ANY, _(L("Travel"))); @@ -328,19 +328,19 @@ bool Preview::init(wxWindow* parent, Model* model) #endif // ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER - m_moves_slider = new DoubleSlider::Control(this, wxID_ANY, 0, 0, 0, 100, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL); + m_moves_slider = new DoubleSlider::Control(this, wxID_ANY, 0, 0, 0, 100, wxDefaultPosition, wxSize(-1, 3 * GetTextExtent("m").y), wxSL_HORIZONTAL); m_moves_slider->SetDrawMode(DoubleSlider::dmSequentialGCodeView); m_moves_slider->Bind(wxEVT_SCROLL_CHANGED, &Preview::on_moves_slider_scroll_changed, this); m_bottom_toolbar_sizer = new wxBoxSizer(wxHORIZONTAL); - m_bottom_toolbar_sizer->AddSpacer(10); + m_bottom_toolbar_sizer->AddSpacer(5); m_bottom_toolbar_sizer->Add(m_label_view_type, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5); - m_bottom_toolbar_sizer->Add(m_choice_view_type, 0, wxALIGN_CENTER_VERTICAL, 5); - m_bottom_toolbar_sizer->AddSpacer(10); + m_bottom_toolbar_sizer->Add(m_choice_view_type, 0, wxALIGN_CENTER_VERTICAL, 0); + m_bottom_toolbar_sizer->AddSpacer(5); m_bottom_toolbar_sizer->Add(m_label_show, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5); - m_bottom_toolbar_sizer->Add(m_combochecklist_options, 0, wxALIGN_CENTER_VERTICAL, 5); + m_bottom_toolbar_sizer->Add(m_combochecklist_options, 0, wxALIGN_CENTER_VERTICAL, 0); m_bottom_toolbar_sizer->Add(m_combochecklist_features, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 5); - m_bottom_toolbar_sizer->AddSpacer(10); + m_bottom_toolbar_sizer->AddSpacer(5); m_bottom_toolbar_sizer->Add(m_moves_slider, 1, wxALL | wxEXPAND, 5); #else wxBoxSizer* bottom_sizer = new wxBoxSizer(wxHORIZONTAL); @@ -686,8 +686,27 @@ void Preview::on_combochecklist_features(wxCommandEvent& evt) #if ENABLE_GCODE_VIEWER void Preview::on_combochecklist_options(wxCommandEvent& evt) { - m_canvas->set_gcode_options_visibility_from_flags(Slic3r::GUI::combochecklist_get_flags(m_combochecklist_options)); - refresh_print(); + auto xor = [](unsigned int flags1, unsigned int flags2, unsigned int flag) { + auto is_flag_set = [](unsigned int flags, unsigned int flag) { + return (flags & (1 << flag)) != 0; + }; + return !is_flag_set(flags1, flag) != !is_flag_set(flags2, flag); + }; + + unsigned int curr_flags = m_canvas->get_gcode_options_visibility_flags(); + unsigned int new_flags = Slic3r::GUI::combochecklist_get_flags(m_combochecklist_options); + if (curr_flags == new_flags) + return; + + m_canvas->set_gcode_options_visibility_from_flags(new_flags); + + bool skip_refresh = xor(curr_flags, new_flags, static_cast(OptionType::Shells)) || + xor(curr_flags, new_flags, static_cast(OptionType::ToolMarker)); + + if (!skip_refresh) + refresh_print(); + else + m_canvas->set_as_dirty(); } #else void Preview::on_checkbox_travel(wxCommandEvent& evt) @@ -1082,16 +1101,16 @@ void Preview::update_layers_slider_from_canvas(wxKeyEvent& event) void Preview::update_moves_slider() { const GCodeViewer::SequentialView& view = m_canvas->get_gcode_sequential_view(); - std::vector values(view.last - view.first + 1); + std::vector values(view.endpoints.last - view.endpoints.first + 1); unsigned int count = 0; - for (unsigned int i = view.first; i <= view.last; ++i) + for (unsigned int i = view.endpoints.first; i <= view.endpoints.last; ++i) { values[count++] = static_cast(i + 1); } m_moves_slider->SetSliderValues(values); - m_moves_slider->SetMaxValue(view.last - view.first); - m_moves_slider->SetSelectionSpan(0, view.current); + m_moves_slider->SetMaxValue(view.endpoints.last - view.endpoints.first); + m_moves_slider->SetSelectionSpan(view.current.first - view.endpoints.first, view.current.last - view.endpoints.first); } #else void Preview::update_double_slider_from_canvas(wxKeyEvent & event) @@ -1356,6 +1375,25 @@ void Preview::on_moves_slider_scroll_changed(wxCommandEvent& event) m_canvas->update_gcode_sequential_view_current(static_cast(m_moves_slider->GetLowerValueD()), static_cast(m_moves_slider->GetHigherValueD())); m_canvas->render(); } + +wxString Preview::get_option_type_string(OptionType type) const +{ + switch (type) + { + case OptionType::Travel: { return _L("Travel"); } + case OptionType::Retractions: { return _L("Retractions"); } + case OptionType::Unretractions: { return _L("Unretractions"); } + case OptionType::ToolChanges: { return _L("Tool changes"); } + case OptionType::ColorChanges: { return _L("Color changes"); } + case OptionType::PausePrints: { return _L("Pause prints"); } + case OptionType::CustomGCodes: { return _L("Custom GCodes"); } + case OptionType::Shells: { return _L("Shells"); } + case OptionType::ToolMarker: { return _L("Tool marker"); } + case OptionType::Legend: { return _L("Legend"); } + default: { return ""; } + } +} + #endif // ENABLE_GCODE_VIEWER } // namespace GUI diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 3f0d4b4e68..9cf694ece3 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -136,6 +136,20 @@ class Preview : public wxPanel public: #if ENABLE_GCODE_VIEWER + enum class OptionType : unsigned int + { + Travel, + Retractions, + Unretractions, + ToolChanges, + ColorChanges, + PausePrints, + CustomGCodes, + Shells, + ToolMarker, + Legend + }; + Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process, GCodeProcessor::Result* gcode_result, std::function schedule_background_process = []() {}); #else @@ -235,6 +249,7 @@ private: #if ENABLE_GCODE_VIEWER void on_layers_slider_scroll_changed(wxCommandEvent& event); void on_moves_slider_scroll_changed(wxCommandEvent& event); + wxString get_option_type_string(OptionType type) const; #else void on_sliders_scroll_changed(wxCommandEvent& event); #endif // ENABLE_GCODE_VIEWER From f4303fc419d8ed2a0ded1c1cec795284c49c51fe Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 18 May 2020 13:32:07 +0200 Subject: [PATCH 078/255] Attempt to fix build on OsX --- src/slic3r/GUI/GUI_Preview.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 65e1e50589..bf694b445f 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -686,7 +686,7 @@ void Preview::on_combochecklist_features(wxCommandEvent& evt) #if ENABLE_GCODE_VIEWER void Preview::on_combochecklist_options(wxCommandEvent& evt) { - auto xor = [](unsigned int flags1, unsigned int flags2, unsigned int flag) { + auto xored = [](unsigned int flags1, unsigned int flags2, unsigned int flag) { auto is_flag_set = [](unsigned int flags, unsigned int flag) { return (flags & (1 << flag)) != 0; }; @@ -700,8 +700,8 @@ void Preview::on_combochecklist_options(wxCommandEvent& evt) m_canvas->set_gcode_options_visibility_from_flags(new_flags); - bool skip_refresh = xor(curr_flags, new_flags, static_cast(OptionType::Shells)) || - xor(curr_flags, new_flags, static_cast(OptionType::ToolMarker)); + bool skip_refresh = xored(curr_flags, new_flags, static_cast(OptionType::Shells)) || + xored(curr_flags, new_flags, static_cast(OptionType::ToolMarker)); if (!skip_refresh) refresh_print(); From 053f509437693938283df052b2376893091bbb8d Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 19 May 2020 10:04:14 +0200 Subject: [PATCH 079/255] GCodeViewer -> Fixed visibility of bottom toolbar --- src/slic3r/GUI/GUI_Preview.cpp | 94 +++++++++++++++++++++++++--------- src/slic3r/GUI/GUI_Preview.hpp | 3 +- 2 files changed, 72 insertions(+), 25 deletions(-) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index bf694b445f..fdbd396e26 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -184,8 +184,8 @@ Preview::Preview( : m_canvas_widget(nullptr) , m_canvas(nullptr) #if ENABLE_GCODE_VIEWER - , m_bottom_toolbar_sizer(nullptr) , m_layers_slider_sizer(nullptr) + , m_bottom_toolbar_panel(nullptr) #else , m_double_slider_sizer(nullptr) #endif // ENABLE_GCODE_VIEWER @@ -194,6 +194,7 @@ Preview::Preview( , m_label_show(nullptr) , m_combochecklist_features(nullptr) #if ENABLE_GCODE_VIEWER + , m_combochecklist_features_pos(0) , m_combochecklist_options(nullptr) #else , m_checkbox_travel(nullptr) @@ -251,14 +252,20 @@ bool Preview::init(wxWindow* parent, Model* model) #if ENABLE_GCODE_VIEWER m_layers_slider_sizer = create_layers_slider_sizer(); + + m_bottom_toolbar_panel = new wxPanel(this); + + m_label_view_type = new wxStaticText(m_bottom_toolbar_panel, wxID_ANY, _L("View")); + + m_choice_view_type = new wxChoice(m_bottom_toolbar_panel, wxID_ANY); #else m_double_slider_sizer = new wxBoxSizer(wxHORIZONTAL); create_double_slider(); -#endif // ENABLE_GCODE_VIEWER m_label_view_type = new wxStaticText(this, wxID_ANY, _L("View")); m_choice_view_type = new wxChoice(this, wxID_ANY); +#endif // ENABLE_GCODE_VIEWER m_choice_view_type->Append(_L("Feature type")); m_choice_view_type->Append(_L("Height")); m_choice_view_type->Append(_L("Width")); @@ -269,10 +276,18 @@ bool Preview::init(wxWindow* parent, Model* model) m_choice_view_type->Append(_L("Color Print")); m_choice_view_type->SetSelection(0); +#if ENABLE_GCODE_VIEWER + m_label_show = new wxStaticText(m_bottom_toolbar_panel, wxID_ANY, _L("Show")); +#else m_label_show = new wxStaticText(this, wxID_ANY, _L("Show")); +#endif // ENABLE_GCODE_VIEWER m_combochecklist_features = new wxComboCtrl(); +#if ENABLE_GCODE_VIEWER + m_combochecklist_features->Create(m_bottom_toolbar_panel, wxID_ANY, _L("Feature types"), wxDefaultPosition, wxDefaultSize, wxCB_READONLY); +#else m_combochecklist_features->Create(this, wxID_ANY, _L("Feature types"), wxDefaultPosition, wxDefaultSize, wxCB_READONLY); +#endif // ENABLE_GCODE_VIEWER std::string feature_items = GUI::into_u8( #if ENABLE_GCODE_VIEWER _L("Unknown") + "|1|" + @@ -296,7 +311,7 @@ bool Preview::init(wxWindow* parent, Model* model) #if ENABLE_GCODE_VIEWER m_combochecklist_options = new wxComboCtrl(); - m_combochecklist_options->Create(this, wxID_ANY, _L("Options"), wxDefaultPosition, wxDefaultSize, wxCB_READONLY); + m_combochecklist_options->Create(m_bottom_toolbar_panel, wxID_ANY, _L("Options"), wxDefaultPosition, wxDefaultSize, wxCB_READONLY); std::string options_items = GUI::into_u8( get_option_type_string(OptionType::Travel) + "|0|" + get_option_type_string(OptionType::Retractions) + "|0|" + @@ -328,20 +343,23 @@ bool Preview::init(wxWindow* parent, Model* model) #endif // ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER - m_moves_slider = new DoubleSlider::Control(this, wxID_ANY, 0, 0, 0, 100, wxDefaultPosition, wxSize(-1, 3 * GetTextExtent("m").y), wxSL_HORIZONTAL); + m_moves_slider = new DoubleSlider::Control(m_bottom_toolbar_panel, wxID_ANY, 0, 0, 0, 100, wxDefaultPosition, wxSize(-1, 3 * GetTextExtent("m").y), wxSL_HORIZONTAL); m_moves_slider->SetDrawMode(DoubleSlider::dmSequentialGCodeView); - m_moves_slider->Bind(wxEVT_SCROLL_CHANGED, &Preview::on_moves_slider_scroll_changed, this); - m_bottom_toolbar_sizer = new wxBoxSizer(wxHORIZONTAL); - m_bottom_toolbar_sizer->AddSpacer(5); - m_bottom_toolbar_sizer->Add(m_label_view_type, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5); - m_bottom_toolbar_sizer->Add(m_choice_view_type, 0, wxALIGN_CENTER_VERTICAL, 0); - m_bottom_toolbar_sizer->AddSpacer(5); - m_bottom_toolbar_sizer->Add(m_label_show, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5); - m_bottom_toolbar_sizer->Add(m_combochecklist_options, 0, wxALIGN_CENTER_VERTICAL, 0); - m_bottom_toolbar_sizer->Add(m_combochecklist_features, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 5); - m_bottom_toolbar_sizer->AddSpacer(5); - m_bottom_toolbar_sizer->Add(m_moves_slider, 1, wxALL | wxEXPAND, 5); + wxBoxSizer* bottom_toolbar_sizer = new wxBoxSizer(wxHORIZONTAL); + bottom_toolbar_sizer->AddSpacer(5); + bottom_toolbar_sizer->Add(m_label_view_type, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5); + bottom_toolbar_sizer->Add(m_choice_view_type, 0, wxALIGN_CENTER_VERTICAL, 0); + bottom_toolbar_sizer->AddSpacer(5); + bottom_toolbar_sizer->Add(m_label_show, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5); + bottom_toolbar_sizer->Add(m_combochecklist_options, 0, wxALIGN_CENTER_VERTICAL, 0); + // change the following number if editing the layout of the bottom toolbar sizer. It is used into update_bottom_toolbar() + m_combochecklist_features_pos = 6; + bottom_toolbar_sizer->Add(m_combochecklist_features, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 5); + bottom_toolbar_sizer->Hide(m_combochecklist_features); + bottom_toolbar_sizer->AddSpacer(5); + bottom_toolbar_sizer->Add(m_moves_slider, 1, wxALL | wxEXPAND, 0); + m_bottom_toolbar_panel->SetSizer(bottom_toolbar_sizer); #else wxBoxSizer* bottom_sizer = new wxBoxSizer(wxHORIZONTAL); bottom_sizer->Add(m_label_view_type, 0, wxALIGN_CENTER_VERTICAL, 5); @@ -364,8 +382,8 @@ bool Preview::init(wxWindow* parent, Model* model) wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); main_sizer->Add(top_sizer, 1, wxALL | wxEXPAND, 0); #if ENABLE_GCODE_VIEWER - main_sizer->Add(m_bottom_toolbar_sizer, 0, wxALL | wxEXPAND, 0); - main_sizer->Hide(m_bottom_toolbar_sizer); + main_sizer->Add(m_bottom_toolbar_panel, 0, wxALL | wxEXPAND, 0); + main_sizer->Hide(m_bottom_toolbar_panel); #else main_sizer->Add(bottom_sizer, 0, wxALL | wxEXPAND, 0); #endif // ENABLE_GCODE_VIEWER @@ -565,6 +583,7 @@ void Preview::bind_event_handlers() m_combochecklist_features->Bind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_features, this); #if ENABLE_GCODE_VIEWER m_combochecklist_options->Bind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_options, this); + m_moves_slider->Bind(wxEVT_SCROLL_CHANGED, &Preview::on_moves_slider_scroll_changed, this); #else m_checkbox_travel->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_travel, this); m_checkbox_retractions->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_retractions, this); @@ -581,6 +600,7 @@ void Preview::unbind_event_handlers() m_combochecklist_features->Unbind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_features, this); #if ENABLE_GCODE_VIEWER m_combochecklist_options->Unbind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_options, this); + m_moves_slider->Unbind(wxEVT_SCROLL_CHANGED, &Preview::on_moves_slider_scroll_changed, this); #else m_checkbox_travel->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_travel, this); m_checkbox_retractions->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_retractions, this); @@ -773,10 +793,33 @@ void Preview::update_bottom_toolbar() combochecklist_set_flags(m_combochecklist_features, m_canvas->get_toolpath_role_visibility_flags()); combochecklist_set_flags(m_combochecklist_options, m_canvas->get_gcode_options_visibility_flags()); - m_bottom_toolbar_sizer->Show(m_combochecklist_features, - !m_canvas->is_gcode_legend_enabled() || m_canvas->get_gcode_view_type() != GCodeViewer::EViewType::FeatureType); - m_bottom_toolbar_sizer->Layout(); - Refresh(); + // updates visibility of features combobox + if (m_bottom_toolbar_panel->IsShown()) + { + wxSizer* sizer = m_bottom_toolbar_panel->GetSizer(); + bool show = !m_canvas->is_gcode_legend_enabled() || m_canvas->get_gcode_view_type() != GCodeViewer::EViewType::FeatureType; + + if (show) + { + if (sizer->GetItem(m_combochecklist_features) == nullptr) + { + sizer->Insert(m_combochecklist_features_pos, m_combochecklist_features, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 5); + sizer->Show(m_combochecklist_features); + sizer->Layout(); + Refresh(); + } + } + else + { + if (sizer->GetItem(m_combochecklist_features) != nullptr) + { + sizer->Hide(m_combochecklist_features); + sizer->Detach(m_combochecklist_features); + sizer->Layout(); + Refresh(); + } + } + } } #endif // ENABLE_GCODE_VIEWER @@ -1243,8 +1286,9 @@ void Preview::load_print_as_fff(bool keep_z_range) #if ENABLE_GCODE_VIEWER m_canvas->load_gcode_preview(*m_gcode_result); m_canvas->refresh_gcode_preview(*m_gcode_result, colors); - GetSizer()->Show(m_bottom_toolbar_sizer); + GetSizer()->Show(m_bottom_toolbar_panel); GetSizer()->Layout(); + Refresh(); zs = m_canvas->get_gcode_layers_zs(); #else m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); @@ -1254,8 +1298,9 @@ void Preview::load_print_as_fff(bool keep_z_range) // Load the initial preview based on slices, not the final G-code. m_canvas->load_preview(colors, color_print_values); #if ENABLE_GCODE_VIEWER - GetSizer()->Hide(m_bottom_toolbar_sizer); + GetSizer()->Hide(m_bottom_toolbar_panel); GetSizer()->Layout(); + Refresh(); zs = m_canvas->get_volumes_print_zs(true); #endif // ENABLE_GCODE_VIEWER } @@ -1316,8 +1361,9 @@ void Preview::load_print_as_sla() { m_canvas->load_sla_preview(); #if ENABLE_GCODE_VIEWER - GetSizer()->Hide(m_bottom_toolbar_sizer); + GetSizer()->Hide(m_bottom_toolbar_panel); GetSizer()->Layout(); + Refresh(); #else show_hide_ui_elements("none"); #endif // ENABLE_GCODE_VIEWER diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 9cf694ece3..64aa8f7e35 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -84,7 +84,7 @@ class Preview : public wxPanel GLCanvas3D* m_canvas; #if ENABLE_GCODE_VIEWER wxBoxSizer* m_layers_slider_sizer; - wxBoxSizer* m_bottom_toolbar_sizer; + wxPanel* m_bottom_toolbar_panel; #else wxBoxSizer* m_double_slider_sizer; #endif // ENABLE_GCODE_VIEWER @@ -93,6 +93,7 @@ class Preview : public wxPanel wxStaticText* m_label_show; wxComboCtrl* m_combochecklist_features; #if ENABLE_GCODE_VIEWER + size_t m_combochecklist_features_pos; wxComboCtrl* m_combochecklist_options; #else wxCheckBox* m_checkbox_travel; From 98c2e3c7b12b45bba6369330ad980bbe1c825077 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 19 May 2020 11:17:47 +0200 Subject: [PATCH 080/255] GCodeViewer -> New icons for thumbs of horizontal DoubleSlider::Control --- resources/icons/thumb_left.svg | 54 +++++++++++++++++++++++++++++++++ resources/icons/thumb_right.svg | 54 +++++++++++++++++++++++++++++++++ src/slic3r/GUI/DoubleSlider.cpp | 12 +++++++- src/slic3r/GUI/GUI_Preview.cpp | 2 +- 4 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 resources/icons/thumb_left.svg create mode 100644 resources/icons/thumb_right.svg diff --git a/resources/icons/thumb_left.svg b/resources/icons/thumb_left.svg new file mode 100644 index 0000000000..ef78bd1410 --- /dev/null +++ b/resources/icons/thumb_left.svg @@ -0,0 +1,54 @@ + +image/svg+xml + + + + + + diff --git a/resources/icons/thumb_right.svg b/resources/icons/thumb_right.svg new file mode 100644 index 0000000000..f3748525d2 --- /dev/null +++ b/resources/icons/thumb_right.svg @@ -0,0 +1,54 @@ + +image/svg+xml + + + + + + diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index a6c9a5c772..6173680817 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -64,8 +64,13 @@ Control::Control( wxWindow *parent, if (!is_osx) SetDoubleBuffered(true);// SetDoubleBuffered exists on Win and Linux/GTK, but is missing on OSX +#if ENABLE_GCODE_VIEWER + m_bmp_thumb_higher = (style == wxSL_HORIZONTAL ? ScalableBitmap(this, "thumb_right") : ScalableBitmap(this, "thumb_up")); + m_bmp_thumb_lower = (style == wxSL_HORIZONTAL ? ScalableBitmap(this, "thumb_left") : ScalableBitmap(this, "thumb_down")); +#else m_bmp_thumb_higher = (style == wxSL_HORIZONTAL ? ScalableBitmap(this, "right_half_circle.png") : ScalableBitmap(this, "thumb_up")); m_bmp_thumb_lower = (style == wxSL_HORIZONTAL ? ScalableBitmap(this, "left_half_circle.png" ) : ScalableBitmap(this, "thumb_down")); +#endif // ENABLE_GCODE_VIEWER m_thumb_size = m_bmp_thumb_lower.GetBmpSize(); m_bmp_add_tick_on = ScalableBitmap(this, "colorchange_add"); @@ -576,6 +581,10 @@ void Control::draw_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider void Control::draw_thumb_item(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) { +#if ENABLE_GCODE_VIEWER + wxCoord x_draw = pos.x - int(0.5 * m_thumb_size.x); + wxCoord y_draw = pos.y - int(0.5 * m_thumb_size.y); +#else wxCoord x_draw, y_draw; if (selection == ssLower) { if (is_horizontal()) { @@ -587,7 +596,7 @@ void Control::draw_thumb_item(wxDC& dc, const wxPoint& pos, const SelectedSlider y_draw = pos.y - int(0.5*m_thumb_size.y); } } - else{ + else { if (is_horizontal()) { x_draw = pos.x; y_draw = pos.y - int(0.5*m_thumb_size.y); @@ -597,6 +606,7 @@ void Control::draw_thumb_item(wxDC& dc, const wxPoint& pos, const SelectedSlider y_draw = pos.y - int(0.5*m_thumb_size.y); } } +#endif // ENABLE_GCODE_VIEWER dc.DrawBitmap(selection == ssLower ? m_bmp_thumb_lower.bmp() : m_bmp_thumb_higher.bmp(), x_draw, y_draw); // Update thumb rect diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index fdbd396e26..1784dbccc1 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -343,7 +343,7 @@ bool Preview::init(wxWindow* parent, Model* model) #endif // ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER - m_moves_slider = new DoubleSlider::Control(m_bottom_toolbar_panel, wxID_ANY, 0, 0, 0, 100, wxDefaultPosition, wxSize(-1, 3 * GetTextExtent("m").y), wxSL_HORIZONTAL); + m_moves_slider = new DoubleSlider::Control(m_bottom_toolbar_panel, wxID_ANY, 0, 0, 0, 100, wxDefaultPosition, wxSize(-1, 4 * GetTextExtent("m").y), wxSL_HORIZONTAL); m_moves_slider->SetDrawMode(DoubleSlider::dmSequentialGCodeView); wxBoxSizer* bottom_toolbar_sizer = new wxBoxSizer(wxHORIZONTAL); From c7c87973b723a306b95558a476a5b27d8232800d Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 20 May 2020 14:11:22 +0200 Subject: [PATCH 081/255] First installment of tech ENABLE_SHADERS_MANAGER, using class GLShadersManager as a central point to manage OpenGL shaders --- src/libslic3r/GCode/ToolOrdering.cpp | 4 +- src/libslic3r/Technologies.hpp | 3 + src/slic3r/CMakeLists.txt | 2 + src/slic3r/GUI/3DBed.cpp | 75 +++++++ src/slic3r/GUI/3DBed.hpp | 18 ++ src/slic3r/GUI/GCodeViewer.cpp | 197 +++++++++++++++++- src/slic3r/GUI/GCodeViewer.hpp | 55 +++++ src/slic3r/GUI/GLCanvas3D.cpp | 192 +++++++++++++++++- src/slic3r/GUI/GLCanvas3D.hpp | 34 +++- src/slic3r/GUI/GLShader.cpp | 289 ++++++++++++++++++++++++++- src/slic3r/GUI/GLShader.hpp | 61 ++++++ src/slic3r/GUI/GLShadersManager.cpp | 76 +++++++ src/slic3r/GUI/GLShadersManager.hpp | 31 +++ src/slic3r/GUI/GUI_App.hpp | 10 + src/slic3r/GUI/OpenGLManager.cpp | 86 +++++++- src/slic3r/GUI/OpenGLManager.hpp | 22 +- src/slic3r/GUI/Selection.cpp | 263 +++++++++++++++++++++--- src/slic3r/GUI/Selection.hpp | 44 ++++ 18 files changed, 1415 insertions(+), 47 deletions(-) create mode 100644 src/slic3r/GUI/GLShadersManager.cpp create mode 100644 src/slic3r/GUI/GLShadersManager.hpp diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index db398f06c8..9c1a1900fd 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -400,7 +400,9 @@ void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_ // and maybe other problems. We will therefore go through layer_tools and detect and fix this. // So, if there is a non-object layer starting with different extruder than the last one ended with (or containing more than one extruder), // we'll mark it with has_wipe tower. - assert(! m_layer_tools.empty() && m_layer_tools.front().has_wipe_tower); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// assert(! m_layer_tools.empty() && m_layer_tools.front().has_wipe_tower); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (! m_layer_tools.empty() && m_layer_tools.front().has_wipe_tower) { for (size_t i = 0; i + 1 < m_layer_tools.size();) { const LayerTools < = m_layer_tools[i]; diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 3df9da961d..c274c1e841 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -44,6 +44,9 @@ // Enable G-Code viewer #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#define ENABLE_SHADERS_MANAGER (1 && ENABLE_GCODE_VIEWER) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index b085fad456..5d47f97589 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -23,6 +23,8 @@ set(SLIC3R_GUI_SOURCES GUI/3DScene.cpp GUI/3DScene.hpp GUI/format.hpp + GUI/GLShadersManager.hpp + GUI/GLShadersManager.cpp GUI/GLShader.cpp GUI/GLShader.hpp GUI/GLCanvas3D.hpp diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 4ef8679603..4bf8ce900e 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -15,6 +15,11 @@ #if ENABLE_GCODE_VIEWER #include "3DScene.hpp" #endif // ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//#if ENABLE_SHADERS_MANAGER +//#include "GLShader.hpp" +//#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include @@ -163,9 +168,17 @@ Bed3D::Axes::~Axes() void Bed3D::Axes::render() const { #if ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + auto render_axis = [this](const Transform3f& transform) { +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ auto render_axis = [this](const Transform3f& transform, GLint color_id, const std::array& color) { if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)color.data())); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glPushMatrix()); glsafe(::glMultMatrixf(transform.data())); @@ -174,14 +187,43 @@ void Bed3D::Axes::render() const }; m_arrow.init_from(stilized_arrow(16, DefaultTipRadius, DefaultTipLength, DefaultStemRadius, m_stem_length)); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + if (shader == nullptr) + return; +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!m_shader.init("gouraud_light.vs", "gouraud_light.fs")) BOOST_LOG_TRIVIAL(error) << "Unable to initialize gouraud_light shader: please, check that the files gouraud_light.vs and gouraud_light.fs are available"; if (!m_shader.is_initialized()) return; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glEnable(GL_DEPTH_TEST)); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader->start_using(); + + // x axis + shader->set_uniform("uniform_color", { 0.75f, 0.0f, 0.0f, 1.0f }); + render_axis(Geometry::assemble_transform(m_origin, { 0.0, 0.5 * M_PI, 0.0f }).cast()); + + // y axis + shader->set_uniform("uniform_color", { 0.0f, 0.75f, 0.0f, 1.0f }); + render_axis(Geometry::assemble_transform(m_origin, { -0.5 * M_PI, 0.0, 0.0f }).cast()); + + // z axis + shader->set_uniform("uniform_color", { 0.0f, 0.0f, 0.75f, 1.0f }); + render_axis(Geometry::assemble_transform(m_origin).cast()); + + shader->stop_using(); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_shader.start_using(); GLint color_id = ::glGetUniformLocation(m_shader.get_shader_program_id(), "uniform_color"); @@ -195,6 +237,9 @@ void Bed3D::Axes::render() const render_axis(Geometry::assemble_transform(m_origin).cast(), color_id, { 0.0f, 0.0f, 0.75f, 1.0f }); m_shader.stop_using(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glDisable(GL_DEPTH_TEST)); #else @@ -540,6 +585,16 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const if (m_triangles.get_vertices_count() > 0) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + GLShaderProgram* shader = wxGetApp().get_shader("printbed"); + if (shader != nullptr) + { + shader->start_using(); + shader->set_uniform("transparent_background", bottom); + shader->set_uniform("svg_source", boost::algorithm::iends_with(m_texture.get_source(), ".svg")); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (m_shader.get_shader_program_id() == 0) m_shader.init("printbed.vs", "printbed.fs"); @@ -548,6 +603,9 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const m_shader.start_using(); m_shader.set_uniform("transparent_background", bottom); m_shader.set_uniform("svg_source", boost::algorithm::iends_with(m_texture.get_source(), ".svg")); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (m_vbo_id == 0) { @@ -568,8 +626,17 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const unsigned int stride = m_triangles.get_vertex_data_size(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + GLint position_id = shader->get_attrib_location("v_position"); + GLint tex_coords_id = shader->get_attrib_location("v_tex_coords"); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GLint position_id = m_shader.get_attrib_location("v_position"); GLint tex_coords_id = m_shader.get_attrib_location("v_tex_coords"); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // show the temporary texture while no compressed data is available GLuint tex_id = (GLuint)m_temp_texture.get_id(); @@ -607,7 +674,15 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const glsafe(::glDisable(GL_BLEND)); glsafe(::glDepthMask(GL_TRUE)); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader->stop_using(); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_shader.stop_using(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } } } diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp index 440468233c..9603015da8 100644 --- a/src/slic3r/GUI/3DBed.hpp +++ b/src/slic3r/GUI/3DBed.hpp @@ -3,7 +3,13 @@ #include "GLTexture.hpp" #include "3DScene.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "GLShader.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER #include "GLModel.hpp" #endif // ENABLE_GCODE_VIEWER @@ -69,7 +75,13 @@ class Bed3D Vec3d m_origin{ Vec3d::Zero() }; float m_stem_length{ DefaultStemLength }; mutable GL_Model m_arrow; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ mutable Shader m_shader; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ public: #else @@ -118,7 +130,13 @@ private: mutable GLBed m_model; // temporary texture shown until the main texture has still no levels compressed mutable GLTexture m_temp_texture; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ mutable Shader m_shader; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ mutable unsigned int m_vbo_id; Axes m_axes; diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index dcb320766a..55f603829b 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -12,6 +12,11 @@ #include "DoubleSlider.hpp" #include "GLCanvas3D.hpp" #include "GLToolbar.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//#if ENABLE_SHADERS_MANAGER +//#include "GLShader.hpp" +//#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "GUI_Preview.hpp" #include "libslic3r/Model.hpp" #if ENABLE_GCODE_VIEWER_STATISTICS @@ -107,6 +112,9 @@ void GCodeViewer::IBuffer::reset() render_paths = std::vector(); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool GCodeViewer::IBuffer::init_shader(const std::string& vertex_shader_src, const std::string& fragment_shader_src) { if (!shader.init(vertex_shader_src, fragment_shader_src)) { @@ -116,6 +124,9 @@ bool GCodeViewer::IBuffer::init_shader(const std::string& vertex_shader_src, con return true; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move, unsigned int i_id, unsigned int s_id) { @@ -149,11 +160,33 @@ GCodeViewer::Color GCodeViewer::Extrusions::Range::get_color_at(float value) con void GCodeViewer::SequentialView::Marker::init() { m_model.init_from(stilized_arrow(16, 2.0f, 4.0f, 1.0f, 8.0f)); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ init_shader(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } void GCodeViewer::SequentialView::Marker::render() const { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + if (!m_visible) + return; + + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + if (shader == nullptr) + return; + + glsafe(::glEnable(GL_BLEND)); + glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); + + shader->start_using(); + shader->set_uniform("uniform_color", m_color); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!m_visible || !m_shader.is_initialized()) return; @@ -164,6 +197,9 @@ void GCodeViewer::SequentialView::Marker::render() const GLint color_id = ::glGetUniformLocation(m_shader.get_shader_program_id(), "uniform_color"); if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)m_color.data())); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glPushMatrix()); glsafe(::glMultMatrixf(m_world_transform.data())); @@ -172,16 +208,30 @@ void GCodeViewer::SequentialView::Marker::render() const glsafe(::glPopMatrix()); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader->stop_using(); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_shader.stop_using(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glDisable(GL_BLEND)); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GCodeViewer::SequentialView::Marker::init_shader() { if (!m_shader.init("gouraud_light.vs", "gouraud_light.fs")) BOOST_LOG_TRIVIAL(error) << "Unable to initialize gouraud_light shader: please, check that the files gouraud_light.vs and gouraud_light.fs are available"; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const std::vector GCodeViewer::Extrusion_Role_Colors {{ { 0.50f, 0.50f, 0.50f }, // erNone @@ -390,6 +440,31 @@ void GCodeViewer::set_layers_z_range(const std::array& layers_z_range wxGetApp().plater()->update_preview_moves_slider(); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER +void GCodeViewer::init_shaders() +{ + unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); + unsigned char end_id = buffer_id(GCodeProcessor::EMoveType::Count); + + for (unsigned char i = begin_id; i < end_id; ++i) + { + switch (buffer_type(i)) + { + case GCodeProcessor::EMoveType::Tool_change: { m_buffers[i].shader = "toolchanges"; break; } + case GCodeProcessor::EMoveType::Color_change: { m_buffers[i].shader = "colorchanges"; break; } + case GCodeProcessor::EMoveType::Pause_Print: { m_buffers[i].shader = "pauses"; break; } + case GCodeProcessor::EMoveType::Custom_GCode: { m_buffers[i].shader = "customs"; break; } + case GCodeProcessor::EMoveType::Retract: { m_buffers[i].shader = "retractions"; break; } + case GCodeProcessor::EMoveType::Unretract: { m_buffers[i].shader = "unretractions"; break; } + case GCodeProcessor::EMoveType::Extrude: { m_buffers[i].shader = "extrusions"; break; } + case GCodeProcessor::EMoveType::Travel: { m_buffers[i].shader = "travels"; break; } + default: { break; } + } + } +} +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool GCodeViewer::init_shaders() { unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); @@ -424,6 +499,9 @@ bool GCodeViewer::init_shaders() return true; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) { @@ -750,6 +828,9 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool void GCodeViewer::render_toolpaths() const { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ auto set_color = [](GLint current_program_id, const Color& color) { if (current_program_id > 0) { GLint color_id = ::glGetUniformLocation(current_program_id, "uniform_color"); @@ -760,6 +841,9 @@ void GCodeViewer::render_toolpaths() const } BOOST_LOG_TRIVIAL(error) << "Unable to find uniform_color uniform"; }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glCullFace(GL_BACK)); glsafe(::glLineWidth(3.0f)); @@ -779,11 +863,29 @@ void GCodeViewer::render_toolpaths() const if (!buffer.visible) continue; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + GLShaderProgram* shader = wxGetApp().get_shader(buffer.shader.c_str()); + if (shader != nullptr) { +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (buffer.shader.is_initialized()) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + GCodeProcessor::EMoveType type = buffer_type(i); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader->start_using(); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ buffer.shader.start_using(); - +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.ibo_id)); switch (type) @@ -791,7 +893,15 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Tool_change: { Color color = { 1.0f, 1.0f, 1.0f }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader->set_uniform("uniform_color", color); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ set_color(static_cast(buffer.shader.get_shader_program_id()), color); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ for (const RenderPath& path : buffer.render_paths) { glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); @@ -807,7 +917,15 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Color_change: { Color color = { 1.0f, 0.0f, 0.0f }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader->set_uniform("uniform_color", color); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ set_color(static_cast(buffer.shader.get_shader_program_id()), color); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ for (const RenderPath& path : buffer.render_paths) { glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); @@ -823,7 +941,15 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Pause_Print: { Color color = { 0.0f, 1.0f, 0.0f }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader->set_uniform("uniform_color", color); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ set_color(static_cast(buffer.shader.get_shader_program_id()), color); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ for (const RenderPath& path : buffer.render_paths) { glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); @@ -839,7 +965,15 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Custom_GCode: { Color color = { 0.0f, 0.0f, 1.0f }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader->set_uniform("uniform_color", color); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ set_color(static_cast(buffer.shader.get_shader_program_id()), color); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ for (const RenderPath& path : buffer.render_paths) { glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); @@ -855,7 +989,15 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Retract: { Color color = { 1.0f, 0.0f, 1.0f }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader->set_uniform("uniform_color", color); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ set_color(static_cast(buffer.shader.get_shader_program_id()), color); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ for (const RenderPath& path : buffer.render_paths) { glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); @@ -871,7 +1013,15 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Unretract: { Color color = { 0.0f, 1.0f, 1.0f }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader->set_uniform("uniform_color", color); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ set_color(static_cast(buffer.shader.get_shader_program_id()), color); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ for (const RenderPath& path : buffer.render_paths) { glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); @@ -888,7 +1038,15 @@ void GCodeViewer::render_toolpaths() const { for (const RenderPath& path : buffer.render_paths) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader->set_uniform("uniform_color", path.color); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ set_color(static_cast(buffer.shader.get_shader_program_id()), path.color); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glMultiDrawElements(GL_LINE_STRIP, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_line_strip_calls_count; @@ -901,7 +1059,15 @@ void GCodeViewer::render_toolpaths() const { for (const RenderPath& path : buffer.render_paths) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader->set_uniform("uniform_color", path.color); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ set_color(static_cast(buffer.shader.get_shader_program_id()), path.color); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glMultiDrawElements(GL_LINE_STRIP, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_line_strip_calls_count; @@ -913,7 +1079,15 @@ void GCodeViewer::render_toolpaths() const } glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader->stop_using(); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ buffer.shader.stop_using(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } } @@ -923,6 +1097,24 @@ void GCodeViewer::render_toolpaths() const void GCodeViewer::render_shells() const { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + if (!m_shells.visible || m_shells.volumes.empty()) + return; + + GLShaderProgram* shader = wxGetApp().get_shader("shells"); + if (shader == nullptr) + return; + +// glsafe(::glDepthMask(GL_FALSE)); + + shader->start_using(); + m_shells.volumes.render(GLVolumeCollection::Transparent, true, wxGetApp().plater()->get_camera().get_view_matrix()); + shader->stop_using(); + +// glsafe(::glDepthMask(GL_TRUE)); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!m_shells.visible || m_shells.volumes.empty() || !m_shells.shader.is_initialized()) return; @@ -933,6 +1125,9 @@ void GCodeViewer::render_shells() const m_shells.shader.stop_using(); // glsafe(::glDepthMask(GL_TRUE)); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } void GCodeViewer::render_legend() const diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 688f1266b5..df28f4aa63 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -2,7 +2,13 @@ #define slic3r_GCodeViewer_hpp_ #if ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "GLShader.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "3DScene.hpp" #include "libslic3r/GCode/GCodeProcessor.hpp" #include "GLModel.hpp" @@ -78,13 +84,27 @@ class GCodeViewer { unsigned int ibo_id{ 0 }; size_t indices_count{ 0 }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + std::string shader; +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Shader shader; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::vector paths; std::vector render_paths; bool visible{ false }; void reset(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool init_shader(const std::string& vertex_shader_src, const std::string& fragment_shader_src); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void add_path(const GCodeProcessor::MoveVertex& move, unsigned int i_id, unsigned int s_id); }; @@ -93,7 +113,13 @@ class GCodeViewer { GLVolumeCollection volumes; bool visible{ false }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Shader shader; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ }; // helper to render extrusion paths @@ -203,7 +229,13 @@ public: Transform3f m_world_transform; std::array m_color{ 1.0f, 1.0f, 1.0f, 1.0f }; bool m_visible{ false }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Shader m_shader; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ public: void init(); @@ -218,8 +250,14 @@ public: void render() const; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ private: void init_shader(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ }; struct Endpoints @@ -273,7 +311,16 @@ public: bool init() { set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Extrude, true); m_sequential_view.marker.init(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + init_shaders(); + return true; +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ return init_shaders(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } // extract rendering data from the given parameters @@ -317,7 +364,15 @@ public: void enable_legend(bool enable) { m_legend_enabled = enable; } private: +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + void init_shaders(); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool init_shaders(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void load_toolpaths(const GCodeProcessor::Result& gcode_result); void load_shells(const Print& print, bool initialized); void refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 82c7576a25..c1c310b34c 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -156,10 +156,19 @@ GLCanvas3D::LayersEditing::~LayersEditing() const float GLCanvas3D::LayersEditing::THICKNESS_BAR_WIDTH = 70.0f; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER +void GLCanvas3D::LayersEditing::init() +{ +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool GLCanvas3D::LayersEditing::init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename) { if (!m_shader.init(vertex_shader_filename, fragment_shader_filename)) return false; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glGenTextures(1, (GLuint*)&m_z_texture_id)); glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id)); @@ -170,7 +179,13 @@ bool GLCanvas3D::LayersEditing::init(const std::string& vertex_shader_filename, glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1)); glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ return true; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } void GLCanvas3D::LayersEditing::set_config(const DynamicPrintConfig* config) @@ -203,7 +218,15 @@ void GLCanvas3D::LayersEditing::select_object(const Model &model, int object_id) bool GLCanvas3D::LayersEditing::is_allowed() const { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + return wxGetApp().get_shader("variable_layer_height") != nullptr && m_z_texture_id > 0; +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ return m_shader.is_initialized() && m_shader.get_shader()->shader_program_id > 0 && m_z_texture_id > 0; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } bool GLCanvas3D::LayersEditing::is_enabled() const @@ -361,7 +384,15 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas) bool GLCanvas3D::LayersEditing::is_initialized() const { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + return wxGetApp().get_shader("variable_layer_height") != nullptr; +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ return m_shader.is_initialized(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } std::string GLCanvas3D::LayersEditing::get_tooltip(const GLCanvas3D& canvas) const @@ -395,6 +426,21 @@ std::string GLCanvas3D::LayersEditing::get_tooltip(const GLCanvas3D& canvas) con void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect) const { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height"); + if (shader == nullptr) + return; + + shader->start_using(); + + shader->set_uniform("z_to_texture_row", float(m_layers_texture.cells - 1) / (float(m_layers_texture.width) * m_object_max_z)); + shader->set_uniform("z_texture_row_to_normalized", 1.0f / (float)m_layers_texture.height); + shader->set_uniform("z_cursor", m_object_max_z * this->get_cursor_z_relative(canvas)); + shader->set_uniform("z_cursor_band_width", band_width); + shader->set_uniform("object_max_z", m_object_max_z); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_shader.start_using(); m_shader.set_uniform("z_to_texture_row", float(m_layers_texture.cells - 1) / (float(m_layers_texture.width) * m_object_max_z)); @@ -402,6 +448,9 @@ void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3 m_shader.set_uniform("z_cursor", m_object_max_z * this->get_cursor_z_relative(canvas)); m_shader.set_uniform("z_cursor_band_width", band_width); m_shader.set_uniform("object_max_z", m_object_max_z); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id)); @@ -421,7 +470,15 @@ void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3 glsafe(::glEnd()); glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader->stop_using(); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_shader.stop_using(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } void GLCanvas3D::LayersEditing::render_profile(const Rect& bar_rect) const @@ -455,6 +512,29 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G { assert(this->is_allowed()); assert(this->last_object_id != -1); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height"); + assert(shader != nullptr); + + GLint current_program_id = 0; + glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id)); + if (shader->get_id() != static_cast(current_program_id)) + // The layer editing shader is not yet active. Activate it. + shader->start_using(); + else + // The layer editing shader was already active. + current_program_id = 0; + + const_cast(this)->generate_layer_height_texture(); + + // Uniforms were resolved, go ahead using the layer editing shader. + shader->set_uniform("z_to_texture_row", float(m_layers_texture.cells - 1) / (float(m_layers_texture.width) * float(m_object_max_z))); + shader->set_uniform("z_texture_row_to_normalized", 1.0f / float(m_layers_texture.height)); + shader->set_uniform("z_cursor", float(m_object_max_z) * float(this->get_cursor_z_relative(canvas))); + shader->set_uniform("z_cursor_band_width", float(this->band_width)); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GLint shader_id = m_shader.get_shader()->shader_program_id; assert(shader_id > 0); @@ -467,15 +547,16 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G // The layer editing shader was already active. current_program_id = -1; - GLint z_to_texture_row_id = ::glGetUniformLocation(shader_id, "z_to_texture_row"); - GLint z_texture_row_to_normalized_id = ::glGetUniformLocation(shader_id, "z_texture_row_to_normalized"); - GLint z_cursor_id = ::glGetUniformLocation(shader_id, "z_cursor"); - GLint z_cursor_band_width_id = ::glGetUniformLocation(shader_id, "z_cursor_band_width"); - GLint world_matrix_id = ::glGetUniformLocation(shader_id, "volume_world_matrix"); - GLint object_max_z_id = ::glGetUniformLocation(shader_id, "object_max_z"); + GLint z_to_texture_row_id = ::glGetUniformLocation(shader_id, "z_to_texture_row"); + GLint z_texture_row_to_normalized_id = ::glGetUniformLocation(shader_id, "z_texture_row_to_normalized"); + GLint z_cursor_id = ::glGetUniformLocation(shader_id, "z_cursor"); + GLint z_cursor_band_width_id = ::glGetUniformLocation(shader_id, "z_cursor_band_width"); + GLint world_matrix_id = ::glGetUniformLocation(shader_id, "volume_world_matrix"); + GLint object_max_z_id = ::glGetUniformLocation(shader_id, "object_max_z"); glcheck(); - if (z_to_texture_row_id != -1 && z_texture_row_to_normalized_id != -1 && z_cursor_id != -1 && z_cursor_band_width_id != -1 && world_matrix_id != -1) + + if (z_to_texture_row_id != -1 && z_texture_row_to_normalized_id != -1 && z_cursor_id != -1 && z_cursor_band_width_id != -1 && world_matrix_id != -1) { const_cast(this)->generate_layer_height_texture(); @@ -484,6 +565,9 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G glsafe(::glUniform1f(z_texture_row_to_normalized_id, GLfloat(1.0f / m_layers_texture.height))); glsafe(::glUniform1f(z_cursor_id, GLfloat(m_object_max_z) * GLfloat(this->get_cursor_z_relative(canvas)))); glsafe(::glUniform1f(z_cursor_band_width_id, GLfloat(this->band_width))); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Initialize the layer height texture mapping. GLsizei w = (GLsizei)m_layers_texture.width; GLsizei h = (GLsizei)m_layers_texture.height; @@ -499,17 +583,29 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G // Render the object using the layer editing shader and texture. if (! glvolume->is_active || glvolume->composite_id.object_id != this->last_object_id || glvolume->is_modifier) continue; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader->set_uniform("volume_world_matrix", glvolume->world_matrix()); + shader->set_uniform("object_max_z", GLfloat(0)); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (world_matrix_id != -1) glsafe(::glUniformMatrix4fv(world_matrix_id, 1, GL_FALSE, (const GLfloat*)glvolume->world_matrix().cast().data())); if (object_max_z_id != -1) glsafe(::glUniform1f(object_max_z_id, GLfloat(0))); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glvolume->render(); } // Revert back to the previous shader. glBindTexture(GL_TEXTURE_2D, 0); if (current_program_id > 0) glsafe(::glUseProgram(current_program_id)); - } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + } else { // Something went wrong. Just render the object. @@ -522,6 +618,9 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G glvolume->render(); } } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } void GLCanvas3D::LayersEditing::adjust_layer_height_profile() @@ -1645,6 +1744,12 @@ bool GLCanvas3D::init() if (m_multisample_allowed) glsafe(::glEnable(GL_MULTISAMPLE)); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + if (m_main_toolbar.is_enabled()) + m_layers_editing.init(); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!m_shader.init("gouraud.vs", "gouraud.fs")) { std::cout << "Unable to initialize gouraud shader: please, check that the files gouraud.vs and gouraud.fs are available" << std::endl; @@ -1656,6 +1761,9 @@ bool GLCanvas3D::init() std::cout << "Unable to initialize variable_layer_height shader: please, check that the files variable_layer_height.vs and variable_layer_height.fs are available" << std::endl; return false; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER if (!m_main_toolbar.is_enabled()) @@ -4515,8 +4623,17 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, bool return ret; }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + static const std::array orange = { 0.923f, 0.504f, 0.264f, 1.0f }; + static const std::array gray = { 0.64f, 0.64f, 0.64f, 1.0f }; +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ static const GLfloat orange[] = { 0.923f, 0.504f, 0.264f, 1.0f }; static const GLfloat gray[] = { 0.64f, 0.64f, 0.64f, 1.0f }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GLVolumePtrs visible_volumes; @@ -4560,6 +4677,22 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, bool camera.apply_projection(box, near_z, far_z); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + GLShaderProgram* shader = wxGetApp().get_shader("gouraud"); + if (shader == nullptr) + return; + + if (transparent_background) + glsafe(::glClearColor(0.0f, 0.0f, 0.0f, 0.0f)); + + glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); + glsafe(::glEnable(GL_DEPTH_TEST)); + + shader->start_using(); + shader->set_uniform("print_box.volume_detection", 0); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (transparent_background) glsafe(::glClearColor(0.0f, 0.0f, 0.0f, 0.0f)); @@ -4575,24 +4708,44 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, bool if (print_box_detection_id != -1) glsafe(::glUniform1i(print_box_detection_id, 0)); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ for (const GLVolume* vol : visible_volumes) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader->set_uniform("uniform_color", (vol->printable && !vol->is_outside) ? orange : gray); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (vol->printable && !vol->is_outside) ? orange : gray)); else glsafe(::glColor4fv((vol->printable && !vol->is_outside) ? orange : gray)); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ vol->render(); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader->stop_using(); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_shader.stop_using(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glDisable(GL_DEPTH_TEST)); if (show_bed) _render_bed(!camera.is_looking_downward(), false); + // restore background color if (transparent_background) glsafe(::glClearColor(1.0f, 1.0f, 1.0f, 1.0f)); } @@ -5531,7 +5684,18 @@ void GLCanvas3D::_render_objects() const m_volumes.set_clipping_plane(m_camera_clipping_plane.get_data()); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + GLShaderProgram* shader = wxGetApp().get_shader("gouraud"); + if (shader != nullptr) + { + shader->start_using(); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_shader.start_using(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (m_picking_enabled && !m_gizmos.is_dragging() && m_layers_editing.is_enabled() && (m_layers_editing.last_object_id != -1) && (m_layers_editing.object_max_z() > 0.0f)) { int object_id = m_layers_editing.last_object_id; m_volumes.render(GLVolumeCollection::Opaque, false, wxGetApp().plater()->get_camera().get_view_matrix(), [object_id](const GLVolume& volume) { @@ -5540,7 +5704,8 @@ void GLCanvas3D::_render_objects() const }); // Let LayersEditing handle rendering of the active object using the layer height profile shader. m_layers_editing.render_volumes(*this, this->m_volumes); - } else { + } + else { // do not cull backfaces to show broken geometry, if any m_volumes.render(GLVolumeCollection::Opaque, m_picking_enabled, wxGetApp().plater()->get_camera().get_view_matrix(), [this](const GLVolume& volume) { return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0); @@ -5548,7 +5713,16 @@ void GLCanvas3D::_render_objects() const } m_volumes.render(GLVolumeCollection::Transparent, false, wxGetApp().plater()->get_camera().get_view_matrix()); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader->stop_using(); + } +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_shader.stop_using(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_camera_clipping_plane = ClippingPlane::ClipsNothing(); } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 9d77790619..635d23e544 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -7,7 +7,13 @@ #include "3DScene.hpp" #include "GLToolbar.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "GLShader.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "Event.hpp" #include "Selection.hpp" #include "Gizmos/GLGizmosManager.hpp" @@ -167,7 +173,13 @@ private: private: bool m_enabled; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Shader m_shader; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ unsigned int m_z_texture_id; // Not owned by LayersEditing. const DynamicPrintConfig *m_config; @@ -214,8 +226,16 @@ private: LayersEditing(); ~LayersEditing(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + void init(); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename); - void set_config(const DynamicPrintConfig* config); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void set_config(const DynamicPrintConfig* config); void select_object(const Model &model, int object_id); bool is_allowed() const; @@ -457,7 +477,13 @@ private: WarningTexture m_warning_texture; wxTimer m_timer; LayersEditing m_layers_editing; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Shader m_shader; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Mouse m_mouse; mutable GLGizmosManager m_gizmos; mutable GLToolbar m_main_toolbar; @@ -587,7 +613,13 @@ public: void set_color_by(const std::string& value); void refresh_camera_scene_box(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const Shader& get_shader() const { return m_shader; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ BoundingBoxf3 volumes_bounding_box() const; BoundingBoxf3 scene_bounding_box() const; diff --git a/src/slic3r/GUI/GLShader.cpp b/src/slic3r/GUI/GLShader.cpp index c310760603..3b7c2abcc6 100644 --- a/src/slic3r/GUI/GLShader.cpp +++ b/src/slic3r/GUI/GLShader.cpp @@ -1,11 +1,289 @@ -#include - +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#include "libslic3r/libslic3r.h" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "GLShader.hpp" -#include "libslic3r/Utils.hpp" #include "3DScene.hpp" -#include +#include "libslic3r/Utils.hpp" +#include +#include + +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER +#include + +namespace Slic3r { + +GLShaderProgram::~GLShaderProgram() +{ + if (m_id > 0) + glsafe(::glDeleteProgram(m_id)); +} + +bool GLShaderProgram::init_from_files(const std::string& name, const ShaderFilenames& filenames) +{ + auto load_from_file = [](const std::string& filename) { + std::string path = resources_dir() + "/shaders/" + filename; + boost::nowide::ifstream s(path, boost::nowide::ifstream::binary); + if (!s.good()) + { + BOOST_LOG_TRIVIAL(error) << "Couldn't open file: '" << path << "'"; + return std::string(); + } + + s.seekg(0, s.end); + int file_length = static_cast(s.tellg()); + s.seekg(0, s.beg); + std::string source(file_length, '\0'); + s.read(source.data(), file_length); + if (!s.good()) + { + BOOST_LOG_TRIVIAL(error) << "Error while loading file: '" << path << "'"; + return std::string(); + } + + s.close(); + return source; + }; + + ShaderSources sources = {}; + for (size_t i = 0; i < static_cast(EShaderType::Count); ++i) { + sources[i] = filenames[i].empty() ? std::string() : load_from_file(filenames[i]); + } + + bool valid = (!sources[static_cast(EShaderType::Vertex)].empty() && !sources[static_cast(EShaderType::Fragment)].empty()) || + !sources[static_cast(EShaderType::Compute)].empty(); + + return valid ? init_from_texts(name, sources) : false; +} + +bool GLShaderProgram::init_from_texts(const std::string& name, const ShaderSources& sources) +{ + auto shader_type_as_string = [](EShaderType type) { + switch (type) + { + case EShaderType::Vertex: { return "vertex"; } + case EShaderType::Fragment: { return "fragment"; } + case EShaderType::Geometry: { return "geometry"; } + case EShaderType::TessEvaluation: { return "tesselation evaluation"; } + case EShaderType::TessControl: { return "tesselation control"; } + case EShaderType::Compute: { return "compute"; } + default: { return "unknown"; } + } + }; + + auto create_shader = [](EShaderType type) { + GLuint id = 0; + switch (type) + { + case EShaderType::Vertex: { id = ::glCreateShader(GL_VERTEX_SHADER); glcheck(); break; } + case EShaderType::Fragment: { id = ::glCreateShader(GL_FRAGMENT_SHADER); glcheck(); break; } + case EShaderType::Geometry: { id = ::glCreateShader(GL_GEOMETRY_SHADER); glcheck(); break; } + case EShaderType::TessEvaluation: { id = ::glCreateShader(GL_TESS_EVALUATION_SHADER); glcheck(); break; } + case EShaderType::TessControl: { id = ::glCreateShader(GL_TESS_CONTROL_SHADER); glcheck(); break; } + case EShaderType::Compute: { id = ::glCreateShader(GL_COMPUTE_SHADER); glcheck(); break; } + default: { break; } + } + + return (id == 0) ? std::make_pair(false, GLuint(0)) : std::make_pair(true, id); + }; + + auto release_shaders = [](const std::array(EShaderType::Count)>& shader_ids) { + for (size_t i = 0; i < static_cast(EShaderType::Count); ++i) { + if (shader_ids[i] > 0) + glsafe(::glDeleteShader(shader_ids[i])); + } + }; + + assert(m_id == 0); + + m_name = name; + + std::array(EShaderType::Count)> shader_ids = { 0 }; + + for (size_t i = 0; i < static_cast(EShaderType::Count); ++i) { + const std::string& source = sources[i]; + if (!source.empty()) + { + EShaderType type = static_cast(i); + auto [result, id] = create_shader(type); + if (result) + shader_ids[i] = id; + else + { + BOOST_LOG_TRIVIAL(error) << "glCreateShader() failed for " << shader_type_as_string(type) << " shader of shader program '" << name << "'"; + return false; + } + + const char* source_ptr = source.c_str(); + glsafe(::glShaderSource(id, 1, &source_ptr, nullptr)); + glsafe(::glCompileShader(id)); + GLint params; + glsafe(::glGetShaderiv(id, GL_COMPILE_STATUS, ¶ms)); + if (params == GL_FALSE) { + // Compilation failed. + glsafe(::glGetShaderiv(id, GL_INFO_LOG_LENGTH, ¶ms)); + std::vector msg(params); + glsafe(::glGetShaderInfoLog(id, params, ¶ms, msg.data())); + BOOST_LOG_TRIVIAL(error) << "Unable to compile " << shader_type_as_string(type) << " shader of shader program '" << name << "':\n" << msg.data(); + + // release shader + release_shaders(shader_ids); + return false; + } + } + } + + m_id = ::glCreateProgram(); + glcheck(); + if (m_id == 0) { + BOOST_LOG_TRIVIAL(error) << "glCreateProgram() failed for shader program '" << name << "'"; + + // release shaders + release_shaders(shader_ids); + return false; + } + + for (size_t i = 0; i < static_cast(EShaderType::Count); ++i) { + if (shader_ids[i] > 0) + glsafe(::glAttachShader(m_id, shader_ids[i])); + } + + glsafe(::glLinkProgram(m_id)); + GLint params; + glsafe(::glGetProgramiv(m_id, GL_LINK_STATUS, ¶ms)); + if (params == GL_FALSE) { + // Linking failed. + glsafe(::glGetProgramiv(m_id, GL_INFO_LOG_LENGTH, ¶ms)); + std::vector msg(params); + glsafe(::glGetProgramInfoLog(m_id, params, ¶ms, msg.data())); + BOOST_LOG_TRIVIAL(error) << "Unable to link shader program '" << name << "':\n" << msg.data(); + + // release shaders + release_shaders(shader_ids); + + // release shader program + glsafe(::glDeleteProgram(m_id)); + m_id = 0; + + return false; + } + + // release shaders, they are no more needed + release_shaders(shader_ids); + + return true; +} + +bool GLShaderProgram::start_using() const +{ + if (m_id == 0) + return false; + + glsafe(::glUseProgram(m_id)); + return true; +} + +void GLShaderProgram::stop_using() const +{ + glsafe(::glUseProgram(0)); +} + +bool GLShaderProgram::set_uniform(const char* name, int value) const +{ + int id = get_uniform_location(name); + if (id >= 0) { + glsafe(::glUniform1i(id, static_cast(value))); + return true; + } + return false; +} + +bool GLShaderProgram::set_uniform(const char* name, bool value) const +{ + return set_uniform(name, value ? 1 : 0); +} + +bool GLShaderProgram::set_uniform(const char* name, float value) const +{ + int id = get_uniform_location(name); + if (id >= 0) { + glsafe(::glUniform1f(id, static_cast(value))); + return true; + } + return false; +} + +bool GLShaderProgram::set_uniform(const char* name, const std::array& value) const +{ + int id = get_uniform_location(name); + if (id >= 0) { + glsafe(::glUniform3fv(id, 1, static_cast(value.data()))); + return true; + } + return false; +} + +bool GLShaderProgram::set_uniform(const char* name, const std::array& value) const +{ + int id = get_uniform_location(name); + if (id >= 0) { + glsafe(::glUniform4fv(id, 1, static_cast(value.data()))); + return true; + } + return false; +} + +bool GLShaderProgram::set_uniform(const char* name, const float* value, size_t size) const +{ + if (size == 1) + return set_uniform(name, value[0]); + else if (size < 5) + { + int id = get_uniform_location(name); + if (id >= 0) { + if (size == 2) + glsafe(::glUniform2fv(id, 1, static_cast(value))); + else if (size == 3) + glsafe(::glUniform3fv(id, 1, static_cast(value))); + else + glsafe(::glUniform4fv(id, 1, static_cast(value))); + + return true; + } + } + return false; +} + +bool GLShaderProgram::set_uniform(const char* name, const Transform3f& value) const +{ + int id = get_uniform_location(name); + if (id >= 0) { + glsafe(::glUniformMatrix4fv(id, 1, GL_FALSE, static_cast(value.matrix().data()))); + return true; + } + return false; +} + +bool GLShaderProgram::set_uniform(const char* name, const Transform3d& value) const +{ + return set_uniform(name, value.cast()); +} + +int GLShaderProgram::get_attrib_location(const char* name) const +{ + return (m_id > 0) ? ::glGetAttribLocation(m_id, name) : -1; +} + +int GLShaderProgram::get_uniform_location(const char* name) const +{ + return (m_id > 0) ? ::glGetUniformLocation(m_id, name) : -1; +} + +} // namespace Slic3r +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include #include #include @@ -364,3 +642,6 @@ void Shader::reset() } } // namespace Slic3r +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ diff --git a/src/slic3r/GUI/GLShader.hpp b/src/slic3r/GUI/GLShader.hpp index df2a23f15c..a4a8d32cb3 100644 --- a/src/slic3r/GUI/GLShader.hpp +++ b/src/slic3r/GUI/GLShader.hpp @@ -1,6 +1,64 @@ #ifndef slic3r_GLShader_hpp_ #define slic3r_GLShader_hpp_ +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER +#include +#include + +namespace Slic3r { + +class GLShaderProgram +{ +public: + enum class EShaderType + { + Vertex, + Fragment, + Geometry, + TessEvaluation, + TessControl, + Compute, + Count + }; + + typedef std::array(EShaderType::Count)> ShaderFilenames; + typedef std::array(EShaderType::Count)> ShaderSources; + +private: + std::string m_name; + unsigned int m_id{ 0 }; + +public: + ~GLShaderProgram(); + + bool init_from_files(const std::string& name, const ShaderFilenames& filenames); + bool init_from_texts(const std::string& name, const ShaderSources& sources); + + const std::string& get_name() const { return m_name; } + unsigned int get_id() const { return m_id; } + + bool start_using() const; + void stop_using() const; + + bool set_uniform(const char* name, int value) const; + bool set_uniform(const char* name, bool value) const; + bool set_uniform(const char* name, float value) const; + bool set_uniform(const char* name, const std::array& value) const; + bool set_uniform(const char* name, const std::array& value) const; + bool set_uniform(const char* name, const float* value, size_t size) const; + bool set_uniform(const char* name, const Transform3f& value) const; + bool set_uniform(const char* name, const Transform3d& value) const; + + // returns -1 if not found + int get_attrib_location(const char* name) const; + // returns -1 if not found + int get_uniform_location(const char* name) const; +}; + +} // namespace Slic3r +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "libslic3r/libslic3r.h" #include "libslic3r/Point.hpp" @@ -67,5 +125,8 @@ private: }; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif /* slic3r_GLShader_hpp_ */ diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp new file mode 100644 index 0000000000..e4d6407224 --- /dev/null +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -0,0 +1,76 @@ +#include "libslic3r/libslic3r.h" +#include "GLShadersManager.hpp" + +#include +#include + +#if ENABLE_SHADERS_MANAGER + +namespace Slic3r { + +std::pair GLShadersManager::init() +{ + std::string error; + + auto append_shader = [this, &error](const std::string& name, const GLShaderProgram::ShaderFilenames& filenames) { + m_shaders.push_back(std::make_unique()); + if (!m_shaders.back()->init_from_files(name, filenames)) { + error += name + "\n"; + // if any error happens while initializating the shader, we remove it from the list + m_shaders.pop_back(); + return false; + } + return true; + }; + + assert(m_shaders.empty()); + + bool valid = true; + + // used to render bed axes, selection hints + valid &= append_shader("gouraud_light", { "gouraud_light.vs", "gouraud_light.fs" }); + // used to render printbed + valid &= append_shader("printbed", { "printbed.vs", "printbed.fs" }); + // used to render tool changes in gcode preview + valid &= append_shader("toolchanges", { "toolchanges.vs", "toolchanges.fs" }); + // used to render color changes in gcode preview + valid &= append_shader("colorchanges", { "colorchanges.vs", "colorchanges.fs" }); + // used to render pause prints in gcode preview + valid &= append_shader("pauses", { "pauses.vs", "pauses.fs" }); + // used to render custom gcode points in gcode preview + valid &= append_shader("customs", { "customs.vs", "customs.fs" }); + // used to render retractions in gcode preview + valid &= append_shader("retractions", { "retractions.vs", "retractions.fs" }); + // used to render unretractions in gcode preview + valid &= append_shader("unretractions", { "unretractions.vs", "unretractions.fs" }); + // used to render extrusion paths in gcode preview + valid &= append_shader("extrusions", { "extrusions.vs", "extrusions.fs" }); + // used to render travel paths in gcode preview + valid &= append_shader("travels", { "travels.vs", "travels.fs" }); + // used to render shells in gcode preview + valid &= append_shader("shells", { "shells.vs", "shells.fs" }); + // used to render objects in 3d editor + valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" }); + // used to render variable layers heights in 3d editor + valid &= append_shader("variable_layer_height", { "variable_layer_height.vs", "variable_layer_height.fs" }); + + return { valid, error }; +} + +void GLShadersManager::shutdown() +{ + for (std::unique_ptr& shader : m_shaders) + { + shader.reset(); + } +} + +GLShaderProgram* GLShadersManager::get_shader(const std::string& shader_name) +{ + auto it = std::find_if(m_shaders.begin(), m_shaders.end(), [shader_name](std::unique_ptr& p) { return p->get_name() == shader_name; }); + return (it != m_shaders.end()) ? it->get() : nullptr; +} + +} // namespace Slic3r + +#endif // ENABLE_SHADERS_MANAGER diff --git a/src/slic3r/GUI/GLShadersManager.hpp b/src/slic3r/GUI/GLShadersManager.hpp new file mode 100644 index 0000000000..0c624f9161 --- /dev/null +++ b/src/slic3r/GUI/GLShadersManager.hpp @@ -0,0 +1,31 @@ +#ifndef slic3r_GLShadersManager_hpp_ +#define slic3r_GLShadersManager_hpp_ + +#if ENABLE_SHADERS_MANAGER + +#include "GLShader.hpp" + +#include +#include +#include + +namespace Slic3r { + +class GLShadersManager +{ + std::vector> m_shaders; + +public: + std::pair init(); + // call this method before to release the OpenGL context + void shutdown(); + + // returns nullptr if not found + GLShaderProgram* get_shader(const std::string& shader_name); +}; + +} // namespace Slic3r + +#endif // ENABLE_SHADERS_MANAGER + +#endif // slic3r_GLShadersManager_hpp_ diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 984a1241e7..d0c1624d7c 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -217,6 +217,16 @@ public: void gcode_thumbnails_debug(); #endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + // returns nullptr if not found + GLShaderProgram* get_shader(const std::string& shader_name) { return m_opengl_mgr.get_shader(shader_name); } + +// // returns 0 if not found +// unsigned int get_shader_id(const std::string& shader_name) const { return m_opengl_mgr.get_shader_id(shader_name); } +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + private: bool on_init_inner(); void init_app_config(); diff --git a/src/slic3r/GUI/OpenGLManager.cpp b/src/slic3r/GUI/OpenGLManager.cpp index bdb005b1e2..e4674fffd1 100644 --- a/src/slic3r/GUI/OpenGLManager.cpp +++ b/src/slic3r/GUI/OpenGLManager.cpp @@ -28,6 +28,17 @@ namespace Slic3r { namespace GUI { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER +// A safe wrapper around glGetString to report a "N/A" string in case glGetString returns nullptr. +inline std::string gl_get_string_safe(GLenum param, const std::string& default_value) +{ + const char* value = (const char*)::glGetString(param); + return std::string((value != nullptr) ? value : default_value); +} +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + const std::string& OpenGLManager::GLInfo::get_version() const { if (!m_detected) @@ -85,6 +96,14 @@ float OpenGLManager::GLInfo::get_max_anisotropy() const void OpenGLManager::GLInfo::detect() const { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + m_version = gl_get_string_safe(GL_VERSION, "N/A"); + m_glsl_version = gl_get_string_safe(GL_SHADING_LANGUAGE_VERSION, "N/A"); + m_vendor = gl_get_string_safe(GL_VENDOR, "N/A"); + m_renderer = gl_get_string_safe(GL_RENDERER, "N/A"); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const char* data = (const char*)::glGetString(GL_VERSION); if (data != nullptr) m_version = data; @@ -100,6 +119,9 @@ void OpenGLManager::GLInfo::detect() const data = (const char*)::glGetString(GL_RENDERER); if (data != nullptr) m_renderer = data; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_max_tex_size)); @@ -119,6 +141,13 @@ bool OpenGLManager::GLInfo::is_version_greater_or_equal_to(unsigned int major, u if (!m_detected) detect(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + if (m_version == "N/A") + return false; +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + std::vector tokens; boost::split(tokens, m_version, boost::is_any_of(" "), boost::token_compress_on); @@ -159,15 +188,34 @@ std::string OpenGLManager::GLInfo::to_string(bool format_as_html, bool extension std::string line_end = format_as_html ? "
" : "\n"; out << h2_start << "OpenGL installation" << h2_end << line_end; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + out << b_start << "GL version: " << b_end << m_version << line_end; + out << b_start << "Vendor: " << b_end << m_vendor << line_end; + out << b_start << "Renderer: " << b_end << m_renderer << line_end; + out << b_start << "GLSL version: " << b_end << m_glsl_version << line_end; +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ out << b_start << "GL version: " << b_end << (m_version.empty() ? "N/A" : m_version) << line_end; out << b_start << "Vendor: " << b_end << (m_vendor.empty() ? "N/A" : m_vendor) << line_end; out << b_start << "Renderer: " << b_end << (m_renderer.empty() ? "N/A" : m_renderer) << line_end; out << b_start << "GLSL version: " << b_end << (m_glsl_version.empty() ? "N/A" : m_glsl_version) << line_end; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (extensions) { std::vector extensions_list; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + std::string extensions_str = gl_get_string_safe(GL_EXTENSIONS, ""); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::string extensions_str = (const char*)::glGetString(GL_EXTENSIONS); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ boost::split(extensions_list, extensions_str, boost::is_any_of(" "), boost::token_compress_off); if (!extensions_list.empty()) @@ -199,6 +247,12 @@ OpenGLManager::OSInfo OpenGLManager::s_os_info; OpenGLManager::~OpenGLManager() { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + m_shaders_manager.shutdown(); +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + #if ENABLE_HACK_CLOSING_ON_OSX_10_9_5 #ifdef __APPLE__ // This is an ugly hack needed to solve the crash happening when closing the application on OSX 10.9.5 with newer wxWidgets @@ -240,19 +294,43 @@ bool OpenGLManager::init_gl() else s_framebuffers_type = EFramebufferType::Unknown; - if (! s_gl_info.is_version_greater_or_equal_to(2, 0)) { - // Complain about the OpenGL version. +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + bool valid_version = s_gl_info.is_version_greater_or_equal_to(2, 0); + if (!valid_version) { +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + if (!s_gl_info.is_version_greater_or_equal_to(2, 0)) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + + // Complain about the OpenGL version. wxString message = from_u8((boost::format( _utf8(L("PrusaSlicer requires OpenGL 2.0 capable graphics driver to run correctly, \n" "while OpenGL version %s, render %s, vendor %s was detected."))) % s_gl_info.get_version() % s_gl_info.get_renderer() % s_gl_info.get_vendor()).str()); - message += "\n"; + message += "\n"; message += _L("You may need to update your graphics card driver."); #ifdef _WIN32 - message += "\n"; + message += "\n"; message += _L("As a workaround, you may run PrusaSlicer with a software rendered 3D graphics by running prusa-slicer.exe with the --sw_renderer parameter."); #endif wxMessageBox(message, wxString("PrusaSlicer - ") + _L("Unsupported OpenGL version"), wxOK | wxICON_ERROR); } + +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + if (valid_version) { + // load shaders + auto [result, error] = m_shaders_manager.init(); + if (!result) { + wxString message = from_u8((boost::format( + _utf8(L("Unable to load the following shaders:\n%s"))) % error).str()); + wxMessageBox(message, wxString("PrusaSlicer - ") + _L("Error loading shaders"), wxOK | wxICON_ERROR); + } + } +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } return true; diff --git a/src/slic3r/GUI/OpenGLManager.hpp b/src/slic3r/GUI/OpenGLManager.hpp index 9d7ee5babb..c80deb6ef1 100644 --- a/src/slic3r/GUI/OpenGLManager.hpp +++ b/src/slic3r/GUI/OpenGLManager.hpp @@ -1,6 +1,12 @@ #ifndef slic3r_OpenGLManager_hpp_ #define slic3r_OpenGLManager_hpp_ +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER +#include "GLShadersManager.hpp" +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + class wxWindow; class wxGLCanvas; class wxGLContext; @@ -70,6 +76,11 @@ private: bool m_gl_initialized{ false }; wxGLContext* m_context{ nullptr }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + GLShadersManager m_shaders_manager; +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ static GLInfo s_gl_info; #if ENABLE_HACK_CLOSING_ON_OSX_10_9_5 #ifdef __APPLE__ @@ -86,9 +97,18 @@ public: ~OpenGLManager(); bool init_gl(); - wxGLContext* init_glcontext(wxGLCanvas& canvas); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + // returns nullptr if not found + GLShaderProgram* get_shader(const std::string& shader_name) { return m_shaders_manager.get_shader(shader_name); } + +// // returns 0 if not found +// unsigned int get_shader_id(const std::string& shader_name) const { return m_shaders_manager.get_shader_id(shader_name); } +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + static bool are_compressed_textures_supported() { return s_compressed_textures_supported; } static bool can_multisample() { return s_multisample == EMultisampleState::Enabled; } static bool are_framebuffers_supported() { return (s_framebuffers_type != EFramebufferType::Unknown); } diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 3bab06b4d5..982a16bf00 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -8,6 +8,11 @@ #include "GUI_ObjectList.hpp" #include "Gizmos/GLGizmoBase.hpp" #include "3DScene.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//#if ENABLE_SHADERS_MANAGER +//#include "GLShader.hpp" +//#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "Camera.hpp" #include @@ -113,11 +118,17 @@ bool Selection::init() m_arrow.init_from(straight_arrow(10.0f, 5.0f, 5.0f, 10.0f, 1.0f)); m_curved_arrow.init_from(circular_arrow(16, 10.0f, 5.0f, 10.0f, 5.0f, 1.0f)); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!m_arrows_shader.init("gouraud_light.vs", "gouraud_light.fs")) { BOOST_LOG_TRIVIAL(error) << "Unable to initialize gouraud_light shader: please, check that the files gouraud_light.vs and gouraud_light.fs are available"; return false; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #else if (!m_arrow.init()) return false; @@ -1253,13 +1264,31 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field, const Sha if (sidebar_field.empty()) return; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + GLShaderProgram* shader = nullptr; +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + if (!boost::starts_with(sidebar_field, "layer")) { #if ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader = wxGetApp().get_shader("gouraud_light"); + if (shader == nullptr) + return; + + shader->start_using(); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!m_arrows_shader.is_initialized()) return; m_arrows_shader.start_using(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); #else shader.start_using(); @@ -1322,13 +1351,46 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field, const Sha } if (boost::starts_with(sidebar_field, "position")) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + render_sidebar_position_hints(sidebar_field, *shader); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ render_sidebar_position_hints(sidebar_field); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ else if (boost::starts_with(sidebar_field, "rotation")) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + render_sidebar_rotation_hints(sidebar_field, *shader); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ render_sidebar_rotation_hints(sidebar_field); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_GCODE_VIEWER + else if (boost::starts_with(sidebar_field, "scale") || boost::starts_with(sidebar_field, "size")) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER +render_sidebar_scale_hints(sidebar_field, *shader); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + render_sidebar_scale_hints(sidebar_field); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ else if (boost::starts_with(sidebar_field, "scale")) render_sidebar_scale_hints(sidebar_field); else if (boost::starts_with(sidebar_field, "size")) render_sidebar_size_hints(sidebar_field); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ else if (boost::starts_with(sidebar_field, "layer")) render_sidebar_layers_hints(sidebar_field); @@ -1337,7 +1399,15 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field, const Sha if (!boost::starts_with(sidebar_field, "layer")) { #if ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader->stop_using(); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_arrows_shader.stop_using(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #else glsafe(::glDisable(GL_LIGHTING)); shader.stop_using(); @@ -1942,35 +2012,76 @@ void Selection::render_bounding_box(const BoundingBoxf3& box, float* color) cons glsafe(::glEnd()); } -void Selection::render_sidebar_position_hints(const std::string& sidebar_field) const -{ #if ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER +void Selection::render_sidebar_position_hints(const std::string& sidebar_field, GLShaderProgram& shader) const +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +void Selection::render_sidebar_position_hints(const std::string& sidebar_field) const +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +{ +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GLint color_id = ::glGetUniformLocation(m_arrows_shader.get_shader_program_id(), "uniform_color"); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (boost::ends_with(sidebar_field, "x")) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader.set_uniform("uniform_color", AXES_COLOR[0], 4); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[0])); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0)); m_arrow.render(); } else if (boost::ends_with(sidebar_field, "y")) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader.set_uniform("uniform_color", AXES_COLOR[1], 4); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[1])); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_arrow.render(); } else if (boost::ends_with(sidebar_field, "z")) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader.set_uniform("uniform_color", AXES_COLOR[2], 4); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[2])); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); m_arrow.render(); } +} #else +void Selection::render_sidebar_position_hints(const std::string & sidebar_field) const +{ if (boost::ends_with(sidebar_field, "x")) { glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0)); @@ -1983,38 +2094,79 @@ void Selection::render_sidebar_position_hints(const std::string& sidebar_field) glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); render_sidebar_position_hint(Z); } -#endif // ENABLE_GCODE_VIEWER } +#endif // ENABLE_GCODE_VIEWER -void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) const -{ #if ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER +void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field, GLShaderProgram& shader) const +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) const +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +{ +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GLint color_id = ::glGetUniformLocation(m_arrows_shader.get_shader_program_id(), "uniform_color"); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (boost::ends_with(sidebar_field, "x")) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader.set_uniform("uniform_color", AXES_COLOR[0], 4); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[0])); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glRotated(90.0, 0.0, 1.0, 0.0)); render_sidebar_rotation_hint(X); } else if (boost::ends_with(sidebar_field, "y")) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader.set_uniform("uniform_color", AXES_COLOR[1], 4); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[1])); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0)); render_sidebar_rotation_hint(Y); } else if (boost::ends_with(sidebar_field, "z")) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader.set_uniform("uniform_color", AXES_COLOR[2], 4); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[2])); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ render_sidebar_rotation_hint(Z); } +} #else +void Selection::render_sidebar_rotation_hints(const std::string & sidebar_field) const +{ if (boost::ends_with(sidebar_field, "x")) { glsafe(::glRotated(90.0, 0.0, 1.0, 0.0)); @@ -2027,37 +2179,74 @@ void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) } else if (boost::ends_with(sidebar_field, "z")) render_sidebar_rotation_hint(Z); -#endif // ENABLE_GCODE_VIEWER } +#endif // ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER +void Selection::render_sidebar_scale_hints(const std::string& sidebar_field, GLShaderProgram& shader) const +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) const +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { bool uniform_scale = requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling(); -#if ENABLE_GCODE_VIEWER if (boost::ends_with(sidebar_field, "x") || uniform_scale) { glsafe(::glPushMatrix()); glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0)); - render_sidebar_scale_hint(X); - glsafe(::glPopMatrix()); - } - - if (boost::ends_with(sidebar_field, "y") || uniform_scale) - { - glsafe(::glPushMatrix()); - render_sidebar_scale_hint(Y); - glsafe(::glPopMatrix()); - } - - if (boost::ends_with(sidebar_field, "z") || uniform_scale) - { - glsafe(::glPushMatrix()); - glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); - render_sidebar_scale_hint(Z); - glsafe(::glPopMatrix()); - } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + render_sidebar_scale_hint(X, shader); #else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + render_sidebar_scale_hint(X); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + glsafe(::glPopMatrix()); + } + + if (boost::ends_with(sidebar_field, "y") || uniform_scale) + { + glsafe(::glPushMatrix()); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + render_sidebar_scale_hint(Y, shader); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + render_sidebar_scale_hint(Y); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + glsafe(::glPopMatrix()); + } + + if (boost::ends_with(sidebar_field, "z") || uniform_scale) + { + glsafe(::glPushMatrix()); + glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + render_sidebar_scale_hint(Z, shader); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + render_sidebar_scale_hint(Z); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + glsafe(::glPopMatrix()); + } +} +#else +void Selection::render_sidebar_scale_hints(const std::string & sidebar_field) const +{ + bool uniform_scale = requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling(); + if (boost::ends_with(sidebar_field, "x") || uniform_scale) { glsafe(::glPushMatrix()); @@ -2080,13 +2269,19 @@ void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) con render_sidebar_scale_hint(Z); glsafe(::glPopMatrix()); } -#endif // ENABLE_GCODE_VIEWER } +#endif // ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void Selection::render_sidebar_size_hints(const std::string& sidebar_field) const { render_sidebar_scale_hints(sidebar_field); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) const { @@ -2178,13 +2373,29 @@ void Selection::render_sidebar_rotation_hint(Axis axis) const m_curved_arrow.render(); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER +void Selection::render_sidebar_scale_hint(Axis axis, GLShaderProgram& shader) const +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void Selection::render_sidebar_scale_hint(Axis axis) const +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { #if ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + shader.set_uniform("uniform_color", (requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling()) ? UNIFORM_SCALE_COLOR : AXES_COLOR[axis], 4); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GLint color_id = ::glGetUniformLocation(m_arrows_shader.get_shader_program_id(), "uniform_color"); if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling()) ? (const GLfloat*)UNIFORM_SCALE_COLOR : (const GLfloat*)AXES_COLOR[axis])); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #else m_arrow.set_color(((requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling()) ? UNIFORM_SCALE_COLOR : AXES_COLOR[axis]), 3); #endif // ENABLE_GCODE_VIEWER diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 53caf11060..7411fc97e5 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -6,7 +6,13 @@ #include "3DScene.hpp" #if ENABLE_GCODE_VIEWER #include "GLModel.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "GLShader.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER #if ENABLE_RENDER_SELECTION_CENTER @@ -15,7 +21,15 @@ typedef class GLUquadric GLUquadricObj; #endif // ENABLE_RENDER_SELECTION_CENTER namespace Slic3r { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER +class GLShaderProgram; +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ class Shader; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ namespace GUI { class TransformationType { @@ -207,7 +221,13 @@ private: #if ENABLE_GCODE_VIEWER GL_Model m_arrow; GL_Model m_curved_arrow; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Shader m_arrows_shader; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #else mutable GLArrow m_arrow; mutable GLCurvedArrow m_curved_arrow; @@ -368,16 +388,40 @@ private: void render_selected_volumes() const; void render_synchronized_volumes() const; void render_bounding_box(const BoundingBoxf3& box, float* color) const; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + void render_sidebar_position_hints(const std::string& sidebar_field, GLShaderProgram& shader) const; + void render_sidebar_rotation_hints(const std::string& sidebar_field, GLShaderProgram& shader) const; + void render_sidebar_scale_hints(const std::string& sidebar_field, GLShaderProgram& shader) const; +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void render_sidebar_position_hints(const std::string& sidebar_field) const; void render_sidebar_rotation_hints(const std::string& sidebar_field) const; void render_sidebar_scale_hints(const std::string& sidebar_field) const; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void render_sidebar_size_hints(const std::string& sidebar_field) const; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void render_sidebar_layers_hints(const std::string& sidebar_field) const; #if !ENABLE_GCODE_VIEWER void render_sidebar_position_hint(Axis axis) const; #endif // !ENABLE_GCODE_VIEWER void render_sidebar_rotation_hint(Axis axis) const; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SHADERS_MANAGER + void render_sidebar_scale_hint(Axis axis, GLShaderProgram& shader) const; +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void render_sidebar_scale_hint(Axis axis) const; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SHADERS_MANAGER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_GCODE_VIEWER void render_sidebar_size_hint(Axis axis, double length) const; #endif // !ENABLE_GCODE_VIEWER From cbfb09a241eeca1337a85bbb361518c304e29895 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 20 May 2020 17:03:53 +0200 Subject: [PATCH 082/255] Fixed build for all 4 cases of tech ENABLE_SHADERS_MANAGER and ENABLE_GCODE_VIEWER enabled/disabled and code cleanup --- src/libslic3r/GCode/ToolOrdering.cpp | 4 +- src/libslic3r/Technologies.hpp | 6 +- src/slic3r/GUI/3DBed.cpp | 29 ----- src/slic3r/GUI/3DBed.hpp | 12 -- src/slic3r/GUI/GCodeViewer.cpp | 81 ------------- src/slic3r/GUI/GCodeViewer.hpp | 32 ----- src/slic3r/GUI/GLCanvas3D.cpp | 68 +---------- src/slic3r/GUI/GLCanvas3D.hpp | 20 ---- src/slic3r/GUI/GLShader.cpp | 7 +- src/slic3r/GUI/GLShader.hpp | 6 +- src/slic3r/GUI/GUI_App.hpp | 5 - src/slic3r/GUI/OpenGLManager.cpp | 24 ---- src/slic3r/GUI/OpenGLManager.hpp | 9 -- src/slic3r/GUI/Selection.cpp | 171 +++++++-------------------- src/slic3r/GUI/Selection.hpp | 53 ++++----- 15 files changed, 72 insertions(+), 455 deletions(-) diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index 9c1a1900fd..db398f06c8 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -400,9 +400,7 @@ void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_ // and maybe other problems. We will therefore go through layer_tools and detect and fix this. // So, if there is a non-object layer starting with different extruder than the last one ended with (or containing more than one extruder), // we'll mark it with has_wipe tower. -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// assert(! m_layer_tools.empty() && m_layer_tools.front().has_wipe_tower); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + assert(! m_layer_tools.empty() && m_layer_tools.front().has_wipe_tower); if (! m_layer_tools.empty() && m_layer_tools.front().has_wipe_tower) { for (size_t i = 0; i + 1 < m_layer_tools.size();) { const LayerTools < = m_layer_tools[i]; diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index c274c1e841..d0673e2b4b 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -44,9 +44,9 @@ // Enable G-Code viewer #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#define ENABLE_SHADERS_MANAGER (1 && ENABLE_GCODE_VIEWER) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) +// Enable the OpenGL shaders manager +#define ENABLE_SHADERS_MANAGER (1 && ENABLE_2_3_0_ALPHA1) + #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 4bf8ce900e..73162645fc 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -15,11 +15,6 @@ #if ENABLE_GCODE_VIEWER #include "3DScene.hpp" #endif // ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -//#if ENABLE_SHADERS_MANAGER -//#include "GLShader.hpp" -//#endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include @@ -168,17 +163,13 @@ Bed3D::Axes::~Axes() void Bed3D::Axes::render() const { #if ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER auto render_axis = [this](const Transform3f& transform) { #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ auto render_axis = [this](const Transform3f& transform, GLint color_id, const std::array& color) { if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)color.data())); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glPushMatrix()); glsafe(::glMultMatrixf(transform.data())); @@ -187,25 +178,20 @@ void Bed3D::Axes::render() const }; m_arrow.init_from(stilized_arrow(16, DefaultTipRadius, DefaultTipLength, DefaultStemRadius, m_stem_length)); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); if (shader == nullptr) return; #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!m_shader.init("gouraud_light.vs", "gouraud_light.fs")) BOOST_LOG_TRIVIAL(error) << "Unable to initialize gouraud_light shader: please, check that the files gouraud_light.vs and gouraud_light.fs are available"; if (!m_shader.is_initialized()) return; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glEnable(GL_DEPTH_TEST)); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader->start_using(); @@ -223,7 +209,6 @@ void Bed3D::Axes::render() const shader->stop_using(); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_shader.start_using(); GLint color_id = ::glGetUniformLocation(m_shader.get_shader_program_id(), "uniform_color"); @@ -237,9 +222,7 @@ void Bed3D::Axes::render() const render_axis(Geometry::assemble_transform(m_origin).cast(), color_id, { 0.0f, 0.0f, 0.75f, 1.0f }); m_shader.stop_using(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glDisable(GL_DEPTH_TEST)); #else @@ -585,7 +568,6 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const if (m_triangles.get_vertices_count() > 0) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER GLShaderProgram* shader = wxGetApp().get_shader("printbed"); if (shader != nullptr) @@ -594,7 +576,6 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const shader->set_uniform("transparent_background", bottom); shader->set_uniform("svg_source", boost::algorithm::iends_with(m_texture.get_source(), ".svg")); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (m_shader.get_shader_program_id() == 0) m_shader.init("printbed.vs", "printbed.fs"); @@ -603,9 +584,7 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const m_shader.start_using(); m_shader.set_uniform("transparent_background", bottom); m_shader.set_uniform("svg_source", boost::algorithm::iends_with(m_texture.get_source(), ".svg")); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (m_vbo_id == 0) { @@ -626,17 +605,13 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const unsigned int stride = m_triangles.get_vertex_data_size(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER GLint position_id = shader->get_attrib_location("v_position"); GLint tex_coords_id = shader->get_attrib_location("v_tex_coords"); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GLint position_id = m_shader.get_attrib_location("v_position"); GLint tex_coords_id = m_shader.get_attrib_location("v_tex_coords"); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // show the temporary texture while no compressed data is available GLuint tex_id = (GLuint)m_temp_texture.get_id(); @@ -674,15 +649,11 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const glsafe(::glDisable(GL_BLEND)); glsafe(::glDepthMask(GL_TRUE)); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader->stop_using(); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_shader.stop_using(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } } } diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp index 9603015da8..d9a2c82620 100644 --- a/src/slic3r/GUI/3DBed.hpp +++ b/src/slic3r/GUI/3DBed.hpp @@ -3,13 +3,9 @@ #include "GLTexture.hpp" #include "3DScene.hpp" -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "GLShader.hpp" -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER #include "GLModel.hpp" #endif // ENABLE_GCODE_VIEWER @@ -75,13 +71,9 @@ class Bed3D Vec3d m_origin{ Vec3d::Zero() }; float m_stem_length{ DefaultStemLength }; mutable GL_Model m_arrow; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ mutable Shader m_shader; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ public: #else @@ -130,13 +122,9 @@ private: mutable GLBed m_model; // temporary texture shown until the main texture has still no levels compressed mutable GLTexture m_temp_texture; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ mutable Shader m_shader; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ mutable unsigned int m_vbo_id; Axes m_axes; diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 55f603829b..a584dc7eb1 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -12,11 +12,6 @@ #include "DoubleSlider.hpp" #include "GLCanvas3D.hpp" #include "GLToolbar.hpp" -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -//#if ENABLE_SHADERS_MANAGER -//#include "GLShader.hpp" -//#endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "GUI_Preview.hpp" #include "libslic3r/Model.hpp" #if ENABLE_GCODE_VIEWER_STATISTICS @@ -112,9 +107,7 @@ void GCodeViewer::IBuffer::reset() render_paths = std::vector(); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool GCodeViewer::IBuffer::init_shader(const std::string& vertex_shader_src, const std::string& fragment_shader_src) { if (!shader.init(vertex_shader_src, fragment_shader_src)) { @@ -124,9 +117,7 @@ bool GCodeViewer::IBuffer::init_shader(const std::string& vertex_shader_src, con return true; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move, unsigned int i_id, unsigned int s_id) { @@ -160,18 +151,13 @@ GCodeViewer::Color GCodeViewer::Extrusions::Range::get_color_at(float value) con void GCodeViewer::SequentialView::Marker::init() { m_model.init_from(stilized_arrow(16, 2.0f, 4.0f, 1.0f, 8.0f)); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ init_shader(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } void GCodeViewer::SequentialView::Marker::render() const { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER if (!m_visible) return; @@ -186,7 +172,6 @@ void GCodeViewer::SequentialView::Marker::render() const shader->start_using(); shader->set_uniform("uniform_color", m_color); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!m_visible || !m_shader.is_initialized()) return; @@ -197,9 +182,7 @@ void GCodeViewer::SequentialView::Marker::render() const GLint color_id = ::glGetUniformLocation(m_shader.get_shader_program_id(), "uniform_color"); if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)m_color.data())); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glPushMatrix()); glsafe(::glMultMatrixf(m_world_transform.data())); @@ -208,30 +191,22 @@ void GCodeViewer::SequentialView::Marker::render() const glsafe(::glPopMatrix()); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader->stop_using(); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_shader.stop_using(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glDisable(GL_BLEND)); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GCodeViewer::SequentialView::Marker::init_shader() { if (!m_shader.init("gouraud_light.vs", "gouraud_light.fs")) BOOST_LOG_TRIVIAL(error) << "Unable to initialize gouraud_light shader: please, check that the files gouraud_light.vs and gouraud_light.fs are available"; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const std::vector GCodeViewer::Extrusion_Role_Colors {{ { 0.50f, 0.50f, 0.50f }, // erNone @@ -440,7 +415,6 @@ void GCodeViewer::set_layers_z_range(const std::array& layers_z_range wxGetApp().plater()->update_preview_moves_slider(); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER void GCodeViewer::init_shaders() { @@ -464,7 +438,6 @@ void GCodeViewer::init_shaders() } } #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool GCodeViewer::init_shaders() { unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); @@ -499,9 +472,7 @@ bool GCodeViewer::init_shaders() return true; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) { @@ -828,9 +799,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool void GCodeViewer::render_toolpaths() const { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ auto set_color = [](GLint current_program_id, const Color& color) { if (current_program_id > 0) { GLint color_id = ::glGetUniformLocation(current_program_id, "uniform_color"); @@ -841,9 +810,7 @@ void GCodeViewer::render_toolpaths() const } BOOST_LOG_TRIVIAL(error) << "Unable to find uniform_color uniform"; }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glCullFace(GL_BACK)); glsafe(::glLineWidth(3.0f)); @@ -863,28 +830,20 @@ void GCodeViewer::render_toolpaths() const if (!buffer.visible) continue; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER GLShaderProgram* shader = wxGetApp().get_shader(buffer.shader.c_str()); if (shader != nullptr) { #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (buffer.shader.is_initialized()) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GCodeProcessor::EMoveType type = buffer_type(i); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader->start_using(); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ buffer.shader.start_using(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.ibo_id)); @@ -893,15 +852,11 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Tool_change: { Color color = { 1.0f, 1.0f, 1.0f }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", color); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ set_color(static_cast(buffer.shader.get_shader_program_id()), color); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ for (const RenderPath& path : buffer.render_paths) { glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); @@ -917,15 +872,11 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Color_change: { Color color = { 1.0f, 0.0f, 0.0f }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", color); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ set_color(static_cast(buffer.shader.get_shader_program_id()), color); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ for (const RenderPath& path : buffer.render_paths) { glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); @@ -941,15 +892,11 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Pause_Print: { Color color = { 0.0f, 1.0f, 0.0f }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", color); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ set_color(static_cast(buffer.shader.get_shader_program_id()), color); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ for (const RenderPath& path : buffer.render_paths) { glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); @@ -965,15 +912,11 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Custom_GCode: { Color color = { 0.0f, 0.0f, 1.0f }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", color); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ set_color(static_cast(buffer.shader.get_shader_program_id()), color); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ for (const RenderPath& path : buffer.render_paths) { glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); @@ -989,15 +932,11 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Retract: { Color color = { 1.0f, 0.0f, 1.0f }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", color); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ set_color(static_cast(buffer.shader.get_shader_program_id()), color); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ for (const RenderPath& path : buffer.render_paths) { glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); @@ -1013,15 +952,11 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Unretract: { Color color = { 0.0f, 1.0f, 1.0f }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", color); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ set_color(static_cast(buffer.shader.get_shader_program_id()), color); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ for (const RenderPath& path : buffer.render_paths) { glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); @@ -1038,15 +973,11 @@ void GCodeViewer::render_toolpaths() const { for (const RenderPath& path : buffer.render_paths) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", path.color); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ set_color(static_cast(buffer.shader.get_shader_program_id()), path.color); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glMultiDrawElements(GL_LINE_STRIP, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_line_strip_calls_count; @@ -1059,15 +990,11 @@ void GCodeViewer::render_toolpaths() const { for (const RenderPath& path : buffer.render_paths) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", path.color); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ set_color(static_cast(buffer.shader.get_shader_program_id()), path.color); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glMultiDrawElements(GL_LINE_STRIP, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_line_strip_calls_count; @@ -1079,15 +1006,11 @@ void GCodeViewer::render_toolpaths() const } glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader->stop_using(); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ buffer.shader.stop_using(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } } @@ -1097,7 +1020,6 @@ void GCodeViewer::render_toolpaths() const void GCodeViewer::render_shells() const { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER if (!m_shells.visible || m_shells.volumes.empty()) return; @@ -1114,7 +1036,6 @@ void GCodeViewer::render_shells() const // glsafe(::glDepthMask(GL_TRUE)); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!m_shells.visible || m_shells.volumes.empty() || !m_shells.shader.is_initialized()) return; @@ -1125,9 +1046,7 @@ void GCodeViewer::render_shells() const m_shells.shader.stop_using(); // glsafe(::glDepthMask(GL_TRUE)); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } void GCodeViewer::render_legend() const diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index df28f4aa63..c1f9cfdd7b 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -2,13 +2,9 @@ #define slic3r_GCodeViewer_hpp_ #if ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "GLShader.hpp" -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "3DScene.hpp" #include "libslic3r/GCode/GCodeProcessor.hpp" #include "GLModel.hpp" @@ -84,27 +80,19 @@ class GCodeViewer { unsigned int ibo_id{ 0 }; size_t indices_count{ 0 }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER std::string shader; #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Shader shader; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::vector paths; std::vector render_paths; bool visible{ false }; void reset(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool init_shader(const std::string& vertex_shader_src, const std::string& fragment_shader_src); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void add_path(const GCodeProcessor::MoveVertex& move, unsigned int i_id, unsigned int s_id); }; @@ -113,13 +101,9 @@ class GCodeViewer { GLVolumeCollection volumes; bool visible{ false }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Shader shader; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ }; // helper to render extrusion paths @@ -229,13 +213,9 @@ public: Transform3f m_world_transform; std::array m_color{ 1.0f, 1.0f, 1.0f, 1.0f }; bool m_visible{ false }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Shader m_shader; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ public: void init(); @@ -250,14 +230,10 @@ public: void render() const; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ private: void init_shader(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ }; struct Endpoints @@ -311,16 +287,12 @@ public: bool init() { set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Extrude, true); m_sequential_view.marker.init(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER init_shaders(); return true; #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ return init_shaders(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } // extract rendering data from the given parameters @@ -364,15 +336,11 @@ public: void enable_legend(bool enable) { m_legend_enabled = enable; } private: -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER void init_shaders(); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool init_shaders(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void load_toolpaths(const GCodeProcessor::Result& gcode_result); void load_shells(const Print& print, bool initialized); void refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index c1c310b34c..51079c892f 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -156,19 +156,15 @@ GLCanvas3D::LayersEditing::~LayersEditing() const float GLCanvas3D::LayersEditing::THICKNESS_BAR_WIDTH = 70.0f; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER void GLCanvas3D::LayersEditing::init() { #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool GLCanvas3D::LayersEditing::init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename) { if (!m_shader.init(vertex_shader_filename, fragment_shader_filename)) return false; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glGenTextures(1, (GLuint*)&m_z_texture_id)); glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id)); @@ -179,13 +175,9 @@ bool GLCanvas3D::LayersEditing::init(const std::string& vertex_shader_filename, glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1)); glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ return true; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } void GLCanvas3D::LayersEditing::set_config(const DynamicPrintConfig* config) @@ -218,15 +210,11 @@ void GLCanvas3D::LayersEditing::select_object(const Model &model, int object_id) bool GLCanvas3D::LayersEditing::is_allowed() const { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER return wxGetApp().get_shader("variable_layer_height") != nullptr && m_z_texture_id > 0; #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ return m_shader.is_initialized() && m_shader.get_shader()->shader_program_id > 0 && m_z_texture_id > 0; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } bool GLCanvas3D::LayersEditing::is_enabled() const @@ -384,15 +372,11 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas) bool GLCanvas3D::LayersEditing::is_initialized() const { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER return wxGetApp().get_shader("variable_layer_height") != nullptr; #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ return m_shader.is_initialized(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } std::string GLCanvas3D::LayersEditing::get_tooltip(const GLCanvas3D& canvas) const @@ -426,7 +410,6 @@ std::string GLCanvas3D::LayersEditing::get_tooltip(const GLCanvas3D& canvas) con void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect) const { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height"); if (shader == nullptr) @@ -440,7 +423,6 @@ void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3 shader->set_uniform("z_cursor_band_width", band_width); shader->set_uniform("object_max_z", m_object_max_z); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_shader.start_using(); m_shader.set_uniform("z_to_texture_row", float(m_layers_texture.cells - 1) / (float(m_layers_texture.width) * m_object_max_z)); @@ -448,9 +430,7 @@ void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3 m_shader.set_uniform("z_cursor", m_object_max_z * this->get_cursor_z_relative(canvas)); m_shader.set_uniform("z_cursor_band_width", band_width); m_shader.set_uniform("object_max_z", m_object_max_z); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id)); @@ -470,15 +450,11 @@ void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3 glsafe(::glEnd()); glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader->stop_using(); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_shader.stop_using(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } void GLCanvas3D::LayersEditing::render_profile(const Rect& bar_rect) const @@ -512,7 +488,6 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G { assert(this->is_allowed()); assert(this->last_object_id != -1); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height"); assert(shader != nullptr); @@ -534,7 +509,6 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G shader->set_uniform("z_cursor", float(m_object_max_z) * float(this->get_cursor_z_relative(canvas))); shader->set_uniform("z_cursor_band_width", float(this->band_width)); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GLint shader_id = m_shader.get_shader()->shader_program_id; assert(shader_id > 0); @@ -565,9 +539,7 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G glsafe(::glUniform1f(z_texture_row_to_normalized_id, GLfloat(1.0f / m_layers_texture.height))); glsafe(::glUniform1f(z_cursor_id, GLfloat(m_object_max_z) * GLfloat(this->get_cursor_z_relative(canvas)))); glsafe(::glUniform1f(z_cursor_band_width_id, GLfloat(this->band_width))); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Initialize the layer height texture mapping. GLsizei w = (GLsizei)m_layers_texture.width; GLsizei h = (GLsizei)m_layers_texture.height; @@ -583,28 +555,22 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G // Render the object using the layer editing shader and texture. if (! glvolume->is_active || glvolume->composite_id.object_id != this->last_object_id || glvolume->is_modifier) continue; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader->set_uniform("volume_world_matrix", glvolume->world_matrix()); shader->set_uniform("object_max_z", GLfloat(0)); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (world_matrix_id != -1) glsafe(::glUniformMatrix4fv(world_matrix_id, 1, GL_FALSE, (const GLfloat*)glvolume->world_matrix().cast().data())); if (object_max_z_id != -1) glsafe(::glUniform1f(object_max_z_id, GLfloat(0))); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glvolume->render(); } // Revert back to the previous shader. glBindTexture(GL_TEXTURE_2D, 0); if (current_program_id > 0) glsafe(::glUseProgram(current_program_id)); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } else { @@ -618,9 +584,7 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G glvolume->render(); } } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } void GLCanvas3D::LayersEditing::adjust_layer_height_profile() @@ -1744,12 +1708,10 @@ bool GLCanvas3D::init() if (m_multisample_allowed) glsafe(::glEnable(GL_MULTISAMPLE)); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER if (m_main_toolbar.is_enabled()) m_layers_editing.init(); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!m_shader.init("gouraud.vs", "gouraud.fs")) { std::cout << "Unable to initialize gouraud shader: please, check that the files gouraud.vs and gouraud.fs are available" << std::endl; @@ -1761,9 +1723,7 @@ bool GLCanvas3D::init() std::cout << "Unable to initialize variable_layer_height shader: please, check that the files variable_layer_height.vs and variable_layer_height.fs are available" << std::endl; return false; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER if (!m_main_toolbar.is_enabled()) @@ -4623,17 +4583,13 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, bool return ret; }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER static const std::array orange = { 0.923f, 0.504f, 0.264f, 1.0f }; static const std::array gray = { 0.64f, 0.64f, 0.64f, 1.0f }; #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ static const GLfloat orange[] = { 0.923f, 0.504f, 0.264f, 1.0f }; static const GLfloat gray[] = { 0.64f, 0.64f, 0.64f, 1.0f }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GLVolumePtrs visible_volumes; @@ -4677,7 +4633,6 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, bool camera.apply_projection(box, near_z, far_z); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER GLShaderProgram* shader = wxGetApp().get_shader("gouraud"); if (shader == nullptr) @@ -4692,7 +4647,6 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, bool shader->start_using(); shader->set_uniform("print_box.volume_detection", 0); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (transparent_background) glsafe(::glClearColor(0.0f, 0.0f, 0.0f, 0.0f)); @@ -4708,37 +4662,27 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, bool if (print_box_detection_id != -1) glsafe(::glUniform1i(print_box_detection_id, 0)); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ for (const GLVolume* vol : visible_volumes) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", (vol->printable && !vol->is_outside) ? orange : gray); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (vol->printable && !vol->is_outside) ? orange : gray)); else glsafe(::glColor4fv((vol->printable && !vol->is_outside) ? orange : gray)); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ vol->render(); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader->stop_using(); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_shader.stop_using(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glDisable(GL_DEPTH_TEST)); @@ -5684,18 +5628,14 @@ void GLCanvas3D::_render_objects() const m_volumes.set_clipping_plane(m_camera_clipping_plane.get_data()); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER GLShaderProgram* shader = wxGetApp().get_shader("gouraud"); if (shader != nullptr) { shader->start_using(); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_shader.start_using(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (m_picking_enabled && !m_gizmos.is_dragging() && m_layers_editing.is_enabled() && (m_layers_editing.last_object_id != -1) && (m_layers_editing.object_max_z() > 0.0f)) { int object_id = m_layers_editing.last_object_id; m_volumes.render(GLVolumeCollection::Opaque, false, wxGetApp().plater()->get_camera().get_view_matrix(), [object_id](const GLVolume& volume) { @@ -5713,16 +5653,12 @@ void GLCanvas3D::_render_objects() const } m_volumes.render(GLVolumeCollection::Transparent, false, wxGetApp().plater()->get_camera().get_view_matrix()); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader->stop_using(); } #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_shader.stop_using(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_camera_clipping_plane = ClippingPlane::ClipsNothing(); } @@ -6142,8 +6078,12 @@ void GLCanvas3D::_render_selection_sidebar_hints() const { #if ENABLE_GCODE_VIEWER m_selection.render_sidebar_hints(m_sidebar_field); +#else +#if ENABLE_SHADERS_MANAGER + m_selection.render_sidebar_hints(m_sidebar_field); #else m_selection.render_sidebar_hints(m_sidebar_field, m_shader); +#endif // ENABLE_SHADERS_MANAGER #endif // ENABLE_GCODE_VIEWER } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 635d23e544..ff775a86e1 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -7,13 +7,9 @@ #include "3DScene.hpp" #include "GLToolbar.hpp" -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "GLShader.hpp" -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "Event.hpp" #include "Selection.hpp" #include "Gizmos/GLGizmosManager.hpp" @@ -173,13 +169,9 @@ private: private: bool m_enabled; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Shader m_shader; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ unsigned int m_z_texture_id; // Not owned by LayersEditing. const DynamicPrintConfig *m_config; @@ -226,15 +218,11 @@ private: LayersEditing(); ~LayersEditing(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER void init(); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void set_config(const DynamicPrintConfig* config); void select_object(const Model &model, int object_id); @@ -477,13 +465,9 @@ private: WarningTexture m_warning_texture; wxTimer m_timer; LayersEditing m_layers_editing; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Shader m_shader; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Mouse m_mouse; mutable GLGizmosManager m_gizmos; mutable GLToolbar m_main_toolbar; @@ -613,13 +597,9 @@ public: void set_color_by(const std::string& value); void refresh_camera_scene_box(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const Shader& get_shader() const { return m_shader; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ BoundingBoxf3 volumes_bounding_box() const; BoundingBoxf3 scene_bounding_box() const; diff --git a/src/slic3r/GUI/GLShader.cpp b/src/slic3r/GUI/GLShader.cpp index 3b7c2abcc6..7aa2aff08a 100644 --- a/src/slic3r/GUI/GLShader.cpp +++ b/src/slic3r/GUI/GLShader.cpp @@ -1,6 +1,4 @@ -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "libslic3r/libslic3r.h" -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "GLShader.hpp" #include "3DScene.hpp" @@ -9,7 +7,6 @@ #include #include -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER #include @@ -283,7 +280,6 @@ int GLShaderProgram::get_uniform_location(const char* name) const } // namespace Slic3r #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include #include #include @@ -642,6 +638,5 @@ void Shader::reset() } } // namespace Slic3r -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ diff --git a/src/slic3r/GUI/GLShader.hpp b/src/slic3r/GUI/GLShader.hpp index a4a8d32cb3..23d04b22c8 100644 --- a/src/slic3r/GUI/GLShader.hpp +++ b/src/slic3r/GUI/GLShader.hpp @@ -1,7 +1,6 @@ #ifndef slic3r_GLShader_hpp_ #define slic3r_GLShader_hpp_ -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER #include #include @@ -58,7 +57,6 @@ public: } // namespace Slic3r #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "libslic3r/libslic3r.h" #include "libslic3r/Point.hpp" @@ -125,8 +123,8 @@ private: }; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + + #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif /* slic3r_GLShader_hpp_ */ diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index d0c1624d7c..c4082cbb21 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -217,15 +217,10 @@ public: void gcode_thumbnails_debug(); #endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER // returns nullptr if not found GLShaderProgram* get_shader(const std::string& shader_name) { return m_opengl_mgr.get_shader(shader_name); } - -// // returns 0 if not found -// unsigned int get_shader_id(const std::string& shader_name) const { return m_opengl_mgr.get_shader_id(shader_name); } #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ private: bool on_init_inner(); diff --git a/src/slic3r/GUI/OpenGLManager.cpp b/src/slic3r/GUI/OpenGLManager.cpp index e4674fffd1..deaa3cd199 100644 --- a/src/slic3r/GUI/OpenGLManager.cpp +++ b/src/slic3r/GUI/OpenGLManager.cpp @@ -28,7 +28,6 @@ namespace Slic3r { namespace GUI { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER // A safe wrapper around glGetString to report a "N/A" string in case glGetString returns nullptr. inline std::string gl_get_string_safe(GLenum param, const std::string& default_value) @@ -37,7 +36,6 @@ inline std::string gl_get_string_safe(GLenum param, const std::string& default_v return std::string((value != nullptr) ? value : default_value); } #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const std::string& OpenGLManager::GLInfo::get_version() const { @@ -96,14 +94,12 @@ float OpenGLManager::GLInfo::get_max_anisotropy() const void OpenGLManager::GLInfo::detect() const { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER m_version = gl_get_string_safe(GL_VERSION, "N/A"); m_glsl_version = gl_get_string_safe(GL_SHADING_LANGUAGE_VERSION, "N/A"); m_vendor = gl_get_string_safe(GL_VENDOR, "N/A"); m_renderer = gl_get_string_safe(GL_RENDERER, "N/A"); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const char* data = (const char*)::glGetString(GL_VERSION); if (data != nullptr) m_version = data; @@ -119,9 +115,7 @@ void OpenGLManager::GLInfo::detect() const data = (const char*)::glGetString(GL_RENDERER); if (data != nullptr) m_renderer = data; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_max_tex_size)); @@ -141,12 +135,10 @@ bool OpenGLManager::GLInfo::is_version_greater_or_equal_to(unsigned int major, u if (!m_detected) detect(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER if (m_version == "N/A") return false; #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::vector tokens; boost::split(tokens, m_version, boost::is_any_of(" "), boost::token_compress_on); @@ -188,34 +180,26 @@ std::string OpenGLManager::GLInfo::to_string(bool format_as_html, bool extension std::string line_end = format_as_html ? "
" : "\n"; out << h2_start << "OpenGL installation" << h2_end << line_end; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER out << b_start << "GL version: " << b_end << m_version << line_end; out << b_start << "Vendor: " << b_end << m_vendor << line_end; out << b_start << "Renderer: " << b_end << m_renderer << line_end; out << b_start << "GLSL version: " << b_end << m_glsl_version << line_end; #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ out << b_start << "GL version: " << b_end << (m_version.empty() ? "N/A" : m_version) << line_end; out << b_start << "Vendor: " << b_end << (m_vendor.empty() ? "N/A" : m_vendor) << line_end; out << b_start << "Renderer: " << b_end << (m_renderer.empty() ? "N/A" : m_renderer) << line_end; out << b_start << "GLSL version: " << b_end << (m_glsl_version.empty() ? "N/A" : m_glsl_version) << line_end; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (extensions) { std::vector extensions_list; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER std::string extensions_str = gl_get_string_safe(GL_EXTENSIONS, ""); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::string extensions_str = (const char*)::glGetString(GL_EXTENSIONS); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ boost::split(extensions_list, extensions_str, boost::is_any_of(" "), boost::token_compress_off); if (!extensions_list.empty()) @@ -247,11 +231,9 @@ OpenGLManager::OSInfo OpenGLManager::s_os_info; OpenGLManager::~OpenGLManager() { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER m_shaders_manager.shutdown(); #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_HACK_CLOSING_ON_OSX_10_9_5 #ifdef __APPLE__ @@ -294,16 +276,12 @@ bool OpenGLManager::init_gl() else s_framebuffers_type = EFramebufferType::Unknown; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER bool valid_version = s_gl_info.is_version_greater_or_equal_to(2, 0); if (!valid_version) { #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!s_gl_info.is_version_greater_or_equal_to(2, 0)) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Complain about the OpenGL version. wxString message = from_u8((boost::format( @@ -318,7 +296,6 @@ bool OpenGLManager::init_gl() wxMessageBox(message, wxString("PrusaSlicer - ") + _L("Unsupported OpenGL version"), wxOK | wxICON_ERROR); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER if (valid_version) { // load shaders @@ -330,7 +307,6 @@ bool OpenGLManager::init_gl() } } #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } return true; diff --git a/src/slic3r/GUI/OpenGLManager.hpp b/src/slic3r/GUI/OpenGLManager.hpp index c80deb6ef1..b645320240 100644 --- a/src/slic3r/GUI/OpenGLManager.hpp +++ b/src/slic3r/GUI/OpenGLManager.hpp @@ -1,11 +1,9 @@ #ifndef slic3r_OpenGLManager_hpp_ #define slic3r_OpenGLManager_hpp_ -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER #include "GLShadersManager.hpp" #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ class wxWindow; class wxGLCanvas; @@ -76,11 +74,9 @@ private: bool m_gl_initialized{ false }; wxGLContext* m_context{ nullptr }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER GLShadersManager m_shaders_manager; #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ static GLInfo s_gl_info; #if ENABLE_HACK_CLOSING_ON_OSX_10_9_5 #ifdef __APPLE__ @@ -99,15 +95,10 @@ public: bool init_gl(); wxGLContext* init_glcontext(wxGLCanvas& canvas); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER // returns nullptr if not found GLShaderProgram* get_shader(const std::string& shader_name) { return m_shaders_manager.get_shader(shader_name); } - -// // returns 0 if not found -// unsigned int get_shader_id(const std::string& shader_name) const { return m_shaders_manager.get_shader_id(shader_name); } #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ static bool are_compressed_textures_supported() { return s_compressed_textures_supported; } static bool can_multisample() { return s_multisample == EMultisampleState::Enabled; } diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 982a16bf00..d3e4e37ef8 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -8,11 +8,6 @@ #include "GUI_ObjectList.hpp" #include "Gizmos/GLGizmoBase.hpp" #include "3DScene.hpp" -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -//#if ENABLE_SHADERS_MANAGER -//#include "GLShader.hpp" -//#endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "Camera.hpp" #include @@ -118,17 +113,13 @@ bool Selection::init() m_arrow.init_from(straight_arrow(10.0f, 5.0f, 5.0f, 10.0f, 1.0f)); m_curved_arrow.init_from(circular_arrow(16, 10.0f, 5.0f, 10.0f, 5.0f, 1.0f)); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!m_arrows_shader.init("gouraud_light.vs", "gouraud_light.fs")) { BOOST_LOG_TRIVIAL(error) << "Unable to initialize gouraud_light shader: please, check that the files gouraud_light.vs and gouraud_light.fs are available"; return false; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #else if (!m_arrow.init()) return false; @@ -1258,22 +1249,23 @@ void Selection::render_center(bool gizmo_is_dragging) const #if ENABLE_GCODE_VIEWER void Selection::render_sidebar_hints(const std::string& sidebar_field) const #else +#if ENABLE_SHADERS_MANAGER +void Selection::render_sidebar_hints(const std::string& sidebar_field) const +#else void Selection::render_sidebar_hints(const std::string& sidebar_field, const Shader& shader) const +#endif // ENABLE_SHADERS_MANAGER #endif // ENABLE_GCODE_VIEWER { if (sidebar_field.empty()) return; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER GLShaderProgram* shader = nullptr; #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!boost::starts_with(sidebar_field, "layer")) { #if ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader = wxGetApp().get_shader("gouraud_light"); if (shader == nullptr) @@ -1281,19 +1273,24 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field, const Sha shader->start_using(); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!m_arrows_shader.is_initialized()) return; m_arrows_shader.start_using(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); +#else +#if ENABLE_SHADERS_MANAGER + shader = wxGetApp().get_shader("gouraud_light"); + if (shader == nullptr) + return; + + shader->start_using(); #else shader.start_using(); - glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); glsafe(::glEnable(GL_LIGHTING)); +#endif // ENABLE_SHADERS_MANAGER + glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); #endif // ENABLE_GCODE_VIEWER } @@ -1351,46 +1348,35 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field, const Sha } if (boost::starts_with(sidebar_field, "position")) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER +#if ENABLE_GCODE_VIEWER render_sidebar_position_hints(sidebar_field, *shader); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ render_sidebar_position_hints(sidebar_field); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_GCODE_VIEWER +#else + render_sidebar_position_hints(sidebar_field); #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ else if (boost::starts_with(sidebar_field, "rotation")) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER +#if ENABLE_GCODE_VIEWER render_sidebar_rotation_hints(sidebar_field, *shader); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ render_sidebar_rotation_hints(sidebar_field); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if ENABLE_GCODE_VIEWER - else if (boost::starts_with(sidebar_field, "scale") || boost::starts_with(sidebar_field, "size")) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if ENABLE_SHADERS_MANAGER -render_sidebar_scale_hints(sidebar_field, *shader); -#else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - render_sidebar_scale_hints(sidebar_field); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - else if (boost::starts_with(sidebar_field, "scale")) - render_sidebar_scale_hints(sidebar_field); - else if (boost::starts_with(sidebar_field, "size")) - render_sidebar_size_hints(sidebar_field); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#else + render_sidebar_rotation_hints(sidebar_field); +#endif // ENABLE_SHADERS_MANAGER + else if (boost::starts_with(sidebar_field, "scale") || boost::starts_with(sidebar_field, "size")) +#if ENABLE_SHADERS_MANAGER +#if ENABLE_GCODE_VIEWER + render_sidebar_scale_hints(sidebar_field, *shader); +#else + render_sidebar_scale_hints(sidebar_field); +#endif // ENABLE_GCODE_VIEWER +#else + render_sidebar_scale_hints(sidebar_field); +#endif // ENABLE_SHADERS_MANAGER else if (boost::starts_with(sidebar_field, "layer")) render_sidebar_layers_hints(sidebar_field); @@ -1399,18 +1385,18 @@ render_sidebar_scale_hints(sidebar_field, *shader); if (!boost::starts_with(sidebar_field, "layer")) { #if ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader->stop_using(); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_arrows_shader.stop_using(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#else +#if ENABLE_SHADERS_MANAGER + shader->stop_using(); #else glsafe(::glDisable(GL_LIGHTING)); shader.stop_using(); +#endif // ENABLE_SHADERS_MANAGER #endif // ENABLE_GCODE_VIEWER } } @@ -2013,74 +1999,54 @@ void Selection::render_bounding_box(const BoundingBoxf3& box, float* color) cons } #if ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER void Selection::render_sidebar_position_hints(const std::string& sidebar_field, GLShaderProgram& shader) const #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void Selection::render_sidebar_position_hints(const std::string& sidebar_field) const -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GLint color_id = ::glGetUniformLocation(m_arrows_shader.get_shader_program_id(), "uniform_color"); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (boost::ends_with(sidebar_field, "x")) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader.set_uniform("uniform_color", AXES_COLOR[0], 4); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[0])); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0)); m_arrow.render(); } else if (boost::ends_with(sidebar_field, "y")) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader.set_uniform("uniform_color", AXES_COLOR[1], 4); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[1])); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_arrow.render(); } else if (boost::ends_with(sidebar_field, "z")) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader.set_uniform("uniform_color", AXES_COLOR[2], 4); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[2])); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); m_arrow.render(); } } #else -void Selection::render_sidebar_position_hints(const std::string & sidebar_field) const +void Selection::render_sidebar_position_hints(const std::string& sidebar_field) const { if (boost::ends_with(sidebar_field, "x")) { @@ -2098,68 +2064,48 @@ void Selection::render_sidebar_position_hints(const std::string & sidebar_field) #endif // ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field, GLShaderProgram& shader) const #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) const -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GLint color_id = ::glGetUniformLocation(m_arrows_shader.get_shader_program_id(), "uniform_color"); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (boost::ends_with(sidebar_field, "x")) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader.set_uniform("uniform_color", AXES_COLOR[0], 4); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[0])); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glRotated(90.0, 0.0, 1.0, 0.0)); render_sidebar_rotation_hint(X); } else if (boost::ends_with(sidebar_field, "y")) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader.set_uniform("uniform_color", AXES_COLOR[1], 4); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[1])); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0)); render_sidebar_rotation_hint(Y); } else if (boost::ends_with(sidebar_field, "z")) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader.set_uniform("uniform_color", AXES_COLOR[2], 4); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[2])); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ render_sidebar_rotation_hint(Z); } @@ -2183,15 +2129,11 @@ void Selection::render_sidebar_rotation_hints(const std::string & sidebar_field) #endif // ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER void Selection::render_sidebar_scale_hints(const std::string& sidebar_field, GLShaderProgram& shader) const #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) const -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { bool uniform_scale = requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling(); @@ -2199,30 +2141,22 @@ void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) con { glsafe(::glPushMatrix()); glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0)); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER render_sidebar_scale_hint(X, shader); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ render_sidebar_scale_hint(X); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glPopMatrix()); } if (boost::ends_with(sidebar_field, "y") || uniform_scale) { glsafe(::glPushMatrix()); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER render_sidebar_scale_hint(Y, shader); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ render_sidebar_scale_hint(Y); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glPopMatrix()); } @@ -2230,15 +2164,11 @@ void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) con { glsafe(::glPushMatrix()); glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER render_sidebar_scale_hint(Z, shader); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ render_sidebar_scale_hint(Z); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glPopMatrix()); } } @@ -2272,17 +2202,6 @@ void Selection::render_sidebar_scale_hints(const std::string & sidebar_field) co } #endif // ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if !ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -void Selection::render_sidebar_size_hints(const std::string& sidebar_field) const -{ - render_sidebar_scale_hints(sidebar_field); -} -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#endif // !ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) const { static const double Margin = 10.0; @@ -2373,29 +2292,25 @@ void Selection::render_sidebar_rotation_hint(Axis axis) const m_curved_arrow.render(); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER +#if ENABLE_GCODE_VIEWER void Selection::render_sidebar_scale_hint(Axis axis, GLShaderProgram& shader) const #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void Selection::render_sidebar_scale_hint(Axis axis) const -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_GCODE_VIEWER +#else +void Selection::render_sidebar_scale_hint(Axis axis) const #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { #if ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER shader.set_uniform("uniform_color", (requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling()) ? UNIFORM_SCALE_COLOR : AXES_COLOR[axis], 4); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GLint color_id = ::glGetUniformLocation(m_arrows_shader.get_shader_program_id(), "uniform_color"); if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling()) ? (const GLfloat*)UNIFORM_SCALE_COLOR : (const GLfloat*)AXES_COLOR[axis])); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #else m_arrow.set_color(((requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling()) ? UNIFORM_SCALE_COLOR : AXES_COLOR[axis]), 3); #endif // ENABLE_GCODE_VIEWER @@ -2408,12 +2323,6 @@ void Selection::render_sidebar_scale_hint(Axis axis) const m_arrow.render(); } -#if !ENABLE_GCODE_VIEWER -void Selection::render_sidebar_size_hint(Axis axis, double length) const -{ -} -#endif // !ENABLE_GCODE_VIEWER - #ifndef NDEBUG static bool is_rotation_xy_synchronized(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to) { diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 7411fc97e5..2f8ffe58c8 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -6,13 +6,13 @@ #include "3DScene.hpp" #if ENABLE_GCODE_VIEWER #include "GLModel.hpp" -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "GLShader.hpp" -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#else +#if !ENABLE_SHADERS_MANAGER +#include "GLShader.hpp" +#endif // !ENABLE_SHADERS_MANAGER #endif // ENABLE_GCODE_VIEWER #if ENABLE_RENDER_SELECTION_CENTER @@ -21,15 +21,12 @@ typedef class GLUquadric GLUquadricObj; #endif // ENABLE_RENDER_SELECTION_CENTER namespace Slic3r { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_GCODE_VIEWER +class Shader; +#endif // !ENABLE_GCODE_VIEWER #if ENABLE_SHADERS_MANAGER class GLShaderProgram; -#else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -class Shader; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ namespace GUI { class TransformationType { @@ -221,13 +218,9 @@ private: #if ENABLE_GCODE_VIEWER GL_Model m_arrow; GL_Model m_curved_arrow; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Shader m_arrows_shader; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #else mutable GLArrow m_arrow; mutable GLCurvedArrow m_curved_arrow; @@ -348,8 +341,12 @@ public: #endif // ENABLE_RENDER_SELECTION_CENTER #if ENABLE_GCODE_VIEWER void render_sidebar_hints(const std::string& sidebar_field) const; +#else +#if ENABLE_SHADERS_MANAGER + void render_sidebar_hints(const std::string& sidebar_field) const; #else void render_sidebar_hints(const std::string& sidebar_field, const Shader& shader) const; +#endif // ENABLE_SHADERS_MANAGER #endif // ENABLE_GCODE_VIEWER bool requires_local_axes() const; @@ -388,43 +385,35 @@ private: void render_selected_volumes() const; void render_synchronized_volumes() const; void render_bounding_box(const BoundingBoxf3& box, float* color) const; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER +#if ENABLE_GCODE_VIEWER void render_sidebar_position_hints(const std::string& sidebar_field, GLShaderProgram& shader) const; void render_sidebar_rotation_hints(const std::string& sidebar_field, GLShaderProgram& shader) const; void render_sidebar_scale_hints(const std::string& sidebar_field, GLShaderProgram& shader) const; #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void render_sidebar_position_hints(const std::string& sidebar_field) const; void render_sidebar_rotation_hints(const std::string& sidebar_field) const; void render_sidebar_scale_hints(const std::string& sidebar_field) const; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_GCODE_VIEWER +#else + void render_sidebar_position_hints(const std::string& sidebar_field) const; + void render_sidebar_rotation_hints(const std::string& sidebar_field) const; + void render_sidebar_scale_hints(const std::string& sidebar_field) const; #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if !ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - void render_sidebar_size_hints(const std::string& sidebar_field) const; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#endif // !ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void render_sidebar_layers_hints(const std::string& sidebar_field) const; #if !ENABLE_GCODE_VIEWER void render_sidebar_position_hint(Axis axis) const; #endif // !ENABLE_GCODE_VIEWER void render_sidebar_rotation_hint(Axis axis) const; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_SHADERS_MANAGER +#if ENABLE_GCODE_VIEWER void render_sidebar_scale_hint(Axis axis, GLShaderProgram& shader) const; #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void render_sidebar_scale_hint(Axis axis) const; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_GCODE_VIEWER +#else + void render_sidebar_scale_hint(Axis axis) const; #endif // ENABLE_SHADERS_MANAGER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if !ENABLE_GCODE_VIEWER - void render_sidebar_size_hint(Axis axis, double length) const; -#endif // !ENABLE_GCODE_VIEWER public: enum SyncRotationType { From 5aa8cc577988ec3f9b335aa6c609b1f5f6c0e88f Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 21 May 2020 10:15:00 +0200 Subject: [PATCH 083/255] ENABLE_SHADERS_MANAGER -> Unified client code of new GLShadersManager and GLShaderProgram classes --- src/slic3r/GUI/3DBed.cpp | 19 +++++++++-- src/slic3r/GUI/3DScene.cpp | 40 +++++++++++++++++++++++ src/slic3r/GUI/3DScene.hpp | 6 ---- src/slic3r/GUI/GLCanvas3D.cpp | 18 ++++++----- src/slic3r/GUI/GLShader.cpp | 50 ++++++++++++++++++++--------- src/slic3r/GUI/GLShader.hpp | 4 ++- src/slic3r/GUI/GLShadersManager.cpp | 14 ++++++++ src/slic3r/GUI/GLShadersManager.hpp | 3 ++ src/slic3r/GUI/GUI_App.hpp | 4 +-- src/slic3r/GUI/OpenGLManager.hpp | 2 +- 10 files changed, 123 insertions(+), 37 deletions(-) diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 73162645fc..3fdcdd6fab 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -196,15 +196,18 @@ void Bed3D::Axes::render() const shader->start_using(); // x axis - shader->set_uniform("uniform_color", { 0.75f, 0.0f, 0.0f, 1.0f }); + std::array color = { 0.75f, 0.0f, 0.0f, 1.0f }; + shader->set_uniform("uniform_color", color); render_axis(Geometry::assemble_transform(m_origin, { 0.0, 0.5 * M_PI, 0.0f }).cast()); // y axis - shader->set_uniform("uniform_color", { 0.0f, 0.75f, 0.0f, 1.0f }); + color = { 0.0f, 0.75f, 0.0f, 1.0f }; + shader->set_uniform("uniform_color", color); render_axis(Geometry::assemble_transform(m_origin, { -0.5 * M_PI, 0.0, 0.0f }).cast()); // z axis - shader->set_uniform("uniform_color", { 0.0f, 0.0f, 0.75f, 1.0f }); + color = { 0.0f, 0.0f, 0.75f, 1.0f }; + shader->set_uniform("uniform_color", color); render_axis(Geometry::assemble_transform(m_origin).cast()); shader->stop_using(); @@ -676,9 +679,19 @@ void Bed3D::render_model() const if (!m_model.get_filename().empty()) { +#if ENABLE_SHADERS_MANAGER + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); + if (shader != nullptr) + { + shader->start_using(); + m_model.render(); + shader->stop_using(); + } +#else glsafe(::glEnable(GL_LIGHTING)); m_model.render(); glsafe(::glDisable(GL_LIGHTING)); +#endif // ENABLE_SHADERS_MANAGER } } diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 29a4b84a30..6e42e52a21 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -1,6 +1,10 @@ #include #include "3DScene.hpp" +#if ENABLE_SHADERS_MANAGER +#include "GLShader.hpp" +#include "GUI_App.hpp" +#endif // ENABLE_SHADERS_MANAGER #include "libslic3r/ExtrusionEntity.hpp" #include "libslic3r/ExtrusionEntityCollection.hpp" @@ -640,6 +644,12 @@ GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCo void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function filter_func) const { +#if ENABLE_SHADERS_MANAGER + GLShaderProgram* shader = GUI::wxGetApp().get_current_shader(); + if (shader == nullptr) + return; +#endif // ENABLE_SHADERS_MANAGER + glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); @@ -650,6 +660,15 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); +#if ENABLE_SHADERS_MANAGER + shader->set_uniform("print_box.min", m_print_box_min, 3); + shader->set_uniform("print_box.max", m_print_box_max, 3); + shader->set_uniform("z_range", m_z_range, 2); + shader->set_uniform("clipping_plane", m_clipping_plane, 4); +#if ENABLE_SLOPE_RENDERING + shader->set_uniform("slope.z_range", m_slope.z_range); +#endif // ENABLE_SLOPE_RENDERING +#else GLint current_program_id; glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id)); GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1; @@ -684,11 +703,19 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab if (slope_z_range_id != -1) glsafe(::glUniform2fv(slope_z_range_id, 1, (const GLfloat*)m_slope.z_range.data())); #endif // ENABLE_SLOPE_RENDERING +#endif // ENABLE_SHADERS_MANAGER GLVolumeWithIdAndZList to_render = volumes_to_render(this->volumes, type, view_matrix, filter_func); for (GLVolumeWithIdAndZ& volume : to_render) { volume.first->set_render_color(); #if ENABLE_SLOPE_RENDERING +#if ENABLE_SHADERS_MANAGER + shader->set_uniform("uniform_color", volume.first->render_color, 4); + shader->set_uniform("print_box.actived", volume.first->shader_outside_printer_detection_enabled); + shader->set_uniform("print_box.volume_world_matrix", volume.first->world_matrix()); + shader->set_uniform("slope.actived", m_slope.active && !volume.first->is_modifier && !volume.first->is_wipe_tower); + shader->set_uniform("slope.volume_world_normal_matrix", volume.first->world_matrix().matrix().block(0, 0, 3, 3).inverse().transpose().cast()); +#else if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)volume.first->render_color)); else @@ -708,6 +735,7 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab Matrix3f normal_matrix = volume.first->world_matrix().matrix().block(0, 0, 3, 3).inverse().transpose().cast(); glsafe(::glUniformMatrix3fv(slope_normal_matrix_id, 1, GL_FALSE, (const GLfloat*)normal_matrix.data())); } +#endif // ENABLE_SHADERS_MANAGER volume.first->render(); #else @@ -1912,6 +1940,12 @@ void GLModel::reset() void GLModel::render() const { +#if ENABLE_SHADERS_MANAGER + GLShaderProgram* shader = GUI::wxGetApp().get_current_shader(); + if (shader == nullptr) + return; +#endif // ENABLE_SHADERS_MANAGER + glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); @@ -1919,16 +1953,22 @@ void GLModel::render() const glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); +#if !ENABLE_SHADERS_MANAGER GLint current_program_id; glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id)); GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1; glcheck(); +#endif // !ENABLE_SHADERS_MANAGER #if ENABLE_SLOPE_RENDERING +#if ENABLE_SHADERS_MANAGER + shader->set_uniform("uniform_color", m_volume.render_color, 4); +#else if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)m_volume.render_color)); else glsafe(::glColor4fv(m_volume.render_color)); +#endif // ENABLE_SHADERS_MANAGER m_volume.render(); #else diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 86072754d7..fd74cd4912 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -26,12 +26,6 @@ inline void glAssertRecentCall() { } #endif namespace Slic3r { -namespace GUI { -class Bed3D; -struct Camera; -class GLToolbar; -} // namespace GUI - class SLAPrintObject; enum SLAPrintObjectStep : unsigned int; class DynamicPrintConfig; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 51079c892f..2eff9ac193 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -490,16 +490,16 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G assert(this->last_object_id != -1); #if ENABLE_SHADERS_MANAGER GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height"); - assert(shader != nullptr); + if (shader == nullptr) + return; - GLint current_program_id = 0; - glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id)); - if (shader->get_id() != static_cast(current_program_id)) + GLShaderProgram* current_shader = wxGetApp().get_current_shader(); + if (shader->get_id() != current_shader->get_id()) // The layer editing shader is not yet active. Activate it. shader->start_using(); else // The layer editing shader was already active. - current_program_id = 0; + current_shader = nullptr; const_cast(this)->generate_layer_height_texture(); @@ -529,7 +529,6 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G GLint object_max_z_id = ::glGetUniformLocation(shader_id, "object_max_z"); glcheck(); - if (z_to_texture_row_id != -1 && z_texture_row_to_normalized_id != -1 && z_cursor_id != -1 && z_cursor_band_width_id != -1 && world_matrix_id != -1) { const_cast(this)->generate_layer_height_texture(); @@ -568,9 +567,12 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G } // Revert back to the previous shader. glBindTexture(GL_TEXTURE_2D, 0); +#if ENABLE_SHADERS_MANAGER + if (current_shader != nullptr) + current_shader->start_using(); +#else if (current_program_id > 0) glsafe(::glUseProgram(current_program_id)); -#if !ENABLE_SHADERS_MANAGER } else { @@ -584,7 +586,7 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G glvolume->render(); } } -#endif // !ENABLE_SHADERS_MANAGER +#endif // ENABLE_SHADERS_MANAGER } void GLCanvas3D::LayersEditing::adjust_layer_height_profile() diff --git a/src/slic3r/GUI/GLShader.cpp b/src/slic3r/GUI/GLShader.cpp index 7aa2aff08a..d0b9267945 100644 --- a/src/slic3r/GUI/GLShader.cpp +++ b/src/slic3r/GUI/GLShader.cpp @@ -6,6 +6,7 @@ #include #include +#include #if ENABLE_SHADERS_MANAGER #include @@ -23,8 +24,7 @@ bool GLShaderProgram::init_from_files(const std::string& name, const ShaderFilen auto load_from_file = [](const std::string& filename) { std::string path = resources_dir() + "/shaders/" + filename; boost::nowide::ifstream s(path, boost::nowide::ifstream::binary); - if (!s.good()) - { + if (!s.good()) { BOOST_LOG_TRIVIAL(error) << "Couldn't open file: '" << path << "'"; return std::string(); } @@ -34,8 +34,7 @@ bool GLShaderProgram::init_from_files(const std::string& name, const ShaderFilen s.seekg(0, s.beg); std::string source(file_length, '\0'); s.read(source.data(), file_length); - if (!s.good()) - { + if (!s.good()) { BOOST_LOG_TRIVIAL(error) << "Error while loading file: '" << path << "'"; return std::string(); } @@ -49,8 +48,9 @@ bool GLShaderProgram::init_from_files(const std::string& name, const ShaderFilen sources[i] = filenames[i].empty() ? std::string() : load_from_file(filenames[i]); } - bool valid = (!sources[static_cast(EShaderType::Vertex)].empty() && !sources[static_cast(EShaderType::Fragment)].empty()) || - !sources[static_cast(EShaderType::Compute)].empty(); + bool valid = !sources[static_cast(EShaderType::Vertex)].empty() && !sources[static_cast(EShaderType::Fragment)].empty() && sources[static_cast(EShaderType::Compute)].empty(); + valid |= !sources[static_cast(EShaderType::Compute)].empty() && sources[static_cast(EShaderType::Vertex)].empty() && sources[static_cast(EShaderType::Fragment)].empty() && + sources[static_cast(EShaderType::Geometry)].empty() && sources[static_cast(EShaderType::TessEvaluation)].empty() && sources[static_cast(EShaderType::TessControl)].empty(); return valid ? init_from_texts(name, sources) : false; } @@ -107,9 +107,11 @@ bool GLShaderProgram::init_from_texts(const std::string& name, const ShaderSourc auto [result, id] = create_shader(type); if (result) shader_ids[i] = id; - else - { + else { BOOST_LOG_TRIVIAL(error) << "glCreateShader() failed for " << shader_type_as_string(type) << " shader of shader program '" << name << "'"; + + // release shaders + release_shaders(shader_ids); return false; } @@ -125,7 +127,7 @@ bool GLShaderProgram::init_from_texts(const std::string& name, const ShaderSourc glsafe(::glGetShaderInfoLog(id, params, ¶ms, msg.data())); BOOST_LOG_TRIVIAL(error) << "Unable to compile " << shader_type_as_string(type) << " shader of shader program '" << name << "':\n" << msg.data(); - // release shader + // release shaders release_shaders(shader_ids); return false; } @@ -173,13 +175,10 @@ bool GLShaderProgram::init_from_texts(const std::string& name, const ShaderSourc return true; } -bool GLShaderProgram::start_using() const +void GLShaderProgram::start_using() const { - if (m_id == 0) - return false; - + assert(m_id > 0); glsafe(::glUseProgram(m_id)); - return true; } void GLShaderProgram::stop_using() const @@ -212,6 +211,16 @@ bool GLShaderProgram::set_uniform(const char* name, float value) const return false; } +bool GLShaderProgram::set_uniform(const char* name, const std::array& value) const +{ + int id = get_uniform_location(name); + if (id >= 0) { + glsafe(::glUniform2fv(id, 1, static_cast(value.data()))); + return true; + } + return false; +} + bool GLShaderProgram::set_uniform(const char* name, const std::array& value) const { int id = get_uniform_location(name); @@ -236,8 +245,7 @@ bool GLShaderProgram::set_uniform(const char* name, const float* value, size_t s { if (size == 1) return set_uniform(name, value[0]); - else if (size < 5) - { + else if (size < 5) { int id = get_uniform_location(name); if (id >= 0) { if (size == 2) @@ -268,6 +276,16 @@ bool GLShaderProgram::set_uniform(const char* name, const Transform3d& value) co return set_uniform(name, value.cast()); } +bool GLShaderProgram::set_uniform(const char* name, const Matrix3f& value) const +{ + int id = get_uniform_location(name); + if (id >= 0) { + glsafe(::glUniformMatrix3fv(id, 1, GL_FALSE, static_cast(value.data()))); + return true; + } + return false; +} + int GLShaderProgram::get_attrib_location(const char* name) const { return (m_id > 0) ? ::glGetAttribLocation(m_id, name) : -1; diff --git a/src/slic3r/GUI/GLShader.hpp b/src/slic3r/GUI/GLShader.hpp index 23d04b22c8..6994b91caf 100644 --- a/src/slic3r/GUI/GLShader.hpp +++ b/src/slic3r/GUI/GLShader.hpp @@ -37,17 +37,19 @@ public: const std::string& get_name() const { return m_name; } unsigned int get_id() const { return m_id; } - bool start_using() const; + void start_using() const; void stop_using() const; bool set_uniform(const char* name, int value) const; bool set_uniform(const char* name, bool value) const; bool set_uniform(const char* name, float value) const; + bool set_uniform(const char* name, const std::array& value) const; bool set_uniform(const char* name, const std::array& value) const; bool set_uniform(const char* name, const std::array& value) const; bool set_uniform(const char* name, const float* value, size_t size) const; bool set_uniform(const char* name, const Transform3f& value) const; bool set_uniform(const char* name, const Transform3d& value) const; + bool set_uniform(const char* name, const Matrix3f& value) const; // returns -1 if not found int get_attrib_location(const char* name) const; diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index e4d6407224..feffaecdee 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -1,9 +1,12 @@ #include "libslic3r/libslic3r.h" #include "GLShadersManager.hpp" +#include "3DScene.hpp" #include #include +#include + #if ENABLE_SHADERS_MANAGER namespace Slic3r { @@ -71,6 +74,17 @@ GLShaderProgram* GLShadersManager::get_shader(const std::string& shader_name) return (it != m_shaders.end()) ? it->get() : nullptr; } +GLShaderProgram* GLShadersManager::get_current_shader() +{ + GLint id = 0; + glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, &id)); + if (id == 0) + return false; + + auto it = std::find_if(m_shaders.begin(), m_shaders.end(), [id](std::unique_ptr& p) { return p->get_id() == id; }); + return (it != m_shaders.end()) ? it->get() : nullptr; +} + } // namespace Slic3r #endif // ENABLE_SHADERS_MANAGER diff --git a/src/slic3r/GUI/GLShadersManager.hpp b/src/slic3r/GUI/GLShadersManager.hpp index 0c624f9161..f30472b123 100644 --- a/src/slic3r/GUI/GLShadersManager.hpp +++ b/src/slic3r/GUI/GLShadersManager.hpp @@ -22,6 +22,9 @@ public: // returns nullptr if not found GLShaderProgram* get_shader(const std::string& shader_name); + + // returns currently active shader, nullptr if none + GLShaderProgram* get_current_shader(); }; } // namespace Slic3r diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index c4082cbb21..9bd8697815 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -218,8 +218,8 @@ public: #endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG #if ENABLE_SHADERS_MANAGER - // returns nullptr if not found GLShaderProgram* get_shader(const std::string& shader_name) { return m_opengl_mgr.get_shader(shader_name); } + GLShaderProgram* get_current_shader() { return m_opengl_mgr.get_current_shader(); } #endif // ENABLE_SHADERS_MANAGER private: @@ -240,6 +240,6 @@ private: DECLARE_APP(GUI_App) } // GUI -} //Slic3r +} // Slic3r #endif // slic3r_GUI_App_hpp_ diff --git a/src/slic3r/GUI/OpenGLManager.hpp b/src/slic3r/GUI/OpenGLManager.hpp index b645320240..fb3b33494b 100644 --- a/src/slic3r/GUI/OpenGLManager.hpp +++ b/src/slic3r/GUI/OpenGLManager.hpp @@ -96,8 +96,8 @@ public: wxGLContext* init_glcontext(wxGLCanvas& canvas); #if ENABLE_SHADERS_MANAGER - // returns nullptr if not found GLShaderProgram* get_shader(const std::string& shader_name) { return m_shaders_manager.get_shader(shader_name); } + GLShaderProgram* get_current_shader() { return m_shaders_manager.get_current_shader(); } #endif // ENABLE_SHADERS_MANAGER static bool are_compressed_textures_supported() { return s_compressed_textures_supported; } From 3bbe2ef9600a03e7e4a4926109c465820274e343 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 21 May 2020 10:27:41 +0200 Subject: [PATCH 084/255] Fixed typo --- src/slic3r/GUI/GLShadersManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index feffaecdee..a3e48ca554 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -79,7 +79,7 @@ GLShaderProgram* GLShadersManager::get_current_shader() GLint id = 0; glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, &id)); if (id == 0) - return false; + return nullptr; auto it = std::find_if(m_shaders.begin(), m_shaders.end(), [id](std::unique_ptr& p) { return p->get_id() == id; }); return (it != m_shaders.end()) ? it->get() : nullptr; From 0d579f5467549ebd4680b0c53e0c8ed42834600f Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 21 May 2020 12:13:24 +0200 Subject: [PATCH 085/255] ENABLE_SHADERS_MANAGER -> Small refactoring --- src/slic3r/GUI/GLShadersManager.cpp | 5 +- src/slic3r/GUI/Selection.cpp | 114 ++++++---------------------- src/slic3r/GUI/Selection.hpp | 20 ----- 3 files changed, 27 insertions(+), 112 deletions(-) diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index a3e48ca554..02d033b5a8 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -30,7 +30,7 @@ std::pair GLShadersManager::init() bool valid = true; - // used to render bed axes, selection hints + // used to render bed axes and model, selection hints, gcode sequential view marker model valid &= append_shader("gouraud_light", { "gouraud_light.vs", "gouraud_light.fs" }); // used to render printbed valid &= append_shader("printbed", { "printbed.vs", "printbed.fs" }); @@ -62,8 +62,7 @@ std::pair GLShadersManager::init() void GLShadersManager::shutdown() { - for (std::unique_ptr& shader : m_shaders) - { + for (std::unique_ptr& shader : m_shaders) { shader.reset(); } } diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index d3e4e37ef8..2949247b80 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1348,35 +1348,11 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field, const Sha } if (boost::starts_with(sidebar_field, "position")) -#if ENABLE_SHADERS_MANAGER -#if ENABLE_GCODE_VIEWER - render_sidebar_position_hints(sidebar_field, *shader); -#else render_sidebar_position_hints(sidebar_field); -#endif // ENABLE_GCODE_VIEWER -#else - render_sidebar_position_hints(sidebar_field); -#endif // ENABLE_SHADERS_MANAGER else if (boost::starts_with(sidebar_field, "rotation")) -#if ENABLE_SHADERS_MANAGER -#if ENABLE_GCODE_VIEWER - render_sidebar_rotation_hints(sidebar_field, *shader); -#else render_sidebar_rotation_hints(sidebar_field); -#endif // ENABLE_GCODE_VIEWER -#else - render_sidebar_rotation_hints(sidebar_field); -#endif // ENABLE_SHADERS_MANAGER else if (boost::starts_with(sidebar_field, "scale") || boost::starts_with(sidebar_field, "size")) -#if ENABLE_SHADERS_MANAGER -#if ENABLE_GCODE_VIEWER - render_sidebar_scale_hints(sidebar_field, *shader); -#else render_sidebar_scale_hints(sidebar_field); -#endif // ENABLE_GCODE_VIEWER -#else - render_sidebar_scale_hints(sidebar_field); -#endif // ENABLE_SHADERS_MANAGER else if (boost::starts_with(sidebar_field, "layer")) render_sidebar_layers_hints(sidebar_field); @@ -1999,12 +1975,16 @@ void Selection::render_bounding_box(const BoundingBoxf3& box, float* color) cons } #if ENABLE_GCODE_VIEWER -#if ENABLE_SHADERS_MANAGER -void Selection::render_sidebar_position_hints(const std::string& sidebar_field, GLShaderProgram& shader) const -#else void Selection::render_sidebar_position_hints(const std::string& sidebar_field) const -#endif // ENABLE_SHADERS_MANAGER { +#if ENABLE_SHADERS_MANAGER + auto set_color = [](Axis axis) { + GLShaderProgram* shader = wxGetApp().get_current_shader(); + if (shader != nullptr) + shader->set_uniform("uniform_color", AXES_COLOR[axis], 4); + }; +#endif // ENABLE_SHADERS_MANAGER + #if !ENABLE_SHADERS_MANAGER GLint color_id = ::glGetUniformLocation(m_arrows_shader.get_shader_program_id(), "uniform_color"); #endif // !ENABLE_SHADERS_MANAGER @@ -2012,7 +1992,7 @@ void Selection::render_sidebar_position_hints(const std::string& sidebar_field) if (boost::ends_with(sidebar_field, "x")) { #if ENABLE_SHADERS_MANAGER - shader.set_uniform("uniform_color", AXES_COLOR[0], 4); + set_color(X); #else if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[0])); @@ -2024,7 +2004,7 @@ void Selection::render_sidebar_position_hints(const std::string& sidebar_field) else if (boost::ends_with(sidebar_field, "y")) { #if ENABLE_SHADERS_MANAGER - shader.set_uniform("uniform_color", AXES_COLOR[1], 4); + set_color(Y); #else if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[1])); @@ -2035,7 +2015,7 @@ void Selection::render_sidebar_position_hints(const std::string& sidebar_field) else if (boost::ends_with(sidebar_field, "z")) { #if ENABLE_SHADERS_MANAGER - shader.set_uniform("uniform_color", AXES_COLOR[2], 4); + set_color(Z); #else if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[2])); @@ -2064,12 +2044,16 @@ void Selection::render_sidebar_position_hints(const std::string& sidebar_field) #endif // ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER -#if ENABLE_SHADERS_MANAGER -void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field, GLShaderProgram& shader) const -#else void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) const -#endif // ENABLE_SHADERS_MANAGER { +#if ENABLE_SHADERS_MANAGER + auto set_color = [](Axis axis) { + GLShaderProgram* shader = wxGetApp().get_current_shader(); + if (shader != nullptr) + shader->set_uniform("uniform_color", AXES_COLOR[axis], 4); + }; +#endif // ENABLE_SHADERS_MANAGER + #if !ENABLE_SHADERS_MANAGER GLint color_id = ::glGetUniformLocation(m_arrows_shader.get_shader_program_id(), "uniform_color"); #endif // !ENABLE_SHADERS_MANAGER @@ -2077,7 +2061,7 @@ void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) if (boost::ends_with(sidebar_field, "x")) { #if ENABLE_SHADERS_MANAGER - shader.set_uniform("uniform_color", AXES_COLOR[0], 4); + set_color(X); #else if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[0])); @@ -2089,7 +2073,7 @@ void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) else if (boost::ends_with(sidebar_field, "y")) { #if ENABLE_SHADERS_MANAGER - shader.set_uniform("uniform_color", AXES_COLOR[1], 4); + set_color(Y); #else if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[1])); @@ -2101,7 +2085,7 @@ void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) else if (boost::ends_with(sidebar_field, "z")) { #if ENABLE_SHADERS_MANAGER - shader.set_uniform("uniform_color", AXES_COLOR[2], 4); + set_color(Z); #else if (color_id >= 0) glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[2])); @@ -2128,52 +2112,7 @@ void Selection::render_sidebar_rotation_hints(const std::string & sidebar_field) } #endif // ENABLE_GCODE_VIEWER -#if ENABLE_GCODE_VIEWER -#if ENABLE_SHADERS_MANAGER -void Selection::render_sidebar_scale_hints(const std::string& sidebar_field, GLShaderProgram& shader) const -#else void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) const -#endif // ENABLE_SHADERS_MANAGER -{ - bool uniform_scale = requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling(); - - if (boost::ends_with(sidebar_field, "x") || uniform_scale) - { - glsafe(::glPushMatrix()); - glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0)); -#if ENABLE_SHADERS_MANAGER - render_sidebar_scale_hint(X, shader); -#else - render_sidebar_scale_hint(X); -#endif // ENABLE_SHADERS_MANAGER - glsafe(::glPopMatrix()); - } - - if (boost::ends_with(sidebar_field, "y") || uniform_scale) - { - glsafe(::glPushMatrix()); -#if ENABLE_SHADERS_MANAGER - render_sidebar_scale_hint(Y, shader); -#else - render_sidebar_scale_hint(Y); -#endif // ENABLE_SHADERS_MANAGER - glsafe(::glPopMatrix()); - } - - if (boost::ends_with(sidebar_field, "z") || uniform_scale) - { - glsafe(::glPushMatrix()); - glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); -#if ENABLE_SHADERS_MANAGER - render_sidebar_scale_hint(Z, shader); -#else - render_sidebar_scale_hint(Z); -#endif // ENABLE_SHADERS_MANAGER - glsafe(::glPopMatrix()); - } -} -#else -void Selection::render_sidebar_scale_hints(const std::string & sidebar_field) const { bool uniform_scale = requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling(); @@ -2200,7 +2139,6 @@ void Selection::render_sidebar_scale_hints(const std::string & sidebar_field) co glsafe(::glPopMatrix()); } } -#endif // ENABLE_GCODE_VIEWER void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) const { @@ -2293,18 +2231,16 @@ void Selection::render_sidebar_rotation_hint(Axis axis) const } #if ENABLE_SHADERS_MANAGER -#if ENABLE_GCODE_VIEWER -void Selection::render_sidebar_scale_hint(Axis axis, GLShaderProgram& shader) const -#else void Selection::render_sidebar_scale_hint(Axis axis) const -#endif // ENABLE_GCODE_VIEWER #else void Selection::render_sidebar_scale_hint(Axis axis) const #endif // ENABLE_SHADERS_MANAGER { #if ENABLE_GCODE_VIEWER #if ENABLE_SHADERS_MANAGER - shader.set_uniform("uniform_color", (requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling()) ? UNIFORM_SCALE_COLOR : AXES_COLOR[axis], 4); + GLShaderProgram* shader = wxGetApp().get_current_shader(); + if (shader != nullptr) + shader->set_uniform("uniform_color", (requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling()) ? UNIFORM_SCALE_COLOR : AXES_COLOR[axis], 4); #else GLint color_id = ::glGetUniformLocation(m_arrows_shader.get_shader_program_id(), "uniform_color"); diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 2f8ffe58c8..5541cc3fa9 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -385,35 +385,15 @@ private: void render_selected_volumes() const; void render_synchronized_volumes() const; void render_bounding_box(const BoundingBoxf3& box, float* color) const; -#if ENABLE_SHADERS_MANAGER -#if ENABLE_GCODE_VIEWER - void render_sidebar_position_hints(const std::string& sidebar_field, GLShaderProgram& shader) const; - void render_sidebar_rotation_hints(const std::string& sidebar_field, GLShaderProgram& shader) const; - void render_sidebar_scale_hints(const std::string& sidebar_field, GLShaderProgram& shader) const; -#else void render_sidebar_position_hints(const std::string& sidebar_field) const; void render_sidebar_rotation_hints(const std::string& sidebar_field) const; void render_sidebar_scale_hints(const std::string& sidebar_field) const; -#endif // ENABLE_GCODE_VIEWER -#else - void render_sidebar_position_hints(const std::string& sidebar_field) const; - void render_sidebar_rotation_hints(const std::string& sidebar_field) const; - void render_sidebar_scale_hints(const std::string& sidebar_field) const; -#endif // ENABLE_SHADERS_MANAGER void render_sidebar_layers_hints(const std::string& sidebar_field) const; #if !ENABLE_GCODE_VIEWER void render_sidebar_position_hint(Axis axis) const; #endif // !ENABLE_GCODE_VIEWER void render_sidebar_rotation_hint(Axis axis) const; -#if ENABLE_SHADERS_MANAGER -#if ENABLE_GCODE_VIEWER - void render_sidebar_scale_hint(Axis axis, GLShaderProgram& shader) const; -#else void render_sidebar_scale_hint(Axis axis) const; -#endif // ENABLE_GCODE_VIEWER -#else - void render_sidebar_scale_hint(Axis axis) const; -#endif // ENABLE_SHADERS_MANAGER public: enum SyncRotationType { From 4eb1b9432f9c90b6d57e96626d6b313e4b686944 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 21 May 2020 13:07:55 +0200 Subject: [PATCH 086/255] Fixed selection of thumbs into gcode sequential view slider --- src/slic3r/GUI/DoubleSlider.cpp | 7 +++++-- src/slic3r/GUI/DoubleSlider.hpp | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index 6173680817..5c16e11eef 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -869,9 +869,12 @@ void Control::draw_cog_icon(wxDC& dc) m_rect_cog_icon = wxRect(x_draw, y_draw, m_cog_icon_dim, m_cog_icon_dim); } -void Control::update_thumb_rect(const wxCoord& begin_x, const wxCoord& begin_y, const SelectedSlider& selection) +void Control::update_thumb_rect(const wxCoord begin_x, const wxCoord begin_y, const SelectedSlider& selection) { - const wxRect& rect = wxRect(begin_x, begin_y + (selection == ssLower ? int(m_thumb_size.y * 0.5) : 0), m_thumb_size.x, int(m_thumb_size.y*0.5)); + const wxRect rect = is_horizontal() ? + wxRect(begin_x + (selection == ssHigher ? m_thumb_size.x / 2 : 0), begin_y, m_thumb_size.x / 2, m_thumb_size.y) : + wxRect(begin_x, begin_y + (selection == ssLower ? m_thumb_size.y / 2 : 0), m_thumb_size.x, m_thumb_size.y / 2); + if (selection == ssLower) m_rect_lower_thumb = rect; else diff --git a/src/slic3r/GUI/DoubleSlider.hpp b/src/slic3r/GUI/DoubleSlider.hpp index 71949f7f3e..7fbcf607ea 100644 --- a/src/slic3r/GUI/DoubleSlider.hpp +++ b/src/slic3r/GUI/DoubleSlider.hpp @@ -283,7 +283,7 @@ protected: void draw_tick_text(wxDC& dc, const wxPoint& pos, int tick, bool right_side = true) const; void draw_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) const; - void update_thumb_rect(const wxCoord& begin_x, const wxCoord& begin_y, const SelectedSlider& selection); + void update_thumb_rect(const wxCoord begin_x, const wxCoord begin_y, const SelectedSlider& selection); bool detect_selected_slider(const wxPoint& pt); void correct_lower_value(); void correct_higher_value(); From 8a9dbb3414d5f9179e4884ef9a6af05ff83a1bc3 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 21 May 2020 13:19:07 +0200 Subject: [PATCH 087/255] ENABLE_SHADERS_MANAGER -> Fixed crash while rendering selection hints --- src/slic3r/GUI/GCodeViewer.cpp | 14 +++++++------- src/slic3r/GUI/Selection.cpp | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index a584dc7eb1..5d298c0ee1 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1108,14 +1108,14 @@ void GCodeViewer::render_legend() const ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); switch (m_view_type) { - case EViewType::FeatureType: { imgui.text(_u8L("Feature type")); break; } - case EViewType::Height: { imgui.text(_u8L("Height (mm)")); break; } - case EViewType::Width: { imgui.text(_u8L("Width (mm)")); break; } - case EViewType::Feedrate: { imgui.text(_u8L("Speed (mm/s)")); break; } - case EViewType::FanSpeed: { imgui.text(_u8L("Fan Speed (%%)")); break; } + case EViewType::FeatureType: { imgui.text(_u8L("Feature type")); break; } + case EViewType::Height: { imgui.text(_u8L("Height (mm)")); break; } + case EViewType::Width: { imgui.text(_u8L("Width (mm)")); break; } + case EViewType::Feedrate: { imgui.text(_u8L("Speed (mm/s)")); break; } + case EViewType::FanSpeed: { imgui.text(_u8L("Fan Speed (%%)")); break; } case EViewType::VolumetricRate: { imgui.text(_u8L("Volumetric flow rate (mm³/s)")); break; } - case EViewType::Tool: { imgui.text(_u8L("Tool")); break; } - case EViewType::ColorPrint: { imgui.text(_u8L("Color Print")); break; } + case EViewType::Tool: { imgui.text(_u8L("Tool")); break; } + case EViewType::ColorPrint: { imgui.text(_u8L("Color Print")); break; } default: { break; } } ImGui::PopStyleColor(); diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 2949247b80..f890f0f012 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -17,7 +17,7 @@ #include #endif // ENABLE_GCODE_VIEWER -static const float UNIFORM_SCALE_COLOR[3] = { 1.0f, 0.38f, 0.0f }; +static const float UNIFORM_SCALE_COLOR[4] = { 0.923f, 0.504f, 0.264f, 1.0f }; namespace Slic3r { namespace GUI { From df010a1d4e26d8279fc61262481c0f33132a3841 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 22 May 2020 09:45:31 +0200 Subject: [PATCH 088/255] Added methods GUI_App::is_gl_version_greater_or_equal_to() and GUI_App::is_glsl_version_greater_or_equal_to() --- src/slic3r/GUI/GUI_App.hpp | 3 +++ src/slic3r/GUI/OpenGLManager.cpp | 25 +++++++++++++++++++------ src/slic3r/GUI/OpenGLManager.hpp | 1 + 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 9bd8697815..cbe2aafe16 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -222,6 +222,9 @@ public: GLShaderProgram* get_current_shader() { return m_opengl_mgr.get_current_shader(); } #endif // ENABLE_SHADERS_MANAGER + bool is_gl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const { return m_opengl_mgr.get_gl_info().is_version_greater_or_equal_to(major, minor); } + bool is_glsl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const { return m_opengl_mgr.get_gl_info().is_glsl_version_greater_or_equal_to(major, minor); } + private: bool on_init_inner(); void init_app_config(); diff --git a/src/slic3r/GUI/OpenGLManager.cpp b/src/slic3r/GUI/OpenGLManager.cpp index deaa3cd199..b21fd01439 100644 --- a/src/slic3r/GUI/OpenGLManager.cpp +++ b/src/slic3r/GUI/OpenGLManager.cpp @@ -130,18 +130,15 @@ void OpenGLManager::GLInfo::detect() const m_detected = true; } -bool OpenGLManager::GLInfo::is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const +static bool version_greater_or_equal_to(const std::string& version, unsigned int major, unsigned int minor) { - if (!m_detected) - detect(); - #if ENABLE_SHADERS_MANAGER - if (m_version == "N/A") + if (version == "N/A") return false; #endif // ENABLE_SHADERS_MANAGER std::vector tokens; - boost::split(tokens, m_version, boost::is_any_of(" "), boost::token_compress_on); + boost::split(tokens, version, boost::is_any_of(" "), boost::token_compress_on); if (tokens.empty()) return false; @@ -166,6 +163,22 @@ bool OpenGLManager::GLInfo::is_version_greater_or_equal_to(unsigned int major, u return gl_minor >= minor; } +bool OpenGLManager::GLInfo::is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const +{ + if (!m_detected) + detect(); + + return version_greater_or_equal_to(m_version, major, minor); +} + +bool OpenGLManager::GLInfo::is_glsl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const +{ + if (!m_detected) + detect(); + + return version_greater_or_equal_to(m_glsl_version, major, minor); +} + std::string OpenGLManager::GLInfo::to_string(bool format_as_html, bool extensions) const { if (!m_detected) diff --git a/src/slic3r/GUI/OpenGLManager.hpp b/src/slic3r/GUI/OpenGLManager.hpp index fb3b33494b..e33df42491 100644 --- a/src/slic3r/GUI/OpenGLManager.hpp +++ b/src/slic3r/GUI/OpenGLManager.hpp @@ -45,6 +45,7 @@ public: float get_max_anisotropy() const; bool is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const; + bool is_glsl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const; std::string to_string(bool format_as_html, bool extensions) const; From 082a30a5db051072c846a94a72270ed4cdcbd89e Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 22 May 2020 09:49:42 +0200 Subject: [PATCH 089/255] ENABLE_SHADERS_MANAGER -> Added method GLShaderProgram::set_uniform(const char* name, double value) --- src/slic3r/GUI/GLShader.cpp | 5 +++++ src/slic3r/GUI/GLShader.hpp | 1 + 2 files changed, 6 insertions(+) diff --git a/src/slic3r/GUI/GLShader.cpp b/src/slic3r/GUI/GLShader.cpp index d0b9267945..38ded63326 100644 --- a/src/slic3r/GUI/GLShader.cpp +++ b/src/slic3r/GUI/GLShader.cpp @@ -211,6 +211,11 @@ bool GLShaderProgram::set_uniform(const char* name, float value) const return false; } +bool GLShaderProgram::set_uniform(const char* name, double value) const +{ + return set_uniform(name, static_cast(value)); +} + bool GLShaderProgram::set_uniform(const char* name, const std::array& value) const { int id = get_uniform_location(name); diff --git a/src/slic3r/GUI/GLShader.hpp b/src/slic3r/GUI/GLShader.hpp index 6994b91caf..91a1f66258 100644 --- a/src/slic3r/GUI/GLShader.hpp +++ b/src/slic3r/GUI/GLShader.hpp @@ -43,6 +43,7 @@ public: bool set_uniform(const char* name, int value) const; bool set_uniform(const char* name, bool value) const; bool set_uniform(const char* name, float value) const; + bool set_uniform(const char* name, double value) const; bool set_uniform(const char* name, const std::array& value) const; bool set_uniform(const char* name, const std::array& value) const; bool set_uniform(const char* name, const std::array& value) const; From f345e583582872c06a4421a377ac70d222ff9abb Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 22 May 2020 09:51:57 +0200 Subject: [PATCH 090/255] Fix in ENABLE_CAMERA_STATISTICS --- src/slic3r/GUI/GLCanvas3D.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 5f9325b14d..5c49eb8295 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2182,7 +2182,7 @@ void GLCanvas3D::render() #endif // ENABLE_RENDER_STATISTICS #if ENABLE_CAMERA_STATISTICS - m_camera.debug_render(); + camera.debug_render(); #endif // ENABLE_CAMERA_STATISTICS std::string tooltip; From 6e279cbec28b6faf2b65b1016341718e0a8bd287 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 22 May 2020 10:43:59 +0200 Subject: [PATCH 091/255] GCodeViewer -> Refactoring of sequential view marker positioning --- src/slic3r/GUI/GCodeViewer.cpp | 8 +++++++- src/slic3r/GUI/GCodeViewer.hpp | 6 ++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 5d298c0ee1..b727388464 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -156,6 +156,12 @@ void GCodeViewer::SequentialView::Marker::init() #endif // !ENABLE_SHADERS_MANAGER } +void GCodeViewer::SequentialView::Marker::set_world_position(const Vec3f& position) +{ + m_world_transform = (Geometry::assemble_transform(position.cast()) * Geometry::assemble_transform(m_model.get_bounding_box().size()[2] * Vec3d::UnitZ(), { M_PI, 0.0, 0.0 })).cast(); + m_world_bounding_box = m_model.get_bounding_box().transformed(m_world_transform.cast()); +} + void GCodeViewer::SequentialView::Marker::render() const { #if ENABLE_SHADERS_MANAGER @@ -346,7 +352,7 @@ void GCodeViewer::render() const glsafe(::glEnable(GL_DEPTH_TEST)); render_toolpaths(); - m_sequential_view.marker.set_world_transform(Geometry::assemble_transform(m_sequential_view.current_position.cast() + (0.5 + 12.0) * Vec3d::UnitZ(), { M_PI, 0.0, 0.0 }).cast()); + m_sequential_view.marker.set_world_position(m_sequential_view.current_position + m_sequential_view_marker_z_offset * Vec3f::UnitZ()); m_sequential_view.marker.render(); render_shells(); render_legend(); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index c1f9cfdd7b..45a87a0069 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -211,6 +211,7 @@ public: { GL_Model m_model; Transform3f m_world_transform; + BoundingBoxf3 m_world_bounding_box; std::array m_color{ 1.0f, 1.0f, 1.0f, 1.0f }; bool m_visible{ false }; #if !ENABLE_SHADERS_MANAGER @@ -220,9 +221,9 @@ public: public: void init(); - const BoundingBoxf3& get_bounding_box() const { return m_model.get_bounding_box(); } + const BoundingBoxf3& get_bounding_box() const { return m_world_bounding_box; } - void set_world_transform(const Transform3f& transform) { m_world_transform = transform; } + void set_world_position(const Vec3f& position); void set_color(const std::array& color) { m_color = color; } bool is_visible() const { return m_visible; } @@ -273,6 +274,7 @@ private: std::vector m_extruder_ids; mutable Extrusions m_extrusions; mutable SequentialView m_sequential_view; + float m_sequential_view_marker_z_offset{ 0.5f }; Shells m_shells; EViewType m_view_type{ EViewType::FeatureType }; bool m_legend_enabled{ true }; From 83ea38c2f31a452d8ad66730398887ed087f79d3 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 22 May 2020 11:52:07 +0200 Subject: [PATCH 092/255] GCodeViewer -> Refactoring of options coloring + options added to legend --- src/slic3r/GUI/GCodeViewer.cpp | 74 +++++++++++++++++++++++++--------- src/slic3r/GUI/GCodeViewer.hpp | 11 +++++ 2 files changed, 67 insertions(+), 18 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index b727388464..453b9ecaeb 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -233,6 +233,15 @@ const std::vector GCodeViewer::Extrusion_Role_Colors {{ { 0.00f, 0.00f, 0.00f } // erMixed }}; +const std::vector GCodeViewer::Options_Colors {{ + { 1.00f, 0.00f, 1.00f }, // Retractions + { 0.00f, 1.00f, 1.00f }, // Unretractions + { 1.00f, 1.00f, 1.00f }, // ToolChanges + { 1.00f, 0.00f, 0.00f }, // ColorChanges + { 0.00f, 1.00f, 0.00f }, // PausePrints + { 0.00f, 0.00f, 1.00f } // CustomGCodes +}}; + const std::vector GCodeViewer::Travel_Colors {{ { 0.0f, 0.0f, 0.5f }, // Move { 0.0f, 0.5f, 0.0f }, // Extrude @@ -857,11 +866,10 @@ void GCodeViewer::render_toolpaths() const { case GCodeProcessor::EMoveType::Tool_change: { - Color color = { 1.0f, 1.0f, 1.0f }; #if ENABLE_SHADERS_MANAGER - shader->set_uniform("uniform_color", color); + shader->set_uniform("uniform_color", Options_Colors[static_cast(EOptionsColors::ToolChanges)]); #else - set_color(static_cast(buffer.shader.get_shader_program_id()), color); + set_color(static_cast(buffer.shader.get_shader_program_id()), Options_Colors[static_cast(EOptionsColors::ToolChanges)]); #endif // ENABLE_SHADERS_MANAGER for (const RenderPath& path : buffer.render_paths) { @@ -877,11 +885,10 @@ void GCodeViewer::render_toolpaths() const } case GCodeProcessor::EMoveType::Color_change: { - Color color = { 1.0f, 0.0f, 0.0f }; #if ENABLE_SHADERS_MANAGER - shader->set_uniform("uniform_color", color); + shader->set_uniform("uniform_color", Options_Colors[static_cast(EOptionsColors::ColorChanges)]); #else - set_color(static_cast(buffer.shader.get_shader_program_id()), color); + set_color(static_cast(buffer.shader.get_shader_program_id()), Options_Colors[static_cast(EOptionsColors::ColorChanges)]); #endif // ENABLE_SHADERS_MANAGER for (const RenderPath& path : buffer.render_paths) { @@ -897,11 +904,10 @@ void GCodeViewer::render_toolpaths() const } case GCodeProcessor::EMoveType::Pause_Print: { - Color color = { 0.0f, 1.0f, 0.0f }; #if ENABLE_SHADERS_MANAGER - shader->set_uniform("uniform_color", color); + shader->set_uniform("uniform_color", Options_Colors[static_cast(EOptionsColors::PausePrints)]); #else - set_color(static_cast(buffer.shader.get_shader_program_id()), color); + set_color(static_cast(buffer.shader.get_shader_program_id()), Options_Colors[static_cast(EOptionsColors::PausePrints)]); #endif // ENABLE_SHADERS_MANAGER for (const RenderPath& path : buffer.render_paths) { @@ -917,11 +923,10 @@ void GCodeViewer::render_toolpaths() const } case GCodeProcessor::EMoveType::Custom_GCode: { - Color color = { 0.0f, 0.0f, 1.0f }; #if ENABLE_SHADERS_MANAGER - shader->set_uniform("uniform_color", color); + shader->set_uniform("uniform_color", Options_Colors[static_cast(EOptionsColors::CustomGCodes)]); #else - set_color(static_cast(buffer.shader.get_shader_program_id()), color); + set_color(static_cast(buffer.shader.get_shader_program_id()), Options_Colors[static_cast(EOptionsColors::CustomGCodes)]); #endif // ENABLE_SHADERS_MANAGER for (const RenderPath& path : buffer.render_paths) { @@ -937,11 +942,10 @@ void GCodeViewer::render_toolpaths() const } case GCodeProcessor::EMoveType::Retract: { - Color color = { 1.0f, 0.0f, 1.0f }; #if ENABLE_SHADERS_MANAGER - shader->set_uniform("uniform_color", color); + shader->set_uniform("uniform_color", Options_Colors[static_cast(EOptionsColors::Retractions)]); #else - set_color(static_cast(buffer.shader.get_shader_program_id()), color); + set_color(static_cast(buffer.shader.get_shader_program_id()), Options_Colors[static_cast(EOptionsColors::Retractions)]); #endif // ENABLE_SHADERS_MANAGER for (const RenderPath& path : buffer.render_paths) { @@ -957,11 +961,10 @@ void GCodeViewer::render_toolpaths() const } case GCodeProcessor::EMoveType::Unretract: { - Color color = { 0.0f, 1.0f, 1.0f }; #if ENABLE_SHADERS_MANAGER - shader->set_uniform("uniform_color", color); + shader->set_uniform("uniform_color", Options_Colors[static_cast(EOptionsColors::Unretractions)]); #else - set_color(static_cast(buffer.shader.get_shader_program_id()), color); + set_color(static_cast(buffer.shader.get_shader_program_id()), Options_Colors[static_cast(EOptionsColors::Unretractions)]); #endif // ENABLE_SHADERS_MANAGER for (const RenderPath& path : buffer.render_paths) { @@ -1279,6 +1282,41 @@ void GCodeViewer::render_legend() const } } + auto any_option_visible = [this]() { + return m_buffers[buffer_id(GCodeProcessor::EMoveType::Color_change)].visible || + m_buffers[buffer_id(GCodeProcessor::EMoveType::Custom_GCode)].visible || + m_buffers[buffer_id(GCodeProcessor::EMoveType::Pause_Print)].visible || + m_buffers[buffer_id(GCodeProcessor::EMoveType::Retract)].visible || + m_buffers[buffer_id(GCodeProcessor::EMoveType::Tool_change)].visible || + m_buffers[buffer_id(GCodeProcessor::EMoveType::Unretract)].visible; + }; + + auto add_option = [this, add_item](GCodeProcessor::EMoveType move_type, EOptionsColors color, const std::string& text) { + const IBuffer& buffer = m_buffers[buffer_id(move_type)]; + if (buffer.visible && buffer.indices_count > 0) + add_item(Options_Colors[static_cast(color)], text); + }; + + // options + if (any_option_visible()) + { + // title + ImGui::Spacing(); + ImGui::Spacing(); + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + imgui.text(_u8L("Options")); + ImGui::PopStyleColor(); + ImGui::Separator(); + + // items + add_option(GCodeProcessor::EMoveType::Retract, EOptionsColors::Retractions, _u8L("Retractions")); + add_option(GCodeProcessor::EMoveType::Unretract, EOptionsColors::Unretractions, _u8L("Unretractions")); + add_option(GCodeProcessor::EMoveType::Tool_change, EOptionsColors::ToolChanges, _u8L("Tool changes")); + add_option(GCodeProcessor::EMoveType::Color_change, EOptionsColors::ColorChanges, _u8L("Color changes")); + add_option(GCodeProcessor::EMoveType::Pause_Print, EOptionsColors::PausePrints, _u8L("Pause prints")); + add_option(GCodeProcessor::EMoveType::Custom_GCode, EOptionsColors::CustomGCodes, _u8L("Custom GCodes")); + } + imgui.end(); ImGui::PopStyleVar(); } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 45a87a0069..72f45aedca 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -22,9 +22,20 @@ class GCodeViewer { using Color = std::array; static const std::vector Extrusion_Role_Colors; + static const std::vector Options_Colors; static const std::vector Travel_Colors; static const std::vector Range_Colors; + enum class EOptionsColors : unsigned char + { + Retractions, + Unretractions, + ToolChanges, + ColorChanges, + PausePrints, + CustomGCodes + }; + // buffer containing vertices data struct VBuffer { From 4d05ec085638d8c5cc94c1291e2c78fed1f6101e Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 22 May 2020 13:21:43 +0200 Subject: [PATCH 093/255] GCodeViewer -> New shaders for options --- resources/shaders/colorchanges.fs | 45 ------------ resources/shaders/colorchanges.vs | 17 ----- resources/shaders/customs.fs | 45 ------------ resources/shaders/customs.vs | 17 ----- resources/shaders/options_110.fs | 8 +++ resources/shaders/options_110.vs | 11 +++ resources/shaders/options_120.fs | 15 ++++ resources/shaders/options_120.vs | 11 +++ resources/shaders/pauses.fs | 45 ------------ resources/shaders/pauses.vs | 17 ----- resources/shaders/retractions.fs | 45 ------------ resources/shaders/retractions.vs | 17 ----- resources/shaders/toolchanges.fs | 45 ------------ resources/shaders/toolchanges.vs | 17 ----- resources/shaders/unretractions.fs | 45 ------------ resources/shaders/unretractions.vs | 17 ----- src/slic3r/GUI/GCodeViewer.cpp | 108 +++++++++++++++++++++------- src/slic3r/GUI/GLShadersManager.cpp | 15 +--- 18 files changed, 132 insertions(+), 408 deletions(-) delete mode 100644 resources/shaders/colorchanges.fs delete mode 100644 resources/shaders/colorchanges.vs delete mode 100644 resources/shaders/customs.fs delete mode 100644 resources/shaders/customs.vs create mode 100644 resources/shaders/options_110.fs create mode 100644 resources/shaders/options_110.vs create mode 100644 resources/shaders/options_120.fs create mode 100644 resources/shaders/options_120.vs delete mode 100644 resources/shaders/pauses.fs delete mode 100644 resources/shaders/pauses.vs delete mode 100644 resources/shaders/retractions.fs delete mode 100644 resources/shaders/retractions.vs delete mode 100644 resources/shaders/toolchanges.fs delete mode 100644 resources/shaders/toolchanges.vs delete mode 100644 resources/shaders/unretractions.fs delete mode 100644 resources/shaders/unretractions.vs diff --git a/resources/shaders/colorchanges.fs b/resources/shaders/colorchanges.fs deleted file mode 100644 index fc81e487fb..0000000000 --- a/resources/shaders/colorchanges.fs +++ /dev/null @@ -1,45 +0,0 @@ -#version 110 - -#define INTENSITY_AMBIENT 0.3 -#define INTENSITY_CORRECTION 0.6 - -// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) -const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); -#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) -#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) -#define LIGHT_TOP_SHININESS 20.0 - -// normalized values for (1./1.43, 0.2/1.43, 1./1.43) -const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0); -#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) - -uniform vec3 uniform_color; - -varying vec3 eye_position; -varying vec3 eye_normal; -//varying float world_normal_z; - -// x = tainted, y = specular; -vec2 intensity; - -void main() -{ - vec3 normal = normalize(eye_normal); - - // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. - // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. - float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0); - - intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; - intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); - - // Perform the same lighting calculation for the 2nd light source (no specular applied). - NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); - intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; - -// // darkens fragments whose normal points downward -// if (world_normal_z < 0.0) -// intensity.x *= (1.0 + world_normal_z * (1.0 - INTENSITY_AMBIENT)); - - gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color * intensity.x, 1.0); -} diff --git a/resources/shaders/colorchanges.vs b/resources/shaders/colorchanges.vs deleted file mode 100644 index 3b78a59700..0000000000 --- a/resources/shaders/colorchanges.vs +++ /dev/null @@ -1,17 +0,0 @@ -#version 110 - -varying vec3 eye_position; -varying vec3 eye_normal; -//// world z component of the normal used to darken the lower side of the toolpaths -//varying float world_normal_z; - -void main() -{ - eye_position = (gl_ModelViewMatrix * gl_Vertex).xyz; - eye_normal = gl_NormalMatrix * vec3(0.0, 0.0, 1.0); -// eye_normal = gl_NormalMatrix * gl_Normal; -// world_normal_z = gl_Normal.z; - gl_Position = ftransform(); - - gl_PointSize = 15.0; -} diff --git a/resources/shaders/customs.fs b/resources/shaders/customs.fs deleted file mode 100644 index fc81e487fb..0000000000 --- a/resources/shaders/customs.fs +++ /dev/null @@ -1,45 +0,0 @@ -#version 110 - -#define INTENSITY_AMBIENT 0.3 -#define INTENSITY_CORRECTION 0.6 - -// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) -const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); -#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) -#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) -#define LIGHT_TOP_SHININESS 20.0 - -// normalized values for (1./1.43, 0.2/1.43, 1./1.43) -const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0); -#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) - -uniform vec3 uniform_color; - -varying vec3 eye_position; -varying vec3 eye_normal; -//varying float world_normal_z; - -// x = tainted, y = specular; -vec2 intensity; - -void main() -{ - vec3 normal = normalize(eye_normal); - - // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. - // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. - float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0); - - intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; - intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); - - // Perform the same lighting calculation for the 2nd light source (no specular applied). - NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); - intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; - -// // darkens fragments whose normal points downward -// if (world_normal_z < 0.0) -// intensity.x *= (1.0 + world_normal_z * (1.0 - INTENSITY_AMBIENT)); - - gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color * intensity.x, 1.0); -} diff --git a/resources/shaders/customs.vs b/resources/shaders/customs.vs deleted file mode 100644 index 3b78a59700..0000000000 --- a/resources/shaders/customs.vs +++ /dev/null @@ -1,17 +0,0 @@ -#version 110 - -varying vec3 eye_position; -varying vec3 eye_normal; -//// world z component of the normal used to darken the lower side of the toolpaths -//varying float world_normal_z; - -void main() -{ - eye_position = (gl_ModelViewMatrix * gl_Vertex).xyz; - eye_normal = gl_NormalMatrix * vec3(0.0, 0.0, 1.0); -// eye_normal = gl_NormalMatrix * gl_Normal; -// world_normal_z = gl_Normal.z; - gl_Position = ftransform(); - - gl_PointSize = 15.0; -} diff --git a/resources/shaders/options_110.fs b/resources/shaders/options_110.fs new file mode 100644 index 0000000000..3722058c87 --- /dev/null +++ b/resources/shaders/options_110.fs @@ -0,0 +1,8 @@ +#version 120 + +uniform vec3 uniform_color; + +void main() +{ + gl_FragColor = vec4(uniform_color, 1.0); +} diff --git a/resources/shaders/options_110.vs b/resources/shaders/options_110.vs new file mode 100644 index 0000000000..5361c88cec --- /dev/null +++ b/resources/shaders/options_110.vs @@ -0,0 +1,11 @@ +#version 110 + +uniform float zoom; +// x = min, y = max +uniform vec2 point_sizes; + +void main() +{ + gl_PointSize = clamp(zoom, point_sizes.x, point_sizes.y); + gl_Position = ftransform(); +} diff --git a/resources/shaders/options_120.fs b/resources/shaders/options_120.fs new file mode 100644 index 0000000000..090cde292f --- /dev/null +++ b/resources/shaders/options_120.fs @@ -0,0 +1,15 @@ +#version 120 + +uniform vec3 uniform_color; + +void main() +{ + vec2 pos = gl_PointCoord - vec2(0.5, 0.5); + float sq_radius = pos.x * pos.x + pos.y * pos.y; + if (sq_radius > 0.25) + discard; + else if (sq_radius > 0.180625) + gl_FragColor = vec4(0.5 * uniform_color, 1.0); + else + gl_FragColor = vec4(uniform_color, 1.0); +} diff --git a/resources/shaders/options_120.vs b/resources/shaders/options_120.vs new file mode 100644 index 0000000000..ebf7428c9a --- /dev/null +++ b/resources/shaders/options_120.vs @@ -0,0 +1,11 @@ +#version 120 + +uniform float zoom; +// x = min, y = max +uniform vec2 point_sizes; + +void main() +{ + gl_PointSize = clamp(zoom, point_sizes.x, point_sizes.y); + gl_Position = ftransform(); +} diff --git a/resources/shaders/pauses.fs b/resources/shaders/pauses.fs deleted file mode 100644 index fc81e487fb..0000000000 --- a/resources/shaders/pauses.fs +++ /dev/null @@ -1,45 +0,0 @@ -#version 110 - -#define INTENSITY_AMBIENT 0.3 -#define INTENSITY_CORRECTION 0.6 - -// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) -const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); -#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) -#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) -#define LIGHT_TOP_SHININESS 20.0 - -// normalized values for (1./1.43, 0.2/1.43, 1./1.43) -const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0); -#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) - -uniform vec3 uniform_color; - -varying vec3 eye_position; -varying vec3 eye_normal; -//varying float world_normal_z; - -// x = tainted, y = specular; -vec2 intensity; - -void main() -{ - vec3 normal = normalize(eye_normal); - - // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. - // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. - float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0); - - intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; - intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); - - // Perform the same lighting calculation for the 2nd light source (no specular applied). - NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); - intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; - -// // darkens fragments whose normal points downward -// if (world_normal_z < 0.0) -// intensity.x *= (1.0 + world_normal_z * (1.0 - INTENSITY_AMBIENT)); - - gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color * intensity.x, 1.0); -} diff --git a/resources/shaders/pauses.vs b/resources/shaders/pauses.vs deleted file mode 100644 index 3b78a59700..0000000000 --- a/resources/shaders/pauses.vs +++ /dev/null @@ -1,17 +0,0 @@ -#version 110 - -varying vec3 eye_position; -varying vec3 eye_normal; -//// world z component of the normal used to darken the lower side of the toolpaths -//varying float world_normal_z; - -void main() -{ - eye_position = (gl_ModelViewMatrix * gl_Vertex).xyz; - eye_normal = gl_NormalMatrix * vec3(0.0, 0.0, 1.0); -// eye_normal = gl_NormalMatrix * gl_Normal; -// world_normal_z = gl_Normal.z; - gl_Position = ftransform(); - - gl_PointSize = 15.0; -} diff --git a/resources/shaders/retractions.fs b/resources/shaders/retractions.fs deleted file mode 100644 index fc81e487fb..0000000000 --- a/resources/shaders/retractions.fs +++ /dev/null @@ -1,45 +0,0 @@ -#version 110 - -#define INTENSITY_AMBIENT 0.3 -#define INTENSITY_CORRECTION 0.6 - -// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) -const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); -#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) -#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) -#define LIGHT_TOP_SHININESS 20.0 - -// normalized values for (1./1.43, 0.2/1.43, 1./1.43) -const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0); -#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) - -uniform vec3 uniform_color; - -varying vec3 eye_position; -varying vec3 eye_normal; -//varying float world_normal_z; - -// x = tainted, y = specular; -vec2 intensity; - -void main() -{ - vec3 normal = normalize(eye_normal); - - // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. - // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. - float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0); - - intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; - intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); - - // Perform the same lighting calculation for the 2nd light source (no specular applied). - NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); - intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; - -// // darkens fragments whose normal points downward -// if (world_normal_z < 0.0) -// intensity.x *= (1.0 + world_normal_z * (1.0 - INTENSITY_AMBIENT)); - - gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color * intensity.x, 1.0); -} diff --git a/resources/shaders/retractions.vs b/resources/shaders/retractions.vs deleted file mode 100644 index 3b78a59700..0000000000 --- a/resources/shaders/retractions.vs +++ /dev/null @@ -1,17 +0,0 @@ -#version 110 - -varying vec3 eye_position; -varying vec3 eye_normal; -//// world z component of the normal used to darken the lower side of the toolpaths -//varying float world_normal_z; - -void main() -{ - eye_position = (gl_ModelViewMatrix * gl_Vertex).xyz; - eye_normal = gl_NormalMatrix * vec3(0.0, 0.0, 1.0); -// eye_normal = gl_NormalMatrix * gl_Normal; -// world_normal_z = gl_Normal.z; - gl_Position = ftransform(); - - gl_PointSize = 15.0; -} diff --git a/resources/shaders/toolchanges.fs b/resources/shaders/toolchanges.fs deleted file mode 100644 index fc81e487fb..0000000000 --- a/resources/shaders/toolchanges.fs +++ /dev/null @@ -1,45 +0,0 @@ -#version 110 - -#define INTENSITY_AMBIENT 0.3 -#define INTENSITY_CORRECTION 0.6 - -// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) -const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); -#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) -#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) -#define LIGHT_TOP_SHININESS 20.0 - -// normalized values for (1./1.43, 0.2/1.43, 1./1.43) -const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0); -#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) - -uniform vec3 uniform_color; - -varying vec3 eye_position; -varying vec3 eye_normal; -//varying float world_normal_z; - -// x = tainted, y = specular; -vec2 intensity; - -void main() -{ - vec3 normal = normalize(eye_normal); - - // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. - // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. - float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0); - - intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; - intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); - - // Perform the same lighting calculation for the 2nd light source (no specular applied). - NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); - intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; - -// // darkens fragments whose normal points downward -// if (world_normal_z < 0.0) -// intensity.x *= (1.0 + world_normal_z * (1.0 - INTENSITY_AMBIENT)); - - gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color * intensity.x, 1.0); -} diff --git a/resources/shaders/toolchanges.vs b/resources/shaders/toolchanges.vs deleted file mode 100644 index 3b78a59700..0000000000 --- a/resources/shaders/toolchanges.vs +++ /dev/null @@ -1,17 +0,0 @@ -#version 110 - -varying vec3 eye_position; -varying vec3 eye_normal; -//// world z component of the normal used to darken the lower side of the toolpaths -//varying float world_normal_z; - -void main() -{ - eye_position = (gl_ModelViewMatrix * gl_Vertex).xyz; - eye_normal = gl_NormalMatrix * vec3(0.0, 0.0, 1.0); -// eye_normal = gl_NormalMatrix * gl_Normal; -// world_normal_z = gl_Normal.z; - gl_Position = ftransform(); - - gl_PointSize = 15.0; -} diff --git a/resources/shaders/unretractions.fs b/resources/shaders/unretractions.fs deleted file mode 100644 index fc81e487fb..0000000000 --- a/resources/shaders/unretractions.fs +++ /dev/null @@ -1,45 +0,0 @@ -#version 110 - -#define INTENSITY_AMBIENT 0.3 -#define INTENSITY_CORRECTION 0.6 - -// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) -const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); -#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) -#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) -#define LIGHT_TOP_SHININESS 20.0 - -// normalized values for (1./1.43, 0.2/1.43, 1./1.43) -const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0); -#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) - -uniform vec3 uniform_color; - -varying vec3 eye_position; -varying vec3 eye_normal; -//varying float world_normal_z; - -// x = tainted, y = specular; -vec2 intensity; - -void main() -{ - vec3 normal = normalize(eye_normal); - - // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. - // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. - float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0); - - intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; - intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); - - // Perform the same lighting calculation for the 2nd light source (no specular applied). - NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); - intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; - -// // darkens fragments whose normal points downward -// if (world_normal_z < 0.0) -// intensity.x *= (1.0 + world_normal_z * (1.0 - INTENSITY_AMBIENT)); - - gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color * intensity.x, 1.0); -} diff --git a/resources/shaders/unretractions.vs b/resources/shaders/unretractions.vs deleted file mode 100644 index 3b78a59700..0000000000 --- a/resources/shaders/unretractions.vs +++ /dev/null @@ -1,17 +0,0 @@ -#version 110 - -varying vec3 eye_position; -varying vec3 eye_normal; -//// world z component of the normal used to darken the lower side of the toolpaths -//varying float world_normal_z; - -void main() -{ - eye_position = (gl_ModelViewMatrix * gl_Vertex).xyz; - eye_normal = gl_NormalMatrix * vec3(0.0, 0.0, 1.0); -// eye_normal = gl_NormalMatrix * gl_Normal; -// world_normal_z = gl_Normal.z; - gl_Position = ftransform(); - - gl_PointSize = 15.0; -} diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 453b9ecaeb..cf2f689cef 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -440,12 +440,12 @@ void GCodeViewer::init_shaders() { switch (buffer_type(i)) { - case GCodeProcessor::EMoveType::Tool_change: { m_buffers[i].shader = "toolchanges"; break; } - case GCodeProcessor::EMoveType::Color_change: { m_buffers[i].shader = "colorchanges"; break; } - case GCodeProcessor::EMoveType::Pause_Print: { m_buffers[i].shader = "pauses"; break; } - case GCodeProcessor::EMoveType::Custom_GCode: { m_buffers[i].shader = "customs"; break; } - case GCodeProcessor::EMoveType::Retract: { m_buffers[i].shader = "retractions"; break; } - case GCodeProcessor::EMoveType::Unretract: { m_buffers[i].shader = "unretractions"; break; } + case GCodeProcessor::EMoveType::Tool_change: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110"; break; } + case GCodeProcessor::EMoveType::Color_change: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110"; break; } + case GCodeProcessor::EMoveType::Pause_Print: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110"; break; } + case GCodeProcessor::EMoveType::Custom_GCode: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110"; break; } + case GCodeProcessor::EMoveType::Retract: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110"; break; } + case GCodeProcessor::EMoveType::Unretract: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110"; break; } case GCodeProcessor::EMoveType::Extrude: { m_buffers[i].shader = "extrusions"; break; } case GCodeProcessor::EMoveType::Travel: { m_buffers[i].shader = "travels"; break; } default: { break; } @@ -827,6 +827,12 @@ void GCodeViewer::render_toolpaths() const }; #endif // !ENABLE_SHADERS_MANAGER + bool is_glsl_120 = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20); + int detected_point_sizes[2]; + ::glGetIntegerv(GL_ALIASED_POINT_SIZE_RANGE, detected_point_sizes); + std::array point_sizes = { 2.0f, std::min(64.0f, static_cast(detected_point_sizes[1])) }; + double zoom = wxGetApp().plater()->get_camera().get_zoom(); + glsafe(::glCullFace(GL_BACK)); glsafe(::glLineWidth(3.0f)); @@ -868,94 +874,139 @@ void GCodeViewer::render_toolpaths() const { #if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", Options_Colors[static_cast(EOptionsColors::ToolChanges)]); + shader->set_uniform("zoom", zoom); + shader->set_uniform("point_sizes", point_sizes); + if (is_glsl_120) + { + glsafe(::glEnable(GL_POINT_SPRITE)); + glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); + } #else set_color(static_cast(buffer.shader.get_shader_program_id()), Options_Colors[static_cast(EOptionsColors::ToolChanges)]); #endif // ENABLE_SHADERS_MANAGER for (const RenderPath& path : buffer.render_paths) { - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); - #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } + if (is_glsl_120) + { + glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); + glsafe(::glDisable(GL_POINT_SPRITE)); + } break; } case GCodeProcessor::EMoveType::Color_change: { #if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", Options_Colors[static_cast(EOptionsColors::ColorChanges)]); + shader->set_uniform("zoom", zoom); + shader->set_uniform("point_sizes", point_sizes); + if (is_glsl_120) + { + glsafe(::glEnable(GL_POINT_SPRITE)); + glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); + } #else set_color(static_cast(buffer.shader.get_shader_program_id()), Options_Colors[static_cast(EOptionsColors::ColorChanges)]); #endif // ENABLE_SHADERS_MANAGER for (const RenderPath& path : buffer.render_paths) { - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); - #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } + if (is_glsl_120) + { + glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); + glsafe(::glDisable(GL_POINT_SPRITE)); + } break; } case GCodeProcessor::EMoveType::Pause_Print: { #if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", Options_Colors[static_cast(EOptionsColors::PausePrints)]); + shader->set_uniform("zoom", zoom); + shader->set_uniform("point_sizes", point_sizes); + if (is_glsl_120) + { + glsafe(::glEnable(GL_POINT_SPRITE)); + glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); + } #else set_color(static_cast(buffer.shader.get_shader_program_id()), Options_Colors[static_cast(EOptionsColors::PausePrints)]); #endif // ENABLE_SHADERS_MANAGER for (const RenderPath& path : buffer.render_paths) { - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); - #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } + if (is_glsl_120) + { + glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); + glsafe(::glDisable(GL_POINT_SPRITE)); + } break; } case GCodeProcessor::EMoveType::Custom_GCode: { #if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", Options_Colors[static_cast(EOptionsColors::CustomGCodes)]); + shader->set_uniform("zoom", zoom); + shader->set_uniform("point_sizes", point_sizes); + if (is_glsl_120) + { + glsafe(::glEnable(GL_POINT_SPRITE)); + glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); + } #else set_color(static_cast(buffer.shader.get_shader_program_id()), Options_Colors[static_cast(EOptionsColors::CustomGCodes)]); #endif // ENABLE_SHADERS_MANAGER for (const RenderPath& path : buffer.render_paths) { - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); - #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } + if (is_glsl_120) + { + glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); + glsafe(::glDisable(GL_POINT_SPRITE)); + } break; } case GCodeProcessor::EMoveType::Retract: { #if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", Options_Colors[static_cast(EOptionsColors::Retractions)]); + shader->set_uniform("zoom", zoom); + shader->set_uniform("point_sizes", point_sizes); + if (is_glsl_120) + { + glsafe(::glEnable(GL_POINT_SPRITE)); + glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); + } #else set_color(static_cast(buffer.shader.get_shader_program_id()), Options_Colors[static_cast(EOptionsColors::Retractions)]); #endif // ENABLE_SHADERS_MANAGER for (const RenderPath& path : buffer.render_paths) { - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); - #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS + if (is_glsl_120) + { + glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); + glsafe(::glDisable(GL_POINT_SPRITE)); + } } break; } @@ -963,19 +1014,28 @@ void GCodeViewer::render_toolpaths() const { #if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", Options_Colors[static_cast(EOptionsColors::Unretractions)]); + shader->set_uniform("zoom", zoom); + shader->set_uniform("point_sizes", point_sizes); + if (is_glsl_120) + { + glsafe(::glEnable(GL_POINT_SPRITE)); + glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); + } #else set_color(static_cast(buffer.shader.get_shader_program_id()), Options_Colors[static_cast(EOptionsColors::Unretractions)]); #endif // ENABLE_SHADERS_MANAGER for (const RenderPath& path : buffer.render_paths) { - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); - #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } + if (is_glsl_120) + { + glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); + glsafe(::glDisable(GL_POINT_SPRITE)); + } break; } case GCodeProcessor::EMoveType::Extrude: diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index 02d033b5a8..6df8c75208 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -34,18 +34,9 @@ std::pair GLShadersManager::init() valid &= append_shader("gouraud_light", { "gouraud_light.vs", "gouraud_light.fs" }); // used to render printbed valid &= append_shader("printbed", { "printbed.vs", "printbed.fs" }); - // used to render tool changes in gcode preview - valid &= append_shader("toolchanges", { "toolchanges.vs", "toolchanges.fs" }); - // used to render color changes in gcode preview - valid &= append_shader("colorchanges", { "colorchanges.vs", "colorchanges.fs" }); - // used to render pause prints in gcode preview - valid &= append_shader("pauses", { "pauses.vs", "pauses.fs" }); - // used to render custom gcode points in gcode preview - valid &= append_shader("customs", { "customs.vs", "customs.fs" }); - // used to render retractions in gcode preview - valid &= append_shader("retractions", { "retractions.vs", "retractions.fs" }); - // used to render unretractions in gcode preview - valid &= append_shader("unretractions", { "unretractions.vs", "unretractions.fs" }); + // used to render options in gcode preview + valid &= append_shader("options_110", { "options_110.vs", "options_110.fs" }); + valid &= append_shader("options_120", { "options_120.vs", "options_120.fs" }); // used to render extrusion paths in gcode preview valid &= append_shader("extrusions", { "extrusions.vs", "extrusions.fs" }); // used to render travel paths in gcode preview From 314995fa0b5a9a0d49178cf934a0ea418991f93d Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 22 May 2020 16:08:02 +0200 Subject: [PATCH 094/255] ENABLE_SHADERS_MANAGER set as default --- resources/shaders/options_120.fs | 2 +- src/libslic3r/Technologies.hpp | 3 - src/slic3r/GUI/3DBed.cpp | 58 +---- src/slic3r/GUI/3DBed.hpp | 9 - src/slic3r/GUI/3DScene.cpp | 80 ------ src/slic3r/GUI/GCodeViewer.cpp | 150 +----------- src/slic3r/GUI/GCodeViewer.hpp | 29 --- src/slic3r/GUI/GLCanvas3D.cpp | 233 +++--------------- src/slic3r/GUI/GLCanvas3D.hpp | 17 +- src/slic3r/GUI/GLShader.cpp | 362 ---------------------------- src/slic3r/GUI/GLShader.hpp | 71 ------ src/slic3r/GUI/GLShadersManager.cpp | 3 - src/slic3r/GUI/GLShadersManager.hpp | 4 - src/slic3r/GUI/GUI_App.hpp | 2 - src/slic3r/GUI/OpenGLManager.cpp | 45 +--- src/slic3r/GUI/OpenGLManager.hpp | 6 - src/slic3r/GUI/Selection.cpp | 161 ++----------- src/slic3r/GUI/Selection.hpp | 20 -- 18 files changed, 57 insertions(+), 1198 deletions(-) diff --git a/resources/shaders/options_120.fs b/resources/shaders/options_120.fs index 090cde292f..5f699f9204 100644 --- a/resources/shaders/options_120.fs +++ b/resources/shaders/options_120.fs @@ -8,7 +8,7 @@ void main() float sq_radius = pos.x * pos.x + pos.y * pos.y; if (sq_radius > 0.25) discard; - else if (sq_radius > 0.180625) + else if ((sq_radius < 0.005625) || (sq_radius > 0.180625)) gl_FragColor = vec4(0.5 * uniform_color, 1.0); else gl_FragColor = vec4(uniform_color, 1.0); diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index d0673e2b4b..3df9da961d 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -46,7 +46,4 @@ #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) #define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) -// Enable the OpenGL shaders manager -#define ENABLE_SHADERS_MANAGER (1 && ENABLE_2_3_0_ALPHA1) - #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 3fdcdd6fab..b5a34b2ee7 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -163,14 +163,7 @@ Bed3D::Axes::~Axes() void Bed3D::Axes::render() const { #if ENABLE_GCODE_VIEWER -#if ENABLE_SHADERS_MANAGER auto render_axis = [this](const Transform3f& transform) { -#else - auto render_axis = [this](const Transform3f& transform, GLint color_id, const std::array& color) { - if (color_id >= 0) - glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)color.data())); -#endif // ENABLE_SHADERS_MANAGER - glsafe(::glPushMatrix()); glsafe(::glMultMatrixf(transform.data())); m_arrow.render(); @@ -178,21 +171,13 @@ void Bed3D::Axes::render() const }; m_arrow.init_from(stilized_arrow(16, DefaultTipRadius, DefaultTipLength, DefaultStemRadius, m_stem_length)); -#if ENABLE_SHADERS_MANAGER + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); if (shader == nullptr) return; -#else - if (!m_shader.init("gouraud_light.vs", "gouraud_light.fs")) - BOOST_LOG_TRIVIAL(error) << "Unable to initialize gouraud_light shader: please, check that the files gouraud_light.vs and gouraud_light.fs are available"; - - if (!m_shader.is_initialized()) - return; -#endif // ENABLE_SHADERS_MANAGER glsafe(::glEnable(GL_DEPTH_TEST)); -#if ENABLE_SHADERS_MANAGER shader->start_using(); // x axis @@ -211,21 +196,6 @@ void Bed3D::Axes::render() const render_axis(Geometry::assemble_transform(m_origin).cast()); shader->stop_using(); -#else - m_shader.start_using(); - GLint color_id = ::glGetUniformLocation(m_shader.get_shader_program_id(), "uniform_color"); - - // x axis - render_axis(Geometry::assemble_transform(m_origin, { 0.0, 0.5 * M_PI, 0.0f }).cast(), color_id, { 0.75f, 0.0f, 0.0f, 1.0f }); - - // y axis - render_axis(Geometry::assemble_transform(m_origin, { -0.5 * M_PI, 0.0, 0.0f }).cast(), color_id, { 0.0f, 0.75f, 0.0f, 1.0f }); - - // z axis - render_axis(Geometry::assemble_transform(m_origin).cast(), color_id, { 0.0f, 0.0f, 0.75f, 1.0f }); - - m_shader.stop_using(); -#endif // ENABLE_SHADERS_MANAGER glsafe(::glDisable(GL_DEPTH_TEST)); #else @@ -571,23 +541,12 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const if (m_triangles.get_vertices_count() > 0) { -#if ENABLE_SHADERS_MANAGER GLShaderProgram* shader = wxGetApp().get_shader("printbed"); if (shader != nullptr) { shader->start_using(); shader->set_uniform("transparent_background", bottom); shader->set_uniform("svg_source", boost::algorithm::iends_with(m_texture.get_source(), ".svg")); -#else - if (m_shader.get_shader_program_id() == 0) - m_shader.init("printbed.vs", "printbed.fs"); - - if (m_shader.is_initialized()) - { - m_shader.start_using(); - m_shader.set_uniform("transparent_background", bottom); - m_shader.set_uniform("svg_source", boost::algorithm::iends_with(m_texture.get_source(), ".svg")); -#endif // ENABLE_SHADERS_MANAGER if (m_vbo_id == 0) { @@ -608,13 +567,8 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const unsigned int stride = m_triangles.get_vertex_data_size(); -#if ENABLE_SHADERS_MANAGER GLint position_id = shader->get_attrib_location("v_position"); GLint tex_coords_id = shader->get_attrib_location("v_tex_coords"); -#else - GLint position_id = m_shader.get_attrib_location("v_position"); - GLint tex_coords_id = m_shader.get_attrib_location("v_tex_coords"); -#endif // ENABLE_SHADERS_MANAGER // show the temporary texture while no compressed data is available GLuint tex_id = (GLuint)m_temp_texture.get_id(); @@ -652,11 +606,7 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const glsafe(::glDisable(GL_BLEND)); glsafe(::glDepthMask(GL_TRUE)); -#if ENABLE_SHADERS_MANAGER shader->stop_using(); -#else - m_shader.stop_using(); -#endif // ENABLE_SHADERS_MANAGER } } } @@ -679,7 +629,6 @@ void Bed3D::render_model() const if (!m_model.get_filename().empty()) { -#if ENABLE_SHADERS_MANAGER GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); if (shader != nullptr) { @@ -687,11 +636,6 @@ void Bed3D::render_model() const m_model.render(); shader->stop_using(); } -#else - glsafe(::glEnable(GL_LIGHTING)); - m_model.render(); - glsafe(::glDisable(GL_LIGHTING)); -#endif // ENABLE_SHADERS_MANAGER } } diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp index d9a2c82620..2487be2e47 100644 --- a/src/slic3r/GUI/3DBed.hpp +++ b/src/slic3r/GUI/3DBed.hpp @@ -3,9 +3,6 @@ #include "GLTexture.hpp" #include "3DScene.hpp" -#if !ENABLE_SHADERS_MANAGER -#include "GLShader.hpp" -#endif // !ENABLE_SHADERS_MANAGER #if ENABLE_GCODE_VIEWER #include "GLModel.hpp" #endif // ENABLE_GCODE_VIEWER @@ -71,9 +68,6 @@ class Bed3D Vec3d m_origin{ Vec3d::Zero() }; float m_stem_length{ DefaultStemLength }; mutable GL_Model m_arrow; -#if !ENABLE_SHADERS_MANAGER - mutable Shader m_shader; -#endif // !ENABLE_SHADERS_MANAGER public: #else @@ -122,9 +116,6 @@ private: mutable GLBed m_model; // temporary texture shown until the main texture has still no levels compressed mutable GLTexture m_temp_texture; -#if !ENABLE_SHADERS_MANAGER - mutable Shader m_shader; -#endif // !ENABLE_SHADERS_MANAGER mutable unsigned int m_vbo_id; Axes m_axes; diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 6e42e52a21..fb7d4c24cf 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -1,10 +1,8 @@ #include #include "3DScene.hpp" -#if ENABLE_SHADERS_MANAGER #include "GLShader.hpp" #include "GUI_App.hpp" -#endif // ENABLE_SHADERS_MANAGER #include "libslic3r/ExtrusionEntity.hpp" #include "libslic3r/ExtrusionEntityCollection.hpp" @@ -644,11 +642,9 @@ GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCo void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function filter_func) const { -#if ENABLE_SHADERS_MANAGER GLShaderProgram* shader = GUI::wxGetApp().get_current_shader(); if (shader == nullptr) return; -#endif // ENABLE_SHADERS_MANAGER glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); @@ -660,7 +656,6 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); -#if ENABLE_SHADERS_MANAGER shader->set_uniform("print_box.min", m_print_box_min, 3); shader->set_uniform("print_box.max", m_print_box_max, 3); shader->set_uniform("z_range", m_z_range, 2); @@ -668,74 +663,16 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab #if ENABLE_SLOPE_RENDERING shader->set_uniform("slope.z_range", m_slope.z_range); #endif // ENABLE_SLOPE_RENDERING -#else - GLint current_program_id; - glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id)); - GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1; - GLint z_range_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "z_range") : -1; - GLint clipping_plane_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "clipping_plane") : -1; - - GLint print_box_min_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.min") : -1; - GLint print_box_max_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.max") : -1; - GLint print_box_active_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.actived") : -1; - GLint print_box_worldmatrix_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.volume_world_matrix") : -1; - -#if ENABLE_SLOPE_RENDERING - GLint slope_active_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "slope.actived") : -1; - GLint slope_normal_matrix_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "slope.volume_world_normal_matrix") : -1; - GLint slope_z_range_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "slope.z_range") : -1; -#endif // ENABLE_SLOPE_RENDERING - glcheck(); - - if (print_box_min_id != -1) - glsafe(::glUniform3fv(print_box_min_id, 1, (const GLfloat*)m_print_box_min)); - - if (print_box_max_id != -1) - glsafe(::glUniform3fv(print_box_max_id, 1, (const GLfloat*)m_print_box_max)); - - if (z_range_id != -1) - glsafe(::glUniform2fv(z_range_id, 1, (const GLfloat*)m_z_range)); - - if (clipping_plane_id != -1) - glsafe(::glUniform4fv(clipping_plane_id, 1, (const GLfloat*)m_clipping_plane)); - -#if ENABLE_SLOPE_RENDERING - if (slope_z_range_id != -1) - glsafe(::glUniform2fv(slope_z_range_id, 1, (const GLfloat*)m_slope.z_range.data())); -#endif // ENABLE_SLOPE_RENDERING -#endif // ENABLE_SHADERS_MANAGER GLVolumeWithIdAndZList to_render = volumes_to_render(this->volumes, type, view_matrix, filter_func); for (GLVolumeWithIdAndZ& volume : to_render) { volume.first->set_render_color(); #if ENABLE_SLOPE_RENDERING -#if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", volume.first->render_color, 4); shader->set_uniform("print_box.actived", volume.first->shader_outside_printer_detection_enabled); shader->set_uniform("print_box.volume_world_matrix", volume.first->world_matrix()); shader->set_uniform("slope.actived", m_slope.active && !volume.first->is_modifier && !volume.first->is_wipe_tower); shader->set_uniform("slope.volume_world_normal_matrix", volume.first->world_matrix().matrix().block(0, 0, 3, 3).inverse().transpose().cast()); -#else - if (color_id >= 0) - glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)volume.first->render_color)); - else - glsafe(::glColor4fv(volume.first->render_color)); - - if (print_box_active_id != -1) - glsafe(::glUniform1i(print_box_active_id, volume.first->shader_outside_printer_detection_enabled ? 1 : 0)); - - if (print_box_worldmatrix_id != -1) - glsafe(::glUniformMatrix4fv(print_box_worldmatrix_id, 1, GL_FALSE, (const GLfloat*)volume.first->world_matrix().cast().data())); - - if (slope_active_id != -1) - glsafe(::glUniform1i(slope_active_id, m_slope.active && !volume.first->is_modifier && !volume.first->is_wipe_tower ? 1 : 0)); - - if (slope_normal_matrix_id != -1) - { - Matrix3f normal_matrix = volume.first->world_matrix().matrix().block(0, 0, 3, 3).inverse().transpose().cast(); - glsafe(::glUniformMatrix3fv(slope_normal_matrix_id, 1, GL_FALSE, (const GLfloat*)normal_matrix.data())); - } -#endif // ENABLE_SHADERS_MANAGER volume.first->render(); #else @@ -1940,11 +1877,9 @@ void GLModel::reset() void GLModel::render() const { -#if ENABLE_SHADERS_MANAGER GLShaderProgram* shader = GUI::wxGetApp().get_current_shader(); if (shader == nullptr) return; -#endif // ENABLE_SHADERS_MANAGER glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); @@ -1953,23 +1888,8 @@ void GLModel::render() const glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); -#if !ENABLE_SHADERS_MANAGER - GLint current_program_id; - glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id)); - GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1; - glcheck(); -#endif // !ENABLE_SHADERS_MANAGER - #if ENABLE_SLOPE_RENDERING -#if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", m_volume.render_color, 4); -#else - if (color_id >= 0) - glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)m_volume.render_color)); - else - glsafe(::glColor4fv(m_volume.render_color)); -#endif // ENABLE_SHADERS_MANAGER - m_volume.render(); #else m_volume.render(color_id, -1, -1); diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index cf2f689cef..c2e680b0eb 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -107,18 +107,6 @@ void GCodeViewer::IBuffer::reset() render_paths = std::vector(); } -#if !ENABLE_SHADERS_MANAGER -bool GCodeViewer::IBuffer::init_shader(const std::string& vertex_shader_src, const std::string& fragment_shader_src) -{ - if (!shader.init(vertex_shader_src, fragment_shader_src)) { - BOOST_LOG_TRIVIAL(error) << "Unable to initialize toolpaths shader: please, check that the files " << vertex_shader_src << " and " << fragment_shader_src << " are available"; - return false; - } - - return true; -} -#endif // !ENABLE_SHADERS_MANAGER - void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move, unsigned int i_id, unsigned int s_id) { Path::Endpoint endpoint = { i_id, s_id, move.position }; @@ -151,9 +139,6 @@ GCodeViewer::Color GCodeViewer::Extrusions::Range::get_color_at(float value) con void GCodeViewer::SequentialView::Marker::init() { m_model.init_from(stilized_arrow(16, 2.0f, 4.0f, 1.0f, 8.0f)); -#if !ENABLE_SHADERS_MANAGER - init_shader(); -#endif // !ENABLE_SHADERS_MANAGER } void GCodeViewer::SequentialView::Marker::set_world_position(const Vec3f& position) @@ -164,7 +149,6 @@ void GCodeViewer::SequentialView::Marker::set_world_position(const Vec3f& positi void GCodeViewer::SequentialView::Marker::render() const { -#if ENABLE_SHADERS_MANAGER if (!m_visible) return; @@ -177,18 +161,6 @@ void GCodeViewer::SequentialView::Marker::render() const shader->start_using(); shader->set_uniform("uniform_color", m_color); -#else - if (!m_visible || !m_shader.is_initialized()) - return; - - glsafe(::glEnable(GL_BLEND)); - glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); - - m_shader.start_using(); - GLint color_id = ::glGetUniformLocation(m_shader.get_shader_program_id(), "uniform_color"); - if (color_id >= 0) - glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)m_color.data())); -#endif // ENABLE_SHADERS_MANAGER glsafe(::glPushMatrix()); glsafe(::glMultMatrixf(m_world_transform.data())); @@ -197,23 +169,11 @@ void GCodeViewer::SequentialView::Marker::render() const glsafe(::glPopMatrix()); -#if ENABLE_SHADERS_MANAGER shader->stop_using(); -#else - m_shader.stop_using(); -#endif // ENABLE_SHADERS_MANAGER glsafe(::glDisable(GL_BLEND)); } -#if !ENABLE_SHADERS_MANAGER -void GCodeViewer::SequentialView::Marker::init_shader() -{ - if (!m_shader.init("gouraud_light.vs", "gouraud_light.fs")) - BOOST_LOG_TRIVIAL(error) << "Unable to initialize gouraud_light shader: please, check that the files gouraud_light.vs and gouraud_light.fs are available"; -} -#endif // !ENABLE_SHADERS_MANAGER - const std::vector GCodeViewer::Extrusion_Role_Colors {{ { 0.50f, 0.50f, 0.50f }, // erNone { 1.00f, 1.00f, 0.40f }, // erPerimeter @@ -430,7 +390,6 @@ void GCodeViewer::set_layers_z_range(const std::array& layers_z_range wxGetApp().plater()->update_preview_moves_slider(); } -#if ENABLE_SHADERS_MANAGER void GCodeViewer::init_shaders() { unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); @@ -452,42 +411,6 @@ void GCodeViewer::init_shaders() } } } -#else -bool GCodeViewer::init_shaders() -{ - unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); - unsigned char end_id = buffer_id(GCodeProcessor::EMoveType::Count); - - for (unsigned char i = begin_id; i < end_id; ++i) - { - std::string vertex_shader; - std::string fragment_shader; - - switch (buffer_type(i)) - { - case GCodeProcessor::EMoveType::Tool_change: { vertex_shader = "toolchanges.vs"; fragment_shader = "toolchanges.fs"; break; } - case GCodeProcessor::EMoveType::Color_change: { vertex_shader = "colorchanges.vs"; fragment_shader = "colorchanges.fs"; break; } - case GCodeProcessor::EMoveType::Pause_Print: { vertex_shader = "pauses.vs"; fragment_shader = "pauses.fs"; break; } - case GCodeProcessor::EMoveType::Custom_GCode: { vertex_shader = "customs.vs"; fragment_shader = "customs.fs"; break; } - case GCodeProcessor::EMoveType::Retract: { vertex_shader = "retractions.vs"; fragment_shader = "retractions.fs"; break; } - case GCodeProcessor::EMoveType::Unretract: { vertex_shader = "unretractions.vs"; fragment_shader = "unretractions.fs"; break; } - case GCodeProcessor::EMoveType::Extrude: { vertex_shader = "extrusions.vs"; fragment_shader = "extrusions.fs"; break; } - case GCodeProcessor::EMoveType::Travel: { vertex_shader = "travels.vs"; fragment_shader = "travels.fs"; break; } - default: { break; } - } - - if (vertex_shader.empty() || fragment_shader.empty() || !m_buffers[i].init_shader(vertex_shader, fragment_shader)) - return false; - } - - if (!m_shells.shader.init("shells.vs", "shells.fs")) { - BOOST_LOG_TRIVIAL(error) << "Unable to initialize shells shader: please, check that the files shells.vs and shells.fs are available"; - return false; - } - - return true; -} -#endif // ENABLE_SHADERS_MANAGER void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) { @@ -814,19 +737,6 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool void GCodeViewer::render_toolpaths() const { -#if !ENABLE_SHADERS_MANAGER - auto set_color = [](GLint current_program_id, const Color& color) { - if (current_program_id > 0) { - GLint color_id = ::glGetUniformLocation(current_program_id, "uniform_color"); - if (color_id >= 0) { - glsafe(::glUniform3fv(color_id, 1, (const GLfloat*)color.data())); - return; - } - } - BOOST_LOG_TRIVIAL(error) << "Unable to find uniform_color uniform"; - }; -#endif // !ENABLE_SHADERS_MANAGER - bool is_glsl_120 = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20); int detected_point_sizes[2]; ::glGetIntegerv(GL_ALIASED_POINT_SIZE_RANGE, detected_point_sizes); @@ -851,28 +761,18 @@ void GCodeViewer::render_toolpaths() const if (!buffer.visible) continue; -#if ENABLE_SHADERS_MANAGER GLShaderProgram* shader = wxGetApp().get_shader(buffer.shader.c_str()); if (shader != nullptr) { -#else - if (buffer.shader.is_initialized()) { -#endif // ENABLE_SHADERS_MANAGER + shader->start_using(); GCodeProcessor::EMoveType type = buffer_type(i); -#if ENABLE_SHADERS_MANAGER - shader->start_using(); -#else - buffer.shader.start_using(); -#endif // ENABLE_SHADERS_MANAGER - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.ibo_id)); switch (type) { case GCodeProcessor::EMoveType::Tool_change: { -#if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", Options_Colors[static_cast(EOptionsColors::ToolChanges)]); shader->set_uniform("zoom", zoom); shader->set_uniform("point_sizes", point_sizes); @@ -881,9 +781,6 @@ void GCodeViewer::render_toolpaths() const glsafe(::glEnable(GL_POINT_SPRITE)); glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); } -#else - set_color(static_cast(buffer.shader.get_shader_program_id()), Options_Colors[static_cast(EOptionsColors::ToolChanges)]); -#endif // ENABLE_SHADERS_MANAGER for (const RenderPath& path : buffer.render_paths) { glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); @@ -900,7 +797,6 @@ void GCodeViewer::render_toolpaths() const } case GCodeProcessor::EMoveType::Color_change: { -#if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", Options_Colors[static_cast(EOptionsColors::ColorChanges)]); shader->set_uniform("zoom", zoom); shader->set_uniform("point_sizes", point_sizes); @@ -909,9 +805,6 @@ void GCodeViewer::render_toolpaths() const glsafe(::glEnable(GL_POINT_SPRITE)); glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); } -#else - set_color(static_cast(buffer.shader.get_shader_program_id()), Options_Colors[static_cast(EOptionsColors::ColorChanges)]); -#endif // ENABLE_SHADERS_MANAGER for (const RenderPath& path : buffer.render_paths) { glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); @@ -928,7 +821,6 @@ void GCodeViewer::render_toolpaths() const } case GCodeProcessor::EMoveType::Pause_Print: { -#if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", Options_Colors[static_cast(EOptionsColors::PausePrints)]); shader->set_uniform("zoom", zoom); shader->set_uniform("point_sizes", point_sizes); @@ -937,9 +829,6 @@ void GCodeViewer::render_toolpaths() const glsafe(::glEnable(GL_POINT_SPRITE)); glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); } -#else - set_color(static_cast(buffer.shader.get_shader_program_id()), Options_Colors[static_cast(EOptionsColors::PausePrints)]); -#endif // ENABLE_SHADERS_MANAGER for (const RenderPath& path : buffer.render_paths) { glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); @@ -956,7 +845,6 @@ void GCodeViewer::render_toolpaths() const } case GCodeProcessor::EMoveType::Custom_GCode: { -#if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", Options_Colors[static_cast(EOptionsColors::CustomGCodes)]); shader->set_uniform("zoom", zoom); shader->set_uniform("point_sizes", point_sizes); @@ -965,9 +853,6 @@ void GCodeViewer::render_toolpaths() const glsafe(::glEnable(GL_POINT_SPRITE)); glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); } -#else - set_color(static_cast(buffer.shader.get_shader_program_id()), Options_Colors[static_cast(EOptionsColors::CustomGCodes)]); -#endif // ENABLE_SHADERS_MANAGER for (const RenderPath& path : buffer.render_paths) { glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); @@ -984,7 +869,6 @@ void GCodeViewer::render_toolpaths() const } case GCodeProcessor::EMoveType::Retract: { -#if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", Options_Colors[static_cast(EOptionsColors::Retractions)]); shader->set_uniform("zoom", zoom); shader->set_uniform("point_sizes", point_sizes); @@ -993,9 +877,6 @@ void GCodeViewer::render_toolpaths() const glsafe(::glEnable(GL_POINT_SPRITE)); glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); } -#else - set_color(static_cast(buffer.shader.get_shader_program_id()), Options_Colors[static_cast(EOptionsColors::Retractions)]); -#endif // ENABLE_SHADERS_MANAGER for (const RenderPath& path : buffer.render_paths) { glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); @@ -1012,7 +893,6 @@ void GCodeViewer::render_toolpaths() const } case GCodeProcessor::EMoveType::Unretract: { -#if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", Options_Colors[static_cast(EOptionsColors::Unretractions)]); shader->set_uniform("zoom", zoom); shader->set_uniform("point_sizes", point_sizes); @@ -1021,9 +901,6 @@ void GCodeViewer::render_toolpaths() const glsafe(::glEnable(GL_POINT_SPRITE)); glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); } -#else - set_color(static_cast(buffer.shader.get_shader_program_id()), Options_Colors[static_cast(EOptionsColors::Unretractions)]); -#endif // ENABLE_SHADERS_MANAGER for (const RenderPath& path : buffer.render_paths) { glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); @@ -1042,11 +919,7 @@ void GCodeViewer::render_toolpaths() const { for (const RenderPath& path : buffer.render_paths) { -#if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", path.color); -#else - set_color(static_cast(buffer.shader.get_shader_program_id()), path.color); -#endif // ENABLE_SHADERS_MANAGER glsafe(::glMultiDrawElements(GL_LINE_STRIP, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_line_strip_calls_count; @@ -1059,11 +932,7 @@ void GCodeViewer::render_toolpaths() const { for (const RenderPath& path : buffer.render_paths) { -#if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", path.color); -#else - set_color(static_cast(buffer.shader.get_shader_program_id()), path.color); -#endif // ENABLE_SHADERS_MANAGER glsafe(::glMultiDrawElements(GL_LINE_STRIP, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_line_strip_calls_count; @@ -1075,11 +944,7 @@ void GCodeViewer::render_toolpaths() const } glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); -#if ENABLE_SHADERS_MANAGER shader->stop_using(); -#else - buffer.shader.stop_using(); -#endif // ENABLE_SHADERS_MANAGER } } @@ -1089,7 +954,6 @@ void GCodeViewer::render_toolpaths() const void GCodeViewer::render_shells() const { -#if ENABLE_SHADERS_MANAGER if (!m_shells.visible || m_shells.volumes.empty()) return; @@ -1104,18 +968,6 @@ void GCodeViewer::render_shells() const shader->stop_using(); // glsafe(::glDepthMask(GL_TRUE)); -#else - if (!m_shells.visible || m_shells.volumes.empty() || !m_shells.shader.is_initialized()) - return; - -// glsafe(::glDepthMask(GL_FALSE)); - - m_shells.shader.start_using(); - m_shells.volumes.render(GLVolumeCollection::Transparent, true, wxGetApp().plater()->get_camera().get_view_matrix()); - m_shells.shader.stop_using(); - -// glsafe(::glDepthMask(GL_TRUE)); -#endif // ENABLE_SHADERS_MANAGER } void GCodeViewer::render_legend() const diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 72f45aedca..5ab9f68325 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -2,9 +2,6 @@ #define slic3r_GCodeViewer_hpp_ #if ENABLE_GCODE_VIEWER -#if !ENABLE_SHADERS_MANAGER -#include "GLShader.hpp" -#endif // !ENABLE_SHADERS_MANAGER #include "3DScene.hpp" #include "libslic3r/GCode/GCodeProcessor.hpp" #include "GLModel.hpp" @@ -91,19 +88,12 @@ class GCodeViewer { unsigned int ibo_id{ 0 }; size_t indices_count{ 0 }; -#if ENABLE_SHADERS_MANAGER std::string shader; -#else - Shader shader; -#endif // ENABLE_SHADERS_MANAGER std::vector paths; std::vector render_paths; bool visible{ false }; void reset(); -#if !ENABLE_SHADERS_MANAGER - bool init_shader(const std::string& vertex_shader_src, const std::string& fragment_shader_src); -#endif // !ENABLE_SHADERS_MANAGER void add_path(const GCodeProcessor::MoveVertex& move, unsigned int i_id, unsigned int s_id); }; @@ -112,9 +102,6 @@ class GCodeViewer { GLVolumeCollection volumes; bool visible{ false }; -#if !ENABLE_SHADERS_MANAGER - Shader shader; -#endif // !ENABLE_SHADERS_MANAGER }; // helper to render extrusion paths @@ -225,9 +212,6 @@ public: BoundingBoxf3 m_world_bounding_box; std::array m_color{ 1.0f, 1.0f, 1.0f, 1.0f }; bool m_visible{ false }; -#if !ENABLE_SHADERS_MANAGER - Shader m_shader; -#endif // !ENABLE_SHADERS_MANAGER public: void init(); @@ -241,11 +225,6 @@ public: void set_visible(bool visible) { m_visible = visible; } void render() const; - -#if !ENABLE_SHADERS_MANAGER - private: - void init_shader(); -#endif // !ENABLE_SHADERS_MANAGER }; struct Endpoints @@ -300,12 +279,8 @@ public: bool init() { set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Extrude, true); m_sequential_view.marker.init(); -#if ENABLE_SHADERS_MANAGER init_shaders(); return true; -#else - return init_shaders(); -#endif // ENABLE_SHADERS_MANAGER } // extract rendering data from the given parameters @@ -349,11 +324,7 @@ public: void enable_legend(bool enable) { m_legend_enabled = enable; } private: -#if ENABLE_SHADERS_MANAGER void init_shaders(); -#else - bool init_shaders(); -#endif // ENABLE_SHADERS_MANAGER void load_toolpaths(const GCodeProcessor::Result& gcode_result); void load_shells(const Print& print, bool initialized); void refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 5c49eb8295..3a0958b109 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -156,16 +156,8 @@ GLCanvas3D::LayersEditing::~LayersEditing() const float GLCanvas3D::LayersEditing::THICKNESS_BAR_WIDTH = 70.0f; -#if ENABLE_SHADERS_MANAGER void GLCanvas3D::LayersEditing::init() { -#else -bool GLCanvas3D::LayersEditing::init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename) -{ - if (!m_shader.init(vertex_shader_filename, fragment_shader_filename)) - return false; -#endif // ENABLE_SHADERS_MANAGER - glsafe(::glGenTextures(1, (GLuint*)&m_z_texture_id)); glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id)); glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)); @@ -174,10 +166,6 @@ bool GLCanvas3D::LayersEditing::init(const std::string& vertex_shader_filename, glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST)); glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1)); glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); - -#if !ENABLE_SHADERS_MANAGER - return true; -#endif // !ENABLE_SHADERS_MANAGER } void GLCanvas3D::LayersEditing::set_config(const DynamicPrintConfig* config) @@ -210,11 +198,7 @@ void GLCanvas3D::LayersEditing::select_object(const Model &model, int object_id) bool GLCanvas3D::LayersEditing::is_allowed() const { -#if ENABLE_SHADERS_MANAGER return wxGetApp().get_shader("variable_layer_height") != nullptr && m_z_texture_id > 0; -#else - return m_shader.is_initialized() && m_shader.get_shader()->shader_program_id > 0 && m_z_texture_id > 0; -#endif // ENABLE_SHADERS_MANAGER } bool GLCanvas3D::LayersEditing::is_enabled() const @@ -372,11 +356,7 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas) bool GLCanvas3D::LayersEditing::is_initialized() const { -#if ENABLE_SHADERS_MANAGER return wxGetApp().get_shader("variable_layer_height") != nullptr; -#else - return m_shader.is_initialized(); -#endif // ENABLE_SHADERS_MANAGER } std::string GLCanvas3D::LayersEditing::get_tooltip(const GLCanvas3D& canvas) const @@ -410,7 +390,6 @@ std::string GLCanvas3D::LayersEditing::get_tooltip(const GLCanvas3D& canvas) con void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect) const { -#if ENABLE_SHADERS_MANAGER GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height"); if (shader == nullptr) return; @@ -422,15 +401,6 @@ void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3 shader->set_uniform("z_cursor", m_object_max_z * this->get_cursor_z_relative(canvas)); shader->set_uniform("z_cursor_band_width", band_width); shader->set_uniform("object_max_z", m_object_max_z); -#else - m_shader.start_using(); - - m_shader.set_uniform("z_to_texture_row", float(m_layers_texture.cells - 1) / (float(m_layers_texture.width) * m_object_max_z)); - m_shader.set_uniform("z_texture_row_to_normalized", 1.0f / (float)m_layers_texture.height); - m_shader.set_uniform("z_cursor", m_object_max_z * this->get_cursor_z_relative(canvas)); - m_shader.set_uniform("z_cursor_band_width", band_width); - m_shader.set_uniform("object_max_z", m_object_max_z); -#endif // ENABLE_SHADERS_MANAGER glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id)); @@ -450,11 +420,7 @@ void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3 glsafe(::glEnd()); glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); -#if ENABLE_SHADERS_MANAGER shader->stop_using(); -#else - m_shader.stop_using(); -#endif // ENABLE_SHADERS_MANAGER } void GLCanvas3D::LayersEditing::render_profile(const Rect& bar_rect) const @@ -488,7 +454,6 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G { assert(this->is_allowed()); assert(this->last_object_id != -1); -#if ENABLE_SHADERS_MANAGER GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height"); if (shader == nullptr) return; @@ -508,85 +473,31 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G shader->set_uniform("z_texture_row_to_normalized", 1.0f / float(m_layers_texture.height)); shader->set_uniform("z_cursor", float(m_object_max_z) * float(this->get_cursor_z_relative(canvas))); shader->set_uniform("z_cursor_band_width", float(this->band_width)); -#else - GLint shader_id = m_shader.get_shader()->shader_program_id; - assert(shader_id > 0); - GLint current_program_id; - glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id)); - if (shader_id > 0 && shader_id != current_program_id) - // The layer editing shader is not yet active. Activate it. - glsafe(::glUseProgram(shader_id)); - else - // The layer editing shader was already active. - current_program_id = -1; + // Initialize the layer height texture mapping. + GLsizei w = (GLsizei)m_layers_texture.width; + GLsizei h = (GLsizei)m_layers_texture.height; + GLsizei half_w = w / 2; + GLsizei half_h = h / 2; + glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); + glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id)); + glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0)); + glsafe(::glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, half_w, half_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0)); + glsafe(::glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, m_layers_texture.data.data())); + glsafe(::glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, half_w, half_h, GL_RGBA, GL_UNSIGNED_BYTE, m_layers_texture.data.data() + m_layers_texture.width * m_layers_texture.height * 4)); + for (const GLVolume* glvolume : volumes.volumes) { + // Render the object using the layer editing shader and texture. + if (! glvolume->is_active || glvolume->composite_id.object_id != this->last_object_id || glvolume->is_modifier) + continue; - GLint z_to_texture_row_id = ::glGetUniformLocation(shader_id, "z_to_texture_row"); - GLint z_texture_row_to_normalized_id = ::glGetUniformLocation(shader_id, "z_texture_row_to_normalized"); - GLint z_cursor_id = ::glGetUniformLocation(shader_id, "z_cursor"); - GLint z_cursor_band_width_id = ::glGetUniformLocation(shader_id, "z_cursor_band_width"); - GLint world_matrix_id = ::glGetUniformLocation(shader_id, "volume_world_matrix"); - GLint object_max_z_id = ::glGetUniformLocation(shader_id, "object_max_z"); - glcheck(); - - if (z_to_texture_row_id != -1 && z_texture_row_to_normalized_id != -1 && z_cursor_id != -1 && z_cursor_band_width_id != -1 && world_matrix_id != -1) - { - const_cast(this)->generate_layer_height_texture(); - - // Uniforms were resolved, go ahead using the layer editing shader. - glsafe(::glUniform1f(z_to_texture_row_id, GLfloat(m_layers_texture.cells - 1) / (GLfloat(m_layers_texture.width) * GLfloat(m_object_max_z)))); - glsafe(::glUniform1f(z_texture_row_to_normalized_id, GLfloat(1.0f / m_layers_texture.height))); - glsafe(::glUniform1f(z_cursor_id, GLfloat(m_object_max_z) * GLfloat(this->get_cursor_z_relative(canvas)))); - glsafe(::glUniform1f(z_cursor_band_width_id, GLfloat(this->band_width))); -#endif // ENABLE_SHADERS_MANAGER - // Initialize the layer height texture mapping. - GLsizei w = (GLsizei)m_layers_texture.width; - GLsizei h = (GLsizei)m_layers_texture.height; - GLsizei half_w = w / 2; - GLsizei half_h = h / 2; - glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); - glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id)); - glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0)); - glsafe(::glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, half_w, half_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0)); - glsafe(::glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, m_layers_texture.data.data())); - glsafe(::glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, half_w, half_h, GL_RGBA, GL_UNSIGNED_BYTE, m_layers_texture.data.data() + m_layers_texture.width * m_layers_texture.height * 4)); - for (const GLVolume* glvolume : volumes.volumes) { - // Render the object using the layer editing shader and texture. - if (! glvolume->is_active || glvolume->composite_id.object_id != this->last_object_id || glvolume->is_modifier) - continue; -#if ENABLE_SHADERS_MANAGER - shader->set_uniform("volume_world_matrix", glvolume->world_matrix()); - shader->set_uniform("object_max_z", GLfloat(0)); -#else - if (world_matrix_id != -1) - glsafe(::glUniformMatrix4fv(world_matrix_id, 1, GL_FALSE, (const GLfloat*)glvolume->world_matrix().cast().data())); - if (object_max_z_id != -1) - glsafe(::glUniform1f(object_max_z_id, GLfloat(0))); -#endif // ENABLE_SHADERS_MANAGER - glvolume->render(); - } - // Revert back to the previous shader. - glBindTexture(GL_TEXTURE_2D, 0); -#if ENABLE_SHADERS_MANAGER - if (current_shader != nullptr) - current_shader->start_using(); -#else - if (current_program_id > 0) - glsafe(::glUseProgram(current_program_id)); + shader->set_uniform("volume_world_matrix", glvolume->world_matrix()); + shader->set_uniform("object_max_z", GLfloat(0)); + glvolume->render(); } - else - { - // Something went wrong. Just render the object. - assert(false); - for (const GLVolume* glvolume : volumes.volumes) { - // Render the object using the layer editing shader and texture. - if (!glvolume->is_active || glvolume->composite_id.object_id != this->last_object_id || glvolume->is_modifier) - continue; - glsafe(::glUniformMatrix4fv(world_matrix_id, 1, GL_FALSE, (const GLfloat*)glvolume->world_matrix().cast().data())); - glvolume->render(); - } - } -#endif // ENABLE_SHADERS_MANAGER + // Revert back to the previous shader. + glBindTexture(GL_TEXTURE_2D, 0); + if (current_shader != nullptr) + current_shader->start_using(); } void GLCanvas3D::LayersEditing::adjust_layer_height_profile() @@ -1710,22 +1621,8 @@ bool GLCanvas3D::init() if (m_multisample_allowed) glsafe(::glEnable(GL_MULTISAMPLE)); -#if ENABLE_SHADERS_MANAGER if (m_main_toolbar.is_enabled()) m_layers_editing.init(); -#else - if (!m_shader.init("gouraud.vs", "gouraud.fs")) - { - std::cout << "Unable to initialize gouraud shader: please, check that the files gouraud.vs and gouraud.fs are available" << std::endl; - return false; - } - - if (m_main_toolbar.is_enabled() && !m_layers_editing.init("variable_layer_height.vs", "variable_layer_height.fs")) - { - std::cout << "Unable to initialize variable_layer_height shader: please, check that the files variable_layer_height.vs and variable_layer_height.fs are available" << std::endl; - return false; - } -#endif // ENABLE_SHADERS_MANAGER #if ENABLE_GCODE_VIEWER if (!m_main_toolbar.is_enabled()) @@ -4585,13 +4482,8 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, bool return ret; }; -#if ENABLE_SHADERS_MANAGER static const std::array orange = { 0.923f, 0.504f, 0.264f, 1.0f }; static const std::array gray = { 0.64f, 0.64f, 0.64f, 1.0f }; -#else - static const GLfloat orange[] = { 0.923f, 0.504f, 0.264f, 1.0f }; - static const GLfloat gray[] = { 0.64f, 0.64f, 0.64f, 1.0f }; -#endif // ENABLE_SHADERS_MANAGER GLVolumePtrs visible_volumes; @@ -4635,7 +4527,6 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, bool camera.apply_projection(box, near_z, far_z); -#if ENABLE_SHADERS_MANAGER GLShaderProgram* shader = wxGetApp().get_shader("gouraud"); if (shader == nullptr) return; @@ -4648,43 +4539,14 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, bool shader->start_using(); shader->set_uniform("print_box.volume_detection", 0); -#else - if (transparent_background) - glsafe(::glClearColor(0.0f, 0.0f, 0.0f, 0.0f)); - - glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); - glsafe(::glEnable(GL_DEPTH_TEST)); - - m_shader.start_using(); - - GLint shader_id = m_shader.get_shader_program_id(); - GLint color_id = ::glGetUniformLocation(shader_id, "uniform_color"); - GLint print_box_detection_id = ::glGetUniformLocation(shader_id, "print_box.volume_detection"); - glcheck(); - - if (print_box_detection_id != -1) - glsafe(::glUniform1i(print_box_detection_id, 0)); -#endif // ENABLE_SHADERS_MANAGER for (const GLVolume* vol : visible_volumes) { -#if ENABLE_SHADERS_MANAGER shader->set_uniform("uniform_color", (vol->printable && !vol->is_outside) ? orange : gray); -#else - if (color_id >= 0) - glsafe(::glUniform4fv(color_id, 1, (vol->printable && !vol->is_outside) ? orange : gray)); - else - glsafe(::glColor4fv((vol->printable && !vol->is_outside) ? orange : gray)); -#endif // ENABLE_SHADERS_MANAGER - vol->render(); } -#if ENABLE_SHADERS_MANAGER shader->stop_using(); -#else - m_shader.stop_using(); -#endif // ENABLE_SHADERS_MANAGER glsafe(::glDisable(GL_DEPTH_TEST)); @@ -5610,13 +5472,11 @@ void GLCanvas3D::_render_objects() const m_camera_clipping_plane = m_gizmos.get_clipping_plane(); - if (m_picking_enabled) - { + if (m_picking_enabled) { // Update the layer editing selection to the first object selected, update the current object maximum Z. const_cast(m_layers_editing).select_object(*m_model, this->is_layers_editing_enabled() ? m_selection.get_object_idx() : -1); - if (m_config != nullptr) - { + if (m_config != nullptr) { const BoundingBoxf3& bed_bb = wxGetApp().plater()->get_bed().get_bounding_box(false); m_volumes.set_print_box((float)bed_bb.min(0), (float)bed_bb.min(1), 0.0f, (float)bed_bb.max(0), (float)bed_bb.max(1), (float)m_config->opt_float("max_print_height")); m_volumes.check_outside_state(m_config, nullptr); @@ -5630,37 +5490,28 @@ void GLCanvas3D::_render_objects() const m_volumes.set_clipping_plane(m_camera_clipping_plane.get_data()); -#if ENABLE_SHADERS_MANAGER GLShaderProgram* shader = wxGetApp().get_shader("gouraud"); - if (shader != nullptr) - { + if (shader != nullptr) { shader->start_using(); -#else - m_shader.start_using(); -#endif // ENABLE_SHADERS_MANAGER - if (m_picking_enabled && !m_gizmos.is_dragging() && m_layers_editing.is_enabled() && (m_layers_editing.last_object_id != -1) && (m_layers_editing.object_max_z() > 0.0f)) { - int object_id = m_layers_editing.last_object_id; - m_volumes.render(GLVolumeCollection::Opaque, false, wxGetApp().plater()->get_camera().get_view_matrix(), [object_id](const GLVolume& volume) { - // Which volume to paint without the layer height profile shader? - return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id); - }); - // Let LayersEditing handle rendering of the active object using the layer height profile shader. - m_layers_editing.render_volumes(*this, this->m_volumes); - } - else { + + if (m_picking_enabled && !m_gizmos.is_dragging() && m_layers_editing.is_enabled() && (m_layers_editing.last_object_id != -1) && (m_layers_editing.object_max_z() > 0.0f)) { + int object_id = m_layers_editing.last_object_id; + m_volumes.render(GLVolumeCollection::Opaque, false, wxGetApp().plater()->get_camera().get_view_matrix(), [object_id](const GLVolume& volume) { + // Which volume to paint without the layer height profile shader? + return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id); + }); + // Let LayersEditing handle rendering of the active object using the layer height profile shader. + m_layers_editing.render_volumes(*this, this->m_volumes); + } else { // do not cull backfaces to show broken geometry, if any m_volumes.render(GLVolumeCollection::Opaque, m_picking_enabled, wxGetApp().plater()->get_camera().get_view_matrix(), [this](const GLVolume& volume) { return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0); }); - } + } - m_volumes.render(GLVolumeCollection::Transparent, false, wxGetApp().plater()->get_camera().get_view_matrix()); -#if ENABLE_SHADERS_MANAGER - shader->stop_using(); + m_volumes.render(GLVolumeCollection::Transparent, false, wxGetApp().plater()->get_camera().get_view_matrix()); + shader->stop_using(); } -#else - m_shader.stop_using(); -#endif // ENABLE_SHADERS_MANAGER m_camera_clipping_plane = ClippingPlane::ClipsNothing(); } @@ -6078,15 +5929,7 @@ void GLCanvas3D::_render_sla_slices() const void GLCanvas3D::_render_selection_sidebar_hints() const { -#if ENABLE_GCODE_VIEWER m_selection.render_sidebar_hints(m_sidebar_field); -#else -#if ENABLE_SHADERS_MANAGER - m_selection.render_sidebar_hints(m_sidebar_field); -#else - m_selection.render_sidebar_hints(m_sidebar_field, m_shader); -#endif // ENABLE_SHADERS_MANAGER -#endif // ENABLE_GCODE_VIEWER } void GLCanvas3D::_update_volumes_hover_state() const diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index ff775a86e1..7b6f67c2b3 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -7,9 +7,6 @@ #include "3DScene.hpp" #include "GLToolbar.hpp" -#if !ENABLE_SHADERS_MANAGER -#include "GLShader.hpp" -#endif // !ENABLE_SHADERS_MANAGER #include "Event.hpp" #include "Selection.hpp" #include "Gizmos/GLGizmosManager.hpp" @@ -169,9 +166,6 @@ private: private: bool m_enabled; -#if !ENABLE_SHADERS_MANAGER - Shader m_shader; -#endif // !ENABLE_SHADERS_MANAGER unsigned int m_z_texture_id; // Not owned by LayersEditing. const DynamicPrintConfig *m_config; @@ -218,11 +212,8 @@ private: LayersEditing(); ~LayersEditing(); -#if ENABLE_SHADERS_MANAGER void init(); -#else - bool init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename); -#endif // ENABLE_SHADERS_MANAGER + void set_config(const DynamicPrintConfig* config); void select_object(const Model &model, int object_id); @@ -465,9 +456,6 @@ private: WarningTexture m_warning_texture; wxTimer m_timer; LayersEditing m_layers_editing; -#if !ENABLE_SHADERS_MANAGER - Shader m_shader; -#endif // !ENABLE_SHADERS_MANAGER Mouse m_mouse; mutable GLGizmosManager m_gizmos; mutable GLToolbar m_main_toolbar; @@ -597,9 +585,6 @@ public: void set_color_by(const std::string& value); void refresh_camera_scene_box(); -#if !ENABLE_SHADERS_MANAGER - const Shader& get_shader() const { return m_shader; } -#endif // !ENABLE_SHADERS_MANAGER BoundingBoxf3 volumes_bounding_box() const; BoundingBoxf3 scene_bounding_box() const; diff --git a/src/slic3r/GUI/GLShader.cpp b/src/slic3r/GUI/GLShader.cpp index 38ded63326..42e5b0a9f5 100644 --- a/src/slic3r/GUI/GLShader.cpp +++ b/src/slic3r/GUI/GLShader.cpp @@ -8,7 +8,6 @@ #include #include -#if ENABLE_SHADERS_MANAGER #include namespace Slic3r { @@ -302,364 +301,3 @@ int GLShaderProgram::get_uniform_location(const char* name) const } } // namespace Slic3r -#else -#include -#include -#include - -namespace Slic3r { - -GLShader::~GLShader() -{ - assert(fragment_program_id == 0); - assert(vertex_program_id == 0); - assert(shader_program_id == 0); -} - -// A safe wrapper around glGetString to report a "N/A" string in case glGetString returns nullptr. -inline std::string gl_get_string_safe(GLenum param) -{ - const char *value = (const char*)glGetString(param); - return std::string(value ? value : "N/A"); -} - -bool GLShader::load_from_text(const char *fragment_shader, const char *vertex_shader) -{ - std::string gl_version = gl_get_string_safe(GL_VERSION); - int major = atoi(gl_version.c_str()); - //int minor = atoi(gl_version.c_str() + gl_version.find('.') + 1); - if (major < 2) { - // Cannot create a shader object on OpenGL 1.x. - // Form an error message. - std::string gl_vendor = gl_get_string_safe(GL_VENDOR); - std::string gl_renderer = gl_get_string_safe(GL_RENDERER); - std::string glsl_version = gl_get_string_safe(GL_SHADING_LANGUAGE_VERSION); - last_error = "Your computer does not support OpenGL shaders.\n"; -#ifdef _WIN32 - if (gl_vendor == "Microsoft Corporation" && gl_renderer == "GDI Generic") { - last_error = "Windows is using a software OpenGL renderer.\n" - "You are either connected over remote desktop,\n" - "or a hardware acceleration is not available.\n"; - } -#endif - last_error += "GL version: " + gl_version + "\n"; - last_error += "vendor: " + gl_vendor + "\n"; - last_error += "renderer: " + gl_renderer + "\n"; - last_error += "GLSL version: " + glsl_version + "\n"; - return false; - } - - if (fragment_shader != nullptr) { - this->fragment_program_id = ::glCreateShader(GL_FRAGMENT_SHADER); - glcheck(); - if (this->fragment_program_id == 0) { - last_error = "glCreateShader(GL_FRAGMENT_SHADER) failed."; - return false; - } - GLint len = (GLint)strlen(fragment_shader); - glsafe(::glShaderSource(this->fragment_program_id, 1, &fragment_shader, &len)); - glsafe(::glCompileShader(this->fragment_program_id)); - GLint params; - glsafe(::glGetShaderiv(this->fragment_program_id, GL_COMPILE_STATUS, ¶ms)); - if (params == GL_FALSE) { - // Compilation failed. Get the log. - glsafe(::glGetShaderiv(this->fragment_program_id, GL_INFO_LOG_LENGTH, ¶ms)); - std::vector msg(params); - glsafe(::glGetShaderInfoLog(this->fragment_program_id, params, ¶ms, msg.data())); - this->last_error = std::string("Fragment shader compilation failed:\n") + msg.data(); - this->release(); - return false; - } - } - - if (vertex_shader != nullptr) { - this->vertex_program_id = ::glCreateShader(GL_VERTEX_SHADER); - glcheck(); - if (this->vertex_program_id == 0) { - last_error = "glCreateShader(GL_VERTEX_SHADER) failed."; - this->release(); - return false; - } - GLint len = (GLint)strlen(vertex_shader); - glsafe(::glShaderSource(this->vertex_program_id, 1, &vertex_shader, &len)); - glsafe(::glCompileShader(this->vertex_program_id)); - GLint params; - glsafe(::glGetShaderiv(this->vertex_program_id, GL_COMPILE_STATUS, ¶ms)); - if (params == GL_FALSE) { - // Compilation failed. Get the log. - glsafe(::glGetShaderiv(this->vertex_program_id, GL_INFO_LOG_LENGTH, ¶ms)); - std::vector msg(params); - glsafe(::glGetShaderInfoLog(this->vertex_program_id, params, ¶ms, msg.data())); - this->last_error = std::string("Vertex shader compilation failed:\n") + msg.data(); - this->release(); - return false; - } - } - - // Link shaders - this->shader_program_id = ::glCreateProgram(); - glcheck(); - if (this->shader_program_id == 0) { - last_error = "glCreateProgram() failed."; - this->release(); - return false; - } - - if (this->fragment_program_id) - glsafe(::glAttachShader(this->shader_program_id, this->fragment_program_id)); - if (this->vertex_program_id) - glsafe(::glAttachShader(this->shader_program_id, this->vertex_program_id)); - glsafe(::glLinkProgram(this->shader_program_id)); - - GLint params; - glsafe(::glGetProgramiv(this->shader_program_id, GL_LINK_STATUS, ¶ms)); - if (params == GL_FALSE) { - // Linking failed. Get the log. - glsafe(::glGetProgramiv(this->shader_program_id, GL_INFO_LOG_LENGTH, ¶ms)); - std::vector msg(params); - glsafe(::glGetProgramInfoLog(this->shader_program_id, params, ¶ms, msg.data())); - this->last_error = std::string("Shader linking failed:\n") + msg.data(); - this->release(); - return false; - } - - last_error.clear(); - return true; -} - -bool GLShader::load_from_file(const char* fragment_shader_filename, const char* vertex_shader_filename) -{ - const std::string& path = resources_dir() + "/shaders/"; - - boost::nowide::ifstream vs(path + std::string(vertex_shader_filename), boost::nowide::ifstream::binary); - if (!vs.good()) - return false; - - vs.seekg(0, vs.end); - int file_length = (int)vs.tellg(); - vs.seekg(0, vs.beg); - std::string vertex_shader(file_length, '\0'); - vs.read(vertex_shader.data(), file_length); - if (!vs.good()) - return false; - - vs.close(); - - boost::nowide::ifstream fs(path + std::string(fragment_shader_filename), boost::nowide::ifstream::binary); - if (!fs.good()) - return false; - - fs.seekg(0, fs.end); - file_length = (int)fs.tellg(); - fs.seekg(0, fs.beg); - std::string fragment_shader(file_length, '\0'); - fs.read(fragment_shader.data(), file_length); - if (!fs.good()) - return false; - - fs.close(); - - return load_from_text(fragment_shader.c_str(), vertex_shader.c_str()); -} - -void GLShader::release() -{ - if (this->shader_program_id) { - if (this->vertex_program_id) - glsafe(::glDetachShader(this->shader_program_id, this->vertex_program_id)); - if (this->fragment_program_id) - glsafe(::glDetachShader(this->shader_program_id, this->fragment_program_id)); - glsafe(::glDeleteProgram(this->shader_program_id)); - this->shader_program_id = 0; - } - - if (this->vertex_program_id) { - glsafe(::glDeleteShader(this->vertex_program_id)); - this->vertex_program_id = 0; - } - if (this->fragment_program_id) { - glsafe(::glDeleteShader(this->fragment_program_id)); - this->fragment_program_id = 0; - } -} - -void GLShader::enable() const -{ - glsafe(::glUseProgram(this->shader_program_id)); -} - -void GLShader::disable() const -{ - glsafe(::glUseProgram(0)); -} - -// Return shader vertex attribute ID -int GLShader::get_attrib_location(const char *name) const -{ - return this->shader_program_id ? glGetAttribLocation(this->shader_program_id, name) : -1; -} - -// Return shader uniform variable ID -int GLShader::get_uniform_location(const char *name) const -{ - return this->shader_program_id ? glGetUniformLocation(this->shader_program_id, name) : -1; -} - -bool GLShader::set_uniform(const char *name, float value) const -{ - int id = this->get_uniform_location(name); - if (id >= 0) { - glsafe(::glUniform1fARB(id, value)); - return true; - } - return false; -} - -bool GLShader::set_uniform(const char* name, const float* matrix) const -{ - int id = get_uniform_location(name); - if (id >= 0) - { - glsafe(::glUniformMatrix4fv(id, 1, GL_FALSE, (const GLfloat*)matrix)); - return true; - } - return false; -} - -bool GLShader::set_uniform(const char* name, int value) const -{ - int id = get_uniform_location(name); - if (id >= 0) - { - glsafe(::glUniform1i(id, value)); - return true; - } - return false; -} - -/* -# Set shader vector -sub SetVector -{ - my($self,$var,@values) = @_; - - my $id = $self->Map($var); - return 'Unable to map $var' if (!defined($id)); - - my $count = scalar(@values); - eval('glUniform'.$count.'fARB($id,@values)'); - - return ''; -} - -# Set shader 4x4 matrix -sub SetMatrix -{ - my($self,$var,$oga) = @_; - - my $id = $self->Map($var); - return 'Unable to map $var' if (!defined($id)); - - glUniformMatrix4fvARB_c($id,1,0,$oga->ptr()); - return ''; -} -*/ - -Shader::Shader() - : m_shader(nullptr) -{ -} - -Shader::~Shader() -{ - reset(); -} - -bool Shader::init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename) -{ - if (is_initialized()) - return true; - - m_shader = new GLShader(); - if (m_shader != nullptr) - { - if (!m_shader->load_from_file(fragment_shader_filename.c_str(), vertex_shader_filename.c_str())) - { - std::cout << "Compilaton of shader failed:" << std::endl; - std::cout << m_shader->last_error << std::endl; - reset(); - return false; - } - } - - return true; -} - -bool Shader::is_initialized() const -{ - return (m_shader != nullptr); -} - -bool Shader::start_using() const -{ - if (is_initialized()) - { - m_shader->enable(); - return true; - } - else - return false; -} - -void Shader::stop_using() const -{ - if (m_shader != nullptr) - m_shader->disable(); -} - -int Shader::get_attrib_location(const std::string& name) const -{ - return (m_shader != nullptr) ? m_shader->get_attrib_location(name.c_str()) : -1; -} - -int Shader::get_uniform_location(const std::string& name) const -{ - return (m_shader != nullptr) ? m_shader->get_uniform_location(name.c_str()) : -1; -} - -void Shader::set_uniform(const std::string& name, float value) const -{ - if (m_shader != nullptr) - m_shader->set_uniform(name.c_str(), value); -} - -void Shader::set_uniform(const std::string& name, const float* matrix) const -{ - if (m_shader != nullptr) - m_shader->set_uniform(name.c_str(), matrix); -} - -void Shader::set_uniform(const std::string& name, bool value) const -{ - if (m_shader != nullptr) - m_shader->set_uniform(name.c_str(), value ? 1 : 0); -} - -unsigned int Shader::get_shader_program_id() const -{ - return (m_shader != nullptr) ? m_shader->shader_program_id : 0; -} - -void Shader::reset() -{ - if (m_shader != nullptr) - { - m_shader->release(); - delete m_shader; - m_shader = nullptr; - } -} - -} // namespace Slic3r - -#endif // ENABLE_SHADERS_MANAGER diff --git a/src/slic3r/GUI/GLShader.hpp b/src/slic3r/GUI/GLShader.hpp index 91a1f66258..e58437fbd1 100644 --- a/src/slic3r/GUI/GLShader.hpp +++ b/src/slic3r/GUI/GLShader.hpp @@ -1,7 +1,6 @@ #ifndef slic3r_GLShader_hpp_ #define slic3r_GLShader_hpp_ -#if ENABLE_SHADERS_MANAGER #include #include @@ -59,75 +58,5 @@ public: }; } // namespace Slic3r -#else -#include "libslic3r/libslic3r.h" -#include "libslic3r/Point.hpp" - -namespace Slic3r { - -class GLShader -{ -public: - GLShader() : - fragment_program_id(0), - vertex_program_id(0), - shader_program_id(0) - {} - ~GLShader(); - - bool load_from_text(const char *fragment_shader, const char *vertex_shader); - bool load_from_file(const char* fragment_shader_filename, const char* vertex_shader_filename); - - void release(); - - int get_attrib_location(const char *name) const; - int get_uniform_location(const char *name) const; - - bool set_uniform(const char *name, float value) const; - bool set_uniform(const char* name, const float* matrix) const; - bool set_uniform(const char* name, int value) const; - - void enable() const; - void disable() const; - - unsigned int fragment_program_id; - unsigned int vertex_program_id; - unsigned int shader_program_id; - std::string last_error; -}; - -class Shader -{ - GLShader* m_shader; - -public: - Shader(); - ~Shader(); - - bool init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename); - - bool is_initialized() const; - - bool start_using() const; - void stop_using() const; - - int get_attrib_location(const std::string& name) const; - int get_uniform_location(const std::string& name) const; - - void set_uniform(const std::string& name, float value) const; - void set_uniform(const std::string& name, const float* matrix) const; - void set_uniform(const std::string& name, bool value) const; - - const GLShader* get_shader() const { return m_shader; } - unsigned int get_shader_program_id() const; - -private: - void reset(); -}; - -} - - -#endif // ENABLE_SHADERS_MANAGER #endif /* slic3r_GLShader_hpp_ */ diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index 6df8c75208..dd77351bd0 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -7,8 +7,6 @@ #include -#if ENABLE_SHADERS_MANAGER - namespace Slic3r { std::pair GLShadersManager::init() @@ -77,4 +75,3 @@ GLShaderProgram* GLShadersManager::get_current_shader() } // namespace Slic3r -#endif // ENABLE_SHADERS_MANAGER diff --git a/src/slic3r/GUI/GLShadersManager.hpp b/src/slic3r/GUI/GLShadersManager.hpp index f30472b123..b2bbc140bd 100644 --- a/src/slic3r/GUI/GLShadersManager.hpp +++ b/src/slic3r/GUI/GLShadersManager.hpp @@ -1,8 +1,6 @@ #ifndef slic3r_GLShadersManager_hpp_ #define slic3r_GLShadersManager_hpp_ -#if ENABLE_SHADERS_MANAGER - #include "GLShader.hpp" #include @@ -29,6 +27,4 @@ public: } // namespace Slic3r -#endif // ENABLE_SHADERS_MANAGER - #endif // slic3r_GLShadersManager_hpp_ diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index cbe2aafe16..bdbc164acb 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -217,10 +217,8 @@ public: void gcode_thumbnails_debug(); #endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG -#if ENABLE_SHADERS_MANAGER GLShaderProgram* get_shader(const std::string& shader_name) { return m_opengl_mgr.get_shader(shader_name); } GLShaderProgram* get_current_shader() { return m_opengl_mgr.get_current_shader(); } -#endif // ENABLE_SHADERS_MANAGER bool is_gl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const { return m_opengl_mgr.get_gl_info().is_version_greater_or_equal_to(major, minor); } bool is_glsl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const { return m_opengl_mgr.get_gl_info().is_glsl_version_greater_or_equal_to(major, minor); } diff --git a/src/slic3r/GUI/OpenGLManager.cpp b/src/slic3r/GUI/OpenGLManager.cpp index b21fd01439..13c58f8472 100644 --- a/src/slic3r/GUI/OpenGLManager.cpp +++ b/src/slic3r/GUI/OpenGLManager.cpp @@ -28,14 +28,12 @@ namespace Slic3r { namespace GUI { -#if ENABLE_SHADERS_MANAGER // A safe wrapper around glGetString to report a "N/A" string in case glGetString returns nullptr. inline std::string gl_get_string_safe(GLenum param, const std::string& default_value) { const char* value = (const char*)::glGetString(param); return std::string((value != nullptr) ? value : default_value); } -#endif // ENABLE_SHADERS_MANAGER const std::string& OpenGLManager::GLInfo::get_version() const { @@ -94,28 +92,10 @@ float OpenGLManager::GLInfo::get_max_anisotropy() const void OpenGLManager::GLInfo::detect() const { -#if ENABLE_SHADERS_MANAGER m_version = gl_get_string_safe(GL_VERSION, "N/A"); m_glsl_version = gl_get_string_safe(GL_SHADING_LANGUAGE_VERSION, "N/A"); m_vendor = gl_get_string_safe(GL_VENDOR, "N/A"); m_renderer = gl_get_string_safe(GL_RENDERER, "N/A"); -#else - const char* data = (const char*)::glGetString(GL_VERSION); - if (data != nullptr) - m_version = data; - - data = (const char*)::glGetString(GL_SHADING_LANGUAGE_VERSION); - if (data != nullptr) - m_glsl_version = data; - - data = (const char*)::glGetString(GL_VENDOR); - if (data != nullptr) - m_vendor = data; - - data = (const char*)::glGetString(GL_RENDERER); - if (data != nullptr) - m_renderer = data; -#endif // ENABLE_SHADERS_MANAGER glsafe(::glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_max_tex_size)); @@ -132,10 +112,8 @@ void OpenGLManager::GLInfo::detect() const static bool version_greater_or_equal_to(const std::string& version, unsigned int major, unsigned int minor) { -#if ENABLE_SHADERS_MANAGER if (version == "N/A") return false; -#endif // ENABLE_SHADERS_MANAGER std::vector tokens; boost::split(tokens, version, boost::is_any_of(" "), boost::token_compress_on); @@ -193,26 +171,15 @@ std::string OpenGLManager::GLInfo::to_string(bool format_as_html, bool extension std::string line_end = format_as_html ? "
" : "\n"; out << h2_start << "OpenGL installation" << h2_end << line_end; -#if ENABLE_SHADERS_MANAGER out << b_start << "GL version: " << b_end << m_version << line_end; out << b_start << "Vendor: " << b_end << m_vendor << line_end; out << b_start << "Renderer: " << b_end << m_renderer << line_end; out << b_start << "GLSL version: " << b_end << m_glsl_version << line_end; -#else - out << b_start << "GL version: " << b_end << (m_version.empty() ? "N/A" : m_version) << line_end; - out << b_start << "Vendor: " << b_end << (m_vendor.empty() ? "N/A" : m_vendor) << line_end; - out << b_start << "Renderer: " << b_end << (m_renderer.empty() ? "N/A" : m_renderer) << line_end; - out << b_start << "GLSL version: " << b_end << (m_glsl_version.empty() ? "N/A" : m_glsl_version) << line_end; -#endif // ENABLE_SHADERS_MANAGER if (extensions) { std::vector extensions_list; -#if ENABLE_SHADERS_MANAGER std::string extensions_str = gl_get_string_safe(GL_EXTENSIONS, ""); -#else - std::string extensions_str = (const char*)::glGetString(GL_EXTENSIONS); -#endif // ENABLE_SHADERS_MANAGER boost::split(extensions_list, extensions_str, boost::is_any_of(" "), boost::token_compress_off); if (!extensions_list.empty()) @@ -244,9 +211,7 @@ OpenGLManager::OSInfo OpenGLManager::s_os_info; OpenGLManager::~OpenGLManager() { -#if ENABLE_SHADERS_MANAGER m_shaders_manager.shutdown(); -#endif // ENABLE_SHADERS_MANAGER #if ENABLE_HACK_CLOSING_ON_OSX_10_9_5 #ifdef __APPLE__ @@ -289,13 +254,8 @@ bool OpenGLManager::init_gl() else s_framebuffers_type = EFramebufferType::Unknown; -#if ENABLE_SHADERS_MANAGER bool valid_version = s_gl_info.is_version_greater_or_equal_to(2, 0); if (!valid_version) { -#else - if (!s_gl_info.is_version_greater_or_equal_to(2, 0)) { -#endif // ENABLE_SHADERS_MANAGER - // Complain about the OpenGL version. wxString message = from_u8((boost::format( _utf8(L("PrusaSlicer requires OpenGL 2.0 capable graphics driver to run correctly, \n" @@ -309,7 +269,6 @@ bool OpenGLManager::init_gl() wxMessageBox(message, wxString("PrusaSlicer - ") + _L("Unsupported OpenGL version"), wxOK | wxICON_ERROR); } -#if ENABLE_SHADERS_MANAGER if (valid_version) { // load shaders auto [result, error] = m_shaders_manager.init(); @@ -319,7 +278,6 @@ bool OpenGLManager::init_gl() wxMessageBox(message, wxString("PrusaSlicer - ") + _L("Error loading shaders"), wxOK | wxICON_ERROR); } } -#endif // ENABLE_SHADERS_MANAGER } return true; @@ -327,8 +285,7 @@ bool OpenGLManager::init_gl() wxGLContext* OpenGLManager::init_glcontext(wxGLCanvas& canvas) { - if (m_context == nullptr) - { + if (m_context == nullptr) { m_context = new wxGLContext(&canvas); #if ENABLE_HACK_CLOSING_ON_OSX_10_9_5 diff --git a/src/slic3r/GUI/OpenGLManager.hpp b/src/slic3r/GUI/OpenGLManager.hpp index e33df42491..c89cdf3a61 100644 --- a/src/slic3r/GUI/OpenGLManager.hpp +++ b/src/slic3r/GUI/OpenGLManager.hpp @@ -1,9 +1,7 @@ #ifndef slic3r_OpenGLManager_hpp_ #define slic3r_OpenGLManager_hpp_ -#if ENABLE_SHADERS_MANAGER #include "GLShadersManager.hpp" -#endif // ENABLE_SHADERS_MANAGER class wxWindow; class wxGLCanvas; @@ -75,9 +73,7 @@ private: bool m_gl_initialized{ false }; wxGLContext* m_context{ nullptr }; -#if ENABLE_SHADERS_MANAGER GLShadersManager m_shaders_manager; -#endif // ENABLE_SHADERS_MANAGER static GLInfo s_gl_info; #if ENABLE_HACK_CLOSING_ON_OSX_10_9_5 #ifdef __APPLE__ @@ -96,10 +92,8 @@ public: bool init_gl(); wxGLContext* init_glcontext(wxGLCanvas& canvas); -#if ENABLE_SHADERS_MANAGER GLShaderProgram* get_shader(const std::string& shader_name) { return m_shaders_manager.get_shader(shader_name); } GLShaderProgram* get_current_shader() { return m_shaders_manager.get_current_shader(); } -#endif // ENABLE_SHADERS_MANAGER static bool are_compressed_textures_supported() { return s_compressed_textures_supported; } static bool can_multisample() { return s_multisample == EMultisampleState::Enabled; } diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index f890f0f012..cbc3942305 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -112,14 +112,6 @@ bool Selection::init() #if ENABLE_GCODE_VIEWER m_arrow.init_from(straight_arrow(10.0f, 5.0f, 5.0f, 10.0f, 1.0f)); m_curved_arrow.init_from(circular_arrow(16, 10.0f, 5.0f, 10.0f, 5.0f, 1.0f)); - -#if !ENABLE_SHADERS_MANAGER - if (!m_arrows_shader.init("gouraud_light.vs", "gouraud_light.fs")) - { - BOOST_LOG_TRIVIAL(error) << "Unable to initialize gouraud_light shader: please, check that the files gouraud_light.vs and gouraud_light.fs are available"; - return false; - } -#endif // !ENABLE_SHADERS_MANAGER #else if (!m_arrow.init()) return false; @@ -1246,76 +1238,40 @@ void Selection::render_center(bool gizmo_is_dragging) const } #endif // ENABLE_RENDER_SELECTION_CENTER -#if ENABLE_GCODE_VIEWER void Selection::render_sidebar_hints(const std::string& sidebar_field) const -#else -#if ENABLE_SHADERS_MANAGER -void Selection::render_sidebar_hints(const std::string& sidebar_field) const -#else -void Selection::render_sidebar_hints(const std::string& sidebar_field, const Shader& shader) const -#endif // ENABLE_SHADERS_MANAGER -#endif // ENABLE_GCODE_VIEWER { if (sidebar_field.empty()) return; -#if ENABLE_SHADERS_MANAGER GLShaderProgram* shader = nullptr; -#endif // ENABLE_SHADERS_MANAGER if (!boost::starts_with(sidebar_field, "layer")) { -#if ENABLE_GCODE_VIEWER -#if ENABLE_SHADERS_MANAGER shader = wxGetApp().get_shader("gouraud_light"); if (shader == nullptr) return; shader->start_using(); -#else - if (!m_arrows_shader.is_initialized()) - return; - - m_arrows_shader.start_using(); -#endif // ENABLE_SHADERS_MANAGER glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); -#else -#if ENABLE_SHADERS_MANAGER - shader = wxGetApp().get_shader("gouraud_light"); - if (shader == nullptr) - return; - - shader->start_using(); -#else - shader.start_using(); - glsafe(::glEnable(GL_LIGHTING)); -#endif // ENABLE_SHADERS_MANAGER - glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); -#endif // ENABLE_GCODE_VIEWER } glsafe(::glEnable(GL_DEPTH_TEST)); glsafe(::glPushMatrix()); - if (!boost::starts_with(sidebar_field, "layer")) - { + if (!boost::starts_with(sidebar_field, "layer")) { const Vec3d& center = get_bounding_box().center(); - if (is_single_full_instance() && !wxGetApp().obj_manipul()->get_world_coordinates()) - { + if (is_single_full_instance() && !wxGetApp().obj_manipul()->get_world_coordinates()) { glsafe(::glTranslated(center(0), center(1), center(2))); - if (!boost::starts_with(sidebar_field, "position")) - { + if (!boost::starts_with(sidebar_field, "position")) { Transform3d orient_matrix = Transform3d::Identity(); if (boost::starts_with(sidebar_field, "scale")) orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); - else if (boost::starts_with(sidebar_field, "rotation")) - { + else if (boost::starts_with(sidebar_field, "rotation")) { if (boost::ends_with(sidebar_field, "x")) orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); - else if (boost::ends_with(sidebar_field, "y")) - { + else if (boost::ends_with(sidebar_field, "y")) { const Vec3d& rotation = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation(); if (rotation(0) == 0.0) orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); @@ -1326,21 +1282,16 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field, const Sha glsafe(::glMultMatrixd(orient_matrix.data())); } - } - else if (is_single_volume() || is_single_modifier()) - { + } else if (is_single_volume() || is_single_modifier()) { glsafe(::glTranslated(center(0), center(1), center(2))); Transform3d orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); if (!boost::starts_with(sidebar_field, "position")) orient_matrix = orient_matrix * (*m_volumes)[*m_list.begin()]->get_volume_transformation().get_matrix(true, false, true, true); glsafe(::glMultMatrixd(orient_matrix.data())); - } - else - { + } else { glsafe(::glTranslated(center(0), center(1), center(2))); - if (requires_local_axes()) - { + if (requires_local_axes()) { Transform3d orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); glsafe(::glMultMatrixd(orient_matrix.data())); } @@ -1359,22 +1310,7 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field, const Sha glsafe(::glPopMatrix()); if (!boost::starts_with(sidebar_field, "layer")) - { -#if ENABLE_GCODE_VIEWER -#if ENABLE_SHADERS_MANAGER shader->stop_using(); -#else - m_arrows_shader.stop_using(); -#endif // ENABLE_SHADERS_MANAGER -#else -#if ENABLE_SHADERS_MANAGER - shader->stop_using(); -#else - glsafe(::glDisable(GL_LIGHTING)); - shader.stop_using(); -#endif // ENABLE_SHADERS_MANAGER -#endif // ENABLE_GCODE_VIEWER - } } bool Selection::requires_local_axes() const @@ -1977,50 +1913,21 @@ void Selection::render_bounding_box(const BoundingBoxf3& box, float* color) cons #if ENABLE_GCODE_VIEWER void Selection::render_sidebar_position_hints(const std::string& sidebar_field) const { -#if ENABLE_SHADERS_MANAGER auto set_color = [](Axis axis) { GLShaderProgram* shader = wxGetApp().get_current_shader(); if (shader != nullptr) shader->set_uniform("uniform_color", AXES_COLOR[axis], 4); }; -#endif // ENABLE_SHADERS_MANAGER -#if !ENABLE_SHADERS_MANAGER - GLint color_id = ::glGetUniformLocation(m_arrows_shader.get_shader_program_id(), "uniform_color"); -#endif // !ENABLE_SHADERS_MANAGER - - if (boost::ends_with(sidebar_field, "x")) - { -#if ENABLE_SHADERS_MANAGER + if (boost::ends_with(sidebar_field, "x")) { set_color(X); -#else - if (color_id >= 0) - glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[0])); -#endif // ENABLE_SHADERS_MANAGER - glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0)); m_arrow.render(); - } - else if (boost::ends_with(sidebar_field, "y")) - { -#if ENABLE_SHADERS_MANAGER + } else if (boost::ends_with(sidebar_field, "y")) { set_color(Y); -#else - if (color_id >= 0) - glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[1])); -#endif // ENABLE_SHADERS_MANAGER - m_arrow.render(); - } - else if (boost::ends_with(sidebar_field, "z")) - { -#if ENABLE_SHADERS_MANAGER + } else if (boost::ends_with(sidebar_field, "z")) { set_color(Z); -#else - if (color_id >= 0) - glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[2])); -#endif // ENABLE_SHADERS_MANAGER - glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); m_arrow.render(); } @@ -2046,51 +1953,22 @@ void Selection::render_sidebar_position_hints(const std::string& sidebar_field) #if ENABLE_GCODE_VIEWER void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) const { -#if ENABLE_SHADERS_MANAGER auto set_color = [](Axis axis) { GLShaderProgram* shader = wxGetApp().get_current_shader(); if (shader != nullptr) shader->set_uniform("uniform_color", AXES_COLOR[axis], 4); }; -#endif // ENABLE_SHADERS_MANAGER -#if !ENABLE_SHADERS_MANAGER - GLint color_id = ::glGetUniformLocation(m_arrows_shader.get_shader_program_id(), "uniform_color"); -#endif // !ENABLE_SHADERS_MANAGER - - if (boost::ends_with(sidebar_field, "x")) - { -#if ENABLE_SHADERS_MANAGER + if (boost::ends_with(sidebar_field, "x")) { set_color(X); -#else - if (color_id >= 0) - glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[0])); -#endif // ENABLE_SHADERS_MANAGER - glsafe(::glRotated(90.0, 0.0, 1.0, 0.0)); render_sidebar_rotation_hint(X); - } - else if (boost::ends_with(sidebar_field, "y")) - { -#if ENABLE_SHADERS_MANAGER + } else if (boost::ends_with(sidebar_field, "y")) { set_color(Y); -#else - if (color_id >= 0) - glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[1])); -#endif // ENABLE_SHADERS_MANAGER - glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0)); render_sidebar_rotation_hint(Y); - } - else if (boost::ends_with(sidebar_field, "z")) - { -#if ENABLE_SHADERS_MANAGER + } else if (boost::ends_with(sidebar_field, "z")) { set_color(Z); -#else - if (color_id >= 0) - glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[2])); -#endif // ENABLE_SHADERS_MANAGER - render_sidebar_rotation_hint(Z); } } @@ -2230,23 +2108,12 @@ void Selection::render_sidebar_rotation_hint(Axis axis) const m_curved_arrow.render(); } -#if ENABLE_SHADERS_MANAGER void Selection::render_sidebar_scale_hint(Axis axis) const -#else -void Selection::render_sidebar_scale_hint(Axis axis) const -#endif // ENABLE_SHADERS_MANAGER { #if ENABLE_GCODE_VIEWER -#if ENABLE_SHADERS_MANAGER GLShaderProgram* shader = wxGetApp().get_current_shader(); if (shader != nullptr) shader->set_uniform("uniform_color", (requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling()) ? UNIFORM_SCALE_COLOR : AXES_COLOR[axis], 4); -#else - GLint color_id = ::glGetUniformLocation(m_arrows_shader.get_shader_program_id(), "uniform_color"); - - if (color_id >= 0) - glsafe(::glUniform4fv(color_id, 1, (requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling()) ? (const GLfloat*)UNIFORM_SCALE_COLOR : (const GLfloat*)AXES_COLOR[axis])); -#endif // ENABLE_SHADERS_MANAGER #else m_arrow.set_color(((requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling()) ? UNIFORM_SCALE_COLOR : AXES_COLOR[axis]), 3); #endif // ENABLE_GCODE_VIEWER diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 5541cc3fa9..34024875b3 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -6,13 +6,6 @@ #include "3DScene.hpp" #if ENABLE_GCODE_VIEWER #include "GLModel.hpp" -#if !ENABLE_SHADERS_MANAGER -#include "GLShader.hpp" -#endif // !ENABLE_SHADERS_MANAGER -#else -#if !ENABLE_SHADERS_MANAGER -#include "GLShader.hpp" -#endif // !ENABLE_SHADERS_MANAGER #endif // ENABLE_GCODE_VIEWER #if ENABLE_RENDER_SELECTION_CENTER @@ -24,9 +17,7 @@ namespace Slic3r { #if !ENABLE_GCODE_VIEWER class Shader; #endif // !ENABLE_GCODE_VIEWER -#if ENABLE_SHADERS_MANAGER class GLShaderProgram; -#endif // ENABLE_SHADERS_MANAGER namespace GUI { class TransformationType { @@ -218,9 +209,6 @@ private: #if ENABLE_GCODE_VIEWER GL_Model m_arrow; GL_Model m_curved_arrow; -#if !ENABLE_SHADERS_MANAGER - Shader m_arrows_shader; -#endif // !ENABLE_SHADERS_MANAGER #else mutable GLArrow m_arrow; mutable GLCurvedArrow m_curved_arrow; @@ -339,15 +327,7 @@ public: #if ENABLE_RENDER_SELECTION_CENTER void render_center(bool gizmo_is_dragging) const; #endif // ENABLE_RENDER_SELECTION_CENTER -#if ENABLE_GCODE_VIEWER void render_sidebar_hints(const std::string& sidebar_field) const; -#else -#if ENABLE_SHADERS_MANAGER - void render_sidebar_hints(const std::string& sidebar_field) const; -#else - void render_sidebar_hints(const std::string& sidebar_field, const Shader& shader) const; -#endif // ENABLE_SHADERS_MANAGER -#endif // ENABLE_GCODE_VIEWER bool requires_local_axes() const; From 43b78b630cee4979161a0d3757aead16b4c2b3cc Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 22 May 2020 16:37:53 +0200 Subject: [PATCH 095/255] GCodeViewer -> Enhanced legend icons --- src/slic3r/GUI/GCodeViewer.cpp | 67 +++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 18 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index c2e680b0eb..330a5a261b 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -987,12 +987,43 @@ void GCodeViewer::render_legend() const ImDrawList* draw_list = ImGui::GetWindowDrawList(); - auto add_item = [draw_list, &imgui](const Color& color, const std::string& label, std::function callback = nullptr) { + enum class EItemType : unsigned char + { + Rect, + Circle, + Line + }; + + auto add_item = [draw_list, &imgui](EItemType type, const Color& color, const std::string& label, std::function callback = nullptr) { float icon_size = ImGui::GetTextLineHeight(); ImVec2 pos = ImGui::GetCursorPos(); - draw_list->AddRect({ pos.x, pos.y }, { pos.x + icon_size, pos.y + icon_size }, ICON_BORDER_COLOR, 0.0f, 0); - draw_list->AddRectFilled({ pos.x + 1.0f, pos.y + 1.0f }, { pos.x + icon_size - 1.0f, pos.y + icon_size - 1.0f }, - ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f })); + switch (type) + { + default: + case EItemType::Rect: + { + draw_list->AddRect({ pos.x, pos.y }, { pos.x + icon_size, pos.y + icon_size }, ICON_BORDER_COLOR, 0.0f, 0); + draw_list->AddRectFilled({ pos.x + 1.0f, pos.y + 1.0f }, { pos.x + icon_size - 1.0f, pos.y + icon_size - 1.0f }, + ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f })); + break; + } + case EItemType::Circle: + { + draw_list->AddCircle({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, 0.5f * icon_size, ICON_BORDER_COLOR, 16); + draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, (0.5f * icon_size) - 2.0f, + ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); + draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, (0.5f * icon_size) - 3.0f, + ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); + draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, 1.5f, + ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); + break; + } + case EItemType::Line: + { + draw_list->AddLine({ pos.x + 1, pos.y + icon_size - 1}, { pos.x + icon_size - 1, pos.y + 1 }, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 3.0f); + break; + } + } // draw text ImGui::Dummy({ icon_size, icon_size }); @@ -1010,7 +1041,7 @@ void GCodeViewer::render_legend() const auto add_range_item = [this, draw_list, &imgui, add_item](int i, float value, unsigned int decimals) { char buf[1024]; ::sprintf(buf, "%.*f", decimals, value); - add_item(Range_Colors[i], buf); + add_item(EItemType::Rect, Range_Colors[i], buf); }; float step_size = range.step_size(); @@ -1052,7 +1083,7 @@ void GCodeViewer::render_legend() const if (!visible) ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.3333f); - add_item(Extrusion_Role_Colors[static_cast(role)], _u8L(ExtrusionEntity::role_to_string(role)), [this, role]() { + add_item(EItemType::Rect, Extrusion_Role_Colors[static_cast(role)], _u8L(ExtrusionEntity::role_to_string(role)), [this, role]() { if (role < erCount) { m_extrusions.role_visibility_flags = is_visible(role) ? m_extrusions.role_visibility_flags & ~(1 << role) : m_extrusions.role_visibility_flags | (1 << role); @@ -1082,7 +1113,7 @@ void GCodeViewer::render_legend() const if (it == m_extruder_ids.end()) continue; - add_item(m_tool_colors[i], (boost::format(_u8L("Extruder %d")) % (i + 1)).str()); + add_item(EItemType::Rect, m_tool_colors[i], (boost::format(_u8L("Extruder %d")) % (i + 1)).str()); } break; } @@ -1093,7 +1124,7 @@ void GCodeViewer::render_legend() const if (extruders_count == 1) { // single extruder use case if (custom_gcode_per_print_z.empty()) // no data to show - add_item(m_tool_colors.front(), _u8L("Default print color")); + add_item(EItemType::Rect, m_tool_colors.front(), _u8L("Default print color")); else { std::vector> cp_values; cp_values.reserve(custom_gcode_per_print_z.size()); @@ -1117,7 +1148,7 @@ void GCodeViewer::render_legend() const const int items_cnt = static_cast(cp_values.size()); if (items_cnt == 0) { // There is no one color change, but there are some pause print or custom Gcode - add_item(m_tool_colors.front(), _u8L("Default print color")); + add_item(EItemType::Rect, m_tool_colors.front(), _u8L("Default print color")); } else { for (int i = items_cnt; i >= 0; --i) { @@ -1125,14 +1156,14 @@ void GCodeViewer::render_legend() const std::string id_str = " (" + std::to_string(i + 1) + ")"; if (i == 0) { - add_item(m_tool_colors[i], (boost::format(_u8L("up to %.2f mm")) % cp_values.front().first).str() + id_str); + add_item(EItemType::Rect, m_tool_colors[i], (boost::format(_u8L("up to %.2f mm")) % cp_values.front().first).str() + id_str); break; } else if (i == items_cnt) { - add_item(m_tool_colors[i], (boost::format(_u8L("above %.2f mm")) % cp_values[i - 1].second).str() + id_str); + add_item(EItemType::Rect, m_tool_colors[i], (boost::format(_u8L("above %.2f mm")) % cp_values[i - 1].second).str() + id_str); continue; } - add_item(m_tool_colors[i], (boost::format(_u8L("%.2f - %.2f mm")) % cp_values[i - 1].second% cp_values[i].first).str() + id_str); + add_item(EItemType::Rect, m_tool_colors[i], (boost::format(_u8L("%.2f - %.2f mm")) % cp_values[i - 1].second% cp_values[i].first).str() + id_str); } } } @@ -1141,7 +1172,7 @@ void GCodeViewer::render_legend() const { // extruders for (unsigned int i = 0; i < (unsigned int)extruders_count; ++i) { - add_item(m_tool_colors[i], (boost::format(_u8L("Extruder %d")) % (i + 1)).str()); + add_item(EItemType::Rect, m_tool_colors[i], (boost::format(_u8L("Extruder %d")) % (i + 1)).str()); } // color changes @@ -1152,7 +1183,7 @@ void GCodeViewer::render_legend() const // create label for color change item std::string id_str = " (" + std::to_string(color_change_idx--) + ")"; - add_item(m_tool_colors[last_color_id--], + add_item(EItemType::Rect, m_tool_colors[last_color_id--], (boost::format(_u8L("Color change for Extruder %d at %.2f mm")) % custom_gcode_per_print_z[i].extruder % custom_gcode_per_print_z[i].print_z).str() + id_str); } } @@ -1185,9 +1216,9 @@ void GCodeViewer::render_legend() const ImGui::Separator(); // items - add_item(Travel_Colors[0], _u8L("Movement")); - add_item(Travel_Colors[1], _u8L("Extrusion")); - add_item(Travel_Colors[2], _u8L("Retraction")); + add_item(EItemType::Line, Travel_Colors[0], _u8L("Movement")); + add_item(EItemType::Line, Travel_Colors[1], _u8L("Extrusion")); + add_item(EItemType::Line, Travel_Colors[2], _u8L("Retraction")); break; } @@ -1206,7 +1237,7 @@ void GCodeViewer::render_legend() const auto add_option = [this, add_item](GCodeProcessor::EMoveType move_type, EOptionsColors color, const std::string& text) { const IBuffer& buffer = m_buffers[buffer_id(move_type)]; if (buffer.visible && buffer.indices_count > 0) - add_item(Options_Colors[static_cast(color)], text); + add_item(EItemType::Circle, Options_Colors[static_cast(color)], text); }; // options From 1c826c063b4bf75a0ec1fff991e219deb6b1e8fa Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 25 May 2020 10:48:53 +0200 Subject: [PATCH 096/255] GCodeViewer refactoring and GLShaderProgram upgrade --- resources/shaders/options_120.fs | 5 +- src/slic3r/GUI/3DScene.cpp | 2 +- src/slic3r/GUI/GCodeViewer.cpp | 148 ++++++------------------------- src/slic3r/GUI/GLShader.cpp | 25 ++++++ src/slic3r/GUI/GLShader.hpp | 3 + 5 files changed, 59 insertions(+), 124 deletions(-) diff --git a/resources/shaders/options_120.fs b/resources/shaders/options_120.fs index 5f699f9204..236174f3a3 100644 --- a/resources/shaders/options_120.fs +++ b/resources/shaders/options_120.fs @@ -5,10 +5,11 @@ uniform vec3 uniform_color; void main() { vec2 pos = gl_PointCoord - vec2(0.5, 0.5); - float sq_radius = pos.x * pos.x + pos.y * pos.y; + float sq_radius = dot(pos, pos); if (sq_radius > 0.25) discard; - else if ((sq_radius < 0.005625) || (sq_radius > 0.180625)) + + if ((sq_radius < 0.005625) || (sq_radius > 0.180625)) gl_FragColor = vec4(0.5 * uniform_color, 1.0); else gl_FragColor = vec4(uniform_color, 1.0); diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index fb7d4c24cf..49b1c255b7 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -672,7 +672,7 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab shader->set_uniform("print_box.actived", volume.first->shader_outside_printer_detection_enabled); shader->set_uniform("print_box.volume_world_matrix", volume.first->world_matrix()); shader->set_uniform("slope.actived", m_slope.active && !volume.first->is_modifier && !volume.first->is_wipe_tower); - shader->set_uniform("slope.volume_world_normal_matrix", volume.first->world_matrix().matrix().block(0, 0, 3, 3).inverse().transpose().cast()); + shader->set_uniform("slope.volume_world_normal_matrix", static_cast(volume.first->world_matrix().matrix().block(0, 0, 3, 3).inverse().transpose().cast())); volume.first->render(); #else diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 330a5a261b..54c7d3bb5a 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -740,9 +740,29 @@ void GCodeViewer::render_toolpaths() const bool is_glsl_120 = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20); int detected_point_sizes[2]; ::glGetIntegerv(GL_ALIASED_POINT_SIZE_RANGE, detected_point_sizes); - std::array point_sizes = { 2.0f, std::min(64.0f, static_cast(detected_point_sizes[1])) }; + std::array point_sizes = { std::min(8.0f, static_cast(detected_point_sizes[1])), std::min(48.0f, static_cast(detected_point_sizes[1])) }; double zoom = wxGetApp().plater()->get_camera().get_zoom(); + auto render_options = [this, is_glsl_120, zoom, point_sizes](const IBuffer& buffer, EOptionsColors colors_id, GLShaderProgram& shader) { + shader.set_uniform("uniform_color", Options_Colors[static_cast(colors_id)]); + shader.set_uniform("zoom", zoom); + shader.set_uniform("point_sizes", point_sizes); + if (is_glsl_120) { + glsafe(::glEnable(GL_POINT_SPRITE)); + glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); + } + for (const RenderPath& path : buffer.render_paths) { + glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); +#if ENABLE_GCODE_VIEWER_STATISTICS + ++m_statistics.gl_multi_points_calls_count; +#endif // ENABLE_GCODE_VIEWER_STATISTICS + } + if (is_glsl_120) { + glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); + glsafe(::glDisable(GL_POINT_SPRITE)); + } + }; + glsafe(::glCullFace(GL_BACK)); glsafe(::glLineWidth(3.0f)); @@ -773,146 +793,32 @@ void GCodeViewer::render_toolpaths() const { case GCodeProcessor::EMoveType::Tool_change: { - shader->set_uniform("uniform_color", Options_Colors[static_cast(EOptionsColors::ToolChanges)]); - shader->set_uniform("zoom", zoom); - shader->set_uniform("point_sizes", point_sizes); - if (is_glsl_120) - { - glsafe(::glEnable(GL_POINT_SPRITE)); - glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); - } - for (const RenderPath& path : buffer.render_paths) - { - glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_multi_points_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - } - if (is_glsl_120) - { - glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); - glsafe(::glDisable(GL_POINT_SPRITE)); - } + render_options(buffer, EOptionsColors::ToolChanges, *shader); break; } case GCodeProcessor::EMoveType::Color_change: { - shader->set_uniform("uniform_color", Options_Colors[static_cast(EOptionsColors::ColorChanges)]); - shader->set_uniform("zoom", zoom); - shader->set_uniform("point_sizes", point_sizes); - if (is_glsl_120) - { - glsafe(::glEnable(GL_POINT_SPRITE)); - glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); - } - for (const RenderPath& path : buffer.render_paths) - { - glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_multi_points_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - } - if (is_glsl_120) - { - glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); - glsafe(::glDisable(GL_POINT_SPRITE)); - } + render_options(buffer, EOptionsColors::ColorChanges, *shader); break; } case GCodeProcessor::EMoveType::Pause_Print: { - shader->set_uniform("uniform_color", Options_Colors[static_cast(EOptionsColors::PausePrints)]); - shader->set_uniform("zoom", zoom); - shader->set_uniform("point_sizes", point_sizes); - if (is_glsl_120) - { - glsafe(::glEnable(GL_POINT_SPRITE)); - glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); - } - for (const RenderPath& path : buffer.render_paths) - { - glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_multi_points_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - } - if (is_glsl_120) - { - glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); - glsafe(::glDisable(GL_POINT_SPRITE)); - } + render_options(buffer, EOptionsColors::PausePrints, *shader); break; } case GCodeProcessor::EMoveType::Custom_GCode: { - shader->set_uniform("uniform_color", Options_Colors[static_cast(EOptionsColors::CustomGCodes)]); - shader->set_uniform("zoom", zoom); - shader->set_uniform("point_sizes", point_sizes); - if (is_glsl_120) - { - glsafe(::glEnable(GL_POINT_SPRITE)); - glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); - } - for (const RenderPath& path : buffer.render_paths) - { - glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_multi_points_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - } - if (is_glsl_120) - { - glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); - glsafe(::glDisable(GL_POINT_SPRITE)); - } + render_options(buffer, EOptionsColors::CustomGCodes, *shader); break; } case GCodeProcessor::EMoveType::Retract: { - shader->set_uniform("uniform_color", Options_Colors[static_cast(EOptionsColors::Retractions)]); - shader->set_uniform("zoom", zoom); - shader->set_uniform("point_sizes", point_sizes); - if (is_glsl_120) - { - glsafe(::glEnable(GL_POINT_SPRITE)); - glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); - } - for (const RenderPath& path : buffer.render_paths) - { - glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_multi_points_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - if (is_glsl_120) - { - glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); - glsafe(::glDisable(GL_POINT_SPRITE)); - } - } + render_options(buffer, EOptionsColors::Retractions, *shader); break; } case GCodeProcessor::EMoveType::Unretract: { - shader->set_uniform("uniform_color", Options_Colors[static_cast(EOptionsColors::Unretractions)]); - shader->set_uniform("zoom", zoom); - shader->set_uniform("point_sizes", point_sizes); - if (is_glsl_120) - { - glsafe(::glEnable(GL_POINT_SPRITE)); - glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); - } - for (const RenderPath& path : buffer.render_paths) - { - glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_multi_points_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - } - if (is_glsl_120) - { - glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); - glsafe(::glDisable(GL_POINT_SPRITE)); - } + render_options(buffer, EOptionsColors::Unretractions, *shader); break; } case GCodeProcessor::EMoveType::Extrude: diff --git a/src/slic3r/GUI/GLShader.cpp b/src/slic3r/GUI/GLShader.cpp index 42e5b0a9f5..a6d641f89f 100644 --- a/src/slic3r/GUI/GLShader.cpp +++ b/src/slic3r/GUI/GLShader.cpp @@ -215,6 +215,16 @@ bool GLShaderProgram::set_uniform(const char* name, double value) const return set_uniform(name, static_cast(value)); } +bool GLShaderProgram::set_uniform(const char* name, const std::array& value) const +{ + int id = get_uniform_location(name); + if (id >= 0) { + glsafe(::glUniform4iv(id, 1, static_cast(value.data()))); + return true; + } + return false; +} + bool GLShaderProgram::set_uniform(const char* name, const std::array& value) const { int id = get_uniform_location(name); @@ -290,6 +300,21 @@ bool GLShaderProgram::set_uniform(const char* name, const Matrix3f& value) const return false; } +bool GLShaderProgram::set_uniform(const char* name, const Vec3f& value) const +{ + int id = get_uniform_location(name); + if (id >= 0) { + glsafe(::glUniform3fv(id, 1, static_cast(value.data()))); + return true; + } + return false; +} + +bool GLShaderProgram::set_uniform(const char* name, const Vec3d& value) const +{ + return set_uniform(name, static_cast(value.cast())); +} + int GLShaderProgram::get_attrib_location(const char* name) const { return (m_id > 0) ? ::glGetAttribLocation(m_id, name) : -1; diff --git a/src/slic3r/GUI/GLShader.hpp b/src/slic3r/GUI/GLShader.hpp index e58437fbd1..521f6796f1 100644 --- a/src/slic3r/GUI/GLShader.hpp +++ b/src/slic3r/GUI/GLShader.hpp @@ -43,6 +43,7 @@ public: bool set_uniform(const char* name, bool value) const; bool set_uniform(const char* name, float value) const; bool set_uniform(const char* name, double value) const; + bool set_uniform(const char* name, const std::array& value) const; bool set_uniform(const char* name, const std::array& value) const; bool set_uniform(const char* name, const std::array& value) const; bool set_uniform(const char* name, const std::array& value) const; @@ -50,6 +51,8 @@ public: bool set_uniform(const char* name, const Transform3f& value) const; bool set_uniform(const char* name, const Transform3d& value) const; bool set_uniform(const char* name, const Matrix3f& value) const; + bool set_uniform(const char* name, const Vec3f& value) const; + bool set_uniform(const char* name, const Vec3d& value) const; // returns -1 if not found int get_attrib_location(const char* name) const; From 1af798dbd7ed9b4763bd28c9cd9e65911cd7a2bd Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 25 May 2020 11:16:40 +0200 Subject: [PATCH 097/255] DoubleSlider::Control thumb text rendered closer to the slider --- resources/shaders/options_120.fs | 1 + src/slic3r/GUI/DoubleSlider.cpp | 10 +++++----- src/slic3r/GUI/GUI_Preview.cpp | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/resources/shaders/options_120.fs b/resources/shaders/options_120.fs index 236174f3a3..1c53f6c725 100644 --- a/resources/shaders/options_120.fs +++ b/resources/shaders/options_120.fs @@ -1,3 +1,4 @@ +// version 120 is needed for gl_PointCoord #version 120 uniform vec3 uniform_color; diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index 5c16e11eef..7415f333f8 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -566,12 +566,12 @@ void Control::draw_tick_text(wxDC& dc, const wxPoint& pos, int tick, bool right_ dc.GetMultiLineTextExtent(label, &text_width, &text_height); wxPoint text_pos; if (right_side) - text_pos = is_horizontal() ? wxPoint(pos.x + 1, pos.y + m_thumb_size.x) : - wxPoint(pos.x + m_thumb_size.x+1, pos.y - 0.5*text_height - 1); + text_pos = is_horizontal() ? wxPoint(pos.x + 1, pos.y + m_thumb_size.x / 4) : + wxPoint(pos.x + m_thumb_size.x + 1, pos.y - 0.5 * text_height - 1); else - text_pos = is_horizontal() ? wxPoint(pos.x - text_width - 1, pos.y - m_thumb_size.x - text_height) : - wxPoint(pos.x - text_width - 1 - m_thumb_size.x, pos.y - 0.5*text_height + 1); - dc.DrawText(label, text_pos); + text_pos = is_horizontal() ? wxPoint(pos.x - text_width - 1, pos.y - m_thumb_size.x / 4 - text_height) : + wxPoint(pos.x - text_width - 1 - m_thumb_size.x, pos.y - 0.5 * text_height + 1); + dc.DrawText(label, text_pos); } void Control::draw_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) const diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 1784dbccc1..fdbd396e26 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -343,7 +343,7 @@ bool Preview::init(wxWindow* parent, Model* model) #endif // ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER - m_moves_slider = new DoubleSlider::Control(m_bottom_toolbar_panel, wxID_ANY, 0, 0, 0, 100, wxDefaultPosition, wxSize(-1, 4 * GetTextExtent("m").y), wxSL_HORIZONTAL); + m_moves_slider = new DoubleSlider::Control(m_bottom_toolbar_panel, wxID_ANY, 0, 0, 0, 100, wxDefaultPosition, wxSize(-1, 3 * GetTextExtent("m").y), wxSL_HORIZONTAL); m_moves_slider->SetDrawMode(DoubleSlider::dmSequentialGCodeView); wxBoxSizer* bottom_toolbar_sizer = new wxBoxSizer(wxHORIZONTAL); From 6810550a6cb5fcca497f6017e182cc88b4aaa7ba Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 25 May 2020 11:59:12 +0200 Subject: [PATCH 098/255] DoubleSlider::Control background color --- src/slic3r/GUI/DoubleSlider.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index 7415f333f8..1682677df4 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -399,7 +399,11 @@ void Control::draw_focus_rect() void Control::render() { +#if ENABLE_GCODE_VIEWER + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); +#else SetBackgroundColour(GetParent()->GetBackgroundColour()); +#endif // ENABLE_GCODE_VIEWER draw_focus_rect(); wxPaintDC dc(this); @@ -770,7 +774,11 @@ void Control::draw_colored_band(wxDC& dc) // don't color a band for MultiExtruder mode if (m_ticks.empty() || m_mode == t_mode::MultiExtruder) { +#if ENABLE_GCODE_VIEWER + draw_band(dc, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW), main_band); +#else draw_band(dc, GetParent()->GetBackgroundColour(), main_band); +#endif // ENABLE_GCODE_VIEWER return; } From a63e5b352ee91276215fb0b087aa3dcde447f660 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 25 May 2020 12:08:09 +0200 Subject: [PATCH 099/255] ENABLE_GCODE_VIEWER -> Reduced vertical size of horizontal slider --- src/slic3r/GUI/GUI_Preview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index fdbd396e26..08cb3cdd76 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -343,7 +343,7 @@ bool Preview::init(wxWindow* parent, Model* model) #endif // ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER - m_moves_slider = new DoubleSlider::Control(m_bottom_toolbar_panel, wxID_ANY, 0, 0, 0, 100, wxDefaultPosition, wxSize(-1, 3 * GetTextExtent("m").y), wxSL_HORIZONTAL); + m_moves_slider = new DoubleSlider::Control(m_bottom_toolbar_panel, wxID_ANY, 0, 0, 0, 100, wxDefaultPosition, wxSize(-1, 2.5 * GetTextExtent("m").y), wxSL_HORIZONTAL); m_moves_slider->SetDrawMode(DoubleSlider::dmSequentialGCodeView); wxBoxSizer* bottom_toolbar_sizer = new wxBoxSizer(wxHORIZONTAL); From 2759380000f4407ea43e30deb7215dfbaf59b485 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 25 May 2020 13:53:41 +0200 Subject: [PATCH 100/255] DoubleSlider:Control platform dependent background color --- src/slic3r/GUI/DoubleSlider.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index 1682677df4..087b1774e5 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -400,7 +400,11 @@ void Control::draw_focus_rect() void Control::render() { #if ENABLE_GCODE_VIEWER +#ifdef _WIN32 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); +#else + SetBackgroundColour(GetParent()->GetBackgroundColour()); +#endif // _WIN32 #else SetBackgroundColour(GetParent()->GetBackgroundColour()); #endif // ENABLE_GCODE_VIEWER @@ -570,10 +574,10 @@ void Control::draw_tick_text(wxDC& dc, const wxPoint& pos, int tick, bool right_ dc.GetMultiLineTextExtent(label, &text_width, &text_height); wxPoint text_pos; if (right_side) - text_pos = is_horizontal() ? wxPoint(pos.x + 1, pos.y + m_thumb_size.x / 4) : + text_pos = is_horizontal() ? wxPoint(pos.x + 1, pos.y + m_thumb_size.x / 3) : wxPoint(pos.x + m_thumb_size.x + 1, pos.y - 0.5 * text_height - 1); else - text_pos = is_horizontal() ? wxPoint(pos.x - text_width - 1, pos.y - m_thumb_size.x / 4 - text_height) : + text_pos = is_horizontal() ? wxPoint(pos.x - text_width - 1, pos.y - m_thumb_size.x / 3 - text_height) : wxPoint(pos.x - text_width - 1 - m_thumb_size.x, pos.y - 0.5 * text_height + 1); dc.DrawText(label, text_pos); } @@ -775,7 +779,11 @@ void Control::draw_colored_band(wxDC& dc) if (m_ticks.empty() || m_mode == t_mode::MultiExtruder) { #if ENABLE_GCODE_VIEWER +#ifdef _WIN32 draw_band(dc, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW), main_band); +#else + draw_band(dc, GetParent()->GetBackgroundColour(), main_band); +#endif // _WIN32 #else draw_band(dc, GetParent()->GetBackgroundColour(), main_band); #endif // ENABLE_GCODE_VIEWER From 1d317489fd096751335c633a85b2ff2ee1669e2d Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 26 May 2020 08:16:08 +0200 Subject: [PATCH 101/255] GCodeViewer -> Temporary ImGui dialog for editing shaders parameters --- resources/shaders/options_120.fs | 27 +++++-- src/libslic3r/Technologies.hpp | 2 + src/slic3r/GUI/GCodeViewer.cpp | 127 ++++++++++++++++++++++++++++--- src/slic3r/GUI/GCodeViewer.hpp | 26 +++++-- src/slic3r/GUI/GLCanvas3D.cpp | 3 + 5 files changed, 165 insertions(+), 20 deletions(-) diff --git a/resources/shaders/options_120.fs b/resources/shaders/options_120.fs index 1c53f6c725..90d417b6e7 100644 --- a/resources/shaders/options_120.fs +++ b/resources/shaders/options_120.fs @@ -2,6 +2,26 @@ #version 120 uniform vec3 uniform_color; +uniform float percent_outline_radius; +uniform float percent_center_radius; + +vec4 hard_color(float sq_radius) +{ + if ((sq_radius < 0.005625) || (sq_radius > 0.180625)) + return vec4(0.5 * uniform_color, 1.0); + else + return vec4(uniform_color, 1.0); +} + +vec4 custom_color(float sq_radius) +{ + float in_radius = 0.5 * percent_center_radius; + float out_radius = 0.5 * (1.0 - percent_outline_radius); + if ((sq_radius < in_radius * in_radius) || (sq_radius > out_radius * out_radius)) + return vec4(0.5 * uniform_color, 1.0); + else + return vec4(uniform_color, 1.0); +} void main() { @@ -9,9 +29,6 @@ void main() float sq_radius = dot(pos, pos); if (sq_radius > 0.25) discard; - - if ((sq_radius < 0.005625) || (sq_radius > 0.180625)) - gl_FragColor = vec4(0.5 * uniform_color, 1.0); - else - gl_FragColor = vec4(uniform_color, 1.0); + + gl_FragColor = custom_color(sq_radius); } diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 3df9da961d..5631dadf34 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -45,5 +45,7 @@ // Enable G-Code viewer #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) #define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) +#define ENABLE_GCODE_VIEWER_SHADERS_EDITOR (1 && ENABLE_GCODE_VIEWER) + #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 54c7d3bb5a..6d41976941 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -221,6 +221,19 @@ const std::vector GCodeViewer::Range_Colors {{ { 0.761f, 0.322f, 0.235f } // reddish }}; +bool GCodeViewer::init() +{ + set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Extrude, true); + m_sequential_view.marker.init(); + init_shaders(); + + std::array point_sizes; + ::glGetIntegerv(GL_ALIASED_POINT_SIZE_RANGE, point_sizes.data()); + m_detected_point_sizes = { static_cast(point_sizes[0]), static_cast(point_sizes[1]) }; + + return true; +} + void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized) { // avoid processing if called with the same gcode_result @@ -328,6 +341,9 @@ void GCodeViewer::render() const #if ENABLE_GCODE_VIEWER_STATISTICS render_statistics(); #endif // ENABLE_GCODE_VIEWER_STATISTICS +#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR + render_shaders_editor(); +#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR } bool GCodeViewer::is_toolpath_move_type_visible(GCodeProcessor::EMoveType type) const @@ -737,30 +753,47 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool void GCodeViewer::render_toolpaths() const { +#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR + bool is_glsl_120 = m_shaders_editor.glsl_version == 1 && wxGetApp().is_glsl_version_greater_or_equal_to(1, 20); + std::array point_sizes; + if (m_shaders_editor.size_dependent_on_zoom) + { + point_sizes = { std::min(static_cast(m_shaders_editor.sizes[0]), m_detected_point_sizes[1]), std::min(static_cast(m_shaders_editor.sizes[1]), m_detected_point_sizes[1]) }; + } + else + point_sizes = { static_cast(m_shaders_editor.fixed_size), static_cast(m_shaders_editor.fixed_size) }; +#else bool is_glsl_120 = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20); - int detected_point_sizes[2]; - ::glGetIntegerv(GL_ALIASED_POINT_SIZE_RANGE, detected_point_sizes); - std::array point_sizes = { std::min(8.0f, static_cast(detected_point_sizes[1])), std::min(48.0f, static_cast(detected_point_sizes[1])) }; + std::array point_sizes = { std::min(8.0f, m_detected_point_sizes[1]), std::min(48.0f, m_detected_point_sizes[1]) }; +#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR double zoom = wxGetApp().plater()->get_camera().get_zoom(); auto render_options = [this, is_glsl_120, zoom, point_sizes](const IBuffer& buffer, EOptionsColors colors_id, GLShaderProgram& shader) { shader.set_uniform("uniform_color", Options_Colors[static_cast(colors_id)]); +#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR + shader.set_uniform("zoom", m_shaders_editor.size_dependent_on_zoom ? zoom : 1.0f); + shader.set_uniform("percent_outline_radius", 0.01f * static_cast(m_shaders_editor.percent_outline)); + shader.set_uniform("percent_center_radius", 0.01f * static_cast(m_shaders_editor.percent_center)); +#else shader.set_uniform("zoom", zoom); + shader.set_uniform("percent_outline_radius", 0.15f); + shader.set_uniform("percent_center_radius", 0.15f); +#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR shader.set_uniform("point_sizes", point_sizes); - if (is_glsl_120) { + glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); + if (is_glsl_120) glsafe(::glEnable(GL_POINT_SPRITE)); - glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); - } + for (const RenderPath& path : buffer.render_paths) { glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } - if (is_glsl_120) { - glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); + if (is_glsl_120) glsafe(::glDisable(GL_POINT_SPRITE)); - } + + glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); }; glsafe(::glCullFace(GL_BACK)); @@ -900,7 +933,11 @@ void GCodeViewer::render_legend() const Line }; +#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR + auto add_item = [this, draw_list, &imgui](EItemType type, const Color& color, const std::string& label, std::function callback = nullptr) { +#else auto add_item = [draw_list, &imgui](EItemType type, const Color& color, const std::string& label, std::function callback = nullptr) { +#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR float icon_size = ImGui::GetTextLineHeight(); ImVec2 pos = ImGui::GetCursorPos(); switch (type) @@ -915,6 +952,20 @@ void GCodeViewer::render_legend() const } case EItemType::Circle: { +#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR + draw_list->AddCircle({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, 0.5f * icon_size, ICON_BORDER_COLOR, 16); + draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, (0.5f * icon_size) - 2.0f, + ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); + float radius = ((0.5f * icon_size) - 2.0f) * (1.0f - 0.01f * static_cast(m_shaders_editor.percent_outline)); + draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, radius, + ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); + if (m_shaders_editor.percent_center > 0) + { + radius = ((0.5f * icon_size) - 2.0f) * 0.01f * static_cast(m_shaders_editor.percent_center); + draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, radius, + ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); + } +#else draw_list->AddCircle({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, 0.5f * icon_size, ICON_BORDER_COLOR, 16); draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, (0.5f * icon_size) - 2.0f, ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); @@ -922,6 +973,7 @@ void GCodeViewer::render_legend() const ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, 1.5f, ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); +#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR break; } case EItemType::Line: @@ -1266,6 +1318,63 @@ void GCodeViewer::render_statistics() const } #endif // ENABLE_GCODE_VIEWER_STATISTICS +#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR +void GCodeViewer::render_shaders_editor() const +{ + auto set_shader = [this](const std::string& shader) { + unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); + unsigned char end_id = buffer_id(GCodeProcessor::EMoveType::Custom_GCode); + for (unsigned char i = begin_id; i <= end_id; ++i) { + m_buffers[i].shader = shader; + } + }; + + static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); + + ImGuiWrapper& imgui = *wxGetApp().imgui(); + + Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size(); + imgui.set_next_window_pos(static_cast(cnv_size.get_width()), 0.5f * static_cast(cnv_size.get_height()), ImGuiCond_Once, 1.0f, 0.5f); + imgui.begin(std::string("Shaders editor (DEV only)"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize); + + ImGui::RadioButton("glsl version 1.10 (low end PCs)", &m_shaders_editor.glsl_version, 0); + ImGui::RadioButton("glsl version 1.20 (default)", &m_shaders_editor.glsl_version, 1); + switch (m_shaders_editor.glsl_version) + { + case 0: { set_shader("options_110"); break; } + case 1: { set_shader("options_120"); break; } + } + + if (ImGui::CollapsingHeader("Options", ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::Checkbox("size dependent on zoom", &m_shaders_editor.size_dependent_on_zoom); + if (m_shaders_editor.size_dependent_on_zoom) + { + if (ImGui::SliderInt("min size (min zoom)", &m_shaders_editor.sizes[0], 1, 100)) + { + if (m_shaders_editor.sizes[1] < m_shaders_editor.sizes[0]) + m_shaders_editor.sizes[1] = m_shaders_editor.sizes[0]; + } + ImGui::SliderInt("max size (max zoom)", &m_shaders_editor.sizes[1], 1, 100); + { + if (m_shaders_editor.sizes[1] < m_shaders_editor.sizes[0]) + m_shaders_editor.sizes[0] = m_shaders_editor.sizes[1]; + } + } + else + ImGui::SliderInt("fixed size", &m_shaders_editor.fixed_size, 1, 100); + + if (m_shaders_editor.glsl_version == 1) + { + ImGui::SliderInt("percent outline", &m_shaders_editor.percent_outline, 0, 50); + ImGui::SliderInt("percent center", &m_shaders_editor.percent_center, 0, 50); + } + } + + imgui.end(); +} +#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR + bool GCodeViewer::is_travel_in_z_range(size_t id) const { const IBuffer& buffer = m_buffers[buffer_id(GCodeProcessor::EMoveType::Travel)]; diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 5ab9f68325..e7c620fc5e 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -202,6 +202,18 @@ class GCodeViewer }; #endif // ENABLE_GCODE_VIEWER_STATISTICS +#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR + struct ShadersEditor + { + int glsl_version{ 1 }; + bool size_dependent_on_zoom{ true }; + int fixed_size{ 16 }; + std::array sizes{ 8, 64 }; + int percent_outline{ 15 }; + int percent_center{ 15 }; + }; +#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR + public: struct SequentialView { @@ -271,17 +283,16 @@ private: #if ENABLE_GCODE_VIEWER_STATISTICS mutable Statistics m_statistics; #endif // ENABLE_GCODE_VIEWER_STATISTICS +#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR + mutable ShadersEditor m_shaders_editor; +#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR + std::array m_detected_point_sizes = { 0.0f, 0.0f }; public: GCodeViewer() = default; ~GCodeViewer() { reset(); } - bool init() { - set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Extrude, true); - m_sequential_view.marker.init(); - init_shaders(); - return true; - } + bool init(); // extract rendering data from the given parameters void load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized); @@ -334,6 +345,9 @@ private: #if ENABLE_GCODE_VIEWER_STATISTICS void render_statistics() const; #endif // ENABLE_GCODE_VIEWER_STATISTICS +#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR + void render_shaders_editor() const; +#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR bool is_visible(ExtrusionRole role) const { return role < erCount && (m_extrusions.role_visibility_flags & (1 << role)) != 0; } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ee23783c38..0c0bad7a09 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3502,6 +3502,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) #ifdef SLIC3R_DEBUG_MOUSE_EVENTS printf((format_mouse_event_debug_message(evt) + " - Consumed by ImGUI\n").c_str()); #endif /* SLIC3R_DEBUG_MOUSE_EVENTS */ +#if ENABLE_GCODE_VIEWER + m_dirty = true; +#endif // ENABLE_GCODE_VIEWER // do not return if dragging or tooltip not empty to allow for tooltip update if (!m_mouse.dragging && m_tooltip.is_empty()) return; From 8f91b4f4f4a726fe82b961357e284888ea04121d Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 26 May 2020 08:34:19 +0200 Subject: [PATCH 102/255] DoubleSlider::Control -> Tweaks to text position for horizontal case --- src/slic3r/GUI/DoubleSlider.cpp | 4 ++-- src/slic3r/GUI/GUI_Preview.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index 087b1774e5..582a356754 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -574,10 +574,10 @@ void Control::draw_tick_text(wxDC& dc, const wxPoint& pos, int tick, bool right_ dc.GetMultiLineTextExtent(label, &text_width, &text_height); wxPoint text_pos; if (right_side) - text_pos = is_horizontal() ? wxPoint(pos.x + 1, pos.y + m_thumb_size.x / 3) : + text_pos = is_horizontal() ? wxPoint(pos.x + 1, pos.y + m_thumb_size.x / 2 + 1) : wxPoint(pos.x + m_thumb_size.x + 1, pos.y - 0.5 * text_height - 1); else - text_pos = is_horizontal() ? wxPoint(pos.x - text_width - 1, pos.y - m_thumb_size.x / 3 - text_height) : + text_pos = is_horizontal() ? wxPoint(pos.x - text_width - 1, pos.y - m_thumb_size.x / 2 - text_height - 1) : wxPoint(pos.x - text_width - 1 - m_thumb_size.x, pos.y - 0.5 * text_height + 1); dc.DrawText(label, text_pos); } diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 08cb3cdd76..fdbd396e26 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -343,7 +343,7 @@ bool Preview::init(wxWindow* parent, Model* model) #endif // ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER - m_moves_slider = new DoubleSlider::Control(m_bottom_toolbar_panel, wxID_ANY, 0, 0, 0, 100, wxDefaultPosition, wxSize(-1, 2.5 * GetTextExtent("m").y), wxSL_HORIZONTAL); + m_moves_slider = new DoubleSlider::Control(m_bottom_toolbar_panel, wxID_ANY, 0, 0, 0, 100, wxDefaultPosition, wxSize(-1, 3 * GetTextExtent("m").y), wxSL_HORIZONTAL); m_moves_slider->SetDrawMode(DoubleSlider::dmSequentialGCodeView); wxBoxSizer* bottom_toolbar_sizer = new wxBoxSizer(wxHORIZONTAL); From aa04f0e555b1f8e073ec1383324d0e30b5c6da24 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 27 May 2020 08:06:02 +0200 Subject: [PATCH 103/255] ENABLE_GCODE_VIEWER -> Completed implementation of new GLModel class --- src/slic3r/GUI/3DBed.cpp | 29 +++++++++++-- src/slic3r/GUI/3DBed.hpp | 15 ++++++- src/slic3r/GUI/3DScene.cpp | 4 +- src/slic3r/GUI/3DScene.hpp | 4 +- src/slic3r/GUI/GCodeViewer.hpp | 2 +- src/slic3r/GUI/GLModel.cpp | 79 ++++++++++++++++++++++------------ src/slic3r/GUI/GLModel.hpp | 12 ++++-- src/slic3r/GUI/Selection.hpp | 4 +- 8 files changed, 105 insertions(+), 44 deletions(-) diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index b5a34b2ee7..450a538d04 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -358,14 +358,23 @@ void Bed3D::calc_bounding_boxes() const // extend to contain axes #if ENABLE_GCODE_VIEWER - m_extended_bounding_box.merge(m_axes.get_total_length() * Vec3d::Ones()); -#else - m_extended_bounding_box.merge(m_axes.length + Axes::ArrowLength * Vec3d::Ones()); -#endif // ENABLE_GCODE_VIEWER + m_extended_bounding_box.merge(m_axes.get_origin() + m_axes.get_total_length() * Vec3d::Ones()); + m_extended_bounding_box.merge(m_extended_bounding_box.min + Vec3d(-Axes::DefaultTipRadius, -Axes::DefaultTipRadius, m_extended_bounding_box.max(2))); + // extend to contain model, if any + BoundingBoxf3 model_bb = m_model.get_bounding_box(); + if (model_bb.defined) + { + model_bb.translate(m_model_offset); + m_extended_bounding_box.merge(model_bb); + } +#else + m_extended_bounding_box.merge(m_axes.get_total_length() * Vec3d::Ones()); + m_extended_bounding_box.merge(m_axes.length + Axes::ArrowLength * Vec3d::Ones()); // extend to contain model, if any if (!m_model.get_filename().empty()) m_extended_bounding_box.merge(m_model.get_transformed_bounding_box()); +#endif // ENABLE_GCODE_VIEWER } void Bed3D::calc_triangles(const ExPolygon& poly) @@ -621,7 +630,11 @@ void Bed3D::render_model() const // move the model so that its origin (0.0, 0.0, 0.0) goes into the bed shape center and a bit down to avoid z-fighting with the texture quad Vec3d shift = m_bounding_box.center(); shift(2) = -0.03; +#if ENABLE_GCODE_VIEWER + m_model_offset = shift; +#else m_model.set_offset(shift); +#endif // ENABLE_GCODE_VIEWER // update extended bounding box calc_bounding_boxes(); @@ -633,7 +646,15 @@ void Bed3D::render_model() const if (shader != nullptr) { shader->start_using(); +#if ENABLE_GCODE_VIEWER + shader->set_uniform("uniform_color", m_model_color); + ::glPushMatrix(); + ::glTranslated(m_model_offset(0), m_model_offset(1), m_model_offset(2)); +#endif // ENABLE_GCODE_VIEWER m_model.render(); +#if ENABLE_GCODE_VIEWER + ::glPopMatrix(); +#endif // ENABLE_GCODE_VIEWER shader->stop_using(); } } diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp index 2487be2e47..b9e952c4a4 100644 --- a/src/slic3r/GUI/3DBed.hpp +++ b/src/slic3r/GUI/3DBed.hpp @@ -8,6 +8,9 @@ #endif // ENABLE_GCODE_VIEWER #include +#if ENABLE_GCODE_VIEWER +#include +#endif // ENABLE_GCODE_VIEWER #if !ENABLE_GCODE_VIEWER class GLUquadric; @@ -52,10 +55,13 @@ class Bed3D #if ENABLE_GCODE_VIEWER class Axes { + public: static const float DefaultStemRadius; static const float DefaultStemLength; static const float DefaultTipRadius; static const float DefaultTipLength; + + private: #else struct Axes { @@ -67,7 +73,7 @@ class Bed3D #if ENABLE_GCODE_VIEWER Vec3d m_origin{ Vec3d::Zero() }; float m_stem_length{ DefaultStemLength }; - mutable GL_Model m_arrow; + mutable GLModel m_arrow; public: #else @@ -82,6 +88,7 @@ class Bed3D #endif // !ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER + const Vec3d& get_origin() const { return m_origin; } void set_origin(const Vec3d& origin) { m_origin = origin; } void set_stem_length(float length); float get_total_length() const { return m_stem_length + DefaultTipLength; } @@ -113,7 +120,13 @@ private: GeometryBuffer m_triangles; GeometryBuffer m_gridlines; mutable GLTexture m_texture; +#if ENABLE_GCODE_VIEWER + mutable GLModel m_model; + mutable Vec3d m_model_offset{ Vec3d::Zero() }; + std::array m_model_color{ 0.235f, 0.235f, 0.235f, 1.0f }; +#else mutable GLBed m_model; +#endif // ENABLE_GCODE_VIEWER // temporary texture shown until the main texture has still no levels compressed mutable GLTexture m_temp_texture; mutable unsigned int m_vbo_id; diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 49b1c255b7..59be43271a 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -1822,6 +1822,7 @@ void _3DScene::point3_to_verts(const Vec3crd& point, double width, double height thick_point_to_verts(point, width, height, volume); } +#if !ENABLE_GCODE_VIEWER GLModel::GLModel() : m_filename("") { @@ -1904,7 +1905,6 @@ void GLModel::render() const glsafe(::glDisable(GL_BLEND)); } -#if !ENABLE_GCODE_VIEWER bool GLArrow::on_init() { Pointf3s vertices; @@ -2076,7 +2076,6 @@ bool GLCurvedArrow::on_init() m_volume.indexed_vertex_array.finalize_geometry(true); return true; } -#endif // !ENABLE_GCODE_VIEWER bool GLBed::on_init_from_file(const std::string& filename) { @@ -2108,5 +2107,6 @@ bool GLBed::on_init_from_file(const std::string& filename) return true; } +#endif // !ENABLE_GCODE_VIEWER } // namespace Slic3r diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index fd74cd4912..d7bd0c1b3c 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -599,6 +599,7 @@ private: GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCollection::ERenderType type, const Transform3d& view_matrix, std::function filter_func = nullptr); +#if !ENABLE_GCODE_VIEWER class GLModel { protected: @@ -636,7 +637,6 @@ protected: virtual bool on_init_from_file(const std::string& filename) { return false; } }; -#if !ENABLE_GCODE_VIEWER class GLArrow : public GLModel { protected: @@ -653,13 +653,13 @@ public: protected: bool on_init() override; }; -#endif // !ENABLE_GCODE_VIEWER class GLBed : public GLModel { protected: bool on_init_from_file(const std::string& filename) override; }; +#endif // !ENABLE_GCODE_VIEWER struct _3DScene { diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index e7c620fc5e..1d940b66a7 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -219,7 +219,7 @@ public: { class Marker { - GL_Model m_model; + GLModel m_model; Transform3f m_world_transform; BoundingBoxf3 m_world_bounding_box; std::array m_color{ 1.0f, 1.0f, 1.0f, 1.0f }; diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index e5b6cbdcb6..e738aa3c49 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -3,13 +3,17 @@ #include "3DScene.hpp" #include "libslic3r/TriangleMesh.hpp" +#include "libslic3r/Model.hpp" + +#include +#include #include namespace Slic3r { namespace GUI { -void GL_Model::init_from(const GLModelInitializationData& data) +void GLModel::init_from(const GLModelInitializationData& data) { assert(!data.positions.empty() && !data.triangles.empty()); assert(data.positions.size() == data.normals.size()); @@ -20,8 +24,9 @@ void GL_Model::init_from(const GLModelInitializationData& data) // vertices/normals data std::vector vertices(6 * data.positions.size()); for (size_t i = 0; i < data.positions.size(); ++i) { - ::memcpy(static_cast(&vertices[i * 6]), static_cast(data.positions[i].data()), 3 * sizeof(float)); - ::memcpy(static_cast(&vertices[3 + i * 6]), static_cast(data.normals[i].data()), 3 * sizeof(float)); + size_t offset = i * 6; + ::memcpy(static_cast(&vertices[offset]), static_cast(data.positions[i].data()), 3 * sizeof(float)); + ::memcpy(static_cast(&vertices[3 + offset]), static_cast(data.normals[i].data()), 3 * sizeof(float)); } // indices data @@ -41,34 +46,26 @@ void GL_Model::init_from(const GLModelInitializationData& data) send_to_gpu(vertices, indices); } -void GL_Model::init_from(const TriangleMesh& mesh) +void GLModel::init_from(const TriangleMesh& mesh) { - auto get_normal = [](const std::array& triangle) { - return (triangle[1] - triangle[0]).cross(triangle[2] - triangle[0]).normalized(); - }; - if (m_vbo_id > 0) // call reset() if you want to reuse this model return; - assert(!mesh.its.vertices.empty() && !mesh.its.indices.empty()); // call require_shared_vertices() before to pass the mesh to this method + std::vector vertices = std::vector(18 * mesh.stl.stats.number_of_facets); + std::vector indices = std::vector(3 * mesh.stl.stats.number_of_facets); - // vertices data -> load from mesh - std::vector vertices(6 * mesh.its.vertices.size()); - for (size_t i = 0; i < mesh.its.vertices.size(); ++i) { - ::memcpy(static_cast(&vertices[i * 6]), static_cast(mesh.its.vertices[i].data()), 3 * sizeof(float)); - } - - // indices/normals data -> load from mesh - std::vector indices(3 * mesh.its.indices.size()); - for (size_t i = 0; i < mesh.its.indices.size(); ++i) { - const stl_triangle_vertex_indices& triangle = mesh.its.indices[i]; - for (size_t j = 0; j < 3; ++j) { - indices[i * 3 + j] = static_cast(triangle[j]); + unsigned int vertices_count = 0; + for (uint32_t i = 0; i < mesh.stl.stats.number_of_facets; ++i) { + const stl_facet& facet = mesh.stl.facet_start[i]; + for (uint32_t j = 0; j < 3; ++j) { + uint32_t offset = i * 18 + j * 6; + ::memcpy(static_cast(&vertices[offset]), static_cast(facet.vertex[j].data()), 3 * sizeof(float)); + ::memcpy(static_cast(&vertices[3 + offset]), static_cast(facet.normal.data()), 3 * sizeof(float)); } - Vec3f normal = get_normal({ mesh.its.vertices[triangle[0]], mesh.its.vertices[triangle[1]], mesh.its.vertices[triangle[2]] }); - ::memcpy(static_cast(&vertices[3 + static_cast(triangle[0]) * 6]), static_cast(normal.data()), 3 * sizeof(float)); - ::memcpy(static_cast(&vertices[3 + static_cast(triangle[1]) * 6]), static_cast(normal.data()), 3 * sizeof(float)); - ::memcpy(static_cast(&vertices[3 + static_cast(triangle[2]) * 6]), static_cast(normal.data()), 3 * sizeof(float)); + for (uint32_t j = 0; j < 3; ++j) { + indices[i * 3 + j] = vertices_count + j; + } + vertices_count += 3; } m_indices_count = static_cast(indices.size()); @@ -77,7 +74,32 @@ void GL_Model::init_from(const TriangleMesh& mesh) send_to_gpu(vertices, indices); } -void GL_Model::reset() +bool GLModel::init_from_file(const std::string& filename) +{ + if (!boost::filesystem::exists(filename)) + return false; + + if (!boost::algorithm::iends_with(filename, ".stl")) + return false; + + Model model; + try + { + model = Model::read_from_file(filename); + } + catch (std::exception&) + { + return false; + } + + init_from(model.mesh()); + + m_filename = filename; + + return true; +} + +void GLModel::reset() { // release gpu memory if (m_ibo_id > 0) { @@ -92,9 +114,10 @@ void GL_Model::reset() m_indices_count = 0; m_bounding_box = BoundingBoxf3(); + m_filename = std::string(); } -void GL_Model::render() const +void GLModel::render() const { if (m_vbo_id == 0 || m_ibo_id == 0) return; @@ -116,7 +139,7 @@ void GL_Model::render() const glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); } -void GL_Model::send_to_gpu(const std::vector& vertices, const std::vector& indices) +void GLModel::send_to_gpu(const std::vector& vertices, const std::vector& indices) { // vertex data -> send to gpu glsafe(::glGenBuffers(1, &m_vbo_id)); diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index a11073b191..0b4a69bdb0 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -4,6 +4,7 @@ #include "libslic3r/Point.hpp" #include "libslic3r/BoundingBox.hpp" #include +#include namespace Slic3r { @@ -18,24 +19,28 @@ namespace GUI { std::vector triangles; }; - class GL_Model + class GLModel { unsigned int m_vbo_id{ 0 }; unsigned int m_ibo_id{ 0 }; size_t m_indices_count{ 0 }; BoundingBoxf3 m_bounding_box; + std::string m_filename; public: - virtual ~GL_Model() { reset(); } + virtual ~GLModel() { reset(); } void init_from(const GLModelInitializationData& data); void init_from(const TriangleMesh& mesh); + bool init_from_file(const std::string& filename); void reset(); void render() const; const BoundingBoxf3& get_bounding_box() const { return m_bounding_box; } + const std::string& get_filename() const { return m_filename; } + private: void send_to_gpu(const std::vector& vertices, const std::vector& indices); }; @@ -44,8 +49,7 @@ namespace GUI { // create an arrow with cylindrical stem and conical tip, with the given dimensions and resolution // the origin of the arrow is in the center of the stem cap // the arrow has its axis of symmetry along the Z axis and is pointing upward - GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float tip_height, - float stem_radius, float stem_height); + GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float tip_height, float stem_radius, float stem_height); // create an arrow whose stem is a quarter of circle, with the given dimensions and resolution // the origin of the arrow is in the center of the circle diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 34024875b3..c4ba30ed56 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -207,8 +207,8 @@ private: GLUquadricObj* m_quadric; #endif // ENABLE_RENDER_SELECTION_CENTER #if ENABLE_GCODE_VIEWER - GL_Model m_arrow; - GL_Model m_curved_arrow; + GLModel m_arrow; + GLModel m_curved_arrow; #else mutable GLArrow m_arrow; mutable GLCurvedArrow m_curved_arrow; From 94a4689b003b9e6e35487b09213d2dfd29c42954 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 27 May 2020 11:50:29 +0200 Subject: [PATCH 104/255] DoubleSlider::Control -> Change text position at the edges of horizontal slider --- src/slic3r/GUI/DoubleSlider.cpp | 33 +++++++++++++++++++++++++++------ src/slic3r/GUI/DoubleSlider.hpp | 4 ++-- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index 582a356754..8cf4aea35d 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -272,14 +272,14 @@ wxCoord Control::get_position_from_value(const int value) return wxCoord(SLIDER_MARGIN + int(val*step + 0.5)); } -wxSize Control::get_size() +wxSize Control::get_size() const { int w, h; get_size(&w, &h); return wxSize(w, h); } -void Control::get_size(int *w, int *h) +void Control::get_size(int* w, int* h) const { GetSize(w, h); is_horizontal() ? *w -= m_lock_icon_dim : *h -= m_lock_icon_dim; @@ -574,11 +574,32 @@ void Control::draw_tick_text(wxDC& dc, const wxPoint& pos, int tick, bool right_ dc.GetMultiLineTextExtent(label, &text_width, &text_height); wxPoint text_pos; if (right_side) - text_pos = is_horizontal() ? wxPoint(pos.x + 1, pos.y + m_thumb_size.x / 2 + 1) : - wxPoint(pos.x + m_thumb_size.x + 1, pos.y - 0.5 * text_height - 1); + { + if (is_horizontal()) + { + int width; + int height; + get_size(&width, &height); + + int x_right = pos.x + 1 + text_width; + int xx = (x_right < width) ? pos.x + 1 : pos.x - text_width - 1; + text_pos = wxPoint(xx, pos.y + m_thumb_size.x / 2 + 1); + } + else + text_pos = wxPoint(pos.x + m_thumb_size.x + 1, pos.y - 0.5 * text_height - 1); + } else - text_pos = is_horizontal() ? wxPoint(pos.x - text_width - 1, pos.y - m_thumb_size.x / 2 - text_height - 1) : - wxPoint(pos.x - text_width - 1 - m_thumb_size.x, pos.y - 0.5 * text_height + 1); + { + if (is_horizontal()) + { + int x = pos.x - text_width - 1; + int xx = (x > 0) ? x : pos.x + 1; + text_pos = wxPoint(xx, pos.y - m_thumb_size.x / 2 - text_height - 1); + } + else + text_pos = wxPoint(pos.x - text_width - 1 - m_thumb_size.x, pos.y - 0.5 * text_height + 1); + } + dc.DrawText(label, text_pos); } diff --git a/src/slic3r/GUI/DoubleSlider.hpp b/src/slic3r/GUI/DoubleSlider.hpp index a3d836c3f2..8aaba86a63 100644 --- a/src/slic3r/GUI/DoubleSlider.hpp +++ b/src/slic3r/GUI/DoubleSlider.hpp @@ -301,8 +301,8 @@ private: int get_value_from_position(const wxCoord x, const wxCoord y); int get_value_from_position(const wxPoint pos) { return get_value_from_position(pos.x, pos.y); } wxCoord get_position_from_value(const int value); - wxSize get_size(); - void get_size(int *w, int *h); + wxSize get_size() const; + void get_size(int* w, int* h) const; double get_double_value(const SelectedSlider& selection); wxString get_tooltip(int tick = -1); int get_edited_tick_for_position(wxPoint pos, const std::string& gcode = ColorChangeCode); From a0acf24ab8067e14acf977b920d93933f51efb4f Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 27 May 2020 14:29:27 +0200 Subject: [PATCH 105/255] DoubleSlider::Control -> Fixed crash when pressing numpad [+] and [-] keys while the horizontal slider has focus --- src/slic3r/GUI/DoubleSlider.cpp | 38 +++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index 8cf4aea35d..3374863b88 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -1387,6 +1387,22 @@ void Control::OnWheel(wxMouseEvent& event) void Control::OnKeyDown(wxKeyEvent &event) { const int key = event.GetKeyCode(); +#if ENABLE_GCODE_VIEWER + if (m_draw_mode != dmSequentialGCodeView && key == WXK_NUMPAD_ADD) { + // OnChar() is called immediately after OnKeyDown(), which can cause call of add_tick() twice. + // To avoid this case we should suppress second add_tick() call. + m_ticks.suppress_plus(true); + add_current_tick(true); + } + else if (m_draw_mode != dmSequentialGCodeView && (key == WXK_NUMPAD_SUBTRACT || key == WXK_DELETE || key == WXK_BACK)) { + // OnChar() is called immediately after OnKeyDown(), which can cause call of delete_tick() twice. + // To avoid this case we should suppress second delete_tick() call. + m_ticks.suppress_minus(true); + delete_current_tick(); + } + else if (m_draw_mode != dmSequentialGCodeView && event.GetKeyCode() == WXK_SHIFT) + UseDefaultColors(false); +#else if (key == WXK_NUMPAD_ADD) { // OnChar() is called immediately after OnKeyDown(), which can cause call of add_tick() twice. // To avoid this case we should suppress second add_tick() call. @@ -1401,6 +1417,7 @@ void Control::OnKeyDown(wxKeyEvent &event) } else if (event.GetKeyCode() == WXK_SHIFT) UseDefaultColors(false); +#endif // ENABLE_GCODE_VIEWER else if (is_horizontal()) { #if ENABLE_GCODE_VIEWER @@ -1451,14 +1468,21 @@ void Control::OnKeyUp(wxKeyEvent &event) void Control::OnChar(wxKeyEvent& event) { const int key = event.GetKeyCode(); - if (key == '+' && !m_ticks.suppressed_plus()) { - add_current_tick(true); - m_ticks.suppress_plus(false); - } - else if (key == '-' && !m_ticks.suppressed_minus()) { - delete_current_tick(); - m_ticks.suppress_minus(false); +#if ENABLE_GCODE_VIEWER + if (m_draw_mode != dmSequentialGCodeView) + { +#endif // ENABLE_GCODE_VIEWER + if (key == '+' && !m_ticks.suppressed_plus()) { + add_current_tick(true); + m_ticks.suppress_plus(false); + } + else if (key == '-' && !m_ticks.suppressed_minus()) { + delete_current_tick(); + m_ticks.suppress_minus(false); + } +#if ENABLE_GCODE_VIEWER } +#endif // ENABLE_GCODE_VIEWER if (key == 'G') #if ENABLE_GCODE_VIEWER jump_to_value(); From 100484dabe9909b62c9d6646c79f13443aa4727b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 27 May 2020 15:28:24 +0200 Subject: [PATCH 106/255] Added missing include --- src/slic3r/GUI/GCodeViewer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 6d41976941..2ba0a6e39d 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -5,6 +5,7 @@ #include "libslic3r/Print.hpp" #include "libslic3r/Geometry.hpp" #include "GUI_App.hpp" +#include "Plater.hpp" #include "PresetBundle.hpp" #include "Camera.hpp" #include "I18N.hpp" From e77fa3512ac0c9d697b9ad9620a5e955cf35209e Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 27 May 2020 16:03:40 +0200 Subject: [PATCH 107/255] DoubleSlider::Control -> Shift and Ctrl used as accelerators for moving thumbs with arrows key and mouse wheel --- src/slic3r/GUI/DoubleSlider.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index 45e242709d..384c984e52 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -1345,6 +1345,12 @@ void Control::move_current_thumb(const bool condition) if (is_horizontal()) delta *= -1; + // accelerators + if (wxGetKeyState(WXK_SHIFT) && wxGetKeyState(WXK_CONTROL)) + delta *= 10; + else if (wxGetKeyState(WXK_CONTROL)) + delta *= 5; + if (m_selection == ssLower) { m_lower_value -= delta; correct_lower_value(); From af3765c04c6ebba2c2b1e3961f96c4e37b7a4099 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 27 May 2020 16:14:14 +0200 Subject: [PATCH 108/255] Follow up of e77fa3512ac0c9d697b9ad9620a5e955cf35209e -> changed logic for DoubleSlider::Control accelerators --- src/slic3r/GUI/DoubleSlider.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index 384c984e52..b68ff7e4e0 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -1346,10 +1346,13 @@ void Control::move_current_thumb(const bool condition) delta *= -1; // accelerators - if (wxGetKeyState(WXK_SHIFT) && wxGetKeyState(WXK_CONTROL)) - delta *= 10; - else if (wxGetKeyState(WXK_CONTROL)) - delta *= 5; + int accelerator = 0; + if (wxGetKeyState(WXK_SHIFT)) + accelerator += 5; + if (wxGetKeyState(WXK_CONTROL)) + accelerator += 5; + if (accelerator > 0) + delta *= accelerator; if (m_selection == ssLower) { m_lower_value -= delta; From 35190936a3fcca57376f30a9cafd8505c0ce508e Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 27 May 2020 16:19:40 +0200 Subject: [PATCH 109/255] GCodeViewer -> Newer version of shader for options --- .../{options_120.fs => options_120_flat.fs} | 7 +- .../{options_120.vs => options_120_flat.vs} | 0 resources/shaders/options_120_solid.fs | 88 +++++++++++++++++++ resources/shaders/options_120_solid.vs | 14 +++ resources/shaders/shells.fs | 13 --- resources/shaders/shells.vs | 42 --------- src/libslic3r/Technologies.hpp | 2 +- src/slic3r/GUI/Camera.hpp | 1 + src/slic3r/GUI/GCodeViewer.cpp | 77 +++++++++------- src/slic3r/GUI/GCodeViewer.hpp | 8 +- src/slic3r/GUI/GLShader.cpp | 20 +++++ src/slic3r/GUI/GLShader.hpp | 2 + src/slic3r/GUI/GLShadersManager.cpp | 11 ++- 13 files changed, 187 insertions(+), 98 deletions(-) rename resources/shaders/{options_120.fs => options_120_flat.fs} (81%) rename resources/shaders/{options_120.vs => options_120_flat.vs} (100%) create mode 100644 resources/shaders/options_120_solid.fs create mode 100644 resources/shaders/options_120_solid.vs delete mode 100644 resources/shaders/shells.fs delete mode 100644 resources/shaders/shells.vs diff --git a/resources/shaders/options_120.fs b/resources/shaders/options_120_flat.fs similarity index 81% rename from resources/shaders/options_120.fs rename to resources/shaders/options_120_flat.fs index 90d417b6e7..656eccd1d4 100644 --- a/resources/shaders/options_120.fs +++ b/resources/shaders/options_120_flat.fs @@ -5,7 +5,7 @@ uniform vec3 uniform_color; uniform float percent_outline_radius; uniform float percent_center_radius; -vec4 hard_color(float sq_radius) +vec4 hardcoded_color(float sq_radius) { if ((sq_radius < 0.005625) || (sq_radius > 0.180625)) return vec4(0.5 * uniform_color, 1.0); @@ -13,7 +13,7 @@ vec4 hard_color(float sq_radius) return vec4(uniform_color, 1.0); } -vec4 custom_color(float sq_radius) +vec4 customizable_color(float sq_radius) { float in_radius = 0.5 * percent_center_radius; float out_radius = 0.5 * (1.0 - percent_outline_radius); @@ -30,5 +30,6 @@ void main() if (sq_radius > 0.25) discard; - gl_FragColor = custom_color(sq_radius); + gl_FragColor = customizable_color(sq_radius); +// gl_FragColor = hardcoded_color(sq_radius); } diff --git a/resources/shaders/options_120.vs b/resources/shaders/options_120_flat.vs similarity index 100% rename from resources/shaders/options_120.vs rename to resources/shaders/options_120_flat.vs diff --git a/resources/shaders/options_120_solid.fs b/resources/shaders/options_120_solid.fs new file mode 100644 index 0000000000..68d0bd4eec --- /dev/null +++ b/resources/shaders/options_120_solid.fs @@ -0,0 +1,88 @@ +// version 120 is needed for gl_PointCoord +#version 120 + +#define INTENSITY_CORRECTION 0.6 + +// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) +const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); +#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SHININESS 20.0 + +// normalized values for (1./1.43, 0.2/1.43, 1./1.43) +const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074); +#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) + +#define INTENSITY_AMBIENT 0.3 + +uniform vec3 uniform_color; +uniform float percent_outline_radius; +uniform float percent_center_radius; + +// x = width, y = height +uniform ivec2 viewport_sizes; +uniform vec2 z_range; +uniform mat4 inv_proj_matrix; + +varying vec3 eye_center; + +float radius = 0.5; +// x = tainted, y = specular; +vec2 intensity; + +vec3 eye_position_from_fragment() +{ + // Convert screen coordinates to normalized device coordinates (NDC) + vec4 ndc = vec4( + (gl_FragCoord.x / viewport_sizes.x - 0.5) * 2.0, + (gl_FragCoord.y / viewport_sizes.y - 0.5) * 2.0, + (gl_FragCoord.z - 0.5) * 2.0, + 1.0); + + // Convert NDC throuch inverse clip coordinates to view coordinates + vec4 clip = inv_proj_matrix * ndc; + return (clip / clip.w).xyz; +} + +vec3 eye_position_on_sphere(vec3 eye_fragment_position) +{ + vec3 eye_dir = normalize(eye_fragment_position); + float a = dot(eye_dir, eye_dir); + float b = 2.0 * dot(-eye_center, eye_dir); + float c = dot(eye_center, eye_center) - radius * radius; + float discriminant = b * b - 4 * a * c; + float t = -(b + sqrt(discriminant)) / (2.0 * a); + return t * eye_dir; +} + +vec4 on_sphere_color(vec3 eye_on_sphere_position) +{ + vec3 eye_normal = normalize(eye_on_sphere_position - eye_center); + + // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. + // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. + float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0); + + intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_on_sphere_position), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS); + + // Perform the same lighting calculation for the 2nd light source (no specular applied). + NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0); + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + + return vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color.rgb * intensity.x, 1.0); +} + +void main() +{ + vec2 pos = gl_PointCoord - vec2(0.5, 0.5); + float sq_radius = dot(pos, pos); + if (sq_radius > 0.25) + discard; + + vec3 eye_on_sphere_position = eye_position_on_sphere(eye_position_from_fragment()); + +// gl_FragDepth = eye_on_sphere_position.z; +// gl_FragDepth = (eye_on_sphere_position.z - z_range.x) / (z_range.y - z_range.x); + gl_FragColor = on_sphere_color(eye_on_sphere_position); +} diff --git a/resources/shaders/options_120_solid.vs b/resources/shaders/options_120_solid.vs new file mode 100644 index 0000000000..0ad75003c9 --- /dev/null +++ b/resources/shaders/options_120_solid.vs @@ -0,0 +1,14 @@ +#version 120 + +uniform float zoom; +// x = min, y = max +uniform vec2 point_sizes; + +varying vec3 eye_center; + +void main() +{ + gl_PointSize = clamp(zoom, point_sizes.x, point_sizes.y); + eye_center = (gl_ModelViewMatrix * gl_Vertex).xyz; + gl_Position = ftransform(); +} diff --git a/resources/shaders/shells.fs b/resources/shaders/shells.fs deleted file mode 100644 index 0c3388df70..0000000000 --- a/resources/shaders/shells.fs +++ /dev/null @@ -1,13 +0,0 @@ -#version 110 - -const vec3 ZERO = vec3(0.0, 0.0, 0.0); - -uniform vec4 uniform_color; - -// x = tainted, y = specular; -varying vec2 intensity; - -void main() -{ - gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color.rgb * intensity.x, uniform_color.a); -} diff --git a/resources/shaders/shells.vs b/resources/shaders/shells.vs deleted file mode 100644 index bb9c144e65..0000000000 --- a/resources/shaders/shells.vs +++ /dev/null @@ -1,42 +0,0 @@ -#version 110 - -#define INTENSITY_CORRECTION 0.6 - -// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) -const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); -#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) -#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) -#define LIGHT_TOP_SHININESS 20.0 - -// normalized values for (1./1.43, 0.2/1.43, 1./1.43) -const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074); -#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) - -#define INTENSITY_AMBIENT 0.3 - -// x = tainted, y = specular; -varying vec2 intensity; - -void main() -{ - // First transform the normal into camera space and normalize the result. - vec3 normal = normalize(gl_NormalMatrix * gl_Normal); - - // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. - // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. - float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0); - - intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; - intensity.y = 0.0; - - if (NdotL > 0.0) - { - vec3 position = (gl_ModelViewMatrix * gl_Vertex).xyz; - intensity.y += LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); - } - - // Perform the same lighting calculation for the 2nd light source (no specular applied). - intensity.x += max(dot(normal, LIGHT_FRONT_DIR), 0.0) * LIGHT_FRONT_DIFFUSE; - - gl_Position = ftransform(); -} diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 5631dadf34..984373ea4a 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -15,7 +15,7 @@ #define ENABLE_RENDER_STATISTICS 0 // Shows an imgui dialog with camera related data #define ENABLE_CAMERA_STATISTICS 0 -// Render the picking pass instead of the main scene (use [T] key to toggle between regular rendering and picking pass only rendering) +// Render the picking pass instead of the main scene (use [T] key to toggle between regular rendering and picking pass only rendering) #define ENABLE_RENDER_PICKING_PASS 0 // Enable extracting thumbnails from selected gcode and save them as png files #define ENABLE_THUMBNAIL_GENERATOR_DEBUG 0 diff --git a/src/slic3r/GUI/Camera.hpp b/src/slic3r/GUI/Camera.hpp index ece999c078..6e42562351 100644 --- a/src/slic3r/GUI/Camera.hpp +++ b/src/slic3r/GUI/Camera.hpp @@ -84,6 +84,7 @@ public: double get_near_z() const { return m_frustrum_zs.first; } double get_far_z() const { return m_frustrum_zs.second; } + const std::pair& get_z_range() const { return m_frustrum_zs; } double get_fov() const; diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 6d41976941..978b4b95a6 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -415,12 +415,12 @@ void GCodeViewer::init_shaders() { switch (buffer_type(i)) { - case GCodeProcessor::EMoveType::Tool_change: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110"; break; } - case GCodeProcessor::EMoveType::Color_change: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110"; break; } - case GCodeProcessor::EMoveType::Pause_Print: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110"; break; } - case GCodeProcessor::EMoveType::Custom_GCode: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110"; break; } - case GCodeProcessor::EMoveType::Retract: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110"; break; } - case GCodeProcessor::EMoveType::Unretract: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110"; break; } + case GCodeProcessor::EMoveType::Tool_change: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120_solid" : "options_110"; break; } + case GCodeProcessor::EMoveType::Color_change: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120_solid" : "options_110"; break; } + case GCodeProcessor::EMoveType::Pause_Print: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120_solid" : "options_110"; break; } + case GCodeProcessor::EMoveType::Custom_GCode: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120_solid" : "options_110"; break; } + case GCodeProcessor::EMoveType::Retract: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120_solid" : "options_110"; break; } + case GCodeProcessor::EMoveType::Unretract: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120_solid" : "options_110"; break; } case GCodeProcessor::EMoveType::Extrude: { m_buffers[i].shader = "extrusions"; break; } case GCodeProcessor::EMoveType::Travel: { m_buffers[i].shader = "travels"; break; } default: { break; } @@ -754,21 +754,26 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool void GCodeViewer::render_toolpaths() const { #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR - bool is_glsl_120 = m_shaders_editor.glsl_version == 1 && wxGetApp().is_glsl_version_greater_or_equal_to(1, 20); + bool is_glsl_120 = m_shaders_editor.shader_version >= 1 && wxGetApp().is_glsl_version_greater_or_equal_to(1, 20); std::array point_sizes; if (m_shaders_editor.size_dependent_on_zoom) - { point_sizes = { std::min(static_cast(m_shaders_editor.sizes[0]), m_detected_point_sizes[1]), std::min(static_cast(m_shaders_editor.sizes[1]), m_detected_point_sizes[1]) }; - } else point_sizes = { static_cast(m_shaders_editor.fixed_size), static_cast(m_shaders_editor.fixed_size) }; #else bool is_glsl_120 = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20); std::array point_sizes = { std::min(8.0f, m_detected_point_sizes[1]), std::min(48.0f, m_detected_point_sizes[1]) }; #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR - double zoom = wxGetApp().plater()->get_camera().get_zoom(); + const Camera& camera = wxGetApp().plater()->get_camera(); + double zoom = camera.get_zoom(); + const std::array& viewport = camera.get_viewport(); + std::array viewport_sizes = { viewport[2], viewport[3] }; + const std::pair& camera_z_range = camera.get_z_range(); + std::array z_range = { static_cast(camera_z_range.first), static_cast(camera_z_range.second) }; - auto render_options = [this, is_glsl_120, zoom, point_sizes](const IBuffer& buffer, EOptionsColors colors_id, GLShaderProgram& shader) { + Transform3d inv_proj = camera.get_projection_matrix().inverse(); + + auto render_options = [this, is_glsl_120, zoom, viewport, inv_proj, viewport_sizes, z_range, point_sizes](const IBuffer& buffer, EOptionsColors colors_id, GLShaderProgram& shader) { shader.set_uniform("uniform_color", Options_Colors[static_cast(colors_id)]); #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR shader.set_uniform("zoom", m_shaders_editor.size_dependent_on_zoom ? zoom : 1.0f); @@ -779,6 +784,9 @@ void GCodeViewer::render_toolpaths() const shader.set_uniform("percent_outline_radius", 0.15f); shader.set_uniform("percent_center_radius", 0.15f); #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR + shader.set_uniform("viewport_sizes", viewport_sizes); + shader.set_uniform("inv_proj_matrix", inv_proj); + shader.set_uniform("z_range", z_range); shader.set_uniform("point_sizes", point_sizes); glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); if (is_glsl_120) @@ -896,7 +904,7 @@ void GCodeViewer::render_shells() const if (!m_shells.visible || m_shells.volumes.empty()) return; - GLShaderProgram* shader = wxGetApp().get_shader("shells"); + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); if (shader == nullptr) return; @@ -954,25 +962,25 @@ void GCodeViewer::render_legend() const { #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR draw_list->AddCircle({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, 0.5f * icon_size, ICON_BORDER_COLOR, 16); - draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, (0.5f * icon_size) - 2.0f, - ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); - float radius = ((0.5f * icon_size) - 2.0f) * (1.0f - 0.01f * static_cast(m_shaders_editor.percent_outline)); - draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, radius, - ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); - if (m_shaders_editor.percent_center > 0) - { - radius = ((0.5f * icon_size) - 2.0f) * 0.01f * static_cast(m_shaders_editor.percent_center); - draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, radius, + if (m_shaders_editor.shader_version == 1) { + draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, (0.5f * icon_size) - 2.0f, ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); + float radius = ((0.5f * icon_size) - 2.0f) * (1.0f - 0.01f * static_cast(m_shaders_editor.percent_outline)); + draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, radius, + ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); + if (m_shaders_editor.percent_center > 0) { + radius = ((0.5f * icon_size) - 2.0f) * 0.01f * static_cast(m_shaders_editor.percent_center); + draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, radius, + ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); + } + } else { + draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, (0.5f * icon_size) - 2.0f, + ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); } #else draw_list->AddCircle({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, 0.5f * icon_size, ICON_BORDER_COLOR, 16); draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, (0.5f * icon_size) - 2.0f, - ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); - draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, (0.5f * icon_size) - 3.0f, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); - draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, 1.5f, - ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR break; } @@ -1195,7 +1203,11 @@ void GCodeViewer::render_legend() const auto add_option = [this, add_item](GCodeProcessor::EMoveType move_type, EOptionsColors color, const std::string& text) { const IBuffer& buffer = m_buffers[buffer_id(move_type)]; if (buffer.visible && buffer.indices_count > 0) - add_item(EItemType::Circle, Options_Colors[static_cast(color)], text); +#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR + add_item((m_shaders_editor.shader_version == 0) ? EItemType::Rect : EItemType::Circle, Options_Colors[static_cast(color)], text); +#else + add_item((buffer.shader == "options_110") ? EItemType::Rect : EItemType::Circle, Options_Colors[static_cast(color)], text); +#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR }; // options @@ -1337,12 +1349,15 @@ void GCodeViewer::render_shaders_editor() const imgui.set_next_window_pos(static_cast(cnv_size.get_width()), 0.5f * static_cast(cnv_size.get_height()), ImGuiCond_Once, 1.0f, 0.5f); imgui.begin(std::string("Shaders editor (DEV only)"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize); - ImGui::RadioButton("glsl version 1.10 (low end PCs)", &m_shaders_editor.glsl_version, 0); - ImGui::RadioButton("glsl version 1.20 (default)", &m_shaders_editor.glsl_version, 1); - switch (m_shaders_editor.glsl_version) + ImGui::RadioButton("glsl version 1.10 (low end PCs)", &m_shaders_editor.shader_version, 0); + ImGui::RadioButton("glsl version 1.20 flat (billboards)", &m_shaders_editor.shader_version, 1); + ImGui::RadioButton("glsl version 1.20 solid (spheres default)", &m_shaders_editor.shader_version, 2); + + switch (m_shaders_editor.shader_version) { case 0: { set_shader("options_110"); break; } - case 1: { set_shader("options_120"); break; } + case 1: { set_shader("options_120_flat"); break; } + case 2: { set_shader("options_120_solid"); break; } } if (ImGui::CollapsingHeader("Options", ImGuiTreeNodeFlags_DefaultOpen)) @@ -1364,7 +1379,7 @@ void GCodeViewer::render_shaders_editor() const else ImGui::SliderInt("fixed size", &m_shaders_editor.fixed_size, 1, 100); - if (m_shaders_editor.glsl_version == 1) + if (m_shaders_editor.shader_version == 1) { ImGui::SliderInt("percent outline", &m_shaders_editor.percent_outline, 0, 50); ImGui::SliderInt("percent center", &m_shaders_editor.percent_center, 0, 50); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 1d940b66a7..a2f9c14af7 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -205,12 +205,12 @@ class GCodeViewer #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR struct ShadersEditor { - int glsl_version{ 1 }; + int shader_version{ 2 }; bool size_dependent_on_zoom{ true }; int fixed_size{ 16 }; - std::array sizes{ 8, 64 }; - int percent_outline{ 15 }; - int percent_center{ 15 }; + std::array sizes{ 3, 21 }; + int percent_outline{ 0 }; + int percent_center{ 33 }; }; #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR diff --git a/src/slic3r/GUI/GLShader.cpp b/src/slic3r/GUI/GLShader.cpp index a6d641f89f..3c2612b45e 100644 --- a/src/slic3r/GUI/GLShader.cpp +++ b/src/slic3r/GUI/GLShader.cpp @@ -215,6 +215,26 @@ bool GLShaderProgram::set_uniform(const char* name, double value) const return set_uniform(name, static_cast(value)); } +bool GLShaderProgram::set_uniform(const char* name, const std::array& value) const +{ + int id = get_uniform_location(name); + if (id >= 0) { + glsafe(::glUniform2iv(id, 1, static_cast(value.data()))); + return true; + } + return false; +} + +bool GLShaderProgram::set_uniform(const char* name, const std::array& value) const +{ + int id = get_uniform_location(name); + if (id >= 0) { + glsafe(::glUniform3iv(id, 1, static_cast(value.data()))); + return true; + } + return false; +} + bool GLShaderProgram::set_uniform(const char* name, const std::array& value) const { int id = get_uniform_location(name); diff --git a/src/slic3r/GUI/GLShader.hpp b/src/slic3r/GUI/GLShader.hpp index 521f6796f1..a1160f8e98 100644 --- a/src/slic3r/GUI/GLShader.hpp +++ b/src/slic3r/GUI/GLShader.hpp @@ -43,6 +43,8 @@ public: bool set_uniform(const char* name, bool value) const; bool set_uniform(const char* name, float value) const; bool set_uniform(const char* name, double value) const; + bool set_uniform(const char* name, const std::array& value) const; + bool set_uniform(const char* name, const std::array& value) const; bool set_uniform(const char* name, const std::array& value) const; bool set_uniform(const char* name, const std::array& value) const; bool set_uniform(const char* name, const std::array& value) const; diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index dd77351bd0..4bebf7b984 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -1,6 +1,7 @@ #include "libslic3r/libslic3r.h" #include "GLShadersManager.hpp" #include "3DScene.hpp" +#include "GUI_App.hpp" #include #include @@ -28,19 +29,21 @@ std::pair GLShadersManager::init() bool valid = true; - // used to render bed axes and model, selection hints, gcode sequential view marker model + // used to render bed axes and model, selection hints, gcode sequential view marker model, preview shells valid &= append_shader("gouraud_light", { "gouraud_light.vs", "gouraud_light.fs" }); // used to render printbed valid &= append_shader("printbed", { "printbed.vs", "printbed.fs" }); // used to render options in gcode preview valid &= append_shader("options_110", { "options_110.vs", "options_110.fs" }); - valid &= append_shader("options_120", { "options_120.vs", "options_120.fs" }); + if (GUI::wxGetApp().is_glsl_version_greater_or_equal_to(1, 20)) + { + valid &= append_shader("options_120_flat", { "options_120_flat.vs", "options_120_flat.fs" }); + valid &= append_shader("options_120_solid", { "options_120_solid.vs", "options_120_solid.fs" }); + } // used to render extrusion paths in gcode preview valid &= append_shader("extrusions", { "extrusions.vs", "extrusions.fs" }); // used to render travel paths in gcode preview valid &= append_shader("travels", { "travels.vs", "travels.fs" }); - // used to render shells in gcode preview - valid &= append_shader("shells", { "shells.vs", "shells.fs" }); // used to render objects in 3d editor valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" }); // used to render variable layers heights in 3d editor From abd7d7480053060144faa155b08efbce89ff5ad8 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 27 May 2020 16:31:02 +0200 Subject: [PATCH 110/255] GCodeViewer -> Small refactoring --- src/slic3r/GUI/GCodeViewer.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 978b4b95a6..6dea0511bf 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -411,16 +411,17 @@ void GCodeViewer::init_shaders() unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); unsigned char end_id = buffer_id(GCodeProcessor::EMoveType::Count); + bool is_glsl_120 = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20); for (unsigned char i = begin_id; i < end_id; ++i) { switch (buffer_type(i)) { - case GCodeProcessor::EMoveType::Tool_change: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120_solid" : "options_110"; break; } - case GCodeProcessor::EMoveType::Color_change: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120_solid" : "options_110"; break; } - case GCodeProcessor::EMoveType::Pause_Print: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120_solid" : "options_110"; break; } - case GCodeProcessor::EMoveType::Custom_GCode: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120_solid" : "options_110"; break; } - case GCodeProcessor::EMoveType::Retract: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120_solid" : "options_110"; break; } - case GCodeProcessor::EMoveType::Unretract: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120_solid" : "options_110"; break; } + case GCodeProcessor::EMoveType::Tool_change: { m_buffers[i].shader = is_glsl_120 ? "options_120_solid" : "options_110"; break; } + case GCodeProcessor::EMoveType::Color_change: { m_buffers[i].shader = is_glsl_120 ? "options_120_solid" : "options_110"; break; } + case GCodeProcessor::EMoveType::Pause_Print: { m_buffers[i].shader = is_glsl_120 ? "options_120_solid" : "options_110"; break; } + case GCodeProcessor::EMoveType::Custom_GCode: { m_buffers[i].shader = is_glsl_120 ? "options_120_solid" : "options_110"; break; } + case GCodeProcessor::EMoveType::Retract: { m_buffers[i].shader = is_glsl_120 ? "options_120_solid" : "options_110"; break; } + case GCodeProcessor::EMoveType::Unretract: { m_buffers[i].shader = is_glsl_120 ? "options_120_solid" : "options_110"; break; } case GCodeProcessor::EMoveType::Extrude: { m_buffers[i].shader = "extrusions"; break; } case GCodeProcessor::EMoveType::Travel: { m_buffers[i].shader = "travels"; break; } default: { break; } From 0cb4a5ce56f60c07f2e190a9ad9ccdd38cf939cc Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 28 May 2020 07:06:54 +0200 Subject: [PATCH 111/255] GCodeViewer -> Improved depth detection in shader for options --- resources/shaders/options_120_solid.fs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/resources/shaders/options_120_solid.fs b/resources/shaders/options_120_solid.fs index 68d0bd4eec..b7770cf0db 100644 --- a/resources/shaders/options_120_solid.fs +++ b/resources/shaders/options_120_solid.fs @@ -21,7 +21,9 @@ uniform float percent_center_radius; // x = width, y = height uniform ivec2 viewport_sizes; -uniform vec2 z_range; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//uniform vec2 z_range; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ uniform mat4 inv_proj_matrix; varying vec3 eye_center; @@ -73,6 +75,15 @@ vec4 on_sphere_color(vec3 eye_on_sphere_position) return vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color.rgb * intensity.x, 1.0); } +float fragment_depth(vec3 eye_pos) +{ + // see: https://stackoverflow.com/questions/10264949/glsl-gl-fragcoord-z-calculation-and-setting-gl-fragdepth + vec4 clip_pos = gl_ProjectionMatrix * vec4(eye_pos, 1.0); + float ndc_depth = clip_pos.z / clip_pos.w; + + return (((gl_DepthRange.far - gl_DepthRange.near) * ndc_depth) + gl_DepthRange.near + gl_DepthRange.far) / 2.0; +} + void main() { vec2 pos = gl_PointCoord - vec2(0.5, 0.5); @@ -82,6 +93,7 @@ void main() vec3 eye_on_sphere_position = eye_position_on_sphere(eye_position_from_fragment()); + gl_FragDepth = fragment_depth(eye_on_sphere_position); // gl_FragDepth = eye_on_sphere_position.z; // gl_FragDepth = (eye_on_sphere_position.z - z_range.x) / (z_range.y - z_range.x); gl_FragColor = on_sphere_color(eye_on_sphere_position); From edaabf3fbde559698b3e25f547b0c4050bed8aef Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 28 May 2020 07:52:11 +0200 Subject: [PATCH 112/255] GCodeViewer -> Experimental hexagonal icons for toolpaths in legend --- src/slic3r/GUI/GCodeViewer.cpp | 68 +++++++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 10 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index c0acba344e..25432f1cf6 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -929,6 +929,8 @@ void GCodeViewer::render_legend() const ImGuiWrapper& imgui = *wxGetApp().imgui(); +#define USE_ICON_HEXAGON 1 + imgui.set_next_window_pos(0.0f, 0.0f, ImGuiCond_Always); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGui::SetNextWindowBgAlpha(0.6f); @@ -940,6 +942,7 @@ void GCodeViewer::render_legend() const { Rect, Circle, + Hexagon, Line }; @@ -963,22 +966,19 @@ void GCodeViewer::render_legend() const case EItemType::Circle: { #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR - draw_list->AddCircle({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, 0.5f * icon_size, ICON_BORDER_COLOR, 16); + ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size)); + draw_list->AddCircle(center, 0.5f * icon_size, ICON_BORDER_COLOR, 16); if (m_shaders_editor.shader_version == 1) { - draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, (0.5f * icon_size) - 2.0f, + draw_list->AddCircleFilled(center, (0.5f * icon_size) - 2.0f, ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); float radius = ((0.5f * icon_size) - 2.0f) * (1.0f - 0.01f * static_cast(m_shaders_editor.percent_outline)); - draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, radius, - ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); + draw_list->AddCircleFilled(center, radius, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); if (m_shaders_editor.percent_center > 0) { radius = ((0.5f * icon_size) - 2.0f) * 0.01f * static_cast(m_shaders_editor.percent_center); - draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, radius, - ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); + draw_list->AddCircleFilled(center, radius, ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); } - } else { - draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, (0.5f * icon_size) - 2.0f, - ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); - } + } else + draw_list->AddCircleFilled(center, (0.5f * icon_size) - 2.0f, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); #else draw_list->AddCircle({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, 0.5f * icon_size, ICON_BORDER_COLOR, 16); draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, (0.5f * icon_size) - 2.0f, @@ -986,6 +986,14 @@ void GCodeViewer::render_legend() const #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR break; } + case EItemType::Hexagon: + { + ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size)); + draw_list->AddNgon(center, 0.5f * icon_size, ICON_BORDER_COLOR, 6); + draw_list->AddNgonFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, (0.5f * icon_size) - 2.0f, + ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 6); + break; + } case EItemType::Line: { draw_list->AddLine({ pos.x + 1, pos.y + icon_size - 1}, { pos.x + icon_size - 1, pos.y + 1 }, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 3.0f); @@ -1009,7 +1017,11 @@ void GCodeViewer::render_legend() const auto add_range_item = [this, draw_list, &imgui, add_item](int i, float value, unsigned int decimals) { char buf[1024]; ::sprintf(buf, "%.*f", decimals, value); +#if USE_ICON_HEXAGON + add_item(EItemType::Hexagon, Range_Colors[i], buf); +#else add_item(EItemType::Rect, Range_Colors[i], buf); +#endif // USE_ICON_HEXAGON }; float step_size = range.step_size(); @@ -1051,7 +1063,11 @@ void GCodeViewer::render_legend() const if (!visible) ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.3333f); +#if USE_ICON_HEXAGON + add_item(EItemType::Hexagon, Extrusion_Role_Colors[static_cast(role)], _u8L(ExtrusionEntity::role_to_string(role)), [this, role]() { +#else add_item(EItemType::Rect, Extrusion_Role_Colors[static_cast(role)], _u8L(ExtrusionEntity::role_to_string(role)), [this, role]() { +#endif // USE_ICON_HEXAGON if (role < erCount) { m_extrusions.role_visibility_flags = is_visible(role) ? m_extrusions.role_visibility_flags & ~(1 << role) : m_extrusions.role_visibility_flags | (1 << role); @@ -1081,7 +1097,11 @@ void GCodeViewer::render_legend() const if (it == m_extruder_ids.end()) continue; +#if USE_ICON_HEXAGON + add_item(EItemType::Hexagon, m_tool_colors[i], (boost::format(_u8L("Extruder %d")) % (i + 1)).str()); +#else add_item(EItemType::Rect, m_tool_colors[i], (boost::format(_u8L("Extruder %d")) % (i + 1)).str()); +#endif // USE_ICON_HEXAGON } break; } @@ -1092,7 +1112,11 @@ void GCodeViewer::render_legend() const if (extruders_count == 1) { // single extruder use case if (custom_gcode_per_print_z.empty()) // no data to show +#if USE_ICON_HEXAGON + add_item(EItemType::Hexagon, m_tool_colors.front(), _u8L("Default print color")); +#else add_item(EItemType::Rect, m_tool_colors.front(), _u8L("Default print color")); +#endif // USE_ICON_HEXAGON else { std::vector> cp_values; cp_values.reserve(custom_gcode_per_print_z.size()); @@ -1116,7 +1140,11 @@ void GCodeViewer::render_legend() const const int items_cnt = static_cast(cp_values.size()); if (items_cnt == 0) { // There is no one color change, but there are some pause print or custom Gcode +#if USE_ICON_HEXAGON + add_item(EItemType::Hexagon, m_tool_colors.front(), _u8L("Default print color")); +#else add_item(EItemType::Rect, m_tool_colors.front(), _u8L("Default print color")); +#endif // USE_ICON_HEXAGON } else { for (int i = items_cnt; i >= 0; --i) { @@ -1124,14 +1152,26 @@ void GCodeViewer::render_legend() const std::string id_str = " (" + std::to_string(i + 1) + ")"; if (i == 0) { +#if USE_ICON_HEXAGON + add_item(EItemType::Hexagon, m_tool_colors[i], (boost::format(_u8L("up to %.2f mm")) % cp_values.front().first).str() + id_str); +#else add_item(EItemType::Rect, m_tool_colors[i], (boost::format(_u8L("up to %.2f mm")) % cp_values.front().first).str() + id_str); +#endif // USE_ICON_HEXAGON break; } else if (i == items_cnt) { +#if USE_ICON_HEXAGON + add_item(EItemType::Hexagon, m_tool_colors[i], (boost::format(_u8L("above %.2f mm")) % cp_values[i - 1].second).str() + id_str); +#else add_item(EItemType::Rect, m_tool_colors[i], (boost::format(_u8L("above %.2f mm")) % cp_values[i - 1].second).str() + id_str); +#endif // USE_ICON_HEXAGON continue; } +#if USE_ICON_HEXAGON + add_item(EItemType::Hexagon, m_tool_colors[i], (boost::format(_u8L("%.2f - %.2f mm")) % cp_values[i - 1].second% cp_values[i].first).str() + id_str); +#else add_item(EItemType::Rect, m_tool_colors[i], (boost::format(_u8L("%.2f - %.2f mm")) % cp_values[i - 1].second% cp_values[i].first).str() + id_str); +#endif // USE_ICON_HEXAGON } } } @@ -1140,7 +1180,11 @@ void GCodeViewer::render_legend() const { // extruders for (unsigned int i = 0; i < (unsigned int)extruders_count; ++i) { +#if USE_ICON_HEXAGON + add_item(EItemType::Hexagon, m_tool_colors[i], (boost::format(_u8L("Extruder %d")) % (i + 1)).str()); +#else add_item(EItemType::Rect, m_tool_colors[i], (boost::format(_u8L("Extruder %d")) % (i + 1)).str()); +#endif // USE_ICON_HEXAGON } // color changes @@ -1151,7 +1195,11 @@ void GCodeViewer::render_legend() const // create label for color change item std::string id_str = " (" + std::to_string(color_change_idx--) + ")"; +#if USE_ICON_HEXAGON + add_item(EItemType::Hexagon, m_tool_colors[last_color_id--], +#else add_item(EItemType::Rect, m_tool_colors[last_color_id--], +#endif // USE_ICON_HEXAGON (boost::format(_u8L("Color change for Extruder %d at %.2f mm")) % custom_gcode_per_print_z[i].extruder % custom_gcode_per_print_z[i].print_z).str() + id_str); } } From 9c8892c869a4e2421e3097fb588a7a8853b52516 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 28 May 2020 09:23:30 +0200 Subject: [PATCH 113/255] GCodeViewer -> Shaders code cleanup --- resources/shaders/extrusions.fs | 5 ----- resources/shaders/extrusions.vs | 4 ---- resources/shaders/options_120_solid.fs | 9 --------- resources/shaders/travels.fs | 5 ----- resources/shaders/travels.vs | 4 ---- src/slic3r/GUI/GCodeViewer.cpp | 13 ++++++++++--- 6 files changed, 10 insertions(+), 30 deletions(-) diff --git a/resources/shaders/extrusions.fs b/resources/shaders/extrusions.fs index fc81e487fb..65db0667a9 100644 --- a/resources/shaders/extrusions.fs +++ b/resources/shaders/extrusions.fs @@ -17,7 +17,6 @@ uniform vec3 uniform_color; varying vec3 eye_position; varying vec3 eye_normal; -//varying float world_normal_z; // x = tainted, y = specular; vec2 intensity; @@ -37,9 +36,5 @@ void main() NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; -// // darkens fragments whose normal points downward -// if (world_normal_z < 0.0) -// intensity.x *= (1.0 + world_normal_z * (1.0 - INTENSITY_AMBIENT)); - gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color * intensity.x, 1.0); } diff --git a/resources/shaders/extrusions.vs b/resources/shaders/extrusions.vs index d97adbabe0..8980f3944b 100644 --- a/resources/shaders/extrusions.vs +++ b/resources/shaders/extrusions.vs @@ -2,14 +2,10 @@ varying vec3 eye_position; varying vec3 eye_normal; -//// world z component of the normal used to darken the lower side of the toolpaths -//varying float world_normal_z; void main() { eye_position = (gl_ModelViewMatrix * gl_Vertex).xyz; eye_normal = gl_NormalMatrix * vec3(0.0, 0.0, 1.0); -// eye_normal = gl_NormalMatrix * gl_Normal; -// world_normal_z = gl_Normal.z; gl_Position = ftransform(); } diff --git a/resources/shaders/options_120_solid.fs b/resources/shaders/options_120_solid.fs index b7770cf0db..c7a57d547b 100644 --- a/resources/shaders/options_120_solid.fs +++ b/resources/shaders/options_120_solid.fs @@ -16,14 +16,9 @@ const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074); #define INTENSITY_AMBIENT 0.3 uniform vec3 uniform_color; -uniform float percent_outline_radius; -uniform float percent_center_radius; // x = width, y = height uniform ivec2 viewport_sizes; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -//uniform vec2 z_range; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ uniform mat4 inv_proj_matrix; varying vec3 eye_center; @@ -77,10 +72,8 @@ vec4 on_sphere_color(vec3 eye_on_sphere_position) float fragment_depth(vec3 eye_pos) { - // see: https://stackoverflow.com/questions/10264949/glsl-gl-fragcoord-z-calculation-and-setting-gl-fragdepth vec4 clip_pos = gl_ProjectionMatrix * vec4(eye_pos, 1.0); float ndc_depth = clip_pos.z / clip_pos.w; - return (((gl_DepthRange.far - gl_DepthRange.near) * ndc_depth) + gl_DepthRange.near + gl_DepthRange.far) / 2.0; } @@ -94,7 +87,5 @@ void main() vec3 eye_on_sphere_position = eye_position_on_sphere(eye_position_from_fragment()); gl_FragDepth = fragment_depth(eye_on_sphere_position); -// gl_FragDepth = eye_on_sphere_position.z; -// gl_FragDepth = (eye_on_sphere_position.z - z_range.x) / (z_range.y - z_range.x); gl_FragColor = on_sphere_color(eye_on_sphere_position); } diff --git a/resources/shaders/travels.fs b/resources/shaders/travels.fs index fc81e487fb..65db0667a9 100644 --- a/resources/shaders/travels.fs +++ b/resources/shaders/travels.fs @@ -17,7 +17,6 @@ uniform vec3 uniform_color; varying vec3 eye_position; varying vec3 eye_normal; -//varying float world_normal_z; // x = tainted, y = specular; vec2 intensity; @@ -37,9 +36,5 @@ void main() NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; -// // darkens fragments whose normal points downward -// if (world_normal_z < 0.0) -// intensity.x *= (1.0 + world_normal_z * (1.0 - INTENSITY_AMBIENT)); - gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color * intensity.x, 1.0); } diff --git a/resources/shaders/travels.vs b/resources/shaders/travels.vs index d97adbabe0..8980f3944b 100644 --- a/resources/shaders/travels.vs +++ b/resources/shaders/travels.vs @@ -2,14 +2,10 @@ varying vec3 eye_position; varying vec3 eye_normal; -//// world z component of the normal used to darken the lower side of the toolpaths -//varying float world_normal_z; void main() { eye_position = (gl_ModelViewMatrix * gl_Vertex).xyz; eye_normal = gl_NormalMatrix * vec3(0.0, 0.0, 1.0); -// eye_normal = gl_NormalMatrix * gl_Normal; -// world_normal_z = gl_Normal.z; gl_Position = ftransform(); } diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 25432f1cf6..896a42b10f 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -771,11 +771,16 @@ void GCodeViewer::render_toolpaths() const const std::array& viewport = camera.get_viewport(); std::array viewport_sizes = { viewport[2], viewport[3] }; const std::pair& camera_z_range = camera.get_z_range(); - std::array z_range = { static_cast(camera_z_range.first), static_cast(camera_z_range.second) }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// std::array z_range = { static_cast(camera_z_range.first), static_cast(camera_z_range.second) }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Transform3d inv_proj = camera.get_projection_matrix().inverse(); - auto render_options = [this, is_glsl_120, zoom, viewport, inv_proj, viewport_sizes, z_range, point_sizes](const IBuffer& buffer, EOptionsColors colors_id, GLShaderProgram& shader) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + auto render_options = [this, is_glsl_120, zoom, viewport, inv_proj, viewport_sizes, point_sizes](const IBuffer& buffer, EOptionsColors colors_id, GLShaderProgram& shader) { +// auto render_options = [this, is_glsl_120, zoom, viewport, inv_proj, viewport_sizes, z_range, point_sizes](const IBuffer& buffer, EOptionsColors colors_id, GLShaderProgram& shader) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ shader.set_uniform("uniform_color", Options_Colors[static_cast(colors_id)]); #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR shader.set_uniform("zoom", m_shaders_editor.size_dependent_on_zoom ? zoom : 1.0f); @@ -788,7 +793,9 @@ void GCodeViewer::render_toolpaths() const #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR shader.set_uniform("viewport_sizes", viewport_sizes); shader.set_uniform("inv_proj_matrix", inv_proj); - shader.set_uniform("z_range", z_range); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// shader.set_uniform("z_range", z_range); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ shader.set_uniform("point_sizes", point_sizes); glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); if (is_glsl_120) From 2904ee6e1a122012a6d158137261482769aa8ca4 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 28 May 2020 09:38:08 +0200 Subject: [PATCH 114/255] Added missing include --- src/slic3r/GUI/Camera.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/Camera.cpp b/src/slic3r/GUI/Camera.cpp index ac32767c4b..866c7e979d 100644 --- a/src/slic3r/GUI/Camera.cpp +++ b/src/slic3r/GUI/Camera.cpp @@ -5,6 +5,7 @@ #include "AppConfig.hpp" #if ENABLE_CAMERA_STATISTICS #include "Mouse3DController.hpp" +#include "Plater.hpp" #endif // ENABLE_CAMERA_STATISTICS #include From 96db6aaadb936c324f2f07369937a6fac8f8fc11 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 28 May 2020 11:14:56 +0200 Subject: [PATCH 115/255] Attempt to fix rambling crash on Mac Asan --- src/slic3r/GUI/GCodeViewer.cpp | 9 --------- src/slic3r/GUI/GUI_Preview.cpp | 4 ++++ 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 896a42b10f..2cf2bb7057 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -771,16 +771,10 @@ void GCodeViewer::render_toolpaths() const const std::array& viewport = camera.get_viewport(); std::array viewport_sizes = { viewport[2], viewport[3] }; const std::pair& camera_z_range = camera.get_z_range(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// std::array z_range = { static_cast(camera_z_range.first), static_cast(camera_z_range.second) }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Transform3d inv_proj = camera.get_projection_matrix().inverse(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ auto render_options = [this, is_glsl_120, zoom, viewport, inv_proj, viewport_sizes, point_sizes](const IBuffer& buffer, EOptionsColors colors_id, GLShaderProgram& shader) { -// auto render_options = [this, is_glsl_120, zoom, viewport, inv_proj, viewport_sizes, z_range, point_sizes](const IBuffer& buffer, EOptionsColors colors_id, GLShaderProgram& shader) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ shader.set_uniform("uniform_color", Options_Colors[static_cast(colors_id)]); #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR shader.set_uniform("zoom", m_shaders_editor.size_dependent_on_zoom ? zoom : 1.0f); @@ -793,9 +787,6 @@ void GCodeViewer::render_toolpaths() const #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR shader.set_uniform("viewport_sizes", viewport_sizes); shader.set_uniform("inv_proj_matrix", inv_proj); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// shader.set_uniform("z_range", z_range); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ shader.set_uniform("point_sizes", point_sizes); glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); if (is_glsl_120) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index c673292efc..65791150a0 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -1144,6 +1144,10 @@ void Preview::update_layers_slider_from_canvas(wxKeyEvent& event) void Preview::update_moves_slider() { const GCodeViewer::SequentialView& view = m_canvas->get_gcode_sequential_view(); + // this should not be needed, but it is here to try to prevent rambling crashes on Mac Asan + if (view.endpoints.last < view.endpoints.first) + return; + std::vector values(view.endpoints.last - view.endpoints.first + 1); unsigned int count = 0; for (unsigned int i = view.endpoints.first; i <= view.endpoints.last; ++i) From dcec684cc7fe8979d25b726f6bdf560353139691 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 29 May 2020 12:29:04 +0200 Subject: [PATCH 116/255] ENABLE_GCODE_VIEWER -> Refactoring of shaders for options --- resources/shaders/options_110.fs | 2 +- resources/shaders/options_110.vs | 8 +-- resources/shaders/options_120_flat.fs | 20 +++--- resources/shaders/options_120_flat.vs | 8 +-- resources/shaders/options_120_solid.fs | 2 +- resources/shaders/options_120_solid.vs | 8 +-- src/slic3r/GUI/GCodeViewer.cpp | 87 +++++++++++++------------- src/slic3r/GUI/GCodeViewer.hpp | 4 +- 8 files changed, 67 insertions(+), 72 deletions(-) diff --git a/resources/shaders/options_110.fs b/resources/shaders/options_110.fs index 3722058c87..474e355e09 100644 --- a/resources/shaders/options_110.fs +++ b/resources/shaders/options_110.fs @@ -1,4 +1,4 @@ -#version 120 +#version 110 uniform vec3 uniform_color; diff --git a/resources/shaders/options_110.vs b/resources/shaders/options_110.vs index 5361c88cec..7592f86a42 100644 --- a/resources/shaders/options_110.vs +++ b/resources/shaders/options_110.vs @@ -1,11 +1,11 @@ #version 110 uniform float zoom; -// x = min, y = max -uniform vec2 point_sizes; +uniform float point_size; +uniform float near_plane_height; void main() { - gl_PointSize = clamp(zoom, point_sizes.x, point_sizes.y); - gl_Position = ftransform(); + gl_Position = ftransform(); + gl_PointSize = (gl_Position.w == 1.0) ? zoom * near_plane_height * point_size : near_plane_height * point_size / gl_Position.w; } diff --git a/resources/shaders/options_120_flat.fs b/resources/shaders/options_120_flat.fs index 656eccd1d4..e98e5693f3 100644 --- a/resources/shaders/options_120_flat.fs +++ b/resources/shaders/options_120_flat.fs @@ -5,31 +5,31 @@ uniform vec3 uniform_color; uniform float percent_outline_radius; uniform float percent_center_radius; -vec4 hardcoded_color(float sq_radius) +vec4 hardcoded_color(float sq_radius, vec3 color) { if ((sq_radius < 0.005625) || (sq_radius > 0.180625)) - return vec4(0.5 * uniform_color, 1.0); + return vec4(0.5 * color, 1.0); else - return vec4(uniform_color, 1.0); + return vec4(color, 1.0); } -vec4 customizable_color(float sq_radius) +vec4 customizable_color(float sq_radius, vec3 color) { float in_radius = 0.5 * percent_center_radius; float out_radius = 0.5 * (1.0 - percent_outline_radius); if ((sq_radius < in_radius * in_radius) || (sq_radius > out_radius * out_radius)) - return vec4(0.5 * uniform_color, 1.0); + return vec4(0.5 * color, 1.0); else - return vec4(uniform_color, 1.0); + return vec4(color, 1.0); } void main() { - vec2 pos = gl_PointCoord - vec2(0.5, 0.5); + vec2 pos = gl_PointCoord - vec2(0.5); float sq_radius = dot(pos, pos); if (sq_radius > 0.25) discard; - - gl_FragColor = customizable_color(sq_radius); -// gl_FragColor = hardcoded_color(sq_radius); + + gl_FragColor = customizable_color(sq_radius, uniform_color); +// gl_FragColor = hardcoded_color(sq_radius, uniform_color); } diff --git a/resources/shaders/options_120_flat.vs b/resources/shaders/options_120_flat.vs index ebf7428c9a..baf3cd3a7f 100644 --- a/resources/shaders/options_120_flat.vs +++ b/resources/shaders/options_120_flat.vs @@ -1,11 +1,11 @@ #version 120 uniform float zoom; -// x = min, y = max -uniform vec2 point_sizes; +uniform float point_size; +uniform float near_plane_height; void main() { - gl_PointSize = clamp(zoom, point_sizes.x, point_sizes.y); - gl_Position = ftransform(); + gl_Position = ftransform(); + gl_PointSize = (gl_Position.w == 1.0) ? zoom * near_plane_height * point_size : near_plane_height * point_size / gl_Position.w; } diff --git a/resources/shaders/options_120_solid.fs b/resources/shaders/options_120_solid.fs index c7a57d547b..18410b4062 100644 --- a/resources/shaders/options_120_solid.fs +++ b/resources/shaders/options_120_solid.fs @@ -79,7 +79,7 @@ float fragment_depth(vec3 eye_pos) void main() { - vec2 pos = gl_PointCoord - vec2(0.5, 0.5); + vec2 pos = gl_PointCoord - vec2(0.5); float sq_radius = dot(pos, pos); if (sq_radius > 0.25) discard; diff --git a/resources/shaders/options_120_solid.vs b/resources/shaders/options_120_solid.vs index 0ad75003c9..745ec8ddd1 100644 --- a/resources/shaders/options_120_solid.vs +++ b/resources/shaders/options_120_solid.vs @@ -1,14 +1,14 @@ #version 120 uniform float zoom; -// x = min, y = max -uniform vec2 point_sizes; +uniform float point_size; +uniform float near_plane_height; varying vec3 eye_center; void main() { - gl_PointSize = clamp(zoom, point_sizes.x, point_sizes.y); eye_center = (gl_ModelViewMatrix * gl_Vertex).xyz; - gl_Position = ftransform(); + gl_Position = ftransform(); + gl_PointSize = (gl_Position.w == 1.0) ? zoom * near_plane_height * point_size : near_plane_height * point_size / gl_Position.w; } diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index ed98996b41..24960c79fb 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -756,40 +756,36 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool void GCodeViewer::render_toolpaths() const { #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR - bool is_glsl_120 = m_shaders_editor.shader_version >= 1 && wxGetApp().is_glsl_version_greater_or_equal_to(1, 20); - std::array point_sizes; - if (m_shaders_editor.size_dependent_on_zoom) - point_sizes = { std::min(static_cast(m_shaders_editor.sizes[0]), m_detected_point_sizes[1]), std::min(static_cast(m_shaders_editor.sizes[1]), m_detected_point_sizes[1]) }; - else - point_sizes = { static_cast(m_shaders_editor.fixed_size), static_cast(m_shaders_editor.fixed_size) }; + float point_size = m_shaders_editor.point_size; #else - bool is_glsl_120 = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20); - std::array point_sizes = { std::min(8.0f, m_detected_point_sizes[1]), std::min(48.0f, m_detected_point_sizes[1]) }; + float point_size = 1.0f; #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR const Camera& camera = wxGetApp().plater()->get_camera(); double zoom = camera.get_zoom(); const std::array& viewport = camera.get_viewport(); std::array viewport_sizes = { viewport[2], viewport[3] }; + float near_plane_height = camera.get_type() == Camera::Perspective ? static_cast(viewport[3]) / (2.0f * static_cast(2.0 * std::tan(0.5 * Geometry::deg2rad(camera.get_fov())))) : + static_cast(viewport[3]) * 0.0005; Transform3d inv_proj = camera.get_projection_matrix().inverse(); - auto render_options = [this, is_glsl_120, zoom, viewport, inv_proj, viewport_sizes, point_sizes](const IBuffer& buffer, EOptionsColors colors_id, GLShaderProgram& shader) { + auto render_options = [this, zoom, inv_proj, viewport_sizes, point_size, near_plane_height](const IBuffer& buffer, EOptionsColors colors_id, GLShaderProgram& shader) { shader.set_uniform("uniform_color", Options_Colors[static_cast(colors_id)]); + shader.set_uniform("zoom", zoom); #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR - shader.set_uniform("zoom", m_shaders_editor.size_dependent_on_zoom ? zoom : 1.0f); shader.set_uniform("percent_outline_radius", 0.01f * static_cast(m_shaders_editor.percent_outline)); shader.set_uniform("percent_center_radius", 0.01f * static_cast(m_shaders_editor.percent_center)); #else - shader.set_uniform("zoom", zoom); shader.set_uniform("percent_outline_radius", 0.15f); shader.set_uniform("percent_center_radius", 0.15f); #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR shader.set_uniform("viewport_sizes", viewport_sizes); shader.set_uniform("inv_proj_matrix", inv_proj); - shader.set_uniform("point_sizes", point_sizes); + shader.set_uniform("point_size", point_size); + shader.set_uniform("near_plane_height", near_plane_height); + glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); - if (is_glsl_120) - glsafe(::glEnable(GL_POINT_SPRITE)); + glsafe(::glEnable(GL_POINT_SPRITE)); for (const RenderPath& path : buffer.render_paths) { glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); @@ -797,9 +793,8 @@ void GCodeViewer::render_toolpaths() const ++m_statistics.gl_multi_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } - if (is_glsl_120) - glsafe(::glDisable(GL_POINT_SPRITE)); - + + glsafe(::glDisable(GL_POINT_SPRITE)); glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); }; @@ -964,31 +959,49 @@ void GCodeViewer::render_legend() const { #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size)); - draw_list->AddCircle(center, 0.5f * icon_size, ICON_BORDER_COLOR, 16); if (m_shaders_editor.shader_version == 1) { - draw_list->AddCircleFilled(center, (0.5f * icon_size) - 2.0f, + draw_list->AddCircleFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); - float radius = ((0.5f * icon_size) - 2.0f) * (1.0f - 0.01f * static_cast(m_shaders_editor.percent_outline)); + float radius = 0.5f * icon_size * (1.0f - 0.01f * static_cast(m_shaders_editor.percent_outline)); draw_list->AddCircleFilled(center, radius, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); if (m_shaders_editor.percent_center > 0) { - radius = ((0.5f * icon_size) - 2.0f) * 0.01f * static_cast(m_shaders_editor.percent_center); + radius = 0.5f * icon_size * 0.01f * static_cast(m_shaders_editor.percent_center); draw_list->AddCircleFilled(center, radius, ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); } - } else - draw_list->AddCircleFilled(center, (0.5f * icon_size) - 2.0f, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); + } + else + draw_list->AddCircleFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); + +// ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size)); +// draw_list->AddCircle(center, 0.5f * icon_size, ICON_BORDER_COLOR, 16); +// if (m_shaders_editor.shader_version == 1) { +// draw_list->AddCircleFilled(center, (0.5f * icon_size) - 2.0f, +// ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); +// float radius = ((0.5f * icon_size) - 2.0f) * (1.0f - 0.01f * static_cast(m_shaders_editor.percent_outline)); +// draw_list->AddCircleFilled(center, radius, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); +// if (m_shaders_editor.percent_center > 0) { +// radius = ((0.5f * icon_size) - 2.0f) * 0.01f * static_cast(m_shaders_editor.percent_center); +// draw_list->AddCircleFilled(center, radius, ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); +// } +// } else +// draw_list->AddCircleFilled(center, (0.5f * icon_size) - 2.0f, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); #else - draw_list->AddCircle({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, 0.5f * icon_size, ICON_BORDER_COLOR, 16); - draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, (0.5f * icon_size) - 2.0f, + draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, 0.5f * icon_size, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); + +// draw_list->AddCircle({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, 0.5f * icon_size, ICON_BORDER_COLOR, 16); +// draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, (0.5f * icon_size) - 2.0f, +// ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR break; } case EItemType::Hexagon: { ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size)); - draw_list->AddNgon(center, 0.5f * icon_size, ICON_BORDER_COLOR, 6); - draw_list->AddNgonFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, (0.5f * icon_size) - 2.0f, - ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 6); + draw_list->AddNgonFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 6); +// draw_list->AddNgon(center, 0.5f * icon_size, ICON_BORDER_COLOR, 6); +// draw_list->AddNgonFilled(center, (0.5f * icon_size) - 2.0f, +// ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 6); break; } case EItemType::Line: @@ -1409,23 +1422,7 @@ void GCodeViewer::render_shaders_editor() const if (ImGui::CollapsingHeader("Options", ImGuiTreeNodeFlags_DefaultOpen)) { - ImGui::Checkbox("size dependent on zoom", &m_shaders_editor.size_dependent_on_zoom); - if (m_shaders_editor.size_dependent_on_zoom) - { - if (ImGui::SliderInt("min size (min zoom)", &m_shaders_editor.sizes[0], 1, 100)) - { - if (m_shaders_editor.sizes[1] < m_shaders_editor.sizes[0]) - m_shaders_editor.sizes[1] = m_shaders_editor.sizes[0]; - } - ImGui::SliderInt("max size (max zoom)", &m_shaders_editor.sizes[1], 1, 100); - { - if (m_shaders_editor.sizes[1] < m_shaders_editor.sizes[0]) - m_shaders_editor.sizes[0] = m_shaders_editor.sizes[1]; - } - } - else - ImGui::SliderInt("fixed size", &m_shaders_editor.fixed_size, 1, 100); - + ImGui::SliderFloat("point size", &m_shaders_editor.point_size, 0.5f, 1.5f, "%.1f"); if (m_shaders_editor.shader_version == 1) { ImGui::SliderInt("percent outline", &m_shaders_editor.percent_outline, 0, 50); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index a2f9c14af7..6f24eef435 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -206,9 +206,7 @@ class GCodeViewer struct ShadersEditor { int shader_version{ 2 }; - bool size_dependent_on_zoom{ true }; - int fixed_size{ 16 }; - std::array sizes{ 3, 21 }; + float point_size{ 1.0f }; int percent_outline{ 0 }; int percent_center{ 33 }; }; From 707268d41dc737a1aa621ba0ad2cbc1cf63da3d1 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 1 Jun 2020 08:55:44 +0200 Subject: [PATCH 117/255] ENABLE_GCODE_VIEWER -> Improvements in shaders for options --- resources/shaders/options_120_flat.fs | 26 ++++++++------------- resources/shaders/options_120_solid.fs | 31 +++++++++++++------------- src/slic3r/GUI/GCodeViewer.cpp | 7 +++--- 3 files changed, 27 insertions(+), 37 deletions(-) diff --git a/resources/shaders/options_120_flat.fs b/resources/shaders/options_120_flat.fs index e98e5693f3..5bcc718761 100644 --- a/resources/shaders/options_120_flat.fs +++ b/resources/shaders/options_120_flat.fs @@ -5,31 +5,23 @@ uniform vec3 uniform_color; uniform float percent_outline_radius; uniform float percent_center_radius; -vec4 hardcoded_color(float sq_radius, vec3 color) +vec4 hardcoded_color(float radius, vec3 color) { - if ((sq_radius < 0.005625) || (sq_radius > 0.180625)) - return vec4(0.5 * color, 1.0); - else - return vec4(color, 1.0); + return ((radius < 0.15) || (radius > 0.85)) ? vec4(0.5 * color, 1.0) : vec4(color, 1.0); } -vec4 customizable_color(float sq_radius, vec3 color) +vec4 customizable_color(float radius, vec3 color) { - float in_radius = 0.5 * percent_center_radius; - float out_radius = 0.5 * (1.0 - percent_outline_radius); - if ((sq_radius < in_radius * in_radius) || (sq_radius > out_radius * out_radius)) - return vec4(0.5 * color, 1.0); - else - return vec4(color, 1.0); + return ((radius < percent_center_radius) || (radius > 1.0 - percent_outline_radius)) ? + vec4(0.5 * color, 1.0) : vec4(color, 1.0); } void main() { - vec2 pos = gl_PointCoord - vec2(0.5); - float sq_radius = dot(pos, pos); - if (sq_radius > 0.25) + vec2 pos = (gl_PointCoord - 0.5) * 2.0; + float radius = length(pos); + if (radius > 1.0) discard; - gl_FragColor = customizable_color(sq_radius, uniform_color); -// gl_FragColor = hardcoded_color(sq_radius, uniform_color); + gl_FragColor = customizable_color(radius, uniform_color); } diff --git a/resources/shaders/options_120_solid.fs b/resources/shaders/options_120_solid.fs index 18410b4062..ebe7135274 100644 --- a/resources/shaders/options_120_solid.fs +++ b/resources/shaders/options_120_solid.fs @@ -17,28 +17,26 @@ const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074); uniform vec3 uniform_color; -// x = width, y = height -uniform ivec2 viewport_sizes; +uniform ivec4 viewport; +uniform float point_size; uniform mat4 inv_proj_matrix; varying vec3 eye_center; - -float radius = 0.5; // x = tainted, y = specular; vec2 intensity; +float radius = 0.5 * point_size; + vec3 eye_position_from_fragment() { // Convert screen coordinates to normalized device coordinates (NDC) - vec4 ndc = vec4( - (gl_FragCoord.x / viewport_sizes.x - 0.5) * 2.0, - (gl_FragCoord.y / viewport_sizes.y - 0.5) * 2.0, - (gl_FragCoord.z - 0.5) * 2.0, - 1.0); - + vec4 ndc = vec4((gl_FragCoord.x / viewport.z - 0.5) * 2.0, + (gl_FragCoord.y / viewport.w - 0.5) * 2.0, + (gl_FragCoord.z - 0.5) * 2.0, + gl_FragCoord.w); // Convert NDC throuch inverse clip coordinates to view coordinates vec4 clip = inv_proj_matrix * ndc; - return (clip / clip.w).xyz; + return clip.xyz; } vec3 eye_position_on_sphere(vec3 eye_fragment_position) @@ -67,21 +65,22 @@ vec4 on_sphere_color(vec3 eye_on_sphere_position) NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0); intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; - return vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color.rgb * intensity.x, 1.0); + return vec4(intensity + uniform_color.rgb * intensity.x, 1.0); +// return vec4(vec3(intensity.y) + uniform_color.rgb * intensity.x, 1.0); } float fragment_depth(vec3 eye_pos) { vec4 clip_pos = gl_ProjectionMatrix * vec4(eye_pos, 1.0); float ndc_depth = clip_pos.z / clip_pos.w; - return (((gl_DepthRange.far - gl_DepthRange.near) * ndc_depth) + gl_DepthRange.near + gl_DepthRange.far) / 2.0; + return ((gl_DepthRange.far - gl_DepthRange.near) * ndc_depth + gl_DepthRange.near + gl_DepthRange.far) / 2.0; } void main() { - vec2 pos = gl_PointCoord - vec2(0.5); - float sq_radius = dot(pos, pos); - if (sq_radius > 0.25) + vec2 pos = (gl_PointCoord - 0.5) * 2.0; + float radius = length(pos); + if (radius > 1.0) discard; vec3 eye_on_sphere_position = eye_position_on_sphere(eye_position_from_fragment()); diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 24960c79fb..3709aaa888 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -763,13 +763,12 @@ void GCodeViewer::render_toolpaths() const const Camera& camera = wxGetApp().plater()->get_camera(); double zoom = camera.get_zoom(); const std::array& viewport = camera.get_viewport(); - std::array viewport_sizes = { viewport[2], viewport[3] }; float near_plane_height = camera.get_type() == Camera::Perspective ? static_cast(viewport[3]) / (2.0f * static_cast(2.0 * std::tan(0.5 * Geometry::deg2rad(camera.get_fov())))) : static_cast(viewport[3]) * 0.0005; Transform3d inv_proj = camera.get_projection_matrix().inverse(); - auto render_options = [this, zoom, inv_proj, viewport_sizes, point_size, near_plane_height](const IBuffer& buffer, EOptionsColors colors_id, GLShaderProgram& shader) { + auto render_options = [this, zoom, inv_proj, viewport, point_size, near_plane_height](const IBuffer& buffer, EOptionsColors colors_id, GLShaderProgram& shader) { shader.set_uniform("uniform_color", Options_Colors[static_cast(colors_id)]); shader.set_uniform("zoom", zoom); #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR @@ -779,7 +778,7 @@ void GCodeViewer::render_toolpaths() const shader.set_uniform("percent_outline_radius", 0.15f); shader.set_uniform("percent_center_radius", 0.15f); #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR - shader.set_uniform("viewport_sizes", viewport_sizes); + shader.set_uniform("viewport", viewport); shader.set_uniform("inv_proj_matrix", inv_proj); shader.set_uniform("point_size", point_size); shader.set_uniform("near_plane_height", near_plane_height); @@ -1422,7 +1421,7 @@ void GCodeViewer::render_shaders_editor() const if (ImGui::CollapsingHeader("Options", ImGuiTreeNodeFlags_DefaultOpen)) { - ImGui::SliderFloat("point size", &m_shaders_editor.point_size, 0.5f, 1.5f, "%.1f"); + ImGui::SliderFloat("point size", &m_shaders_editor.point_size, 0.5f, 3.0f, "%.1f"); if (m_shaders_editor.shader_version == 1) { ImGui::SliderInt("percent outline", &m_shaders_editor.percent_outline, 0, 50); From 7b33e780a2cf86b819dd6839844142111904efad Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 1 Jun 2020 09:11:16 +0200 Subject: [PATCH 118/255] Follow-up of 707268d41dc737a1aa621ba0ad2cbc1cf63da3d1 -> Fixed typo --- resources/shaders/options_120_solid.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/shaders/options_120_solid.fs b/resources/shaders/options_120_solid.fs index ebe7135274..912b809e07 100644 --- a/resources/shaders/options_120_solid.fs +++ b/resources/shaders/options_120_solid.fs @@ -65,7 +65,7 @@ vec4 on_sphere_color(vec3 eye_on_sphere_position) NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0); intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; - return vec4(intensity + uniform_color.rgb * intensity.x, 1.0); + return vec4(intensity.y + uniform_color.rgb * intensity.x, 1.0); // return vec4(vec3(intensity.y) + uniform_color.rgb * intensity.x, 1.0); } From ca17948f87d68e616a0dc888e906462a48b7699d Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 8 Jun 2020 09:12:20 +0200 Subject: [PATCH 119/255] ENABLE_GCODE_VIEWER_AS_STATE -> Load gcode from file and process it --- src/libslic3r/GCode/GCodeProcessor.cpp | 18 +++------ src/libslic3r/GCode/GCodeProcessor.hpp | 5 ++- src/libslic3r/Technologies.hpp | 2 - src/slic3r/GUI/GCodeViewer.cpp | 23 ++++++++---- src/slic3r/GUI/GLCanvas3D.hpp | 8 ---- src/slic3r/GUI/GUI_App.cpp | 2 - src/slic3r/GUI/GUI_App.hpp | 2 - src/slic3r/GUI/GUI_Preview.cpp | 14 ------- src/slic3r/GUI/MainFrame.cpp | 51 ++------------------------ src/slic3r/GUI/MainFrame.hpp | 8 ---- src/slic3r/GUI/Plater.cpp | 35 +++++------------- src/slic3r/GUI/Plater.hpp | 16 ++++---- 12 files changed, 46 insertions(+), 138 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index b43f1466c1..c74820a04c 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -37,7 +37,7 @@ void GCodeProcessor::CpColor::reset() current = 0; } -unsigned int GCodeProcessor::Result::id = 0; +unsigned int GCodeProcessor::s_result_id = 0; void GCodeProcessor::apply_config(const PrintConfig& config) { @@ -84,19 +84,19 @@ void GCodeProcessor::reset() m_cp_color.reset(); m_result.reset(); + m_result.id = ++s_result_id; } void GCodeProcessor::process_file(const std::string& filename) { + m_result.id = ++s_result_id; m_result.moves.emplace_back(MoveVertex()); m_parser.parse_file(filename, [this](GCodeReader& reader, const GCodeReader::GCodeLine& line) { process_gcode_line(line); }); } void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) { -/* - std::cout << line.raw() << std::endl; -*/ +/* std::cout << line.raw() << std::endl; */ // update start position m_start_position = m_end_position; @@ -296,24 +296,18 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) } else if (delta_pos[X] != 0.0f || delta_pos[Y] != 0.0f || delta_pos[Z] != 0.0f) type = EMoveType::Travel; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE - if (type == EMoveType::Extrude && (m_width == 0.0f || m_height == 0.0f)) - { - if (m_extrusion_role != erCustom) - { + if (type == EMoveType::Extrude && (m_width == 0.0f || m_height == 0.0f)) { + if (m_extrusion_role != erCustom) { m_width = 0.5f; m_height = 0.5f; } type = EMoveType::Travel; } #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (type == EMoveType::Extrude && (m_width == 0.0f || m_height == 0.0f || !is_valid_extrusion_role(m_extrusion_role))) type = EMoveType::Travel; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ return type; }; diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 4f6cf7430f..e8c43350c0 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -104,9 +104,9 @@ namespace Slic3r { struct Result { - static unsigned int id; + unsigned int id; std::vector moves; - void reset() { ++id; moves = std::vector(); } + void reset() { moves = std::vector(); } }; private: @@ -134,6 +134,7 @@ namespace Slic3r { CpColor m_cp_color; Result m_result; + static unsigned int s_result_id; public: GCodeProcessor() { reset(); } diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 6b60517f61..31cd28b0d2 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -55,9 +55,7 @@ #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) #define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_SHADERS_EDITOR (1 && ENABLE_GCODE_VIEWER) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #define ENABLE_GCODE_VIEWER_AS_STATE (1 && ENABLE_GCODE_VIEWER) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 3709aaa888..31065d230d 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -5,6 +5,9 @@ #include "libslic3r/Print.hpp" #include "libslic3r/Geometry.hpp" #include "GUI_App.hpp" +#if ENABLE_GCODE_VIEWER_AS_STATE +#include "MainFrame.hpp" +#endif // ENABLE_GCODE_VIEWER_AS_STATE #include "Plater.hpp" #include "PresetBundle.hpp" #include "Camera.hpp" @@ -443,13 +446,19 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) return; // vertex data / bounding box -> extract from result - std::vector vertices_data(m_vertices.vertices_count * 3); - for (size_t i = 0; i < m_vertices.vertices_count; ++i) { - const GCodeProcessor::MoveVertex& move = gcode_result.moves[i]; - if (move.type == GCodeProcessor::EMoveType::Extrude) - m_bounding_box.merge(move.position.cast()); - ::memcpy(static_cast(&vertices_data[i * 3]), static_cast(move.position.data()), 3 * sizeof(float)); - } + std::vector vertices_data(m_vertices.vertices_count * 3); + for (size_t i = 0; i < m_vertices.vertices_count; ++i) { + const GCodeProcessor::MoveVertex& move = gcode_result.moves[i]; +#if ENABLE_GCODE_VIEWER_AS_STATE + if (wxGetApp().mainframe->get_mode() != MainFrame::EMode::GCodeViewer) { +#endif // ENABLE_GCODE_VIEWER_AS_STATE + if (move.type == GCodeProcessor::EMoveType::Extrude && move.width != 0.0f && move.height != 0.0f) + m_bounding_box.merge(move.position.cast()); +#if ENABLE_GCODE_VIEWER_AS_STATE + } +#endif // ENABLE_GCODE_VIEWER_AS_STATE + ::memcpy(static_cast(&vertices_data[i * 3]), static_cast(move.position.data()), 3 * sizeof(float)); + } m_bounding_box.merge(m_bounding_box.max + m_sequential_view.marker.get_bounding_box().max[2] * Vec3d::UnitZ()); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 810a99f211..c8b7d3231c 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -127,9 +127,7 @@ class GLCanvas3D static const double DefaultCameraZoomToBoxMarginFactor; public: -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ struct GCodePreviewVolumeIndex { enum EType @@ -156,9 +154,7 @@ public: void reset() { first_volumes.clear(); } }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ private: class LayersEditing @@ -514,13 +510,9 @@ private: bool m_reload_delayed; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GCodePreviewVolumeIndex m_gcode_preview_volume_index; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_RENDER_PICKING_PASS bool m_show_picking_texture; diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index ad26582986..d7f019e41b 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -760,7 +760,6 @@ void GUI_App::import_model(wxWindow *parent, wxArrayString& input_files) const dialog.GetPaths(input_files); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE void GUI_App::load_gcode(wxWindow* parent, wxString& input_file) const { @@ -774,7 +773,6 @@ void GUI_App::load_gcode(wxWindow* parent, wxString& input_file) const input_file = dialog.GetPath(); } #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool GUI_App::switch_language() { diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 11f3a7c3cc..ad874bd1ef 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -156,11 +156,9 @@ public: void keyboard_shortcuts(); void load_project(wxWindow *parent, wxString& input_file) const; void import_model(wxWindow *parent, wxArrayString& input_files) const; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE void load_gcode(wxWindow* parent, wxString& input_file) const; #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ static bool catch_error(std::function cb, const std::string& err); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 6b3866ca47..51e8e81876 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -13,11 +13,9 @@ #include "PresetBundle.hpp" #include "DoubleSlider.hpp" #include "Plater.hpp" -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE #include "MainFrame.hpp" #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include #include @@ -1193,13 +1191,11 @@ void Preview::update_double_slider_from_canvas(wxKeyEvent & event) void Preview::load_print_as_fff(bool keep_z_range) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE if (wxGetApp().mainframe == nullptr) // avoid proessing while mainframe is being constructed return; #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (m_loaded || m_process->current_printer_technology() != ptFFF) return; @@ -1224,23 +1220,17 @@ void Preview::load_print_as_fff(bool keep_z_range) } } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE if (wxGetApp().mainframe->get_mode() != MainFrame::EMode::GCodeViewer && !has_layers) #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (! has_layers) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { #if ENABLE_GCODE_VIEWER hide_layers_slider(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GetSizer()->Hide(m_bottom_toolbar_panel); GetSizer()->Layout(); Refresh(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #else reset_sliders(true); m_canvas->reset_legend_texture(); @@ -1270,15 +1260,11 @@ void Preview::load_print_as_fff(bool keep_z_range) #if ENABLE_GCODE_VIEWER GCodeViewer::EViewType gcode_view_type = m_canvas->get_gcode_view_preview_type(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE bool gcode_preview_data_valid = !m_gcode_result->moves.empty(); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool gcode_preview_data_valid = print->is_step_done(psGCodeExport); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #else bool gcode_preview_data_valid = print->is_step_done(psGCodeExport) && ! m_gcode_preview_data->empty(); #endif // ENABLE_GCODE_VIEWER diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 89be99e06c..f09f611e6e 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -81,7 +81,6 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S // initialize tabpanel and menubar init_tabpanel(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE init_editor_menubar(); init_gcodeviewer_menubar(); @@ -99,11 +98,8 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S SetAcceleratorTable(accel); #endif // _WIN32 #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ init_menubar(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // set default tooltip timer in msec // SetAutoPop supposedly accepts long integers but some bug doesn't allow for larger values @@ -248,7 +244,6 @@ void MainFrame::shutdown() } #endif // _WIN32 -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE if (m_plater != nullptr) { m_plater->stop_jobs(); @@ -263,7 +258,6 @@ void MainFrame::shutdown() m_plater->reset_canvas_volumes(); } #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (m_plater) m_plater->stop_jobs(); @@ -275,9 +269,7 @@ void MainFrame::shutdown() // Cleanup of canvases' volumes needs to be done here or a crash may happen on some Linux Debian flavours // see: https://github.com/prusa3d/PrusaSlicer/issues/3964 if (m_plater) m_plater->reset_canvas_volumes(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Weird things happen as the Paint messages are floating around the windows being destructed. // Avoid the Paint messages by hiding the main window. @@ -288,9 +280,8 @@ void MainFrame::shutdown() if (m_settings_dialog) m_settings_dialog->Destroy(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (m_plater != nullptr) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // restore sidebar if it was hidden when switching to gcode viewer mode if (m_restore_from_gcode_viewer.collapsed_sidebar) m_plater->collapse_sidebar(false); // Stop the background thread (Windows and Linux). @@ -298,9 +289,7 @@ void MainFrame::shutdown() m_plater->get_mouse3d_controller().shutdown(); // Store the device parameter database back to appconfig. m_plater->get_mouse3d_controller().save_config(*wxGetApp().app_config); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Stop the background thread of the removable drive manager, so that no new updates will be sent to the Plater. wxGetApp().removable_drive_manager()->shutdown(); @@ -642,7 +631,6 @@ void MainFrame::on_sys_color_changed() msw_rescale_menu(menu_bar->GetMenu(id)); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE #ifdef _MSC_VER // \xA0 is a non-breaking space. It is entered here to spoil the automatic accelerators, @@ -716,11 +704,8 @@ static void add_common_view_menu_items(wxMenu* view_menu, MainFrame* mainFrame, void MainFrame::init_editor_menubar() #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void MainFrame::init_menubar() -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { #ifdef __APPLE__ wxMenuBar::SetAutoWindowMenu(false); @@ -880,21 +865,17 @@ void MainFrame::init_menubar() append_menu_item(fileMenu, wxID_ANY, _L("&Repair STL file") + dots, _L("Automatically repair an STL file"), [this](wxCommandEvent&) { repair_stl(); }, "wrench", nullptr, [this]() {return true; }, this); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE fileMenu->AppendSeparator(); append_menu_item(fileMenu, wxID_ANY, _L("&G-code preview"), _L("Switch to G-code preview mode"), [this](wxCommandEvent&) { set_mode(EMode::GCodeViewer); }); #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ fileMenu->AppendSeparator(); append_menu_item(fileMenu, wxID_EXIT, _L("&Quit"), wxString::Format(_L("Quit %s"), SLIC3R_APP_NAME), [this](wxCommandEvent&) { Close(false); }); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #ifdef _MSC_VER // \xA0 is a non-breaking space. It is entered here to spoil the automatic accelerators, // as the simple numeric accelerators spoil all numeric data entry. @@ -904,9 +885,7 @@ void MainFrame::init_menubar() wxString sep = " - "; wxString sep_space = ""; #endif -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Edit menu wxMenu* editMenu = nullptr; @@ -990,9 +969,7 @@ void MainFrame::init_menubar() [this](){return can_change_view(); }, this); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if _WIN32 // This is needed on Windows to fake the CTRL+# of the window menu when using the numpad wxAcceleratorEntry entries[6]; @@ -1005,9 +982,7 @@ void MainFrame::init_menubar() wxAcceleratorTable accel(6, entries); SetAcceleratorTable(accel); #endif // _WIN32 -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ windowMenu->AppendSeparator(); append_menu_item(windowMenu, wxID_ANY, _L("Print &Host Upload Queue") + "\tCtrl+J", _L("Display the Print Host Upload Queue window"), @@ -1019,11 +994,9 @@ void MainFrame::init_menubar() wxMenu* viewMenu = nullptr; if (m_plater) { viewMenu = new wxMenu(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE add_common_view_menu_items(viewMenu, this, std::bind(&MainFrame::can_change_view, this)); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // The camera control accelerators are captured by GLCanvas3D::on_char(). append_menu_item(viewMenu, wxID_ANY, _L("Iso") + sep + "&0", _L("Iso View"), [this](wxCommandEvent&) { select_view("iso"); }, "", nullptr, [this](){return can_change_view(); }, this); @@ -1042,9 +1015,7 @@ void MainFrame::init_menubar() "", nullptr, [this](){return can_change_view(); }, this); append_menu_item(viewMenu, wxID_ANY, _L("Right") + sep + "&6", _L("Right View"), [this](wxCommandEvent&) { select_view("right"); }, "", nullptr, [this](){return can_change_view(); }, this); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ viewMenu->AppendSeparator(); #if ENABLE_SLOPE_RENDERING wxMenu* options_menu = new wxMenu(); @@ -1066,11 +1037,9 @@ void MainFrame::init_menubar() } // Help menu -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE auto helpMenu = generate_help_menu(); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ auto helpMenu = new wxMenu(); { append_menu_item(helpMenu, wxID_ANY, _L("Prusa 3D &Drivers"), _L("Open the Prusa3D drivers download page in your browser"), @@ -1105,14 +1074,11 @@ void MainFrame::init_menubar() [this](wxCommandEvent&) { wxGetApp().gcode_thumbnails_debug(); }); #endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // menubar // assign menubar to frame after appending items, otherwise special items // will not be handled correctly -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE m_editor_menubar = new wxMenuBar(); m_editor_menubar->Append(fileMenu, _L("&File")); @@ -1124,7 +1090,6 @@ void MainFrame::init_menubar() m_editor_menubar->Append(helpMenu, _L("&Help")); SetMenuBar(m_editor_menubar); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ auto menubar = new wxMenuBar(); menubar->Append(fileMenu, _(L("&File"))); if (editMenu) menubar->Append(editMenu, _(L("&Edit"))); @@ -1134,9 +1099,7 @@ void MainFrame::init_menubar() wxGetApp().add_config_menu(menubar); menubar->Append(helpMenu, _(L("&Help"))); SetMenuBar(menubar); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #ifdef __APPLE__ // This fixes a bug on Mac OS where the quit command doesn't emit window close events @@ -1150,18 +1113,13 @@ void MainFrame::init_menubar() #endif if (plater()->printer_technology() == ptSLA) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE update_editor_menubar(); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ update_menubar(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE void MainFrame::init_gcodeviewer_menubar() { @@ -1204,6 +1162,7 @@ void MainFrame::set_mode(EMode mode) case EMode::Editor: { m_plater->reset(); +// m_plater->reset_last_loaded_gcode(); // switch view m_plater->select_view_3D("3D"); @@ -1229,6 +1188,7 @@ void MainFrame::set_mode(EMode mode) case EMode::GCodeViewer: { m_plater->reset(); + m_plater->reset_last_loaded_gcode(); // reinitialize undo/redo stack m_plater->clear_undo_redo_stack_main(); @@ -1258,17 +1218,12 @@ void MainFrame::set_mode(EMode mode) } } #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE void MainFrame::update_editor_menubar() #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void MainFrame::update_menubar() -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { const bool is_fff = plater()->printer_technology() == ptFFF; diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index 8a68fa36fd..c51567dd31 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -68,7 +68,6 @@ class MainFrame : public DPIFrame wxString m_qs_last_input_file = wxEmptyString; wxString m_qs_last_output_file = wxEmptyString; wxString m_last_config = wxEmptyString; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE wxMenuBar* m_editor_menubar{ nullptr }; wxMenuBar* m_gcodeviewer_menubar{ nullptr }; @@ -81,7 +80,6 @@ class MainFrame : public DPIFrame RestoreFromGCodeViewer m_restore_from_gcode_viewer; #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if 0 wxMenuItem* m_menu_item_repeat { nullptr }; // doesn't used now @@ -135,7 +133,6 @@ class MainFrame : public DPIFrame slDlg, } m_layout; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE public: enum class EMode : unsigned char @@ -147,7 +144,6 @@ public: private: EMode m_mode{ EMode::Editor }; #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ protected: virtual void on_dpi_changed(const wxRect &suggested_rect); @@ -167,7 +163,6 @@ public: void init_tabpanel(); void create_preset_tabs(); void add_created_tab(Tab* panel); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE void init_editor_menubar(); void update_editor_menubar(); @@ -176,12 +171,9 @@ public: EMode get_mode() const { return m_mode; } void set_mode(EMode mode); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void init_menubar(); void update_menubar(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void update_ui_from_settings(); bool is_loaded() const { return m_loaded; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index cb306caba1..7e9779f17e 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -33,17 +33,13 @@ #include "libslic3r/Format/STL.hpp" #include "libslic3r/Format/AMF.hpp" #include "libslic3r/Format/3mf.hpp" -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE #include "libslic3r/GCode/GCodeProcessor.hpp" #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_GCODE_VIEWER #include "libslic3r/GCode/PreviewData.hpp" #endif // !ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "libslic3r/GCode/ThumbnailData.hpp" #include "libslic3r/Model.hpp" #include "libslic3r/SLA/Hollowing.hpp" @@ -2735,11 +2731,9 @@ void Plater::priv::reset() model.custom_gcode_per_print_z.gcodes.clear(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE gcode_result.reset(); #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } void Plater::priv::mirror(Axis axis) @@ -4550,7 +4544,6 @@ void Plater::extract_config_from_project() load_files(input_paths, false, true); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE void Plater::load_gcode() { @@ -4563,25 +4556,27 @@ void Plater::load_gcode() void Plater::load_gcode(const wxString& filename) { - if (filename.empty()) + if (filename.empty() || m_last_loaded_gcode == filename) return; -// p->gcode_result.reset(); + m_last_loaded_gcode = filename; + + // cleanup view before to start loading/processing + p->gcode_result.reset(); + p->preview->reload_print(false); + p->get_current_canvas3D()->render(); wxBusyCursor wait; - wxBusyInfo info(_L("Processing GCode") + "...", get_current_canvas3D()->get_wxglcanvas()); +// wxBusyInfo info(_L("Processing GCode") + "...", get_current_canvas3D()->get_wxglcanvas()); GCodeProcessor processor; // processor.apply_config(config); processor.process_file(filename.ToUTF8().data()); p->gcode_result = std::move(processor.extract_result()); -// select_view_3D("Preview"); - p->preview->load_print(false); -// p->preview->load_gcode_preview(); + p->preview->reload_print(false); } #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::vector Plater::load_files(const std::vector& input_files, bool load_model, bool load_config, bool imperial_units /*= false*/) { return p->load_files(input_files, load_model, load_config, imperial_units); } @@ -5513,16 +5508,12 @@ void Plater::set_printer_technology(PrinterTechnology printer_technology) p->label_btn_export = printer_technology == ptFFF ? L("Export G-code") : L("Export"); p->label_btn_send = printer_technology == ptFFF ? L("Send G-code") : L("Send to printer"); - if (wxGetApp().mainframe) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + if (wxGetApp().mainframe != nullptr) #if ENABLE_GCODE_VIEWER_AS_STATE wxGetApp().mainframe->update_editor_menubar(); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ wxGetApp().mainframe->update_menubar(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ p->update_main_toolbar_tooltips(); @@ -5674,28 +5665,24 @@ bool Plater::init_view_toolbar() return p->init_view_toolbar(); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE void Plater::enable_view_toolbar(bool enable) { p->view_toolbar.set_enabled(enable); } #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool Plater::init_collapse_toolbar() { return p->init_collapse_toolbar(); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE void Plater::enable_collapse_toolbar(bool enable) { p->collapse_toolbar.set_enabled(enable); } #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const Camera& Plater::get_camera() const { @@ -5819,11 +5806,9 @@ bool Plater::can_undo() const { return p->undo_redo_stack().has_undo_snapshot(); bool Plater::can_redo() const { return p->undo_redo_stack().has_redo_snapshot(); } bool Plater::can_reload_from_disk() const { return p->can_reload_from_disk(); } const UndoRedo::Stack& Plater::undo_redo_stack_main() const { return p->undo_redo_stack_main(); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE void Plater::clear_undo_redo_stack_main() { p->undo_redo_stack_main().clear(); } #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void Plater::enter_gizmos_stack() { p->enter_gizmos_stack(); } void Plater::leave_gizmos_stack() { p->leave_gizmos_stack(); } bool Plater::inside_snapshot_capture() { return p->inside_snapshot_capture(); } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 92b46c9373..fdead2a1cc 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -173,12 +173,10 @@ public: void add_model(bool imperial_units = false); void import_sl1_archive(); void extract_config_from_project(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE void load_gcode(); void load_gcode(const wxString& filename); #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::vector load_files(const std::vector& input_files, bool load_model = true, bool load_config = true, bool imperial_units = false); // To be called when providing a list of files to the GUI slic3r on command line. @@ -258,11 +256,9 @@ public: bool search_string_getter(int idx, const char** label, const char** tooltip); // For the memory statistics. const Slic3r::UndoRedo::Stack& undo_redo_stack_main() const; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE void clear_undo_redo_stack_main(); #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Enter / leave the Gizmos specific Undo / Redo stack. To be used by the SLA support point editing gizmo. void enter_gizmos_stack(); void leave_gizmos_stack(); @@ -326,17 +322,13 @@ public: void sys_color_changed(); bool init_view_toolbar(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE void enable_view_toolbar(bool enable); #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool init_collapse_toolbar(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_AS_STATE void enable_collapse_toolbar(bool enable); #endif // ENABLE_GCODE_VIEWER_AS_STATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const Camera& get_camera() const; Camera& get_camera(); @@ -360,6 +352,10 @@ public: void update_preview_moves_slider(); #endif // ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER_AS_STATE + void reset_last_loaded_gcode() { m_last_loaded_gcode = ""; } +#endif // ENABLE_GCODE_VIEWER_AS_STATE + const Mouse3DController& get_mouse3d_controller() const; Mouse3DController& get_mouse3d_controller(); @@ -414,6 +410,10 @@ private: bool m_tracking_popup_menu = false; wxString m_tracking_popup_menu_error_message; +#if ENABLE_GCODE_VIEWER_AS_STATE + wxString m_last_loaded_gcode; +#endif // ENABLE_GCODE_VIEWER_AS_STATE + void suppress_snapshots(); void allow_snapshots(); From 70478f226f739f08dba2fac59e44b0ddd9e009e5 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 8 Jun 2020 12:27:32 +0200 Subject: [PATCH 120/255] ENABLE_GCODE_VIEWER_AS_STATE -> Use default printbed in gcode viewer --- src/slic3r/GUI/GCodeViewer.cpp | 17 +++++++++++++++- src/slic3r/GUI/GLCanvas3D.cpp | 37 +++++++++++++++++++++++++--------- src/slic3r/GUI/GLCanvas3D.hpp | 3 +++ src/slic3r/GUI/MainFrame.cpp | 11 +++++++++- src/slic3r/GUI/Plater.cpp | 37 ++++++++++++++++++---------------- src/slic3r/GUI/Plater.hpp | 3 +++ 6 files changed, 79 insertions(+), 29 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 31065d230d..281ccfa67d 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -251,6 +251,19 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& load_toolpaths(gcode_result); load_shells(print, initialized); + +#if ENABLE_GCODE_VIEWER_AS_STATE + // adjust printbed size + const double margin = 10.0; + Vec2d min(m_bounding_box.min(0) - margin, m_bounding_box.min(1) - margin); + Vec2d max(m_bounding_box.max(0) + margin, m_bounding_box.max(1) + margin); + Pointfs bed_shape = { + { min(0), min(1) }, + { max(0), min(1) }, + { max(0), max(1) }, + { min(0), max(1) } }; + wxGetApp().plater()->set_bed_shape(bed_shape, "", ""); +#endif // ENABLE_GCODE_VIEWER_AS_STATE } void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors) @@ -450,7 +463,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) for (size_t i = 0; i < m_vertices.vertices_count; ++i) { const GCodeProcessor::MoveVertex& move = gcode_result.moves[i]; #if ENABLE_GCODE_VIEWER_AS_STATE - if (wxGetApp().mainframe->get_mode() != MainFrame::EMode::GCodeViewer) { + if (wxGetApp().mainframe->get_mode() == MainFrame::EMode::GCodeViewer) + m_bounding_box.merge(move.position.cast()); + else { #endif // ENABLE_GCODE_VIEWER_AS_STATE if (move.type == GCodeProcessor::EMoveType::Extrude && move.width != 0.0f && move.height != 0.0f) m_bounding_box.merge(move.position.cast()); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 304bc9fe7c..29d3b9aa57 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1930,6 +1930,13 @@ void GLCanvas3D::zoom_to_selection() _zoom_to_box(m_selection.get_bounding_box()); } +#if ENABLE_GCODE_VIEWER_AS_STATE +void GLCanvas3D::zoom_to_gcode() +{ + _zoom_to_box(m_gcode_viewer.get_bounding_box(), 1.05); +} +#endif // ENABLE_GCODE_VIEWER_AS_STATE + void GLCanvas3D::select_view(const std::string& direction) { wxGetApp().plater()->get_camera().select_view(direction); @@ -2706,7 +2713,10 @@ static void load_gcode_retractions(const GCodePreviewData::Retraction& retractio void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result) { m_gcode_viewer.load(gcode_result, *this->fff_print(), m_initialized); - _show_warning_texture_if_needed(WarningTexture::ToolpathOutside); +#if ENABLE_GCODE_VIEWER_AS_STATE + if (wxGetApp().mainframe->get_mode() != MainFrame::EMode::GCodeViewer) +#endif // ENABLE_GCODE_VIEWER_AS_STATE + _show_warning_texture_if_needed(WarningTexture::ToolpathOutside); } void GLCanvas3D::refresh_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors) @@ -5351,8 +5361,7 @@ static BoundingBoxf3 print_volume(const DynamicPrintConfig& config) BoundingBoxf3 ret; const ConfigOptionPoints* opt = dynamic_cast(config.option("bed_shape")); - if (opt != nullptr) - { + if (opt != nullptr) { BoundingBox bed_box_2D = get_extents(Polygon::new_scale(opt->values)); ret = BoundingBoxf3(Vec3d(unscale(bed_box_2D.min(0)) - tolerance_x, unscale(bed_box_2D.min(1)) - tolerance_y, 0.0), Vec3d(unscale(bed_box_2D.max(0)) + tolerance_x, unscale(bed_box_2D.max(1)) + tolerance_y, config.opt_float("max_print_height"))); // Allow the objects to protrude below the print bed @@ -5365,14 +5374,22 @@ static BoundingBoxf3 print_volume(const DynamicPrintConfig& config) void GLCanvas3D::_render_background() const { #if ENABLE_GCODE_VIEWER - bool use_error_color = m_dynamic_background_enabled; - if (!m_volumes.empty()) - use_error_color &= _is_any_volume_outside(); - else - { - BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3(); - use_error_color &= (test_volume.radius() > 0.0) ? !test_volume.contains(m_gcode_viewer.get_bounding_box()) : false; +#if ENABLE_GCODE_VIEWER_AS_STATE + bool use_error_color = false; + if (wxGetApp().mainframe->get_mode() != MainFrame::EMode::GCodeViewer) { + use_error_color = m_dynamic_background_enabled; +#else + bool use_error_color = m_dynamic_background_enabled; +#endif // ENABLE_GCODE_VIEWER_AS_STATE + if (!m_volumes.empty()) + use_error_color &= _is_any_volume_outside(); + else { + BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3(); + use_error_color &= (test_volume.radius() > 0.0) ? !test_volume.contains(m_gcode_viewer.get_bounding_box()) : false; + } +#if ENABLE_GCODE_VIEWER_AS_STATE } +#endif // ENABLE_GCODE_VIEWER_AS_STATE #endif // ENABLE_GCODE_VIEWER glsafe(::glPushMatrix()); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index c8b7d3231c..782a9425d7 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -624,6 +624,9 @@ public: void zoom_to_bed(); void zoom_to_volumes(); void zoom_to_selection(); +#if ENABLE_GCODE_VIEWER_AS_STATE + void zoom_to_gcode(); +#endif // ENABLE_GCODE_VIEWER_AS_STATE void select_view(const std::string& direction); void update_volumes_colors_by_extruder(); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index f09f611e6e..f9e757251f 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -1162,10 +1162,14 @@ void MainFrame::set_mode(EMode mode) case EMode::Editor: { m_plater->reset(); -// m_plater->reset_last_loaded_gcode(); // switch view m_plater->select_view_3D("3D"); + m_plater->select_view("iso"); + + // switch printbed + m_plater->set_bed_shape(); + // switch menubar SetMenuBar(m_editor_menubar); @@ -1196,6 +1200,11 @@ void MainFrame::set_mode(EMode mode) // switch view m_plater->select_view_3D("Preview"); + m_plater->select_view("iso"); + + // switch printbed + m_plater->set_bed_shape({ { 0.0, 0.0 }, { 200.0, 0.0 }, { 200.0, 200.0 }, { 0.0, 200.0 } }, "", ""); + // switch menubar SetMenuBar(m_gcodeviewer_menubar); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 7e9779f17e..e5bbf73c61 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2014,21 +2014,11 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) view3D_canvas->Bind(EVT_GLTOOLBAR_SPLIT_OBJECTS, &priv::on_action_split_objects, this); view3D_canvas->Bind(EVT_GLTOOLBAR_SPLIT_VOLUMES, &priv::on_action_split_volumes, this); view3D_canvas->Bind(EVT_GLTOOLBAR_LAYERSEDITING, &priv::on_action_layersediting, this); - view3D_canvas->Bind(EVT_GLCANVAS_UPDATE_BED_SHAPE, [this](SimpleEvent&) - { - set_bed_shape(config->option("bed_shape")->values, - config->option("bed_custom_texture")->value, - config->option("bed_custom_model")->value); - }); + view3D_canvas->Bind(EVT_GLCANVAS_UPDATE_BED_SHAPE, [q](SimpleEvent&) { q->set_bed_shape(); }); // Preview events: preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_QUESTION_MARK, [this](SimpleEvent&) { wxGetApp().keyboard_shortcuts(); }); - preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_UPDATE_BED_SHAPE, [this](SimpleEvent&) - { - set_bed_shape(config->option("bed_shape")->values, - config->option("bed_custom_texture")->value, - config->option("bed_custom_model")->value); - }); + preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_UPDATE_BED_SHAPE, [q](SimpleEvent&) { q->set_bed_shape(); }); preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_TAB, [this](SimpleEvent&) { select_next_view_3D(); }); #if ENABLE_GCODE_VIEWER preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_MOVE_LAYERS_SLIDER, [this](wxKeyEvent& evt) { preview->move_layers_slider(evt); }); @@ -4567,14 +4557,16 @@ void Plater::load_gcode(const wxString& filename) p->get_current_canvas3D()->render(); wxBusyCursor wait; -// wxBusyInfo info(_L("Processing GCode") + "...", get_current_canvas3D()->get_wxglcanvas()); + // process gcode GCodeProcessor processor; // processor.apply_config(config); processor.process_file(filename.ToUTF8().data()); p->gcode_result = std::move(processor.extract_result()); + // show results p->preview->reload_print(false); + p->preview->get_canvas3d()->zoom_to_gcode(); } #endif // ENABLE_GCODE_VIEWER_AS_STATE @@ -5318,9 +5310,7 @@ void Plater::on_config_change(const DynamicPrintConfig &config) } if (bed_shape_changed) - p->set_bed_shape(p->config->option("bed_shape")->values, - p->config->option("bed_custom_texture")->value, - p->config->option("bed_custom_model")->value); + set_bed_shape(); if (update_scheduled) update(); @@ -5331,11 +5321,24 @@ void Plater::on_config_change(const DynamicPrintConfig &config) void Plater::set_bed_shape() const { - p->set_bed_shape(p->config->option("bed_shape")->values, +#if ENABLE_GCODE_VIEWER_AS_STATE + set_bed_shape(p->config->option("bed_shape")->values, + p->config->option("bed_custom_texture")->value, + p->config->option("bed_custom_model")->value); +#else + p->set_bed_shape(p->config->option("bed_shape")->values, p->config->option("bed_custom_texture")->value, p->config->option("bed_custom_model")->value); +#endif // ENABLE_GCODE_VIEWER_AS_STATE } +#if ENABLE_GCODE_VIEWER_AS_STATE +void Plater::set_bed_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model) const +{ + p->set_bed_shape(shape, custom_texture, custom_model); +} +#endif // ENABLE_GCODE_VIEWER_AS_STATE + void Plater::force_filament_colors_update() { bool update_scheduled = false; diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index fdead2a1cc..9759a7ffc3 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -360,6 +360,9 @@ public: Mouse3DController& get_mouse3d_controller(); void set_bed_shape() const; +#if ENABLE_GCODE_VIEWER_AS_STATE + void set_bed_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model) const; +#endif // ENABLE_GCODE_VIEWER_AS_STATE // ROII wrapper for suppressing the Undo / Redo snapshot to be taken. class SuppressSnapshots From ea0e9a5873aecdc9799d39bc276e034b38126ff1 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 8 Jun 2020 13:17:07 +0200 Subject: [PATCH 121/255] Follow-up of 70478f226f739f08dba2fac59e44b0ddd9e009e5 -> Fixed printbed for regular gcode preview --- src/slic3r/GUI/GCodeViewer.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 281ccfa67d..61d432b9a8 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -253,16 +253,18 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& load_shells(print, initialized); #if ENABLE_GCODE_VIEWER_AS_STATE - // adjust printbed size - const double margin = 10.0; - Vec2d min(m_bounding_box.min(0) - margin, m_bounding_box.min(1) - margin); - Vec2d max(m_bounding_box.max(0) + margin, m_bounding_box.max(1) + margin); - Pointfs bed_shape = { - { min(0), min(1) }, - { max(0), min(1) }, - { max(0), max(1) }, - { min(0), max(1) } }; - wxGetApp().plater()->set_bed_shape(bed_shape, "", ""); + if (wxGetApp().mainframe->get_mode() == MainFrame::EMode::GCodeViewer) { + // adjust printbed size + const double margin = 10.0; + Vec2d min(m_bounding_box.min(0) - margin, m_bounding_box.min(1) - margin); + Vec2d max(m_bounding_box.max(0) + margin, m_bounding_box.max(1) + margin); + Pointfs bed_shape = { + { min(0), min(1) }, + { max(0), min(1) }, + { max(0), max(1) }, + { min(0), max(1) } }; + wxGetApp().plater()->set_bed_shape(bed_shape, "", ""); + } #endif // ENABLE_GCODE_VIEWER_AS_STATE } From 9f94f89808d9651438f51cf45beffb02eaea0f9a Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 8 Jun 2020 14:37:40 +0200 Subject: [PATCH 122/255] ENABLE_GCODE_VIEWER_AS_STATE -> Smoother transition between states --- src/slic3r/GUI/MainFrame.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index f9e757251f..efc3efa8a3 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -1163,6 +1163,8 @@ void MainFrame::set_mode(EMode mode) { m_plater->reset(); + m_plater->Freeze(); + // switch view m_plater->select_view_3D("3D"); m_plater->select_view("iso"); @@ -1187,6 +1189,8 @@ void MainFrame::set_mode(EMode mode) m_restore_from_gcode_viewer.collapsed_sidebar = false; } + m_plater->Thaw(); + break; } case EMode::GCodeViewer: @@ -1194,6 +1198,8 @@ void MainFrame::set_mode(EMode mode) m_plater->reset(); m_plater->reset_last_loaded_gcode(); + m_plater->Freeze(); + // reinitialize undo/redo stack m_plater->clear_undo_redo_stack_main(); m_plater->take_snapshot(_L("New Project")); @@ -1222,6 +1228,8 @@ void MainFrame::set_mode(EMode mode) m_restore_from_gcode_viewer.collapsed_sidebar = true; } + m_plater->Thaw(); + break; } } From d358fe85fa03f6bdc807c14978d592bb066682da Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 9 Jun 2020 08:12:51 +0200 Subject: [PATCH 123/255] GCodeViewer -> Show tool marker position when enabled --- src/slic3r/GUI/GCodeViewer.cpp | 38 +++++++++++++++++++++++++++++++--- src/slic3r/GUI/GCodeViewer.hpp | 3 ++- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 61d432b9a8..0042340992 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -146,8 +146,9 @@ void GCodeViewer::SequentialView::Marker::init() } void GCodeViewer::SequentialView::Marker::set_world_position(const Vec3f& position) -{ - m_world_transform = (Geometry::assemble_transform(position.cast()) * Geometry::assemble_transform(m_model.get_bounding_box().size()[2] * Vec3d::UnitZ(), { M_PI, 0.0, 0.0 })).cast(); +{ + m_world_position = position; + m_world_transform = (Geometry::assemble_transform((position + m_z_offset * Vec3f::UnitZ()).cast()) * Geometry::assemble_transform(m_model.get_bounding_box().size()[2] * Vec3d::UnitZ(), { M_PI, 0.0, 0.0 })).cast(); m_world_bounding_box = m_model.get_bounding_box().transformed(m_world_transform.cast()); } @@ -176,6 +177,37 @@ void GCodeViewer::SequentialView::Marker::render() const shader->stop_using(); glsafe(::glDisable(GL_BLEND)); + + static float last_window_width = 0.0f; + static size_t last_text_length = 0; + static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); + + ImGuiWrapper& imgui = *wxGetApp().imgui(); + Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size(); + imgui.set_next_window_pos(static_cast(cnv_size.get_width()), static_cast(cnv_size.get_height()), ImGuiCond_Always, 1.0f, 1.0f); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + ImGui::SetNextWindowBgAlpha(0.25f); + imgui.begin(std::string("ToolPosition"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + imgui.text(_u8L("Tool position") + ":"); + ImGui::PopStyleColor(); + ImGui::SameLine(); + char buf[1024]; + sprintf(buf, "X: %.2f, Y: %.2f, Z: %.2f", m_world_position(0), m_world_position(1), m_world_position(2)); + imgui.text(std::string(buf)); + + // force extra frame to automatically update window size + float width = ImGui::GetWindowWidth(); + size_t length = strlen(buf); + if (width != last_window_width || length != last_text_length) { + last_window_width = width; + last_text_length = length; + wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); + wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); + } + + imgui.end(); + ImGui::PopStyleVar(); } const std::vector GCodeViewer::Extrusion_Role_Colors {{ @@ -353,7 +385,7 @@ void GCodeViewer::render() const glsafe(::glEnable(GL_DEPTH_TEST)); render_toolpaths(); - m_sequential_view.marker.set_world_position(m_sequential_view.current_position + m_sequential_view_marker_z_offset * Vec3f::UnitZ()); + m_sequential_view.marker.set_world_position(m_sequential_view.current_position); m_sequential_view.marker.render(); render_shells(); render_legend(); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 6f24eef435..413f4ef4ad 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -218,8 +218,10 @@ public: class Marker { GLModel m_model; + Vec3f m_world_position; Transform3f m_world_transform; BoundingBoxf3 m_world_bounding_box; + float m_z_offset{ 0.5f }; std::array m_color{ 1.0f, 1.0f, 1.0f, 1.0f }; bool m_visible{ false }; @@ -274,7 +276,6 @@ private: std::vector m_extruder_ids; mutable Extrusions m_extrusions; mutable SequentialView m_sequential_view; - float m_sequential_view_marker_z_offset{ 0.5f }; Shells m_shells; EViewType m_view_type{ EViewType::FeatureType }; bool m_legend_enabled{ true }; From 345c01c54ff1ef85fbb98a09864aaa124d8fa0a2 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 9 Jun 2020 08:37:24 +0200 Subject: [PATCH 124/255] ENABLE_GCODE_VIEWER -> Updated keyboard shortcuts dialog --- src/slic3r/GUI/KBShortcutsDialog.cpp | 30 ++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index 556b610e91..51ba06ba45 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -1,3 +1,4 @@ +#include "libslic3r/libslic3r.h" #include "KBShortcutsDialog.hpp" #include "I18N.hpp" #include "libslic3r/Utils.hpp" @@ -29,7 +30,7 @@ namespace Slic3r { namespace GUI { KBShortcutsDialog::KBShortcutsDialog() - : DPIDialog(NULL, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _(L("Keyboard Shortcuts")), + : DPIDialog(NULL, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _L("Keyboard Shortcuts"), #if ENABLE_SCROLLABLE wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) #else @@ -146,7 +147,7 @@ void KBShortcutsDialog::fill_shortcuts() { "?", L("Show keyboard shortcuts list") } }; - m_full_shortcuts.push_back(std::make_pair(_(L("Commands")), commands_shortcuts)); + m_full_shortcuts.push_back(std::make_pair(_L("Commands"), commands_shortcuts)); Shortcuts plater_shortcuts = { { "A", L("Arrange") }, @@ -186,7 +187,7 @@ void KBShortcutsDialog::fill_shortcuts() #endif // ENABLE_RENDER_PICKING_PASS }; - m_full_shortcuts.push_back(std::make_pair(_(L("Plater")), plater_shortcuts)); + m_full_shortcuts.push_back(std::make_pair(_L("Plater"), plater_shortcuts)); Shortcuts gizmos_shortcuts = { { "Shift+", L("Press to snap by 5% in Gizmo scale\nor to snap by 1mm in Gizmo move") }, @@ -195,7 +196,7 @@ void KBShortcutsDialog::fill_shortcuts() { alt, L("Press to scale (in Gizmo scale) or rotate (in Gizmo rotate)\nselected objects around their own center") }, }; - m_full_shortcuts.push_back(std::make_pair(_(L("Gizmos")), gizmos_shortcuts)); + m_full_shortcuts.push_back(std::make_pair(_L("Gizmos"), gizmos_shortcuts)); Shortcuts preview_shortcuts = { { L("Arrow Up"), L("Upper Layer") }, @@ -205,7 +206,7 @@ void KBShortcutsDialog::fill_shortcuts() { "L", L("Show/Hide Legend") } }; - m_full_shortcuts.push_back(std::make_pair(_(L("Preview")), preview_shortcuts)); + m_full_shortcuts.push_back(std::make_pair(_L("Preview"), preview_shortcuts)); Shortcuts layers_slider_shortcuts = { { L("Arrow Up"), L("Move current slider thumb Up") }, @@ -213,10 +214,23 @@ void KBShortcutsDialog::fill_shortcuts() { L("Arrow Left"), L("Set upper thumb to current slider thumb") }, { L("Arrow Right"), L("Set lower thumb to current slider thumb") }, { "+", L("Add color change marker for current layer") }, - { "-", L("Delete color change marker for current layer") } + { "-", L("Delete color change marker for current layer") }, + { "Shift+", L("Press to speed up 5 times while moving thumb\nwith arrow keys or mouse wheel") }, + { ctrl, L("Press to speed up 5 times while moving thumb\nwith arrow keys or mouse wheel") }, }; - m_full_shortcuts.push_back(std::make_pair(_(L("Layers Slider")), layers_slider_shortcuts)); + m_full_shortcuts.push_back(std::make_pair(_L("Layers Slider"), layers_slider_shortcuts)); + +#if ENABLE_GCODE_VIEWER + Shortcuts sequential_slider_shortcuts = { + { L("Arrow Left"), L("Move current slider thumb Left") }, + { L("Arrow Right"), L("Move current slider thumb Right") }, + { "Shift+", L("Press to speed up 5 times while moving thumb\nwith arrow keys or mouse wheel") }, + { ctrl, L("Press to speed up 5 times while moving thumb\nwith arrow keys or mouse wheel") }, + }; + + m_full_shortcuts.push_back(std::make_pair(_L("Sequential Slider"), sequential_slider_shortcuts)); +#endif // ENABLE_GCODE_VIEWER } wxPanel* KBShortcutsDialog::create_header(wxWindow* parent, const wxFont& bold_font) @@ -239,7 +253,7 @@ wxPanel* KBShortcutsDialog::create_header(wxWindow* parent, const wxFont& bold_f sizer->Add(m_header_bitmap, 0, wxEXPAND | wxLEFT | wxRIGHT, 10); // text - wxStaticText* text = new wxStaticText(panel, wxID_ANY, _(L("Keyboard shortcuts"))); + wxStaticText* text = new wxStaticText(panel, wxID_ANY, _L("Keyboard shortcuts")); text->SetFont(header_font); sizer->Add(text, 0, wxALIGN_CENTER_VERTICAL); From 48cc358b7271b70f6c5d1ca2aa15ba42ab37eac8 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 9 Jun 2020 11:44:25 +0200 Subject: [PATCH 125/255] Fixed build on Mac --- src/slic3r/GUI/MainFrame.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index efc3efa8a3..ba4568bbce 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -1104,7 +1104,11 @@ void MainFrame::init_menubar() #ifdef __APPLE__ // This fixes a bug on Mac OS where the quit command doesn't emit window close events // wx bug: https://trac.wxwidgets.org/ticket/18328 +#if ENABLE_GCODE_VIEWER_AS_STATE + wxMenu* apple_menu = m_editor_menubar->OSXGetAppleMenu(); +#else wxMenu *apple_menu = menubar->OSXGetAppleMenu(); +#endif // ENABLE_GCODE_VIEWER_AS_STATE if (apple_menu != nullptr) { apple_menu->Bind(wxEVT_MENU, [this](wxCommandEvent &) { Close(); From 4c51a258ef59cab6ce344b52badef40082522b58 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 9 Jun 2020 12:44:22 +0200 Subject: [PATCH 126/255] GCodeViewer -> Fixed bottom panel not disappearing when switching to gcode viewer from preview --- src/slic3r/GUI/Plater.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index e5bbf73c61..0420c1d031 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2708,6 +2708,10 @@ void Plater::priv::reset() if (view3D->is_layers_editing_enabled()) view3D->enable_layers_editing(false); +#if ENABLE_GCODE_VIEWER_AS_STATE + gcode_result.reset(); +#endif // ENABLE_GCODE_VIEWER_AS_STATE + // Stop and reset the Print content. this->background_process.reset(); model.clear_objects(); @@ -2720,10 +2724,6 @@ void Plater::priv::reset() this->sidebar->show_sliced_info_sizer(false); model.custom_gcode_per_print_z.gcodes.clear(); - -#if ENABLE_GCODE_VIEWER_AS_STATE - gcode_result.reset(); -#endif // ENABLE_GCODE_VIEWER_AS_STATE } void Plater::priv::mirror(Axis axis) From aa14b4263841d6e3276ad64c31518190d875bfad Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 12 Jun 2020 09:01:20 +0200 Subject: [PATCH 127/255] GCodeProcessor -> Added processing of gcode lines G0 --- resources/shaders/options_120_solid.fs | 1 - src/libslic3r/GCode/GCodeProcessor.cpp | 6 ++++++ src/libslic3r/GCode/GCodeProcessor.hpp | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/resources/shaders/options_120_solid.fs b/resources/shaders/options_120_solid.fs index 912b809e07..4719ff96a6 100644 --- a/resources/shaders/options_120_solid.fs +++ b/resources/shaders/options_120_solid.fs @@ -66,7 +66,6 @@ vec4 on_sphere_color(vec3 eye_on_sphere_position) intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; return vec4(intensity.y + uniform_color.rgb * intensity.x, 1.0); -// return vec4(vec3(intensity.y) + uniform_color.rgb * intensity.x, 1.0); } float fragment_depth(vec3 eye_pos) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index c74820a04c..d561647262 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -110,6 +110,7 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) { switch (::atoi(&cmd[1])) { + case 0: { process_G0(line); break; } // Move case 1: { process_G1(line); break; } // Move case 10: { process_G10(line); break; } // Retract case 11: { process_G11(line); break; } // Unretract @@ -263,6 +264,11 @@ void GCodeProcessor::process_tags(const std::string& comment) } } +void GCodeProcessor::process_G0(const GCodeReader::GCodeLine& line) +{ + process_G1(line); +} + void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) { auto absolute_position = [this](Axis axis, const GCodeReader::GCodeLine& lineG1) diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index e8c43350c0..bc49245848 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -155,6 +155,7 @@ namespace Slic3r { void process_tags(const std::string& comment); // Move + void process_G0(const GCodeReader::GCodeLine& line); void process_G1(const GCodeReader::GCodeLine& line); // Retract From eb215fe994be09ae3ccaddba044a52e4169b5906 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 19 Jun 2020 15:32:44 +0200 Subject: [PATCH 128/255] ENABLE_GCODE_VIEWER_AS_STATE -> Removed tabs from gcode viewer state --- src/libslic3r/Technologies.hpp | 2 +- src/slic3r/GUI/3DBed.cpp | 16 ++++++++++++++ src/slic3r/GUI/MainFrame.cpp | 40 +++++++++++++++++++++++++++++++--- src/slic3r/GUI/MainFrame.hpp | 3 +++ 4 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 41b204d654..b04e78c4ed 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -60,7 +60,7 @@ // Enable G-Code viewer #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) #define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) -#define ENABLE_GCODE_VIEWER_SHADERS_EDITOR (1 && ENABLE_GCODE_VIEWER) +#define ENABLE_GCODE_VIEWER_SHADERS_EDITOR (0 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_AS_STATE (1 && ENABLE_GCODE_VIEWER) diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 450a538d04..16ab95d6c4 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -694,7 +694,11 @@ void Bed3D::render_default(bool bottom) const { // draw background glsafe(::glDepthMask(GL_FALSE)); +#if ENABLE_LAYOUT_NO_RESTART + glsafe(::glColor4fv(m_model_color.data())); +#else glsafe(::glColor4f(0.35f, 0.35f, 0.35f, 0.4f)); +#endif // ENABLE_LAYOUT_NO_RESTART glsafe(::glNormal3d(0.0f, 0.0f, 1.0f)); glsafe(::glVertexPointer(3, GL_FLOAT, m_triangles.get_vertex_data_size(), (GLvoid*)m_triangles.get_vertices_data())); glsafe(::glDrawArrays(GL_TRIANGLES, 0, (GLsizei)triangles_vcount)); @@ -702,11 +706,23 @@ void Bed3D::render_default(bool bottom) const } // draw grid +#if ENABLE_LAYOUT_NO_RESTART + glsafe(::glLineWidth(1.5f * m_scale_factor)); +#else glsafe(::glLineWidth(3.0f * m_scale_factor)); +#endif // ENABLE_LAYOUT_NO_RESTART if (has_model && !bottom) +#if ENABLE_LAYOUT_NO_RESTART + glsafe(::glColor4f(0.9f, 0.9f, 0.9f, 1.0f)); +#else glsafe(::glColor4f(0.75f, 0.75f, 0.75f, 1.0f)); +#endif // ENABLE_LAYOUT_NO_RESTART else +#if ENABLE_LAYOUT_NO_RESTART + glsafe(::glColor4f(0.9f, 0.9f, 0.9f, 0.6f)); +#else glsafe(::glColor4f(0.2f, 0.2f, 0.2f, 0.4f)); +#endif //ENABLE_LAYOUT_NO_RESTART glsafe(::glVertexPointer(3, GL_FLOAT, m_triangles.get_vertex_data_size(), (GLvoid*)m_gridlines.get_vertices_data())); glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)m_gridlines.get_vertices_count())); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 00cc7d7bb2..7f591bedd8 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -323,9 +323,16 @@ void MainFrame::update_layout() Layout(); }; +#if ENABLE_GCODE_VIEWER_AS_STATE + ESettingsLayout layout = (m_mode == EMode::GCodeViewer) ? ESettingsLayout::GCodeViewer : + (wxGetApp().app_config->get("old_settings_layout_mode") == "1" ? ESettingsLayout::Old : + wxGetApp().app_config->get("new_settings_layout_mode") == "1" ? ESettingsLayout::New : + wxGetApp().app_config->get("dlg_settings_layout_mode") == "1" ? ESettingsLayout::Dlg : ESettingsLayout::Old); +#else ESettingsLayout layout = wxGetApp().app_config->get("old_settings_layout_mode") == "1" ? ESettingsLayout::Old : wxGetApp().app_config->get("new_settings_layout_mode") == "1" ? ESettingsLayout::New : wxGetApp().app_config->get("dlg_settings_layout_mode") == "1" ? ESettingsLayout::Dlg : ESettingsLayout::Old; +#endif // ENABLE_GCODE_VIEWER_AS_STATE if (m_layout == layout) return; @@ -377,6 +384,14 @@ void MainFrame::update_layout() m_plater->Show(); break; } +#if ENABLE_GCODE_VIEWER_AS_STATE + case ESettingsLayout::GCodeViewer: + { + GetSizer()->Add(m_plater, 1, wxEXPAND); + m_plater->Show(); + break; + } +#endif // ENABLE_GCODE_VIEWER_AS_STATE } //#ifdef __APPLE__ @@ -1082,15 +1097,16 @@ void MainFrame::init_menubar() #endif m_menu_item_reslice_now = append_menu_item(fileMenu, wxID_ANY, _L("(Re)Slice No&w") + "\tCtrl+R", _L("Start new slicing process"), [this](wxCommandEvent&) { reslice_now(); }, "re_slice", nullptr, - [this](){return m_plater != nullptr && can_reslice(); }, this); + [this]() { return m_plater != nullptr && can_reslice(); }, this); fileMenu->AppendSeparator(); append_menu_item(fileMenu, wxID_ANY, _L("&Repair STL file") + dots, _L("Automatically repair an STL file"), [this](wxCommandEvent&) { repair_stl(); }, "wrench", nullptr, - [this]() {return true; }, this); + [this]() { return true; }, this); #if ENABLE_GCODE_VIEWER_AS_STATE fileMenu->AppendSeparator(); append_menu_item(fileMenu, wxID_ANY, _L("&G-code preview"), _L("Switch to G-code preview mode"), - [this](wxCommandEvent&) { set_mode(EMode::GCodeViewer); }); + [this](wxCommandEvent&) { set_mode(EMode::GCodeViewer); }, "", nullptr, + [this]() { return m_plater != nullptr && m_plater->printer_technology() != ptSLA; }, this); #endif // ENABLE_GCODE_VIEWER_AS_STATE fileMenu->AppendSeparator(); append_menu_item(fileMenu, wxID_EXIT, _L("&Quit"), wxString::Format(_L("Quit %s"), SLIC3R_APP_NAME), @@ -1381,16 +1397,30 @@ void MainFrame::init_gcodeviewer_menubar() void MainFrame::set_mode(EMode mode) { + if (m_mode == mode) + return; + + wxBusyCursor busy; + m_mode = mode; switch (m_mode) { default: case EMode::Editor: { +#if ENABLE_LAYOUT_NO_RESTART + update_layout(); + select_tab(0); +#endif // ENABLE_LAYOUT_NO_RESTART + m_plater->reset(); m_plater->Freeze(); + // reinitialize undo/redo stack + m_plater->clear_undo_redo_stack_main(); + m_plater->take_snapshot(_L("New Project")); + // switch view m_plater->select_view_3D("3D"); m_plater->select_view("iso"); @@ -1421,6 +1451,10 @@ void MainFrame::set_mode(EMode mode) } case EMode::GCodeViewer: { +#if ENABLE_LAYOUT_NO_RESTART + update_layout(); +#endif // ENABLE_LAYOUT_NO_RESTART + m_plater->reset(); m_plater->reset_last_loaded_gcode(); diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index 9ec2d991a5..931dd87b28 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -138,6 +138,9 @@ class MainFrame : public DPIFrame Old, New, Dlg, +#if ENABLE_GCODE_VIEWER_AS_STATE + GCodeViewer +#endif // ENABLE_GCODE_VIEWER_AS_STATE }; ESettingsLayout m_layout{ ESettingsLayout::Unknown }; From 2a90cd2849b91111f1463d70e15fb755da38e193 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 22 Jun 2020 09:10:41 +0200 Subject: [PATCH 129/255] GCodeViewer -> Do not show modifier shells --- src/slic3r/GUI/GCodeViewer.cpp | 39 +++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 215faee594..cccb31969c 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -282,7 +282,10 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& reset(); load_toolpaths(gcode_result); - load_shells(print, initialized); +#if ENABLE_GCODE_VIEWER_AS_STATE + if (wxGetApp().mainframe->get_mode() != MainFrame::EMode::GCodeViewer) +#endif // ENABLE_GCODE_VIEWER_AS_STATE + load_shells(print, initialized); #if ENABLE_GCODE_VIEWER_AS_STATE if (wxGetApp().mainframe->get_mode() == MainFrame::EMode::GCodeViewer) { @@ -493,21 +496,21 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) return; // vertex data / bounding box -> extract from result - std::vector vertices_data(m_vertices.vertices_count * 3); - for (size_t i = 0; i < m_vertices.vertices_count; ++i) { - const GCodeProcessor::MoveVertex& move = gcode_result.moves[i]; + std::vector vertices_data(m_vertices.vertices_count * 3); + for (size_t i = 0; i < m_vertices.vertices_count; ++i) { + const GCodeProcessor::MoveVertex& move = gcode_result.moves[i]; #if ENABLE_GCODE_VIEWER_AS_STATE - if (wxGetApp().mainframe->get_mode() == MainFrame::EMode::GCodeViewer) + if (wxGetApp().mainframe->get_mode() == MainFrame::EMode::GCodeViewer) + m_bounding_box.merge(move.position.cast()); + else { +#endif // ENABLE_GCODE_VIEWER_AS_STATE + if (move.type == GCodeProcessor::EMoveType::Extrude && move.width != 0.0f && move.height != 0.0f) m_bounding_box.merge(move.position.cast()); - else { -#endif // ENABLE_GCODE_VIEWER_AS_STATE - if (move.type == GCodeProcessor::EMoveType::Extrude && move.width != 0.0f && move.height != 0.0f) - m_bounding_box.merge(move.position.cast()); #if ENABLE_GCODE_VIEWER_AS_STATE - } -#endif // ENABLE_GCODE_VIEWER_AS_STATE - ::memcpy(static_cast(&vertices_data[i * 3]), static_cast(move.position.data()), 3 * sizeof(float)); } +#endif // ENABLE_GCODE_VIEWER_AS_STATE + ::memcpy(static_cast(&vertices_data[i * 3]), static_cast(move.position.data()), 3 * sizeof(float)); + } m_bounding_box.merge(m_bounding_box.max + m_sequential_view.marker.get_bounding_box().max[2] * Vec3d::UnitZ()); @@ -684,6 +687,18 @@ void GCodeViewer::load_shells(const Print& print, bool initialized) } } + // remove modifiers + while (true) { + GLVolumePtrs::iterator it = std::find_if(m_shells.volumes.volumes.begin(), m_shells.volumes.volumes.end(), [](GLVolume* volume) { return volume->is_modifier; }); + if (it != m_shells.volumes.volumes.end()) + { + delete (*it); + m_shells.volumes.volumes.erase(it); + } + else + break; + } + for (GLVolume* volume : m_shells.volumes.volumes) { volume->zoom_to_volumes = false; From dc6f97a6ad473c9f137ebf30b753b298b64a9f56 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 22 Jun 2020 11:49:58 +0200 Subject: [PATCH 130/255] ENABLE_GCODE_VIEWER_AS_STATE -> Fixed toolpaths visualization when switching between states and when exporting g-code --- src/slic3r/GUI/GUI_Preview.cpp | 6 ++---- src/slic3r/GUI/MainFrame.cpp | 2 ++ src/slic3r/GUI/Plater.cpp | 26 ++++++++++++++++++++++++++ src/slic3r/GUI/Plater.hpp | 2 ++ 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 05168fc333..6ba3835075 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -510,11 +510,9 @@ void Preview::reload_print(bool keep_volumes) !keep_volumes) { m_canvas->reset_volumes(); -#if ENABLE_GCODE_VIEWER - m_canvas->reset_gcode_toolpaths(); -#else +#if !ENABLE_GCODE_VIEWER m_canvas->reset_legend_texture(); -#endif // ENABLE_GCODE_VIEWER +#endif // !ENABLE_GCODE_VIEWER m_loaded = false; #ifdef __linux__ m_volumes_cleanup_required = false; diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 7f591bedd8..2e25752a1a 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -1414,6 +1414,7 @@ void MainFrame::set_mode(EMode mode) #endif // ENABLE_LAYOUT_NO_RESTART m_plater->reset(); + m_plater->reset_gcode_toolpaths(); m_plater->Freeze(); @@ -1457,6 +1458,7 @@ void MainFrame::set_mode(EMode mode) m_plater->reset(); m_plater->reset_last_loaded_gcode(); + m_plater->reset_gcode_toolpaths(); m_plater->Freeze(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index ae4c4ba000..18c185551d 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1701,6 +1701,10 @@ struct Plater::priv void update_preview_moves_slider(); #endif // ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER + void reset_gcode_toolpaths(); +#endif // ENABLE_GCODE_VIEWER + void reset_all_gizmos(); void update_ui_from_settings(); void update_main_toolbar_tooltips(); @@ -4008,6 +4012,13 @@ void Plater::priv::update_preview_moves_slider() } #endif // ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER +void Plater::priv::reset_gcode_toolpaths() +{ + preview->get_canvas3d()->reset_gcode_toolpaths(); +} +#endif // ENABLE_GCODE_VIEWER + bool Plater::priv::can_set_instance_to_object() const { const int obj_idx = get_selected_object_idx(); @@ -5060,6 +5071,9 @@ void Plater::reslice() if ((state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) != 0) return; +#if ENABLE_GCODE_VIEWER + bool clean_gcode_toolpaths = true; +#endif // ENABLE_GCODE_VIEWER if (p->background_process.running()) { if (wxGetApp().get_mode() == comSimple) @@ -5072,6 +5086,13 @@ void Plater::reslice() } else if (!p->background_process.empty() && !p->background_process.idle()) p->show_action_buttons(true); +#if ENABLE_GCODE_VIEWER + else + clean_gcode_toolpaths = false; + + if (clean_gcode_toolpaths) + reset_gcode_toolpaths(); +#endif // ENABLE_GCODE_VIEWER // update type of preview p->preview->update_view_type(true); @@ -5750,6 +5771,11 @@ void Plater::update_preview_moves_slider() { p->update_preview_moves_slider(); } + +void Plater::reset_gcode_toolpaths() +{ + p->reset_gcode_toolpaths(); +} #endif // ENABLE_GCODE_VIEWER const Mouse3DController& Plater::get_mouse3d_controller() const diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 9759a7ffc3..8d0c935a4c 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -350,6 +350,8 @@ public: #if ENABLE_GCODE_VIEWER void update_preview_bottom_toolbar(); void update_preview_moves_slider(); + + void reset_gcode_toolpaths(); #endif // ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER_AS_STATE From 88670b48fd66b8f7561d7a4b54ba71460e4fbf19 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 22 Jun 2020 12:10:18 +0200 Subject: [PATCH 131/255] ENABLE_GCODE_VIEWER_AS_STATE -> Added dialog informing user that all objects will be removed when switching to g-code viewer mode --- src/slic3r/GUI/MainFrame.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 2e25752a1a..366dc44711 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -1105,7 +1105,10 @@ void MainFrame::init_menubar() #if ENABLE_GCODE_VIEWER_AS_STATE fileMenu->AppendSeparator(); append_menu_item(fileMenu, wxID_ANY, _L("&G-code preview"), _L("Switch to G-code preview mode"), - [this](wxCommandEvent&) { set_mode(EMode::GCodeViewer); }, "", nullptr, + [this](wxCommandEvent&) { + if (m_plater->model().objects.empty() || wxMessageDialog((wxWindow*)this, _L("Switching to G-code preview mode will remove all objects, continue?"), wxString(SLIC3R_APP_NAME) + " - " + _L("Switch to G-code preview mode"), wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxCENTRE).ShowModal() == wxID_YES) + set_mode(EMode::GCodeViewer); + }, "", nullptr, [this]() { return m_plater != nullptr && m_plater->printer_technology() != ptSLA; }, this); #endif // ENABLE_GCODE_VIEWER_AS_STATE fileMenu->AppendSeparator(); From 7207f215e98289bdc39c157193698b987e720a97 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 22 Jun 2020 12:43:52 +0200 Subject: [PATCH 132/255] ENABLE_GCODE_VIEWER_AS_STATE -> Do not show warning texture in gcode viewer mode --- src/slic3r/GUI/GLCanvas3D.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index e7be2c4019..5c72ae0fa7 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -7110,8 +7110,18 @@ void GLCanvas3D::_show_warning_texture_if_needed(WarningTexture::Warning warning show = _is_any_volume_outside(); else { - BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3(); - show = (test_volume.radius() > 0.0) ? !test_volume.contains(m_gcode_viewer.get_bounding_box()) : false; +#if ENABLE_GCODE_VIEWER_AS_STATE + if (wxGetApp().mainframe->get_mode() != MainFrame::EMode::GCodeViewer) + { + BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3(); + const BoundingBoxf3& paths_volume = m_gcode_viewer.get_bounding_box(); + if (test_volume.radius() > 0.0 && paths_volume.radius() > 0.0) + show = !test_volume.contains(paths_volume); + } +#else + BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3(); + show = (test_volume.radius() > 0.0) ? !test_volume.contains(m_gcode_viewer.get_bounding_box()) : false; +#endif // ENABLE_GCODE_VIEWER_AS_STATE } _set_warning_texture(warning, show); #else From 289f7a14a016b102c91dc7bb15dbaccc07683892 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 22 Jun 2020 14:06:41 +0200 Subject: [PATCH 133/255] Follow-up of dc6f97a6ad473c9f137ebf30b753b298b64a9f56 -> Fixed toolpaths visualization when new slicing is required --- src/slic3r/GUI/GUI_Preview.cpp | 12 +++++++++--- src/slic3r/GUI/GUI_Preview.hpp | 2 +- src/slic3r/GUI/Plater.cpp | 5 ++++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 6ba3835075..48d6e930b0 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -510,9 +510,11 @@ void Preview::reload_print(bool keep_volumes) !keep_volumes) { m_canvas->reset_volumes(); -#if !ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER + m_canvas->reset_gcode_toolpaths(); +#else m_canvas->reset_legend_texture(); -#endif // !ENABLE_GCODE_VIEWER +#endif // ENABLE_GCODE_VIEWER m_loaded = false; #ifdef __linux__ m_volumes_cleanup_required = false; @@ -761,7 +763,7 @@ void Preview::on_checkbox_legend(wxCommandEvent& evt) } #endif // ENABLE_GCODE_VIEWER -void Preview::update_view_type(bool slice_completed) +void Preview::update_view_type(bool keep_volumes) { const DynamicPrintConfig& config = wxGetApp().preset_bundle->project_config; @@ -785,7 +787,11 @@ void Preview::update_view_type(bool slice_completed) m_preferred_color_mode = "feature"; } +#if ENABLE_GCODE_VIEWER + reload_print(keep_volumes); +#else reload_print(); +#endif // ENABLE_GCODE_VIEWER } #if ENABLE_GCODE_VIEWER diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 291ee4156a..bf174c2e09 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -186,7 +186,7 @@ Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config, void edit_double_slider(wxKeyEvent& evt); #endif // ENABLE_GCODE_VIEWER - void update_view_type(bool slice_completed); + void update_view_type(bool keep_volumes); bool is_loaded() const { return m_loaded; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 18c185551d..70ee1a7589 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -5092,10 +5092,13 @@ void Plater::reslice() if (clean_gcode_toolpaths) reset_gcode_toolpaths(); -#endif // ENABLE_GCODE_VIEWER + // update type of preview + p->preview->update_view_type(!clean_gcode_toolpaths); +#else // update type of preview p->preview->update_view_type(true); +#endif // ENABLE_GCODE_VIEWER } void Plater::reslice_SLA_supports(const ModelObject &object, bool postpone_error_messages) From ca7dce9f0296da29f1d52009526d5019903d474a Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 22 Jun 2020 15:42:27 +0200 Subject: [PATCH 134/255] Follow-up of dc6f97a6ad473c9f137ebf30b753b298b64a9f56 -> Fixed toolpaths visualization when editing config data --- src/slic3r/GUI/GUI_Preview.cpp | 6 ++---- src/slic3r/GUI/Plater.cpp | 10 ++++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 48d6e930b0..2ddb59b863 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -510,11 +510,9 @@ void Preview::reload_print(bool keep_volumes) !keep_volumes) { m_canvas->reset_volumes(); -#if ENABLE_GCODE_VIEWER - m_canvas->reset_gcode_toolpaths(); -#else +#if !ENABLE_GCODE_VIEWER m_canvas->reset_legend_texture(); -#endif // ENABLE_GCODE_VIEWER +#endif // !ENABLE_GCODE_VIEWER m_loaded = false; #ifdef __linux__ m_volumes_cleanup_required = false; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 70ee1a7589..bd19c94c79 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2861,10 +2861,20 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool this->sidebar->show_sliced_info_sizer(false); // Reset preview canvases. If the print has been invalidated, the preview canvases will be cleared. // Otherwise they will be just refreshed. +#if ENABLE_GCODE_VIEWER + if (this->preview != nullptr) + { + // If the preview is not visible, the following line just invalidates the preview, + // but the G-code paths or SLA preview are calculated first once the preview is made visible. + this->preview->get_canvas3d()->reset_gcode_toolpaths(); + this->preview->reload_print(); + } +#else if (this->preview != nullptr) // If the preview is not visible, the following line just invalidates the preview, // but the G-code paths or SLA preview are calculated first once the preview is made visible. this->preview->reload_print(); +#endif // ENABLE_GCODE_VIEWER // In FDM mode, we need to reload the 3D scene because of the wipe tower preview box. // In SLA mode, we need to reload the 3D scene every time to show the support structures. if (this->printer_technology == ptSLA || (this->printer_technology == ptFFF && this->config->opt_bool("wipe_tower"))) From 779dcd58c8687725cff75ec7b3540679c2c9631f Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 23 Jun 2020 09:01:28 +0200 Subject: [PATCH 135/255] GCodeViewer -> Line width of toolpaths dependent on zoom --- src/slic3r/GUI/GCodeViewer.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index cccb31969c..3bba4a7723 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -870,8 +870,12 @@ void GCodeViewer::render_toolpaths() const glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); }; + auto line_width = [zoom]() { + return (zoom < 5.0) ? 1.0 : (1.0 + 5.0 * (zoom - 5.0) / (100.0 - 5.0)); + }; + glsafe(::glCullFace(GL_BACK)); - glsafe(::glLineWidth(3.0f)); + glsafe(::glLineWidth(static_cast(line_width()))); unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); unsigned char end_id = buffer_id(GCodeProcessor::EMoveType::Count); From 7e815b47277fbdea481ce5d807c3eb76d588eb6b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 23 Jun 2020 14:31:08 +0200 Subject: [PATCH 136/255] GCodeViewer -> Fixed sequential view endpoints when moving the vertical slider thumb --- src/slic3r/GUI/GUI_Preview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 2ddb59b863..530165001f 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -1440,7 +1440,7 @@ void Preview::on_sliders_scroll_changed(wxCommandEvent& event) #if ENABLE_GCODE_VIEWER void Preview::on_moves_slider_scroll_changed(wxCommandEvent& event) { - m_canvas->update_gcode_sequential_view_current(static_cast(m_moves_slider->GetLowerValueD()), static_cast(m_moves_slider->GetHigherValueD())); + m_canvas->update_gcode_sequential_view_current(static_cast(m_moves_slider->GetLowerValueD() - 1.0), static_cast(m_moves_slider->GetHigherValueD() - 1.0)); m_canvas->render(); } From 81a7b7782b3b9c7cc371011a60d45afcea4983ce Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 23 Jun 2020 15:22:52 +0200 Subject: [PATCH 137/255] GCodeViewer -> Some refactoring --- src/slic3r/GUI/GCodeViewer.cpp | 149 ++++++++++----------------------- 1 file changed, 46 insertions(+), 103 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 3bba4a7723..415b61aeb9 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -44,8 +44,7 @@ std::vector> decode_colors(const std::vector & static const float INV_255 = 1.0f / 255.0f; std::vector> output(colors.size(), { 0.0f, 0.0f, 0.0f }); - for (size_t i = 0; i < colors.size(); ++i) - { + for (size_t i = 0; i < colors.size(); ++i) { const std::string& color = colors[i]; const char* c = color.data() + 1; if ((color.size() == 7) && (color.front() == '#')) { @@ -293,11 +292,10 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& const double margin = 10.0; Vec2d min(m_bounding_box.min(0) - margin, m_bounding_box.min(1) - margin); Vec2d max(m_bounding_box.max(0) + margin, m_bounding_box.max(1) + margin); - Pointfs bed_shape = { - { min(0), min(1) }, - { max(0), min(1) }, - { max(0), max(1) }, - { min(0), max(1) } }; + Pointfs bed_shape = { { min(0), min(1) }, + { max(0), min(1) }, + { max(0), max(1) }, + { min(0), max(1) } }; wxGetApp().plater()->set_bed_shape(bed_shape, "", ""); } #endif // ENABLE_GCODE_VIEWER_AS_STATE @@ -317,8 +315,7 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: // update ranges for coloring / legend m_extrusions.reset_ranges(); - for (size_t i = 0; i < m_vertices.vertices_count; ++i) - { + for (size_t i = 0; i < m_vertices.vertices_count; ++i) { // skip first vertex if (i == 0) continue; @@ -466,8 +463,7 @@ void GCodeViewer::init_shaders() unsigned char end_id = buffer_id(GCodeProcessor::EMoveType::Count); bool is_glsl_120 = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20); - for (unsigned char i = begin_id; i < end_id; ++i) - { + for (unsigned char i = begin_id; i < end_id; ++i) { switch (buffer_type(i)) { case GCodeProcessor::EMoveType::Tool_change: { m_buffers[i].shader = is_glsl_120 ? "options_120_solid" : "options_110"; break; } @@ -530,8 +526,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) // indices data -> extract from result std::vector> indices(m_buffers.size()); - for (size_t i = 0; i < m_vertices.vertices_count; ++i) - { + for (size_t i = 0; i < m_vertices.vertices_count; ++i) { // skip first vertex if (i == 0) continue; @@ -560,10 +555,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) case GCodeProcessor::EMoveType::Travel: { if (prev.type != curr.type || !buffer.paths.back().matches(curr)) { - buffer.add_path(curr, static_cast(buffer_indices.size()), static_cast(i)); + buffer.add_path(curr, static_cast(buffer_indices.size()), static_cast(i - 1)); Path& last_path = buffer.paths.back(); last_path.first.position = prev.position; - last_path.first.s_id = static_cast(i - 1); buffer_indices.push_back(static_cast(i - 1)); } @@ -571,23 +565,18 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) buffer_indices.push_back(static_cast(i)); break; } - default: - { - break; - } + default: { break; } } } #if ENABLE_GCODE_VIEWER_STATISTICS - for (IBuffer& buffer : m_buffers) - { + for (IBuffer& buffer : m_buffers) { m_statistics.paths_size += SLIC3R_STDVEC_MEMSIZE(buffer.paths, Path); } #endif // ENABLE_GCODE_VIEWER_STATISTICS // indices data -> send data to gpu - for (size_t i = 0; i < m_buffers.size(); ++i) - { + for (size_t i = 0; i < m_buffers.size(); ++i) { IBuffer& buffer = m_buffers[i]; std::vector& buffer_indices = indices[i]; buffer.indices_count = buffer_indices.size(); @@ -605,8 +594,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) } // layers zs / roles / extruder ids / cp color ids -> extract from result - for (size_t i = 0; i < m_vertices.vertices_count; ++i) - { + for (size_t i = 0; i < m_vertices.vertices_count; ++i) { const GCodeProcessor::MoveVertex& move = gcode_result.moves[i]; if (move.type == GCodeProcessor::EMoveType::Extrude) m_layers_zs.emplace_back(static_cast(move.position[2])); @@ -655,8 +643,7 @@ void GCodeViewer::load_shells(const Print& print, bool initialized) // adds objects' volumes int object_id = 0; - for (const PrintObject* obj : print.objects()) - { + for (const PrintObject* obj : print.objects()) { const ModelObject* model_obj = obj->model_object(); std::vector instance_ids(model_obj->instances.size()); @@ -690,8 +677,7 @@ void GCodeViewer::load_shells(const Print& print, bool initialized) // remove modifiers while (true) { GLVolumePtrs::iterator it = std::find_if(m_shells.volumes.volumes.begin(), m_shells.volumes.volumes.end(), [](GLVolume* volume) { return volume->is_modifier; }); - if (it != m_shells.volumes.volumes.end()) - { + if (it != m_shells.volumes.volumes.end()) { delete (*it); m_shells.volumes.volumes.erase(it); } @@ -699,8 +685,7 @@ void GCodeViewer::load_shells(const Print& print, bool initialized) break; } - for (GLVolume* volume : m_shells.volumes.volumes) - { + for (GLVolume* volume : m_shells.volumes.volumes) { volume->zoom_to_volumes = false; volume->color[3] = 0.25f; volume->force_native_color = true; @@ -841,8 +826,8 @@ void GCodeViewer::render_toolpaths() const Transform3d inv_proj = camera.get_projection_matrix().inverse(); - auto render_options = [this, zoom, inv_proj, viewport, point_size, near_plane_height](const IBuffer& buffer, EOptionsColors colors_id, GLShaderProgram& shader) { - shader.set_uniform("uniform_color", Options_Colors[static_cast(colors_id)]); + auto render_as_points = [this, zoom, inv_proj, viewport, point_size, near_plane_height](const IBuffer& buffer, EOptionsColors color_id, GLShaderProgram& shader) { + shader.set_uniform("uniform_color", Options_Colors[static_cast(color_id)]); shader.set_uniform("zoom", zoom); #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR shader.set_uniform("percent_outline_radius", 0.01f * static_cast(m_shaders_editor.percent_outline)); @@ -870,6 +855,18 @@ void GCodeViewer::render_toolpaths() const glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); }; + auto render_as_lines = [this](const IBuffer& buffer, GLShaderProgram& shader) { + for (const RenderPath& path : buffer.render_paths) + { + shader.set_uniform("uniform_color", path.color); +// glsafe(::glMultiDrawElements(GL_LINES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); + glsafe(::glMultiDrawElements(GL_LINE_STRIP, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); +#if ENABLE_GCODE_VIEWER_STATISTICS + ++m_statistics.gl_multi_line_strip_calls_count; +#endif // ENABLE_GCODE_VIEWER_STATISTICS + } + }; + auto line_width = [zoom]() { return (zoom < 5.0) ? 1.0 : (1.0 + 5.0 * (zoom - 5.0) / (100.0 - 5.0)); }; @@ -902,62 +899,14 @@ void GCodeViewer::render_toolpaths() const switch (type) { - case GCodeProcessor::EMoveType::Tool_change: - { - render_options(buffer, EOptionsColors::ToolChanges, *shader); - break; - } - case GCodeProcessor::EMoveType::Color_change: - { - render_options(buffer, EOptionsColors::ColorChanges, *shader); - break; - } - case GCodeProcessor::EMoveType::Pause_Print: - { - render_options(buffer, EOptionsColors::PausePrints, *shader); - break; - } - case GCodeProcessor::EMoveType::Custom_GCode: - { - render_options(buffer, EOptionsColors::CustomGCodes, *shader); - break; - } - case GCodeProcessor::EMoveType::Retract: - { - render_options(buffer, EOptionsColors::Retractions, *shader); - break; - } - case GCodeProcessor::EMoveType::Unretract: - { - render_options(buffer, EOptionsColors::Unretractions, *shader); - break; - } + case GCodeProcessor::EMoveType::Tool_change: { render_as_points(buffer, EOptionsColors::ToolChanges, *shader); break; } + case GCodeProcessor::EMoveType::Color_change: { render_as_points(buffer, EOptionsColors::ColorChanges, *shader); break; } + case GCodeProcessor::EMoveType::Pause_Print: { render_as_points(buffer, EOptionsColors::PausePrints, *shader); break; } + case GCodeProcessor::EMoveType::Custom_GCode: { render_as_points(buffer, EOptionsColors::CustomGCodes, *shader); break; } + case GCodeProcessor::EMoveType::Retract: { render_as_points(buffer, EOptionsColors::Retractions, *shader); break; } + case GCodeProcessor::EMoveType::Unretract: { render_as_points(buffer, EOptionsColors::Unretractions, *shader); break; } case GCodeProcessor::EMoveType::Extrude: - { - for (const RenderPath& path : buffer.render_paths) - { - shader->set_uniform("uniform_color", path.color); - glsafe(::glMultiDrawElements(GL_LINE_STRIP, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_multi_line_strip_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - - } - break; - } - case GCodeProcessor::EMoveType::Travel: - { - for (const RenderPath& path : buffer.render_paths) - { - shader->set_uniform("uniform_color", path.color); - glsafe(::glMultiDrawElements(GL_LINE_STRIP, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_multi_line_strip_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - - } - break; - } + case GCodeProcessor::EMoveType::Travel: { render_as_lines(buffer, *shader); break; } } glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); @@ -1090,8 +1039,7 @@ void GCodeViewer::render_legend() const // draw text ImGui::Dummy({ icon_size, icon_size }); ImGui::SameLine(); - if (callback != nullptr) - { + if (callback != nullptr) { if (ImGui::MenuItem(label.c_str())) callback(); } @@ -1114,8 +1062,7 @@ void GCodeViewer::render_legend() const if (step_size == 0.0f) // single item use case add_range_item(0, range.min, decimals); - else - { + else { for (int i = static_cast(Range_Colors.size()) - 1; i >= 0; --i) { add_range_item(i, range.min + static_cast(i) * step_size, decimals); } @@ -1297,8 +1244,7 @@ void GCodeViewer::render_legend() const } // travel paths - if (m_buffers[buffer_id(GCodeProcessor::EMoveType::Travel)].visible) - { + if (m_buffers[buffer_id(GCodeProcessor::EMoveType::Travel)].visible) { switch (m_view_type) { case EViewType::Feedrate: @@ -1347,8 +1293,7 @@ void GCodeViewer::render_legend() const }; // options - if (any_option_visible()) - { + if (any_option_visible()) { // title ImGui::Spacing(); ImGui::Spacing(); @@ -1386,19 +1331,19 @@ void GCodeViewer::render_statistics() const imgui.text(std::string("Load time:")); ImGui::PopStyleColor(); ImGui::SameLine(offset); - imgui.text(std::to_string(m_statistics.load_time) + "ms"); + imgui.text(std::to_string(m_statistics.load_time) + " ms"); ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); imgui.text(std::string("Resfresh time:")); ImGui::PopStyleColor(); ImGui::SameLine(offset); - imgui.text(std::to_string(m_statistics.refresh_time) + "ms"); + imgui.text(std::to_string(m_statistics.refresh_time) + " ms"); ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); imgui.text(std::string("Resfresh paths time:")); ImGui::PopStyleColor(); ImGui::SameLine(offset); - imgui.text(std::to_string(m_statistics.refresh_paths_time) + "ms"); + imgui.text(std::to_string(m_statistics.refresh_paths_time) + " ms"); ImGui::Separator(); @@ -1496,11 +1441,9 @@ void GCodeViewer::render_shaders_editor() const case 2: { set_shader("options_120_solid"); break; } } - if (ImGui::CollapsingHeader("Options", ImGuiTreeNodeFlags_DefaultOpen)) - { + if (ImGui::CollapsingHeader("Options", ImGuiTreeNodeFlags_DefaultOpen)) { ImGui::SliderFloat("point size", &m_shaders_editor.point_size, 0.5f, 3.0f, "%.1f"); - if (m_shaders_editor.shader_version == 1) - { + if (m_shaders_editor.shader_version == 1) { ImGui::SliderInt("percent outline", &m_shaders_editor.percent_outline, 0, 50); ImGui::SliderInt("percent center", &m_shaders_editor.percent_center, 0, 50); } From 648ecb47c23ac44cb10155796c8c979d1019a0eb Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 24 Jun 2020 16:57:09 +0200 Subject: [PATCH 138/255] GCodeViewer -> Fixed incorrect detection of out of printbed for toolpaths --- src/slic3r/GUI/GCodeViewer.cpp | 26 +++++++++++++------------- src/slic3r/GUI/GCodeViewer.hpp | 18 ++++++++++++------ src/slic3r/GUI/GLCanvas3D.cpp | 10 +++++----- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 415b61aeb9..4b308e7030 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -148,7 +148,6 @@ void GCodeViewer::SequentialView::Marker::set_world_position(const Vec3f& positi { m_world_position = position; m_world_transform = (Geometry::assemble_transform((position + m_z_offset * Vec3f::UnitZ()).cast()) * Geometry::assemble_transform(m_model.get_bounding_box().size()[2] * Vec3d::UnitZ(), { M_PI, 0.0, 0.0 })).cast(); - m_world_bounding_box = m_model.get_bounding_box().transformed(m_world_transform.cast()); } void GCodeViewer::SequentialView::Marker::render() const @@ -288,10 +287,10 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& #if ENABLE_GCODE_VIEWER_AS_STATE if (wxGetApp().mainframe->get_mode() == MainFrame::EMode::GCodeViewer) { - // adjust printbed size + // adjust printbed size in dependence of toolpaths bbox const double margin = 10.0; - Vec2d min(m_bounding_box.min(0) - margin, m_bounding_box.min(1) - margin); - Vec2d max(m_bounding_box.max(0) + margin, m_bounding_box.max(1) + margin); + Vec2d min(m_paths_bounding_box.min(0) - margin, m_paths_bounding_box.min(1) - margin); + Vec2d max(m_paths_bounding_box.max(0) + margin, m_paths_bounding_box.max(1) + margin); Pointfs bed_shape = { { min(0), min(1) }, { max(0), min(1) }, { max(0), max(1) }, @@ -359,7 +358,8 @@ void GCodeViewer::reset() buffer.reset(); } - m_bounding_box = BoundingBoxf3(); + m_paths_bounding_box = BoundingBoxf3(); + m_max_bounding_box = BoundingBoxf3(); m_tool_colors = std::vector(); m_extruder_ids = std::vector(); m_extrusions.reset_role_visibility_flags(); @@ -497,18 +497,19 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) const GCodeProcessor::MoveVertex& move = gcode_result.moves[i]; #if ENABLE_GCODE_VIEWER_AS_STATE if (wxGetApp().mainframe->get_mode() == MainFrame::EMode::GCodeViewer) - m_bounding_box.merge(move.position.cast()); + // for the gcode viewer we need all moves to correctly size the printbed + m_paths_bounding_box.merge(move.position.cast()); else { #endif // ENABLE_GCODE_VIEWER_AS_STATE if (move.type == GCodeProcessor::EMoveType::Extrude && move.width != 0.0f && move.height != 0.0f) - m_bounding_box.merge(move.position.cast()); + m_paths_bounding_box.merge(move.position.cast()); #if ENABLE_GCODE_VIEWER_AS_STATE } #endif // ENABLE_GCODE_VIEWER_AS_STATE ::memcpy(static_cast(&vertices_data[i * 3]), static_cast(move.position.data()), 3 * sizeof(float)); } - m_bounding_box.merge(m_bounding_box.max + m_sequential_view.marker.get_bounding_box().max[2] * Vec3d::UnitZ()); + m_max_bounding_box.merge(m_paths_bounding_box.max + m_sequential_view.marker.get_bounding_box().max[2] * Vec3d::UnitZ()); #if ENABLE_GCODE_VIEWER_STATISTICS m_statistics.vertices_size = SLIC3R_STDVEC_MEMSIZE(vertices_data, float); @@ -578,7 +579,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) // indices data -> send data to gpu for (size_t i = 0; i < m_buffers.size(); ++i) { IBuffer& buffer = m_buffers[i]; - std::vector& buffer_indices = indices[i]; + const std::vector& buffer_indices = indices[i]; buffer.indices_count = buffer_indices.size(); #if ENABLE_GCODE_VIEWER_STATISTICS m_statistics.indices_size += SLIC3R_STDVEC_MEMSIZE(buffer_indices, unsigned int); @@ -859,7 +860,6 @@ void GCodeViewer::render_toolpaths() const for (const RenderPath& path : buffer.render_paths) { shader.set_uniform("uniform_color", path.color); -// glsafe(::glMultiDrawElements(GL_LINES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); glsafe(::glMultiDrawElements(GL_LINE_STRIP, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_line_strip_calls_count; @@ -878,8 +878,8 @@ void GCodeViewer::render_toolpaths() const unsigned char end_id = buffer_id(GCodeProcessor::EMoveType::Count); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vertices.vbo_id)); - glsafe(::glVertexPointer(3, GL_FLOAT, VBuffer::vertex_size_bytes(), (const void*)0)); - glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + glsafe(::glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, VBuffer::vertex_size_bytes(), (const void*)0)); + glsafe(::glEnableVertexAttribArray(0)); for (unsigned char i = begin_id; i < end_id; ++i) { const IBuffer& buffer = m_buffers[i]; @@ -914,7 +914,7 @@ void GCodeViewer::render_toolpaths() const } } - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + glsafe(::glDisableVertexAttribArray(0)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 413f4ef4ad..5c60863058 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -43,8 +43,8 @@ class GCodeViewer void reset(); - static size_t vertex_size() { return 3; } - static size_t vertex_size_bytes() { return vertex_size() * sizeof(float); } + static size_t vertex_size_floats() { return 3; } + static size_t vertex_size_bytes() { return vertex_size_floats() * sizeof(float); } }; // Used to identify different toolpath sub-types inside a IBuffer @@ -160,11 +160,14 @@ class GCodeViewer #if ENABLE_GCODE_VIEWER_STATISTICS struct Statistics { + // times long long load_time{ 0 }; long long refresh_time{ 0 }; long long refresh_paths_time{ 0 }; + // opengl calls long long gl_multi_points_calls_count{ 0 }; long long gl_multi_line_strip_calls_count{ 0 }; + // memory long long results_size{ 0 }; long long vertices_size{ 0 }; long long vertices_gpu_size{ 0 }; @@ -220,7 +223,6 @@ public: GLModel m_model; Vec3f m_world_position; Transform3f m_world_transform; - BoundingBoxf3 m_world_bounding_box; float m_z_offset{ 0.5f }; std::array m_color{ 1.0f, 1.0f, 1.0f, 1.0f }; bool m_visible{ false }; @@ -228,7 +230,7 @@ public: public: void init(); - const BoundingBoxf3& get_bounding_box() const { return m_world_bounding_box; } + const BoundingBoxf3& get_bounding_box() const { return m_model.get_bounding_box(); } void set_world_position(const Vec3f& position); void set_color(const std::array& color) { m_color = color; } @@ -268,7 +270,10 @@ private: unsigned int m_last_result_id{ 0 }; VBuffer m_vertices; mutable std::vector m_buffers{ static_cast(GCodeProcessor::EMoveType::Extrude) }; - BoundingBoxf3 m_bounding_box; + // bounding box of toolpaths + BoundingBoxf3 m_paths_bounding_box; + // bounding box of toolpaths + marker tools + BoundingBoxf3 m_max_bounding_box; std::vector m_tool_colors; std::vector m_layers_zs; std::array m_layers_z_range; @@ -303,7 +308,8 @@ public: bool has_data() const { return !m_roles.empty(); } - const BoundingBoxf3& get_bounding_box() const { return m_bounding_box; } + const BoundingBoxf3& get_paths_bounding_box() const { return m_paths_bounding_box; } + const BoundingBoxf3& get_max_bounding_box() const { return m_max_bounding_box; } const std::vector& get_layers_zs() const { return m_layers_zs; }; const SequentialView& get_sequential_view() const { return m_sequential_view; } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 5c72ae0fa7..0ee30a8084 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1933,7 +1933,7 @@ void GLCanvas3D::zoom_to_selection() #if ENABLE_GCODE_VIEWER_AS_STATE void GLCanvas3D::zoom_to_gcode() { - _zoom_to_box(m_gcode_viewer.get_bounding_box(), 1.05); + _zoom_to_box(m_gcode_viewer.get_paths_bounding_box(), 1.05); } #endif // ENABLE_GCODE_VIEWER_AS_STATE @@ -3108,7 +3108,7 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) if (!m_volumes.empty()) zoom_to_volumes(); else - _zoom_to_box(m_gcode_viewer.get_bounding_box()); + _zoom_to_box(m_gcode_viewer.get_paths_bounding_box()); } break; @@ -5189,7 +5189,7 @@ BoundingBoxf3 GLCanvas3D::_max_bounding_box(bool include_gizmos, bool include_be #if ENABLE_GCODE_VIEWER if (!m_main_toolbar.is_enabled()) - bb.merge(m_gcode_viewer.get_bounding_box()); + bb.merge(m_gcode_viewer.get_max_bounding_box()); #endif // ENABLE_GCODE_VIEWER return bb; @@ -5385,7 +5385,7 @@ void GLCanvas3D::_render_background() const use_error_color &= _is_any_volume_outside(); else { BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3(); - use_error_color &= (test_volume.radius() > 0.0) ? !test_volume.contains(m_gcode_viewer.get_bounding_box()) : false; + use_error_color &= (test_volume.radius() > 0.0) ? !test_volume.contains(m_gcode_viewer.get_paths_bounding_box()) : false; } #if ENABLE_GCODE_VIEWER_AS_STATE } @@ -7114,7 +7114,7 @@ void GLCanvas3D::_show_warning_texture_if_needed(WarningTexture::Warning warning if (wxGetApp().mainframe->get_mode() != MainFrame::EMode::GCodeViewer) { BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3(); - const BoundingBoxf3& paths_volume = m_gcode_viewer.get_bounding_box(); + const BoundingBoxf3& paths_volume = m_gcode_viewer.get_paths_bounding_box(); if (test_volume.radius() > 0.0 && paths_volume.radius() > 0.0) show = !test_volume.contains(paths_volume); } From eb683616193f03991cff08dbaf85bb1fe348cd09 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 25 Jun 2020 08:14:45 +0200 Subject: [PATCH 139/255] Follow-up of 648ecb47c23ac44cb10155796c8c979d1019a0eb -> Fixed calculation of max bounding box --- src/slic3r/GUI/GCodeViewer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 4b308e7030..05a8c20bba 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -509,7 +509,8 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) ::memcpy(static_cast(&vertices_data[i * 3]), static_cast(move.position.data()), 3 * sizeof(float)); } - m_max_bounding_box.merge(m_paths_bounding_box.max + m_sequential_view.marker.get_bounding_box().max[2] * Vec3d::UnitZ()); + m_max_bounding_box = m_paths_bounding_box; + m_max_bounding_box.merge(m_paths_bounding_box.max + m_sequential_view.marker.get_bounding_box().size()[2] * Vec3d::UnitZ()); #if ENABLE_GCODE_VIEWER_STATISTICS m_statistics.vertices_size = SLIC3R_STDVEC_MEMSIZE(vertices_data, float); From 69de5c8c9fdb4e51e3b6d489f36b0b6227360770 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 29 Jun 2020 14:00:08 +0200 Subject: [PATCH 140/255] GCodeViewer -> Pass vertex normal to shaders for toolpaths --- resources/shaders/extrusions.fs | 40 --- resources/shaders/extrusions.vs | 11 - resources/shaders/options_120_solid.fs | 2 +- resources/shaders/toolpaths.fs | 31 ++ resources/shaders/toolpaths.vs | 21 ++ resources/shaders/travels.fs | 40 --- resources/shaders/travels.vs | 11 - src/libslic3r/GCode/GCodeProcessor.cpp | 12 + src/libslic3r/GCode/GCodeProcessor.hpp | 5 + src/libslic3r/Technologies.hpp | 4 +- src/slic3r/GUI/GCodeViewer.cpp | 410 +++++++++++++++++-------- src/slic3r/GUI/GCodeViewer.hpp | 100 ++++-- src/slic3r/GUI/GLShadersManager.cpp | 9 +- 13 files changed, 431 insertions(+), 265 deletions(-) delete mode 100644 resources/shaders/extrusions.fs delete mode 100644 resources/shaders/extrusions.vs create mode 100644 resources/shaders/toolpaths.fs create mode 100644 resources/shaders/toolpaths.vs delete mode 100644 resources/shaders/travels.fs delete mode 100644 resources/shaders/travels.vs diff --git a/resources/shaders/extrusions.fs b/resources/shaders/extrusions.fs deleted file mode 100644 index 65db0667a9..0000000000 --- a/resources/shaders/extrusions.fs +++ /dev/null @@ -1,40 +0,0 @@ -#version 110 - -#define INTENSITY_AMBIENT 0.3 -#define INTENSITY_CORRECTION 0.6 - -// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) -const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); -#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) -#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) -#define LIGHT_TOP_SHININESS 20.0 - -// normalized values for (1./1.43, 0.2/1.43, 1./1.43) -const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0); -#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) - -uniform vec3 uniform_color; - -varying vec3 eye_position; -varying vec3 eye_normal; - -// x = tainted, y = specular; -vec2 intensity; - -void main() -{ - vec3 normal = normalize(eye_normal); - - // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. - // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. - float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0); - - intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; - intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); - - // Perform the same lighting calculation for the 2nd light source (no specular applied). - NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); - intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; - - gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color * intensity.x, 1.0); -} diff --git a/resources/shaders/extrusions.vs b/resources/shaders/extrusions.vs deleted file mode 100644 index 8980f3944b..0000000000 --- a/resources/shaders/extrusions.vs +++ /dev/null @@ -1,11 +0,0 @@ -#version 110 - -varying vec3 eye_position; -varying vec3 eye_normal; - -void main() -{ - eye_position = (gl_ModelViewMatrix * gl_Vertex).xyz; - eye_normal = gl_NormalMatrix * vec3(0.0, 0.0, 1.0); - gl_Position = ftransform(); -} diff --git a/resources/shaders/options_120_solid.fs b/resources/shaders/options_120_solid.fs index 4719ff96a6..4480d7b147 100644 --- a/resources/shaders/options_120_solid.fs +++ b/resources/shaders/options_120_solid.fs @@ -84,6 +84,6 @@ void main() vec3 eye_on_sphere_position = eye_position_on_sphere(eye_position_from_fragment()); - gl_FragDepth = fragment_depth(eye_on_sphere_position); +// gl_FragDepth = fragment_depth(eye_on_sphere_position); gl_FragColor = on_sphere_color(eye_on_sphere_position); } diff --git a/resources/shaders/toolpaths.fs b/resources/shaders/toolpaths.fs new file mode 100644 index 0000000000..13f60c0a82 --- /dev/null +++ b/resources/shaders/toolpaths.fs @@ -0,0 +1,31 @@ +#version 110 + +// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) +const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); +const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0); + +// x = ambient, y = top diffuse, z = front diffuse, w = global +uniform vec4 light_intensity; +uniform vec3 uniform_color; + +varying vec3 eye_position; +varying vec3 eye_normal; + +float intensity; + +void main() +{ + vec3 normal = normalize(eye_normal); + + // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. + // Since these two are normalized the cosine is the dot product. Take the abs value to light the lines no matter in which direction the normal points. + float NdotL = abs(dot(normal, LIGHT_TOP_DIR)); + + intensity = light_intensity.x + NdotL * light_intensity.y; + + // Perform the same lighting calculation for the 2nd light source. + NdotL = abs(dot(normal, LIGHT_FRONT_DIR)); + intensity += NdotL * light_intensity.z; + + gl_FragColor = vec4(uniform_color * light_intensity.w * intensity, 1.0); +} diff --git a/resources/shaders/toolpaths.vs b/resources/shaders/toolpaths.vs new file mode 100644 index 0000000000..34d141bfe1 --- /dev/null +++ b/resources/shaders/toolpaths.vs @@ -0,0 +1,21 @@ +#version 110 + +varying vec3 eye_position; +varying vec3 eye_normal; + +vec3 world_normal() +{ + // the world normal is always parallel to the world XY plane + // the x component is stored into gl_Vertex.w + float x = gl_Vertex.w; + float y = sqrt(1.0 - x * x); + return vec3(x, y, 0.0); +} + +void main() +{ + vec4 world_position = vec4(gl_Vertex.xyz, 1.0); + gl_Position = gl_ModelViewProjectionMatrix * world_position; + eye_position = (gl_ModelViewMatrix * world_position).xyz; + eye_normal = gl_NormalMatrix * world_normal(); +} diff --git a/resources/shaders/travels.fs b/resources/shaders/travels.fs deleted file mode 100644 index 65db0667a9..0000000000 --- a/resources/shaders/travels.fs +++ /dev/null @@ -1,40 +0,0 @@ -#version 110 - -#define INTENSITY_AMBIENT 0.3 -#define INTENSITY_CORRECTION 0.6 - -// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) -const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); -#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) -#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) -#define LIGHT_TOP_SHININESS 20.0 - -// normalized values for (1./1.43, 0.2/1.43, 1./1.43) -const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0); -#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) - -uniform vec3 uniform_color; - -varying vec3 eye_position; -varying vec3 eye_normal; - -// x = tainted, y = specular; -vec2 intensity; - -void main() -{ - vec3 normal = normalize(eye_normal); - - // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. - // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. - float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0); - - intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; - intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); - - // Perform the same lighting calculation for the 2nd light source (no specular applied). - NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0); - intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; - - gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color * intensity.x, 1.0); -} diff --git a/resources/shaders/travels.vs b/resources/shaders/travels.vs deleted file mode 100644 index 8980f3944b..0000000000 --- a/resources/shaders/travels.vs +++ /dev/null @@ -1,11 +0,0 @@ -#version 110 - -varying vec3 eye_position; -varying vec3 eye_normal; - -void main() -{ - eye_position = (gl_ModelViewMatrix * gl_Vertex).xyz; - eye_normal = gl_NormalMatrix * vec3(0.0, 0.0, 1.0); - gl_Position = ftransform(); -} diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index d561647262..14f29b56b6 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -7,6 +7,10 @@ #if ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER_STATISTICS +#include +#endif // ENABLE_GCODE_VIEWER_STATISTICS + static const float INCHES_TO_MM = 25.4f; static const float MMMIN_TO_MMSEC = 1.0f / 60.0f; @@ -89,9 +93,17 @@ void GCodeProcessor::reset() void GCodeProcessor::process_file(const std::string& filename) { +#if ENABLE_GCODE_VIEWER_STATISTICS + auto start_time = std::chrono::high_resolution_clock::now(); +#endif // ENABLE_GCODE_VIEWER_STATISTICS + m_result.id = ++s_result_id; m_result.moves.emplace_back(MoveVertex()); m_parser.parse_file(filename, [this](GCodeReader& reader, const GCodeReader::GCodeLine& line) { process_gcode_line(line); }); + +#if ENABLE_GCODE_VIEWER_STATISTICS + m_result.time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); +#endif // ENABLE_GCODE_VIEWER_STATISTICS } void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index bc49245848..3f596c9c2b 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -106,7 +106,12 @@ namespace Slic3r { { unsigned int id; std::vector moves; +#if ENABLE_GCODE_VIEWER_STATISTICS + long long time{ 0 }; + void reset() { time = 0; moves = std::vector(); } +#else void reset() { moves = std::vector(); } +#endif // ENABLE_GCODE_VIEWER_STATISTICS }; private: diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index b04e78c4ed..fb84efe5ab 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -59,8 +59,8 @@ // Enable G-Code viewer #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) -#define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) -#define ENABLE_GCODE_VIEWER_SHADERS_EDITOR (0 && ENABLE_GCODE_VIEWER) +#define ENABLE_GCODE_VIEWER_STATISTICS (1 && ENABLE_GCODE_VIEWER) +#define ENABLE_GCODE_VIEWER_SHADERS_EDITOR (1 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_AS_STATE (1 && ENABLE_GCODE_VIEWER) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 05a8c20bba..6d6ba557e2 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -64,12 +64,23 @@ std::vector> decode_colors(const std::vector & void GCodeViewer::VBuffer::reset() { // release gpu memory - if (vbo_id > 0) { - glsafe(::glDeleteBuffers(1, &vbo_id)); - vbo_id = 0; + if (id > 0) { + glsafe(::glDeleteBuffers(1, &id)); + id = 0; } - vertices_count = 0; + count = 0; +} + +void GCodeViewer::IBuffer::reset() +{ + // release gpu memory + if (id > 0) { + glsafe(::glDeleteBuffers(1, &id)); + id = 0; + } + + count = 0; } bool GCodeViewer::Path::matches(const GCodeProcessor::MoveVertex& move) const @@ -96,21 +107,18 @@ bool GCodeViewer::Path::matches(const GCodeProcessor::MoveVertex& move) const } } -void GCodeViewer::IBuffer::reset() +void GCodeViewer::TBuffer::reset() { // release gpu memory - if (ibo_id > 0) { - glsafe(::glDeleteBuffers(1, &ibo_id)); - ibo_id = 0; - } + vertices.reset(); + indices.reset(); // release cpu memory - indices_count = 0; paths = std::vector(); render_paths = std::vector(); } -void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move, unsigned int i_id, unsigned int s_id) +void GCodeViewer::TBuffer::add_path(const GCodeProcessor::MoveVertex& move, unsigned int i_id, unsigned int s_id) { Path::Endpoint endpoint = { i_id, s_id, move.position }; paths.push_back({ move.type, move.extrusion_role, endpoint, endpoint, move.delta_extruder, move.height, move.width, move.feedrate, move.fan_speed, move.volumetric_rate(), move.extruder_id, move.cp_color_id }); @@ -209,7 +217,7 @@ void GCodeViewer::SequentialView::Marker::render() const } const std::vector GCodeViewer::Extrusion_Role_Colors {{ - { 0.50f, 0.50f, 0.50f }, // erNone + { 0.75f, 0.75f, 0.75f }, // erNone { 1.00f, 1.00f, 0.40f }, // erPerimeter { 1.00f, 0.65f, 0.00f }, // erExternalPerimeter { 0.00f, 0.00f, 1.00f }, // erOverhangPerimeter @@ -257,6 +265,29 @@ const std::vector GCodeViewer::Range_Colors {{ bool GCodeViewer::init() { + for (size_t i = 0; i < m_buffers.size(); ++i) + { + switch (buffer_type(i)) + { + case GCodeProcessor::EMoveType::Tool_change: + case GCodeProcessor::EMoveType::Color_change: + case GCodeProcessor::EMoveType::Pause_Print: + case GCodeProcessor::EMoveType::Custom_GCode: + case GCodeProcessor::EMoveType::Retract: + case GCodeProcessor::EMoveType::Unretract: + { + m_buffers[i].vertices.format = VBuffer::EFormat::Position; + break; + } + case GCodeProcessor::EMoveType::Extrude: + case GCodeProcessor::EMoveType::Travel: + { + m_buffers[i].vertices.format = VBuffer::EFormat::PositionNormal; + break; + } + } + } + set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Extrude, true); m_sequential_view.marker.init(); init_shaders(); @@ -306,7 +337,7 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: auto start_time = std::chrono::high_resolution_clock::now(); #endif // ENABLE_GCODE_VIEWER_STATISTICS - if (m_vertices.vertices_count == 0) + if (m_vertices_count == 0) return; // update tool colors @@ -314,7 +345,7 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: // update ranges for coloring / legend m_extrusions.reset_ranges(); - for (size_t i = 0; i < m_vertices.vertices_count; ++i) { + for (size_t i = 0; i < m_vertices_count; ++i) { // skip first vertex if (i == 0) continue; @@ -342,19 +373,18 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: } } - // update buffers' render paths - refresh_render_paths(false, false); - #if ENABLE_GCODE_VIEWER_STATISTICS m_statistics.refresh_time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); #endif // ENABLE_GCODE_VIEWER_STATISTICS + + // update buffers' render paths + refresh_render_paths(false, false); } void GCodeViewer::reset() { - m_vertices.reset(); - - for (IBuffer& buffer : m_buffers) { + m_vertices_count = 0; + for (TBuffer& buffer : m_buffers) { buffer.reset(); } @@ -472,8 +502,8 @@ void GCodeViewer::init_shaders() case GCodeProcessor::EMoveType::Custom_GCode: { m_buffers[i].shader = is_glsl_120 ? "options_120_solid" : "options_110"; break; } case GCodeProcessor::EMoveType::Retract: { m_buffers[i].shader = is_glsl_120 ? "options_120_solid" : "options_110"; break; } case GCodeProcessor::EMoveType::Unretract: { m_buffers[i].shader = is_glsl_120 ? "options_120_solid" : "options_110"; break; } - case GCodeProcessor::EMoveType::Extrude: { m_buffers[i].shader = "extrusions"; break; } - case GCodeProcessor::EMoveType::Travel: { m_buffers[i].shader = "travels"; break; } + case GCodeProcessor::EMoveType::Extrude: { m_buffers[i].shader = "toolpaths"; break; } + case GCodeProcessor::EMoveType::Travel: { m_buffers[i].shader = "toolpaths"; break; } default: { break; } } } @@ -484,16 +514,15 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) #if ENABLE_GCODE_VIEWER_STATISTICS auto start_time = std::chrono::high_resolution_clock::now(); m_statistics.results_size = SLIC3R_STDVEC_MEMSIZE(gcode_result.moves, GCodeProcessor::MoveVertex); + m_statistics.results_time = gcode_result.time; #endif // ENABLE_GCODE_VIEWER_STATISTICS - // vertex data - m_vertices.vertices_count = gcode_result.moves.size(); - if (m_vertices.vertices_count == 0) + // vertices data + m_vertices_count = gcode_result.moves.size(); + if (m_vertices_count == 0) return; - // vertex data / bounding box -> extract from result - std::vector vertices_data(m_vertices.vertices_count * 3); - for (size_t i = 0; i < m_vertices.vertices_count; ++i) { + for (size_t i = 0; i < m_vertices_count; ++i) { const GCodeProcessor::MoveVertex& move = gcode_result.moves[i]; #if ENABLE_GCODE_VIEWER_AS_STATE if (wxGetApp().mainframe->get_mode() == MainFrame::EMode::GCodeViewer) @@ -506,29 +535,16 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) #if ENABLE_GCODE_VIEWER_AS_STATE } #endif // ENABLE_GCODE_VIEWER_AS_STATE - ::memcpy(static_cast(&vertices_data[i * 3]), static_cast(move.position.data()), 3 * sizeof(float)); } + // max bounding box m_max_bounding_box = m_paths_bounding_box; m_max_bounding_box.merge(m_paths_bounding_box.max + m_sequential_view.marker.get_bounding_box().size()[2] * Vec3d::UnitZ()); -#if ENABLE_GCODE_VIEWER_STATISTICS - m_statistics.vertices_size = SLIC3R_STDVEC_MEMSIZE(vertices_data, float); - m_statistics.vertices_gpu_size = vertices_data.size() * sizeof(float); -#endif // ENABLE_GCODE_VIEWER_STATISTICS - - // vertex data -> send to gpu - glsafe(::glGenBuffers(1, &m_vertices.vbo_id)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vertices.vbo_id)); - glsafe(::glBufferData(GL_ARRAY_BUFFER, vertices_data.size() * sizeof(float), vertices_data.data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - - // vertex data -> no more needed, free ram - vertices_data = std::vector(); - - // indices data -> extract from result + // toolpaths data -> extract from result + std::vector> vertices(m_buffers.size()); std::vector> indices(m_buffers.size()); - for (size_t i = 0; i < m_vertices.vertices_count; ++i) { + for (size_t i = 0; i < m_vertices_count; ++i) { // skip first vertex if (i == 0) continue; @@ -537,7 +553,8 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) const GCodeProcessor::MoveVertex& curr = gcode_result.moves[i]; unsigned char id = buffer_id(curr.type); - IBuffer& buffer = m_buffers[id]; + TBuffer& buffer = m_buffers[id]; + std::vector& buffer_vertices = vertices[id]; std::vector& buffer_indices = indices[id]; switch (curr.type) @@ -549,54 +566,103 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) case GCodeProcessor::EMoveType::Retract: case GCodeProcessor::EMoveType::Unretract: { + for (int j = 0; j < 3; ++j) { + buffer_vertices.push_back(curr.position[j]); + } buffer.add_path(curr, static_cast(buffer_indices.size()), static_cast(i)); - buffer_indices.push_back(static_cast(i)); + buffer_indices.push_back(static_cast(buffer_indices.size())); break; } case GCodeProcessor::EMoveType::Extrude: case GCodeProcessor::EMoveType::Travel: { + // x component of the normal to the current segment (the normal is parallel to the XY plane) + float normal_x = (curr.position - prev.position).normalized()[1]; + if (prev.type != curr.type || !buffer.paths.back().matches(curr)) { - buffer.add_path(curr, static_cast(buffer_indices.size()), static_cast(i - 1)); + // add starting vertex position + for (int j = 0; j < 3; ++j) { + buffer_vertices.push_back(prev.position[j]); + } + // add starting vertex normal x component + buffer_vertices.push_back(normal_x); + // add starting index + buffer_indices.push_back(buffer_indices.size()); + buffer.add_path(curr, static_cast(buffer_indices.size() - 1), static_cast(i - 1)); Path& last_path = buffer.paths.back(); last_path.first.position = prev.position; - buffer_indices.push_back(static_cast(i - 1)); } - - buffer.paths.back().last = { static_cast(buffer_indices.size()), static_cast(i), curr.position }; - buffer_indices.push_back(static_cast(i)); + + Path& last_path = buffer.paths.back(); + if (last_path.first.i_id != last_path.last.i_id) + { + // add previous vertex position + for (int j = 0; j < 3; ++j) { + buffer_vertices.push_back(prev.position[j]); + } + // add previous vertex normal x component + buffer_vertices.push_back(normal_x); + // add previous index + buffer_indices.push_back(buffer_indices.size()); + } + + // add current vertex position + for (int j = 0; j < 3; ++j) { + buffer_vertices.push_back(curr.position[j]); + } + // add current vertex normal x component + buffer_vertices.push_back(normal_x); + // add current index + buffer_indices.push_back(buffer_indices.size()); + last_path.last = { static_cast(buffer_indices.size() - 1), static_cast(i), curr.position }; break; } default: { break; } } } + // toolpaths data -> send data to gpu + for (size_t i = 0; i < m_buffers.size(); ++i) { + TBuffer& buffer = m_buffers[i]; + + // vertices + const std::vector& buffer_vertices = vertices[i]; + buffer.vertices.count = buffer_vertices.size() / buffer.vertices.vertex_size_floats(); #if ENABLE_GCODE_VIEWER_STATISTICS - for (IBuffer& buffer : m_buffers) { - m_statistics.paths_size += SLIC3R_STDVEC_MEMSIZE(buffer.paths, Path); - } + m_statistics.vertices_gpu_size = buffer_vertices.size() * sizeof(float); #endif // ENABLE_GCODE_VIEWER_STATISTICS - // indices data -> send data to gpu - for (size_t i = 0; i < m_buffers.size(); ++i) { - IBuffer& buffer = m_buffers[i]; + glsafe(::glGenBuffers(1, &buffer.vertices.id)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.vertices.id)); + glsafe(::glBufferData(GL_ARRAY_BUFFER, buffer_vertices.size() * sizeof(float), buffer_vertices.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + + // indices const std::vector& buffer_indices = indices[i]; - buffer.indices_count = buffer_indices.size(); + buffer.indices.count = buffer_indices.size(); #if ENABLE_GCODE_VIEWER_STATISTICS m_statistics.indices_size += SLIC3R_STDVEC_MEMSIZE(buffer_indices, unsigned int); - m_statistics.indices_gpu_size += buffer.indices_count * sizeof(unsigned int); + m_statistics.indices_gpu_size += buffer.indices.count * sizeof(unsigned int); #endif // ENABLE_GCODE_VIEWER_STATISTICS - if (buffer.indices_count > 0) { - glsafe(::glGenBuffers(1, &buffer.ibo_id)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.ibo_id)); - glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, buffer.indices_count * sizeof(unsigned int), buffer_indices.data(), GL_STATIC_DRAW)); + if (buffer.indices.count > 0) { + glsafe(::glGenBuffers(1, &buffer.indices.id)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.indices.id)); + glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, buffer.indices.count * sizeof(unsigned int), buffer_indices.data(), GL_STATIC_DRAW)); glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); } } +#if ENABLE_GCODE_VIEWER_STATISTICS + for (const TBuffer& buffer : m_buffers) { + m_statistics.paths_size += SLIC3R_STDVEC_MEMSIZE(buffer.paths, Path); + } + m_statistics.travel_segments_count = indices[buffer_id(GCodeProcessor::EMoveType::Travel)].size() / 2; + m_statistics.extrude_segments_count = indices[buffer_id(GCodeProcessor::EMoveType::Extrude)].size() / 2; +#endif // ENABLE_GCODE_VIEWER_STATISTICS + // layers zs / roles / extruder ids / cp color ids -> extract from result - for (size_t i = 0; i < m_vertices.vertices_count; ++i) { + for (size_t i = 0; i < m_vertices_count; ++i) { const GCodeProcessor::MoveVertex& move = gcode_result.moves[i]; if (move.type == GCodeProcessor::EMoveType::Extrude) m_layers_zs.emplace_back(static_cast(move.position[2])); @@ -728,18 +794,18 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool m_statistics.render_paths_size = 0; #endif // ENABLE_GCODE_VIEWER_STATISTICS - m_sequential_view.endpoints.first = m_vertices.vertices_count; + m_sequential_view.endpoints.first = m_vertices_count; m_sequential_view.endpoints.last = 0; if (!keep_sequential_current_first) m_sequential_view.current.first = 0; if (!keep_sequential_current_last) - m_sequential_view.current.last = m_vertices.vertices_count; + m_sequential_view.current.last = m_vertices_count; // first pass: collect visible paths and update sequential view data - std::vector> paths; - for (IBuffer& buffer : m_buffers) { + std::vector> paths; + for (TBuffer& buffer : m_buffers) { // reset render paths - buffer.render_paths = std::vector(); + buffer.render_paths.clear(); if (!buffer.visible) continue; @@ -767,23 +833,43 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool // update current sequential position m_sequential_view.current.first = keep_sequential_current_first ? std::clamp(m_sequential_view.current.first, m_sequential_view.endpoints.first, m_sequential_view.endpoints.last) : m_sequential_view.endpoints.first; m_sequential_view.current.last = keep_sequential_current_last ? std::clamp(m_sequential_view.current.last, m_sequential_view.endpoints.first, m_sequential_view.endpoints.last) : m_sequential_view.endpoints.last; - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vertices.vbo_id)); - size_t v_size = VBuffer::vertex_size_bytes(); - glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, static_cast(m_sequential_view.current.last * v_size), static_cast(v_size), static_cast(m_sequential_view.current_position.data()))); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - // second pass: filter paths by sequential data + // get the world position from gpu + bool found = false; + for (const TBuffer& buffer : m_buffers) { + // searches the path containing the current position + for (const Path& path : buffer.paths) { + if (path.first.s_id <= m_sequential_view.current.last && m_sequential_view.current.last <= path.last.s_id) { + size_t offset = m_sequential_view.current.last - path.first.s_id; + if (offset > 0 && (path.type == GCodeProcessor::EMoveType::Travel || path.type == GCodeProcessor::EMoveType::Extrude)) + offset = 1 + 2 * (offset - 1); + + offset += path.first.i_id; + + // gets the position from the vertices buffer on gpu + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.vertices.id)); + glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, static_cast(offset * buffer.vertices.vertex_size_bytes()), static_cast(3 * sizeof(float)), static_cast(m_sequential_view.current_position.data()))); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + found = true; + break; + } + } + if (found) + break; + } + + // second pass: filter paths by sequential data and collect them by color for (auto&& [buffer, id] : paths) { const Path& path = buffer->paths[id]; - if ((m_sequential_view.current.last <= path.first.s_id) || (path.last.s_id <= m_sequential_view.current.first)) + if (m_sequential_view.current.last <= path.first.s_id || path.last.s_id <= m_sequential_view.current.first) continue; Color color; switch (path.type) { case GCodeProcessor::EMoveType::Extrude: { color = extrusion_color(path); break; } - case GCodeProcessor::EMoveType::Travel: { color = (m_view_type == EViewType::Feedrate || m_view_type == EViewType::Tool || m_view_type == EViewType::ColorPrint) ? extrusion_color(path) : travel_color(path); break; } - default: { color = { 0.0f, 0.0f, 0.0f }; break; } + case GCodeProcessor::EMoveType::Travel: { color = (m_view_type == EViewType::Feedrate || m_view_type == EViewType::Tool || m_view_type == EViewType::ColorPrint) ? extrusion_color(path) : travel_color(path); break; } + default: { color = { 0.0f, 0.0f, 0.0f }; break; } } auto it = std::find_if(buffer->render_paths.begin(), buffer->render_paths.end(), [color](const RenderPath& path) { return path.color == color; }); @@ -792,7 +878,11 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool it->color = color; } - it->sizes.push_back(std::min(m_sequential_view.current.last, path.last.s_id) - std::max(m_sequential_view.current.first, path.first.s_id) + 1); + unsigned int size = std::min(m_sequential_view.current.last, path.last.s_id) - std::max(m_sequential_view.current.first, path.first.s_id) + 1; + if (path.type == GCodeProcessor::EMoveType::Extrude || path.type == GCodeProcessor::EMoveType::Travel) + size = 2 * (size - 1); + + it->sizes.push_back(size); unsigned int delta_1st = 0; if ((path.first.s_id < m_sequential_view.current.first) && (m_sequential_view.current.first <= path.last.s_id)) delta_1st = m_sequential_view.current.first - path.first.s_id; @@ -801,14 +891,13 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool } #if ENABLE_GCODE_VIEWER_STATISTICS - for (const IBuffer& buffer : m_buffers) { + for (const TBuffer& buffer : m_buffers) { m_statistics.render_paths_size += SLIC3R_STDVEC_MEMSIZE(buffer.render_paths, RenderPath); for (const RenderPath& path : buffer.render_paths) { m_statistics.render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.sizes, unsigned int); m_statistics.render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.offsets, size_t); } } - m_statistics.refresh_paths_time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); #endif // ENABLE_GCODE_VIEWER_STATISTICS } @@ -816,9 +905,9 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool void GCodeViewer::render_toolpaths() const { #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR - float point_size = m_shaders_editor.point_size; + float point_size = m_shaders_editor.points.point_size; #else - float point_size = 1.0f; + float point_size = 0.8f; #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR const Camera& camera = wxGetApp().plater()->get_camera(); double zoom = camera.get_zoom(); @@ -828,12 +917,12 @@ void GCodeViewer::render_toolpaths() const Transform3d inv_proj = camera.get_projection_matrix().inverse(); - auto render_as_points = [this, zoom, inv_proj, viewport, point_size, near_plane_height](const IBuffer& buffer, EOptionsColors color_id, GLShaderProgram& shader) { + auto render_as_points = [this, zoom, inv_proj, viewport, point_size, near_plane_height](const TBuffer& buffer, EOptionsColors color_id, GLShaderProgram& shader) { shader.set_uniform("uniform_color", Options_Colors[static_cast(color_id)]); shader.set_uniform("zoom", zoom); #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR - shader.set_uniform("percent_outline_radius", 0.01f * static_cast(m_shaders_editor.percent_outline)); - shader.set_uniform("percent_center_radius", 0.01f * static_cast(m_shaders_editor.percent_center)); + shader.set_uniform("percent_outline_radius", 0.01f * static_cast(m_shaders_editor.points.percent_outline)); + shader.set_uniform("percent_center_radius", 0.01f * static_cast(m_shaders_editor.points.percent_center)); #else shader.set_uniform("percent_outline_radius", 0.15f); shader.set_uniform("percent_center_radius", 0.15f); @@ -852,16 +941,16 @@ void GCodeViewer::render_toolpaths() const ++m_statistics.gl_multi_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } - + glsafe(::glDisable(GL_POINT_SPRITE)); glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); }; - auto render_as_lines = [this](const IBuffer& buffer, GLShaderProgram& shader) { + auto render_as_lines = [this](const TBuffer& buffer, GLShaderProgram& shader) { for (const RenderPath& path : buffer.render_paths) { shader.set_uniform("uniform_color", path.color); - glsafe(::glMultiDrawElements(GL_LINE_STRIP, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); + glsafe(::glMultiDrawElements(GL_LINES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_line_strip_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -878,27 +967,25 @@ void GCodeViewer::render_toolpaths() const unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); unsigned char end_id = buffer_id(GCodeProcessor::EMoveType::Count); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vertices.vbo_id)); - glsafe(::glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, VBuffer::vertex_size_bytes(), (const void*)0)); - glsafe(::glEnableVertexAttribArray(0)); - for (unsigned char i = begin_id; i < end_id; ++i) { - const IBuffer& buffer = m_buffers[i]; - if (buffer.ibo_id == 0) - continue; - + const TBuffer& buffer = m_buffers[i]; if (!buffer.visible) continue; + if (buffer.vertices.id == 0 || buffer.indices.id == 0) + continue; + GLShaderProgram* shader = wxGetApp().get_shader(buffer.shader.c_str()); if (shader != nullptr) { shader->start_using(); - GCodeProcessor::EMoveType type = buffer_type(i); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.vertices.id)); + glsafe(::glVertexAttribPointer(0, buffer.vertices.vertex_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)0)); + glsafe(::glEnableVertexAttribArray(0)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.ibo_id)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.indices.id)); - switch (type) + switch (buffer_type(i)) { case GCodeProcessor::EMoveType::Tool_change: { render_as_points(buffer, EOptionsColors::ToolChanges, *shader); break; } case GCodeProcessor::EMoveType::Color_change: { render_as_points(buffer, EOptionsColors::ColorChanges, *shader); break; } @@ -907,16 +994,33 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Retract: { render_as_points(buffer, EOptionsColors::Retractions, *shader); break; } case GCodeProcessor::EMoveType::Unretract: { render_as_points(buffer, EOptionsColors::Unretractions, *shader); break; } case GCodeProcessor::EMoveType::Extrude: - case GCodeProcessor::EMoveType::Travel: { render_as_lines(buffer, *shader); break; } + case GCodeProcessor::EMoveType::Travel: + { + std::array light_intensity; +#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR + light_intensity[0] = m_shaders_editor.lines.lights.ambient; + light_intensity[1] = m_shaders_editor.lines.lights.top_diffuse; + light_intensity[2] = m_shaders_editor.lines.lights.front_diffuse; + light_intensity[3] = m_shaders_editor.lines.lights.global; +#else + light_intensity[0] = 0.25f; + light_intensity[1] = 0.7f; + light_intensity[2] = 0.75f; + light_intensity[3] = 0.75f; +#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR + shader->set_uniform("light_intensity", light_intensity); + render_as_lines(buffer, *shader); break; + } } glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + + glsafe(::glDisableVertexAttribArray(0)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + shader->stop_using(); } } - - glsafe(::glDisableVertexAttribArray(0)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); } void GCodeViewer::render_shells() const @@ -985,13 +1089,13 @@ void GCodeViewer::render_legend() const { #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size)); - if (m_shaders_editor.shader_version == 1) { + if (m_shaders_editor.points.shader_version == 1) { draw_list->AddCircleFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); - float radius = 0.5f * icon_size * (1.0f - 0.01f * static_cast(m_shaders_editor.percent_outline)); + float radius = 0.5f * icon_size * (1.0f - 0.01f * static_cast(m_shaders_editor.points.percent_outline)); draw_list->AddCircleFilled(center, radius, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); - if (m_shaders_editor.percent_center > 0) { - radius = 0.5f * icon_size * 0.01f * static_cast(m_shaders_editor.percent_center); + if (m_shaders_editor.points.percent_center > 0) { + radius = 0.5f * icon_size * 0.01f * static_cast(m_shaders_editor.points.percent_center); draw_list->AddCircleFilled(center, radius, ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); } } @@ -1284,10 +1388,10 @@ void GCodeViewer::render_legend() const }; auto add_option = [this, add_item](GCodeProcessor::EMoveType move_type, EOptionsColors color, const std::string& text) { - const IBuffer& buffer = m_buffers[buffer_id(move_type)]; - if (buffer.visible && buffer.indices_count > 0) + const TBuffer& buffer = m_buffers[buffer_id(move_type)]; + if (buffer.visible && buffer.indices.count > 0) #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR - add_item((m_shaders_editor.shader_version == 0) ? EItemType::Rect : EItemType::Circle, Options_Colors[static_cast(color)], text); + add_item((m_shaders_editor.points.shader_version == 0) ? EItemType::Rect : EItemType::Circle, Options_Colors[static_cast(color)], text); #else add_item((buffer.shader == "options_110") ? EItemType::Rect : EItemType::Circle, Options_Colors[static_cast(color)], text); #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR @@ -1320,14 +1424,22 @@ void GCodeViewer::render_legend() const void GCodeViewer::render_statistics() const { static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); - static const float offset = 250.0f; + static const float offset = 230.0f; ImGuiWrapper& imgui = *wxGetApp().imgui(); imgui.set_next_window_pos(0.5f * wxGetApp().plater()->get_current_canvas3D()->get_canvas_size().get_width(), 0.0f, ImGuiCond_Once, 0.5f, 0.0f); - imgui.begin(std::string("Statistics"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); + imgui.begin(std::string("GCodeViewer Statistics"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize); ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindow()); + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + imgui.text(std::string("GCodeProcessor time:")); + ImGui::PopStyleColor(); + ImGui::SameLine(offset); + imgui.text(std::to_string(m_statistics.results_time) + " ms"); + + ImGui::Separator(); + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); imgui.text(std::string("Load time:")); ImGui::PopStyleColor(); @@ -1370,12 +1482,6 @@ void GCodeViewer::render_statistics() const ImGui::Separator(); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); - imgui.text(std::string("Vertices CPU:")); - ImGui::PopStyleColor(); - ImGui::SameLine(offset); - imgui.text(std::to_string(m_statistics.vertices_size) + " bytes"); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); imgui.text(std::string("Indices CPU:")); ImGui::PopStyleColor(); @@ -1408,6 +1514,20 @@ void GCodeViewer::render_statistics() const ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.indices_gpu_size) + " bytes"); + ImGui::Separator(); + + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + imgui.text(std::string("Travel segments:")); + ImGui::PopStyleColor(); + ImGui::SameLine(offset); + imgui.text(std::to_string(m_statistics.travel_segments_count)); + + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + imgui.text(std::string("Extrude segments:")); + ImGui::PopStyleColor(); + ImGui::SameLine(offset); + imgui.text(std::to_string(m_statistics.extrude_segments_count)); + imgui.end(); } #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -1429,34 +1549,58 @@ void GCodeViewer::render_shaders_editor() const Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size(); imgui.set_next_window_pos(static_cast(cnv_size.get_width()), 0.5f * static_cast(cnv_size.get_height()), ImGuiCond_Once, 1.0f, 0.5f); + imgui.begin(std::string("Shaders editor (DEV only)"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize); - ImGui::RadioButton("glsl version 1.10 (low end PCs)", &m_shaders_editor.shader_version, 0); - ImGui::RadioButton("glsl version 1.20 flat (billboards)", &m_shaders_editor.shader_version, 1); - ImGui::RadioButton("glsl version 1.20 solid (spheres default)", &m_shaders_editor.shader_version, 2); + if (ImGui::CollapsingHeader("Points", ImGuiTreeNodeFlags_DefaultOpen)) { + if (ImGui::TreeNode("GLSL version")) { + ImGui::RadioButton("1.10 (low end PCs)", &m_shaders_editor.points.shader_version, 0); + ImGui::RadioButton("1.20 flat (billboards)", &m_shaders_editor.points.shader_version, 1); + ImGui::RadioButton("1.20 solid (spheres default)", &m_shaders_editor.points.shader_version, 2); + ImGui::TreePop(); + } - switch (m_shaders_editor.shader_version) - { - case 0: { set_shader("options_110"); break; } - case 1: { set_shader("options_120_flat"); break; } - case 2: { set_shader("options_120_solid"); break; } + switch (m_shaders_editor.points.shader_version) + { + case 0: { set_shader("options_110"); break; } + case 1: { set_shader("options_120_flat"); break; } + case 2: { set_shader("options_120_solid"); break; } + } + + if (ImGui::TreeNode("Options")) { + ImGui::SliderFloat("point size", &m_shaders_editor.points.point_size, 0.5f, 3.0f, "%.2f"); + if (m_shaders_editor.points.shader_version == 1) { + ImGui::SliderInt("% outline", &m_shaders_editor.points.percent_outline, 0, 50); + ImGui::SliderInt("% center", &m_shaders_editor.points.percent_center, 0, 50); + } + ImGui::TreePop(); + } } - if (ImGui::CollapsingHeader("Options", ImGuiTreeNodeFlags_DefaultOpen)) { - ImGui::SliderFloat("point size", &m_shaders_editor.point_size, 0.5f, 3.0f, "%.1f"); - if (m_shaders_editor.shader_version == 1) { - ImGui::SliderInt("percent outline", &m_shaders_editor.percent_outline, 0, 50); - ImGui::SliderInt("percent center", &m_shaders_editor.percent_center, 0, 50); + if (ImGui::CollapsingHeader("Lines", ImGuiTreeNodeFlags_DefaultOpen)) { + if (ImGui::TreeNode("Lights")) { + ImGui::SliderFloat("ambient", &m_shaders_editor.lines.lights.ambient, 0.0f, 1.0f, "%.2f"); + ImGui::SliderFloat("top diffuse", &m_shaders_editor.lines.lights.top_diffuse, 0.0f, 1.0f, "%.2f"); + ImGui::SliderFloat("front diffuse", &m_shaders_editor.lines.lights.front_diffuse, 0.0f, 1.0f, "%.2f"); + ImGui::SliderFloat("global", &m_shaders_editor.lines.lights.global, 0.0f, 1.0f, "%.2f"); + ImGui::TreePop(); } } + ImGui::SetWindowSize(ImVec2(std::max(ImGui::GetWindowWidth(), 600.0f), -1.0f), ImGuiCond_Always); + if (ImGui::GetWindowPos().x + ImGui::GetWindowWidth() > static_cast(cnv_size.get_width())) { + ImGui::SetWindowPos(ImVec2(static_cast(cnv_size.get_width()) - ImGui::GetWindowWidth(), ImGui::GetWindowPos().y), ImGuiCond_Always); + wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); + wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); + } + imgui.end(); } #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR bool GCodeViewer::is_travel_in_z_range(size_t id) const { - const IBuffer& buffer = m_buffers[buffer_id(GCodeProcessor::EMoveType::Travel)]; + const TBuffer& buffer = m_buffers[buffer_id(GCodeProcessor::EMoveType::Travel)]; if (id >= buffer.paths.size()) return false; diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 5c60863058..5cddeaa75a 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -33,18 +33,47 @@ class GCodeViewer CustomGCodes }; - // buffer containing vertices data + // vbo buffer containing vertices data for a specific toolpath type struct VBuffer { - unsigned int vbo_id{ 0 }; - size_t vertices_count{ 0 }; + enum class EFormat : unsigned char + { + Position, + PositionNormal + }; - size_t data_size_bytes() { return vertices_count * vertex_size_bytes(); } + EFormat format{ EFormat::Position }; + // vbo id + unsigned int id{ 0 }; + // count of vertices, updated after data are sent to gpu + size_t count{ 0 }; + + size_t data_size_bytes() const { return count * vertex_size_bytes(); } + size_t vertex_size_floats() const + { + switch (format) + { + // vertex format: 3 floats -> position.x|position.y|position.z + case EFormat::Position: { return 3; } + // vertex format: 4 floats -> position.x|position.y|position.z|normal.x + case EFormat::PositionNormal: { return 4; } + default: { return 0; } + } + } + size_t vertex_size_bytes() const { return vertex_size_floats() * sizeof(float); } void reset(); + }; - static size_t vertex_size_floats() { return 3; } - static size_t vertex_size_bytes() { return vertex_size_floats() * sizeof(float); } + // ibo buffer containing indices data for a specific toolpath type + struct IBuffer + { + // ibo id + unsigned int id{ 0 }; + // count of indices, updated after data are sent to gpu + size_t count{ 0 }; + + void reset(); }; // Used to identify different toolpath sub-types inside a IBuffer @@ -52,9 +81,9 @@ class GCodeViewer { struct Endpoint { - // index into the buffer indices ibo + // index into the indices buffer unsigned int i_id{ 0u }; - // sequential id (same as index into the vertices vbo) + // sequential id unsigned int s_id{ 0u }; Vec3f position{ Vec3f::Zero() }; }; @@ -83,11 +112,12 @@ class GCodeViewer std::vector offsets; // use size_t because we need the pointer's size (used in the call glMultiDrawElements()) }; - // buffer containing indices data and shader for a specific toolpath type - struct IBuffer + // buffer containing data for rendering a specific toolpath type + struct TBuffer { - unsigned int ibo_id{ 0 }; - size_t indices_count{ 0 }; + VBuffer vertices; + IBuffer indices; + std::string shader; std::vector paths; std::vector render_paths; @@ -161,6 +191,7 @@ class GCodeViewer struct Statistics { // times + long long results_time{ 0 }; long long load_time{ 0 }; long long refresh_time{ 0 }; long long refresh_paths_time{ 0 }; @@ -169,20 +200,24 @@ class GCodeViewer long long gl_multi_line_strip_calls_count{ 0 }; // memory long long results_size{ 0 }; - long long vertices_size{ 0 }; long long vertices_gpu_size{ 0 }; long long indices_size{ 0 }; long long indices_gpu_size{ 0 }; long long paths_size{ 0 }; long long render_paths_size{ 0 }; + // others + long long travel_segments_count{ 0 }; + long long extrude_segments_count{ 0 }; void reset_all() { reset_times(); reset_opengl(); reset_sizes(); + reset_counters(); } void reset_times() { + results_time = 0; load_time = 0; refresh_time = 0; refresh_paths_time = 0; @@ -195,23 +230,46 @@ class GCodeViewer void reset_sizes() { results_size = 0; - vertices_size = 0; vertices_gpu_size = 0; indices_size = 0; indices_gpu_size = 0; - paths_size = 0; + paths_size = 0; render_paths_size = 0; } + + void reset_counters() { + travel_segments_count = 0; + extrude_segments_count = 0; + } }; #endif // ENABLE_GCODE_VIEWER_STATISTICS #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR struct ShadersEditor { - int shader_version{ 2 }; - float point_size{ 1.0f }; - int percent_outline{ 0 }; - int percent_center{ 33 }; + struct Points + { + int shader_version{ 2 }; + float point_size{ 0.8f }; + int percent_outline{ 0 }; + int percent_center{ 33 }; + }; + + struct Lines + { + struct Lights + { + float ambient{ 0.25f }; + float top_diffuse{ 0.7f }; + float front_diffuse{ 0.75f }; + float global{ 0.75f }; + }; + + Lights lights; + }; + + Points points; + Lines lines; }; #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR @@ -268,8 +326,8 @@ public: private: unsigned int m_last_result_id{ 0 }; - VBuffer m_vertices; - mutable std::vector m_buffers{ static_cast(GCodeProcessor::EMoveType::Extrude) }; + size_t m_vertices_count{ 0 }; + mutable std::vector m_buffers{ static_cast(GCodeProcessor::EMoveType::Extrude) }; // bounding box of toolpaths BoundingBoxf3 m_paths_bounding_box; // bounding box of toolpaths + marker tools diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index 4bebf7b984..cb47d79618 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -35,15 +35,12 @@ std::pair GLShadersManager::init() valid &= append_shader("printbed", { "printbed.vs", "printbed.fs" }); // used to render options in gcode preview valid &= append_shader("options_110", { "options_110.vs", "options_110.fs" }); - if (GUI::wxGetApp().is_glsl_version_greater_or_equal_to(1, 20)) - { + if (GUI::wxGetApp().is_glsl_version_greater_or_equal_to(1, 20)) { valid &= append_shader("options_120_flat", { "options_120_flat.vs", "options_120_flat.fs" }); valid &= append_shader("options_120_solid", { "options_120_solid.vs", "options_120_solid.fs" }); } - // used to render extrusion paths in gcode preview - valid &= append_shader("extrusions", { "extrusions.vs", "extrusions.fs" }); - // used to render travel paths in gcode preview - valid &= append_shader("travels", { "travels.vs", "travels.fs" }); + // used to render extrusion and travel paths in gcode preview + valid &= append_shader("toolpaths", { "toolpaths.vs", "toolpaths.fs" }); // used to render objects in 3d editor valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" }); // used to render variable layers heights in 3d editor From feb4857cf8d83829b844d30b86c6eeb9170454be Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 30 Jun 2020 12:53:42 +0200 Subject: [PATCH 141/255] Fixed height of features type combo popup when building against wxWidgets 3.1.3 --- src/slic3r/GUI/wxExtensions.cpp | 12 ++++-------- src/slic3r/GUI/wxExtensions.hpp | 1 - 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 74d790df86..c42933b9b3 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -174,7 +174,6 @@ wxMenuItem* append_menu_check_item(wxMenu* menu, int id, const wxString& string, const unsigned int wxCheckListBoxComboPopup::DefaultWidth = 200; const unsigned int wxCheckListBoxComboPopup::DefaultHeight = 200; -const unsigned int wxCheckListBoxComboPopup::DefaultItemHeight = 18; bool wxCheckListBoxComboPopup::Create(wxWindow* parent) { @@ -202,20 +201,17 @@ wxSize wxCheckListBoxComboPopup::GetAdjustedSize(int minWidth, int prefHeight, i // and set height dinamically in dependence of items count wxComboCtrl* cmb = GetComboCtrl(); - if (cmb != nullptr) - { + if (cmb != nullptr) { wxSize size = GetComboCtrl()->GetSize(); unsigned int count = GetCount(); - if (count > 0) - { + if (count > 0) { int max_width = size.x; - for (unsigned int i = 0; i < count; ++i) - { + for (unsigned int i = 0; i < count; ++i) { max_width = std::max(max_width, 60 + GetTextExtent(GetString(i)).x); } size.SetWidth(max_width); - size.SetHeight(4 + count * (2 + GetTextExtent(GetString(0)).y)); + size.SetHeight(count * cmb->GetCharHeight()); } else size.SetHeight(DefaultHeight); diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 569257e1b4..254dbfad3a 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -63,7 +63,6 @@ class wxCheckListBoxComboPopup : public wxCheckListBox, public wxComboPopup { static const unsigned int DefaultWidth; static const unsigned int DefaultHeight; - static const unsigned int DefaultItemHeight; wxString m_text; From 0b1086f390bbc534f777c9e28480a6b463337be8 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 3 Jul 2020 12:17:12 +0200 Subject: [PATCH 142/255] GCodeViewer -> Export of extrude toolpaths to obj files --- src/slic3r/GUI/3DScene.cpp | 2 + src/slic3r/GUI/3DScene.hpp | 2 + src/slic3r/GUI/GCodeViewer.cpp | 287 ++++++++++++++++++++++++++++++++- src/slic3r/GUI/GCodeViewer.hpp | 5 +- src/slic3r/GUI/GLCanvas3D.cpp | 8 + src/slic3r/GUI/MainFrame.cpp | 6 +- 6 files changed, 300 insertions(+), 10 deletions(-) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index f53e4a55c2..c9c7b72f37 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -1017,6 +1017,7 @@ bool GLVolumeCollection::has_toolpaths_to_export() const return false; } +#if !ENABLE_GCODE_VIEWER void GLVolumeCollection::export_toolpaths_to_obj(const char* filename) const { if (filename == nullptr) @@ -1298,6 +1299,7 @@ void GLVolumeCollection::export_toolpaths_to_obj(const char* filename) const fclose(fp); } +#endif // !ENABLE_GCODE_VIEWER // caller is responsible for supplying NO lines with zero length static void thick_lines_to_indexed_vertex_array( diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 1b4d0fc4f2..7e8ae6fe33 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -597,8 +597,10 @@ public: std::string log_memory_info() const; bool has_toolpaths_to_export() const; +#if !ENABLE_GCODE_VIEWER // Export the geometry of the GLVolumes toolpaths of this collection into the file with the given path, in obj format void export_toolpaths_to_obj(const char* filename) const; +#endif // !ENABLE_GCODE_VIEWER private: GLVolumeCollection(const GLVolumeCollection &other); diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 6d6ba557e2..688134f7c9 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -487,6 +488,284 @@ void GCodeViewer::set_layers_z_range(const std::array& layers_z_range wxGetApp().plater()->update_preview_moves_slider(); } +void GCodeViewer::export_toolpaths_to_obj(const char* filename) const +{ + if (filename == nullptr) + return; + + if (!has_data()) + return; + + wxBusyCursor busy; + + // the data needed is contained into the Extrude TBuffer + const TBuffer& buffer = m_buffers[buffer_id(GCodeProcessor::EMoveType::Extrude)]; + if (buffer.vertices.id == 0 || buffer.indices.id == 0) + return; + + // collect color information to generate materials + std::vector colors; + for (const RenderPath& path : buffer.render_paths) { + colors.push_back(path.color); + } + + // save materials file + boost::filesystem::path mat_filename(filename); + mat_filename.replace_extension("mtl"); + FILE* fp = boost::nowide::fopen(mat_filename.string().c_str(), "w"); + if (fp == nullptr) { + BOOST_LOG_TRIVIAL(error) << "GCodeViewer::export_toolpaths_to_obj: Couldn't open " << mat_filename.string().c_str() << " for writing"; + return; + } + + fprintf(fp, "# G-Code Toolpaths Materials\n"); + fprintf(fp, "# Generated by %s based on Slic3r\n", SLIC3R_BUILD_ID); + + unsigned int colors_count = 1; + for (const Color& color : colors) + { + fprintf(fp, "\nnewmtl material_%d\n", colors_count++); + fprintf(fp, "Ka 1 1 1\n"); + fprintf(fp, "Kd %f %f %f\n", color[0], color[1], color[2]); + fprintf(fp, "Ks 0 0 0\n"); + } + + fclose(fp); + + // save geometry file + fp = boost::nowide::fopen(filename, "w"); + if (fp == nullptr) { + BOOST_LOG_TRIVIAL(error) << "GCodeViewer::export_toolpaths_to_obj: Couldn't open " << filename << " for writing"; + return; + } + + fprintf(fp, "# G-Code Toolpaths\n"); + fprintf(fp, "# Generated by %s based on Slic3r\n", SLIC3R_BUILD_ID); + fprintf(fp, "\nmtllib ./%s\n", mat_filename.filename().string().c_str()); + + // get vertices data from vertex buffer on gpu + size_t floats_per_vertex = buffer.vertices.vertex_size_floats(); + std::vector vertices = std::vector(buffer.vertices.count * floats_per_vertex); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.vertices.id)); + glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, 0, buffer.vertices.data_size_bytes(), vertices.data())); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + + auto get_vertex = [&vertices, floats_per_vertex](size_t id) { + // extract vertex from vector of floats + size_t base_id = id * floats_per_vertex; + return Vec3f(vertices[base_id + 0], vertices[base_id + 1], vertices[base_id + 2]); + }; + + struct Segment + { + Vec3f v1; + Vec3f v2; + Vec3f dir; + Vec3f right; + Vec3f up; + Vec3f rl_displacement; + Vec3f tb_displacement; + float length; + }; + + auto generate_segment = [get_vertex](size_t start_id, float half_width, float half_height) { + auto local_basis = [](const Vec3f& dir) { + // calculate local basis (dir, right, up) on given segment + std::array ret; + ret[0] = dir.normalized(); + if (std::abs(ret[0][2]) < EPSILON) { + // segment parallel to XY plane + ret[1] = { ret[0][1], -ret[0][0], 0.0f }; + ret[2] = Vec3f::UnitZ(); + } + else if (std::abs(std::abs(ret[0].dot(Vec3f::UnitZ())) - 1.0f) < EPSILON) { + // segment parallel to Z axis + ret[1] = Vec3f::UnitX(); + ret[2] = Vec3f::UnitY(); + } + else { + ret[0] = dir.normalized(); + ret[1] = ret[0].cross(Vec3f::UnitZ()).normalized(); + ret[2] = ret[1].cross(ret[0]); + } + return ret; + }; + + Vec3f v1 = get_vertex(start_id); + Vec3f v2 = get_vertex(start_id + 1); + float length = (v2 - v1).norm(); + const auto&& [dir, right, up] = local_basis(v2 - v1); + return Segment({ v1, v2, dir, right, up, half_width * right, half_height * up, length }); + }; + + size_t out_vertices_count = 0; + + for (size_t i = 0; i < buffer.render_paths.size(); ++i) { + // get paths segments from buffer paths + const RenderPath& render_path = buffer.render_paths[i]; + const Path& path = buffer.paths[render_path.path_id]; + float half_width = 0.5f * path.width; + float half_height = 0.5f * path.height; + + // generates vertices/normals/triangles + std::vector out_vertices; + std::vector out_normals; + using Triangle = std::array; + std::vector out_triangles; + for (size_t j = 0; j < render_path.offsets.size(); ++j) { + unsigned int start = static_cast(render_path.offsets[j] / sizeof(unsigned int)); + unsigned int end = start + render_path.sizes[j]; + + for (size_t k = start; k < end; k += 2) { + Segment curr = generate_segment(k, half_width, half_height); + + if (k == start) { + // starting endpoint vertices/normals + out_vertices.push_back(curr.v1 + curr.rl_displacement); out_normals.push_back(curr.right); // right + out_vertices.push_back(curr.v1 + curr.tb_displacement); out_normals.push_back(curr.up); // top + out_vertices.push_back(curr.v1 - curr.rl_displacement); out_normals.push_back(-curr.right); // left + out_vertices.push_back(curr.v1 - curr.tb_displacement); out_normals.push_back(-curr.up); // bottom + out_vertices_count += 4; + + // starting cap triangles + size_t base_id = out_vertices_count - 4 + 1; + out_triangles.push_back({ base_id + 0, base_id + 1, base_id + 2 }); + out_triangles.push_back({ base_id + 0, base_id + 2, base_id + 3 }); + } + else { + // for the endpoint shared by the current and the previous segments + // we keep the top and bottom vertices of the previous vertices + // and add new left/right vertices for the current segment + out_vertices.push_back(curr.v1 + curr.rl_displacement); out_normals.push_back(curr.right); // right + out_vertices.push_back(curr.v1 - curr.rl_displacement); out_normals.push_back(-curr.right); // left + out_vertices_count += 2; + + Segment prev = generate_segment(k - 2, half_width, half_height); + Vec3f med_dir = (prev.dir + curr.dir).normalized(); + float disp = half_width * ::tan(::acos(std::clamp(curr.dir.dot(med_dir), -1.0f, 1.0f))); + Vec3f disp_vec = disp * prev.dir; + + bool is_right_turn = prev.up.dot(prev.dir.cross(curr.dir)) <= 0.0f; + if (prev.dir.dot(curr.dir) < 0.7071068f) { + // if the angle between two consecutive segments is greater than 45 degrees + // we add a cap in the outside corner + // and displace the vertices in the inside corner to the same position, if possible + if (is_right_turn) { + // corner cap triangles (left) + size_t base_id = out_vertices_count - 6 + 1; + out_triangles.push_back({ base_id + 5, base_id + 2, base_id + 1 }); + out_triangles.push_back({ base_id + 5, base_id + 3, base_id + 2 }); + + // update right vertices + if (disp < prev.length) { + base_id = out_vertices.size() - 6; + out_vertices[base_id + 0] -= disp_vec; + out_vertices[base_id + 4] = out_vertices[base_id + 0]; + } + } + else { + // corner cap triangles (right) + size_t base_id = out_vertices_count - 6 + 1; + out_triangles.push_back({ base_id + 0, base_id + 4, base_id + 1 }); + out_triangles.push_back({ base_id + 0, base_id + 3, base_id + 4 }); + + // update left vertices + if (disp < prev.length) { + base_id = out_vertices.size() - 6; + out_vertices[base_id + 2] -= disp_vec; + out_vertices[base_id + 5] = out_vertices[base_id + 2]; + } + } + } + else { + // if the angle between two consecutive segments is lesser than 45 degrees + // displace the vertices to the same position + if (is_right_turn) { + size_t base_id = out_vertices.size() - 6; + // right + out_vertices[base_id + 0] -= disp_vec; + out_vertices[base_id + 4] = out_vertices[base_id + 0]; + // left + out_vertices[base_id + 2] += disp_vec; + out_vertices[base_id + 5] = out_vertices[base_id + 2]; + } + else { + size_t base_id = out_vertices.size() - 6; + // right + out_vertices[base_id + 0] += disp_vec; + out_vertices[base_id + 4] = out_vertices[base_id + 0]; + // left + out_vertices[base_id + 2] -= disp_vec; + out_vertices[base_id + 5] = out_vertices[base_id + 2]; + } + } + } + + // current second endpoint vertices/normals + out_vertices.push_back(curr.v2 + curr.rl_displacement); out_normals.push_back(curr.right); // right + out_vertices.push_back(curr.v2 + curr.tb_displacement); out_normals.push_back(curr.up); // top + out_vertices.push_back(curr.v2 - curr.rl_displacement); out_normals.push_back(-curr.right); // left + out_vertices.push_back(curr.v2 - curr.tb_displacement); out_normals.push_back(-curr.up); // bottom + out_vertices_count += 4; + + // sides triangles + if (k == start) { + size_t base_id = out_vertices_count - 8 + 1; + out_triangles.push_back({ base_id + 0, base_id + 4, base_id + 5 }); + out_triangles.push_back({ base_id + 0, base_id + 5, base_id + 1 }); + out_triangles.push_back({ base_id + 1, base_id + 5, base_id + 6 }); + out_triangles.push_back({ base_id + 1, base_id + 6, base_id + 2 }); + out_triangles.push_back({ base_id + 2, base_id + 6, base_id + 7 }); + out_triangles.push_back({ base_id + 2, base_id + 7, base_id + 3 }); + out_triangles.push_back({ base_id + 3, base_id + 7, base_id + 4 }); + out_triangles.push_back({ base_id + 3, base_id + 4, base_id + 0 }); + } + else { + size_t base_id = out_vertices_count - 10 + 1; + out_triangles.push_back({ base_id + 4, base_id + 6, base_id + 7 }); + out_triangles.push_back({ base_id + 4, base_id + 7, base_id + 1 }); + out_triangles.push_back({ base_id + 1, base_id + 7, base_id + 8 }); + out_triangles.push_back({ base_id + 1, base_id + 8, base_id + 5 }); + out_triangles.push_back({ base_id + 5, base_id + 8, base_id + 9 }); + out_triangles.push_back({ base_id + 5, base_id + 9, base_id + 3 }); + out_triangles.push_back({ base_id + 3, base_id + 9, base_id + 6 }); + out_triangles.push_back({ base_id + 3, base_id + 6, base_id + 4 }); + } + + if (k + 2 == end) { + // ending cap triangles + size_t base_id = out_vertices_count - 4 + 1; + out_triangles.push_back({ base_id + 0, base_id + 2, base_id + 1 }); + out_triangles.push_back({ base_id + 0, base_id + 3, base_id + 2 }); + } + } + } + + // save to file + fprintf(fp, "\n# vertices path %lld\n", i + 1); + for (const Vec3f& v : out_vertices) { + fprintf(fp, "v %g %g %g\n", v[0], v[1], v[2]); + } + + fprintf(fp, "\n# normals path %lld\n", i + 1); + for (const Vec3f& n : out_normals) { + fprintf(fp, "vn %g %g %g\n", n[0], n[1], n[2]); + } + + fprintf(fp, "\n# material path %lld\n", i + 1); + fprintf(fp, "usemtl material_%lld\n", i + 1); + + fprintf(fp, "\n# triangles path %lld\n", i + 1); + for (const Triangle& t : out_triangles) { + fprintf(fp, "f %lld//%lld %lld//%lld %lld//%lld\n", t[0], t[0], t[1], t[1], t[2], t[2]); + } + + } + +// fprintf(fp, "\n#vertices count %lld\n", out_vertices_count); + fclose(fp); +} + void GCodeViewer::init_shaders() { unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); @@ -641,7 +920,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) const std::vector& buffer_indices = indices[i]; buffer.indices.count = buffer_indices.size(); #if ENABLE_GCODE_VIEWER_STATISTICS - m_statistics.indices_size += SLIC3R_STDVEC_MEMSIZE(buffer_indices, unsigned int); m_statistics.indices_gpu_size += buffer.indices.count * sizeof(unsigned int); #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -876,6 +1154,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool if (it == buffer->render_paths.end()) { it = buffer->render_paths.insert(buffer->render_paths.end(), RenderPath()); it->color = color; + it->path_id = id; } unsigned int size = std::min(m_sequential_view.current.last, path.last.s_id) - std::max(m_sequential_view.current.first, path.first.s_id) + 1; @@ -1482,12 +1761,6 @@ void GCodeViewer::render_statistics() const ImGui::Separator(); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); - imgui.text(std::string("Indices CPU:")); - ImGui::PopStyleColor(); - ImGui::SameLine(offset); - imgui.text(std::to_string(m_statistics.indices_size) + " bytes"); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); imgui.text(std::string("Paths CPU:")); ImGui::PopStyleColor(); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 5cddeaa75a..137ae89af7 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -108,6 +108,7 @@ class GCodeViewer struct RenderPath { Color color; + size_t path_id; std::vector sizes; std::vector offsets; // use size_t because we need the pointer's size (used in the call glMultiDrawElements()) }; @@ -201,7 +202,6 @@ class GCodeViewer // memory long long results_size{ 0 }; long long vertices_gpu_size{ 0 }; - long long indices_size{ 0 }; long long indices_gpu_size{ 0 }; long long paths_size{ 0 }; long long render_paths_size{ 0 }; @@ -231,7 +231,6 @@ class GCodeViewer void reset_sizes() { results_size = 0; vertices_gpu_size = 0; - indices_size = 0; indices_gpu_size = 0; paths_size = 0; render_paths_size = 0; @@ -397,6 +396,8 @@ public: bool is_legend_enabled() const { return m_legend_enabled; } void enable_legend(bool enable) { m_legend_enabled = enable; } + void export_toolpaths_to_obj(const char* filename) const; + private: void init_shaders(); void load_toolpaths(const GCodeProcessor::Result& gcode_result); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 0ee30a8084..f8ff9406f3 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4349,12 +4349,20 @@ void GLCanvas3D::update_tooltip_for_settings_item_in_main_toolbar() bool GLCanvas3D::has_toolpaths_to_export() const { +#if ENABLE_GCODE_VIEWER + return m_gcode_viewer.has_data(); +#else return m_volumes.has_toolpaths_to_export(); +#endif // ENABLE_GCODE_VIEWER } void GLCanvas3D::export_toolpaths_to_obj(const char* filename) const { +#if ENABLE_GCODE_VIEWER + m_gcode_viewer.export_toolpaths_to_obj(filename); +#else m_volumes.export_toolpaths_to_obj(filename); +#endif // ENABLE_GCODE_VIEWER } void GLCanvas3D::mouse_up_cleanup() diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 5e26979c3c..9c98f0f2e5 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -1373,9 +1373,13 @@ void MainFrame::init_gcodeviewer_menubar() wxMenu* fileMenu = new wxMenu; { append_menu_item(fileMenu, wxID_ANY, _L("&Open G-code") + dots + "\tCtrl+O", _L("Open a G-code file"), - [this](wxCommandEvent&) { if (m_plater) m_plater->load_gcode(); }, "open", nullptr, + [this](wxCommandEvent&) { if (m_plater != nullptr) m_plater->load_gcode(); }, "open", nullptr, [this]() {return m_plater != nullptr; }, this); fileMenu->AppendSeparator(); + append_menu_item(fileMenu, wxID_ANY, _L("Export &toolpaths as OBJ") + dots, _L("Export toolpaths as OBJ"), + [this](wxCommandEvent&) { if (m_plater != nullptr) m_plater->export_toolpaths_to_obj(); }, "export_plater", nullptr, + [this]() {return can_export_toolpaths(); }, this); + fileMenu->AppendSeparator(); append_menu_item(fileMenu, wxID_ANY, _L("Exit &G-code preview"), _L("Switch to editor mode"), [this](wxCommandEvent&) { set_mode(EMode::Editor); }); fileMenu->AppendSeparator(); From 2a78799f7e0dbdd2d381dbb4482b318264d7f81b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 3 Jul 2020 13:04:52 +0200 Subject: [PATCH 143/255] GCodeViewer -> Fixed layout when switching to/from gcode viewer state --- src/slic3r/GUI/MainFrame.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 9c98f0f2e5..eba169dc96 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -389,7 +389,7 @@ void MainFrame::update_layout() #if ENABLE_GCODE_VIEWER_AS_STATE case ESettingsLayout::GCodeViewer: { - GetSizer()->Add(m_plater, 1, wxEXPAND); + m_main_sizer->Add(m_plater, 1, wxEXPAND); m_plater->Show(); break; } From 73b885fc3711e82ae4c2fabf2464a06714dda435 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 8 Jul 2020 13:33:50 +0200 Subject: [PATCH 144/255] GCodeViewer -> Added imgui dialog for estimated printing times --- src/libslic3r/GCode.cpp | 17 +- src/libslic3r/GCodeTimeEstimator.cpp | 33 ++ src/libslic3r/GCodeTimeEstimator.hpp | 8 + src/libslic3r/Print.hpp | 14 + src/libslic3r/Technologies.hpp | 4 +- src/slic3r/GUI/GCodeViewer.cpp | 379 +++++++++++++------ src/slic3r/GUI/GCodeViewer.hpp | 7 +- src/slic3r/GUI/GLCanvas3D.cpp | 68 ++-- src/slic3r/GUI/GLShadersManager.cpp | 2 +- src/slic3r/GUI/GUI_Preview.cpp | 5 +- src/slic3r/GUI/GUI_Preview.hpp | 3 +- src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp | 3 +- src/slic3r/GUI/ImGuiWrapper.cpp | 36 +- src/slic3r/GUI/ImGuiWrapper.hpp | 7 + src/slic3r/GUI/KBShortcutsDialog.cpp | 5 +- src/slic3r/GUI/MainFrame.cpp | 4 + src/slic3r/GUI/Plater.cpp | 26 +- 17 files changed, 438 insertions(+), 183 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 8de64544c8..7bfb73aa37 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1050,10 +1050,19 @@ namespace DoExport { print_statistics.clear(); print_statistics.estimated_normal_print_time = normal_time_estimator.get_time_dhm/*s*/(); print_statistics.estimated_silent_print_time = silent_time_estimator_enabled ? silent_time_estimator.get_time_dhm/*s*/() : "N/A"; - print_statistics.estimated_normal_custom_gcode_print_times = normal_time_estimator.get_custom_gcode_times_dhm(true); - if (silent_time_estimator_enabled) - print_statistics.estimated_silent_custom_gcode_print_times = silent_time_estimator.get_custom_gcode_times_dhm(true); - print_statistics.total_toolchanges = std::max(0, wipe_tower_data.number_of_toolchanges); +#if ENABLE_GCODE_VIEWER + print_statistics.estimated_normal_custom_gcode_print_times_str = normal_time_estimator.get_custom_gcode_times_dhm(true); + print_statistics.estimated_normal_custom_gcode_print_times = normal_time_estimator.get_custom_gcode_times(true); + if (silent_time_estimator_enabled) { + print_statistics.estimated_silent_custom_gcode_print_times_str = silent_time_estimator.get_custom_gcode_times_dhm(true); + print_statistics.estimated_silent_custom_gcode_print_times = silent_time_estimator.get_custom_gcode_times(true); + } +#else + print_statistics.estimated_normal_custom_gcode_print_times = normal_time_estimator.get_custom_gcode_times_dhm(true); + if (silent_time_estimator_enabled) + print_statistics.estimated_silent_custom_gcode_print_times = silent_time_estimator.get_custom_gcode_times_dhm(true); +#endif // ENABLE_GCODE_VIEWER + print_statistics.total_toolchanges = std::max(0, wipe_tower_data.number_of_toolchanges); if (! extruders.empty()) { std::pair out_filament_used_mm ("; filament used [mm] = ", 0); std::pair out_filament_used_cm3("; filament used [cm3] = ", 0); diff --git a/src/libslic3r/GCodeTimeEstimator.cpp b/src/libslic3r/GCodeTimeEstimator.cpp index 9e8137ef0e..d67db84819 100644 --- a/src/libslic3r/GCodeTimeEstimator.cpp +++ b/src/libslic3r/GCodeTimeEstimator.cpp @@ -678,6 +678,21 @@ namespace Slic3r { return _get_time_minutes(get_time()); } +#if ENABLE_GCODE_VIEWER + std::vector>> GCodeTimeEstimator::get_custom_gcode_times(bool include_remaining) const + { + std::vector>> ret; + + float total_time = 0.0f; + for (const auto& [type, time] : m_custom_gcode_times) { + float remaining = include_remaining ? m_time - total_time : 0.0f; + ret.push_back({ type, { time, remaining } }); + total_time += time; + } + + return ret; + } +#else std::vector> GCodeTimeEstimator::get_custom_gcode_times() const { return m_custom_gcode_times; @@ -721,7 +736,24 @@ namespace Slic3r { } return ret; } +#endif // ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER + std::vector>> GCodeTimeEstimator::get_custom_gcode_times_dhm(bool include_remaining) const + { + std::vector>> ret; + + float total_time = 0.0f; + for (const auto& [type, time] : m_custom_gcode_times) { + std::string duration = _get_time_dhm(time); + std::string remaining = include_remaining ? _get_time_dhm(m_time - total_time) : ""; + ret.push_back({ type, { duration, remaining } }); + total_time += time; + } + + return ret; + } +#else std::vector> GCodeTimeEstimator::get_custom_gcode_times_dhm(bool include_remaining) const { std::vector> ret; @@ -742,6 +774,7 @@ namespace Slic3r { return ret; } +#endif // ENABLE_GCODE_VIEWER // Return an estimate of the memory consumed by the time estimator. size_t GCodeTimeEstimator::memory_used() const diff --git a/src/libslic3r/GCodeTimeEstimator.hpp b/src/libslic3r/GCodeTimeEstimator.hpp index 63e11c4faa..cfa12b40be 100644 --- a/src/libslic3r/GCodeTimeEstimator.hpp +++ b/src/libslic3r/GCodeTimeEstimator.hpp @@ -358,6 +358,9 @@ namespace Slic3r { std::string get_time_minutes() const; // Returns the estimated time, in seconds, for each custom gcode +#if ENABLE_GCODE_VIEWER + std::vector>> get_custom_gcode_times(bool include_remaining) const; +#else std::vector> get_custom_gcode_times() const; // Returns the estimated time, in format DDd HHh MMm SSs, for each color @@ -367,10 +370,15 @@ namespace Slic3r { // Returns the estimated time, in minutes (integer), for each color // If include_remaining==true the strings will be formatted as: "time for color (remaining time at color start)" std::vector get_color_times_minutes(bool include_remaining) const; +#endif // ENABLE_GCODE_VIEWER // Returns the estimated time, in format DDd HHh MMm, for each custom_gcode // If include_remaining==true the strings will be formatted as: "time for custom_gcode (remaining time at color start)" +#if ENABLE_GCODE_VIEWER + std::vector>> get_custom_gcode_times_dhm(bool include_remaining) const; +#else std::vector> get_custom_gcode_times_dhm(bool include_remaining) const; +#endif // ENABLE_GCODE_VIEWER // Return an estimate of the memory consumed by the time estimator. size_t memory_used() const; diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index e4f4c60f57..eb9a4fb4b7 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -305,8 +305,15 @@ struct PrintStatistics PrintStatistics() { clear(); } std::string estimated_normal_print_time; std::string estimated_silent_print_time; +#if ENABLE_GCODE_VIEWER + std::vector>> estimated_normal_custom_gcode_print_times; + std::vector>> estimated_silent_custom_gcode_print_times; + std::vector>> estimated_normal_custom_gcode_print_times_str; + std::vector>> estimated_silent_custom_gcode_print_times_str; +#else std::vector> estimated_normal_custom_gcode_print_times; std::vector> estimated_silent_custom_gcode_print_times; +#endif // ENABLE_GCODE_VIEWER double total_used_filament; double total_extruded_volume; double total_cost; @@ -326,8 +333,15 @@ struct PrintStatistics void clear() { estimated_normal_print_time.clear(); estimated_silent_print_time.clear(); +#if ENABLE_GCODE_VIEWER + estimated_normal_custom_gcode_print_times_str.clear(); + estimated_silent_custom_gcode_print_times_str.clear(); estimated_normal_custom_gcode_print_times.clear(); estimated_silent_custom_gcode_print_times.clear(); +#else + estimated_normal_custom_gcode_print_times.clear(); + estimated_silent_custom_gcode_print_times.clear(); +#endif //ENABLE_GCODE_VIEWER total_used_filament = 0.; total_extruded_volume = 0.; total_cost = 0.; diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index fb84efe5ab..b04e78c4ed 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -59,8 +59,8 @@ // Enable G-Code viewer #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) -#define ENABLE_GCODE_VIEWER_STATISTICS (1 && ENABLE_GCODE_VIEWER) -#define ENABLE_GCODE_VIEWER_SHADERS_EDITOR (1 && ENABLE_GCODE_VIEWER) +#define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) +#define ENABLE_GCODE_VIEWER_SHADERS_EDITOR (0 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_AS_STATE (1 && ENABLE_GCODE_VIEWER) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 688134f7c9..26dc765db4 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -4,6 +4,8 @@ #if ENABLE_GCODE_VIEWER #include "libslic3r/Print.hpp" #include "libslic3r/Geometry.hpp" +#include "libslic3r/Model.hpp" +#include "libslic3r/Utils.hpp" #include "GUI_App.hpp" #if ENABLE_GCODE_VIEWER_AS_STATE #include "MainFrame.hpp" @@ -17,10 +19,7 @@ #include "GLCanvas3D.hpp" #include "GLToolbar.hpp" #include "GUI_Preview.hpp" -#include "libslic3r/Model.hpp" -#if ENABLE_GCODE_VIEWER_STATISTICS #include -#endif // ENABLE_GCODE_VIEWER_STATISTICS #include #include @@ -187,15 +186,14 @@ void GCodeViewer::SequentialView::Marker::render() const static float last_window_width = 0.0f; static size_t last_text_length = 0; - static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); ImGuiWrapper& imgui = *wxGetApp().imgui(); Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size(); - imgui.set_next_window_pos(static_cast(cnv_size.get_width()), static_cast(cnv_size.get_height()), ImGuiCond_Always, 1.0f, 1.0f); + imgui.set_next_window_pos(0.5f * static_cast(cnv_size.get_width()), static_cast(cnv_size.get_height()), ImGuiCond_Always, 0.5f, 1.0f); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGui::SetNextWindowBgAlpha(0.25f); imgui.begin(std::string("ToolPosition"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); imgui.text(_u8L("Tool position") + ":"); ImGui::PopStyleColor(); ImGui::SameLine(); @@ -270,6 +268,7 @@ bool GCodeViewer::init() { switch (buffer_type(i)) { + default: { break; } case GCodeProcessor::EMoveType::Tool_change: case GCodeProcessor::EMoveType::Color_change: case GCodeProcessor::EMoveType::Pause_Print: @@ -420,6 +419,7 @@ void GCodeViewer::render() const m_sequential_view.marker.render(); render_shells(); render_legend(); + render_time_estimate(); #if ENABLE_GCODE_VIEWER_STATISTICS render_statistics(); #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -458,6 +458,7 @@ unsigned int GCodeViewer::get_options_visibility_flags() const flags = set_flag(flags, static_cast(Preview::OptionType::Shells), m_shells.visible); flags = set_flag(flags, static_cast(Preview::OptionType::ToolMarker), m_sequential_view.marker.is_visible()); flags = set_flag(flags, static_cast(Preview::OptionType::Legend), is_legend_enabled()); + flags = set_flag(flags, static_cast(Preview::OptionType::TimeEstimate), is_time_estimate_enabled()); return flags; } @@ -477,6 +478,7 @@ void GCodeViewer::set_options_visibility_from_flags(unsigned int flags) m_shells.visible = is_flag_set(static_cast(Preview::OptionType::Shells)); m_sequential_view.marker.set_visible(is_flag_set(static_cast(Preview::OptionType::ToolMarker))); enable_legend(is_flag_set(static_cast(Preview::OptionType::Legend))); + enable_time_estimate(is_flag_set(static_cast(Preview::OptionType::TimeEstimate))); } void GCodeViewer::set_layers_z_range(const std::array& layers_z_range) @@ -591,8 +593,8 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const return ret; }; - Vec3f v1 = get_vertex(start_id); - Vec3f v2 = get_vertex(start_id + 1); + Vec3f v1 = get_vertex(start_id) - half_height * Vec3f::UnitZ(); + Vec3f v2 = get_vertex(start_id + 1) - half_height * Vec3f::UnitZ(); float length = (v2 - v1).norm(); const auto&& [dir, right, up] = local_basis(v2 - v1); return Segment({ v1, v2, dir, right, up, half_width * right, half_height * up, length }); @@ -605,7 +607,8 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const const RenderPath& render_path = buffer.render_paths[i]; const Path& path = buffer.paths[render_path.path_id]; float half_width = 0.5f * path.width; - float half_height = 0.5f * path.height; + // clamp height to avoid artifacts due to z-fighting when importing the obj file into blender and similar + float half_height = std::max(0.5f * path.height, 0.005f); // generates vertices/normals/triangles std::vector out_vertices; @@ -657,7 +660,7 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const out_triangles.push_back({ base_id + 5, base_id + 3, base_id + 2 }); // update right vertices - if (disp < prev.length) { + if (disp < prev.length && disp < curr.length) { base_id = out_vertices.size() - 6; out_vertices[base_id + 0] -= disp_vec; out_vertices[base_id + 4] = out_vertices[base_id + 0]; @@ -670,7 +673,7 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const out_triangles.push_back({ base_id + 0, base_id + 3, base_id + 4 }); // update left vertices - if (disp < prev.length) { + if (disp < prev.length && disp < curr.length) { base_id = out_vertices.size() - 6; out_vertices[base_id + 2] -= disp_vec; out_vertices[base_id + 5] = out_vertices[base_id + 2]; @@ -742,27 +745,25 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const } // save to file - fprintf(fp, "\n# vertices path %lld\n", i + 1); + fprintf(fp, "\n# vertices path %zu\n", i + 1); for (const Vec3f& v : out_vertices) { fprintf(fp, "v %g %g %g\n", v[0], v[1], v[2]); } - fprintf(fp, "\n# normals path %lld\n", i + 1); + fprintf(fp, "\n# normals path %zu\n", i + 1); for (const Vec3f& n : out_normals) { fprintf(fp, "vn %g %g %g\n", n[0], n[1], n[2]); } - fprintf(fp, "\n# material path %lld\n", i + 1); - fprintf(fp, "usemtl material_%lld\n", i + 1); + fprintf(fp, "\n# material path %zu\n", i + 1); + fprintf(fp, "usemtl material_%zu\n", i + 1); - fprintf(fp, "\n# triangles path %lld\n", i + 1); + fprintf(fp, "\n# triangles path %zu\n", i + 1); for (const Triangle& t : out_triangles) { - fprintf(fp, "f %lld//%lld %lld//%lld %lld//%lld\n", t[0], t[0], t[1], t[1], t[2], t[2]); + fprintf(fp, "f %zu//%zu %zu//%zu %zu//%zu\n", t[0], t[0], t[1], t[1], t[2], t[2]); } - } -// fprintf(fp, "\n#vertices count %lld\n", out_vertices_count); fclose(fp); } @@ -775,12 +776,12 @@ void GCodeViewer::init_shaders() for (unsigned char i = begin_id; i < end_id; ++i) { switch (buffer_type(i)) { - case GCodeProcessor::EMoveType::Tool_change: { m_buffers[i].shader = is_glsl_120 ? "options_120_solid" : "options_110"; break; } - case GCodeProcessor::EMoveType::Color_change: { m_buffers[i].shader = is_glsl_120 ? "options_120_solid" : "options_110"; break; } - case GCodeProcessor::EMoveType::Pause_Print: { m_buffers[i].shader = is_glsl_120 ? "options_120_solid" : "options_110"; break; } - case GCodeProcessor::EMoveType::Custom_GCode: { m_buffers[i].shader = is_glsl_120 ? "options_120_solid" : "options_110"; break; } - case GCodeProcessor::EMoveType::Retract: { m_buffers[i].shader = is_glsl_120 ? "options_120_solid" : "options_110"; break; } - case GCodeProcessor::EMoveType::Unretract: { m_buffers[i].shader = is_glsl_120 ? "options_120_solid" : "options_110"; break; } + case GCodeProcessor::EMoveType::Tool_change: { m_buffers[i].shader = is_glsl_120 ? "options_120_flat" : "options_110"; break; } + case GCodeProcessor::EMoveType::Color_change: { m_buffers[i].shader = is_glsl_120 ? "options_120_flat" : "options_110"; break; } + case GCodeProcessor::EMoveType::Pause_Print: { m_buffers[i].shader = is_glsl_120 ? "options_120_flat" : "options_110"; break; } + case GCodeProcessor::EMoveType::Custom_GCode: { m_buffers[i].shader = is_glsl_120 ? "options_120_flat" : "options_110"; break; } + case GCodeProcessor::EMoveType::Retract: { m_buffers[i].shader = is_glsl_120 ? "options_120_flat" : "options_110"; break; } + case GCodeProcessor::EMoveType::Unretract: { m_buffers[i].shader = is_glsl_120 ? "options_120_flat" : "options_110"; break; } case GCodeProcessor::EMoveType::Extrude: { m_buffers[i].shader = "toolpaths"; break; } case GCodeProcessor::EMoveType::Travel: { m_buffers[i].shader = "toolpaths"; break; } default: { break; } @@ -1137,7 +1138,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool } // second pass: filter paths by sequential data and collect them by color - for (auto&& [buffer, id] : paths) { + for (const auto& [buffer, id] : paths) { const Path& path = buffer->paths[id]; if (m_sequential_view.current.last <= path.first.s_id || path.last.s_id <= m_sequential_view.current.first) continue; @@ -1203,8 +1204,8 @@ void GCodeViewer::render_toolpaths() const shader.set_uniform("percent_outline_radius", 0.01f * static_cast(m_shaders_editor.points.percent_outline)); shader.set_uniform("percent_center_radius", 0.01f * static_cast(m_shaders_editor.points.percent_center)); #else - shader.set_uniform("percent_outline_radius", 0.15f); - shader.set_uniform("percent_center_radius", 0.15f); + shader.set_uniform("percent_outline_radius", 0.0f); + shader.set_uniform("percent_center_radius", 0.33f); #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR shader.set_uniform("viewport", viewport); shader.set_uniform("inv_proj_matrix", inv_proj); @@ -1266,6 +1267,7 @@ void GCodeViewer::render_toolpaths() const switch (buffer_type(i)) { + default: { break; } case GCodeProcessor::EMoveType::Tool_change: { render_as_points(buffer, EOptionsColors::ToolChanges, *shader); break; } case GCodeProcessor::EMoveType::Color_change: { render_as_points(buffer, EOptionsColors::ColorChanges, *shader); break; } case GCodeProcessor::EMoveType::Pause_Print: { render_as_points(buffer, EOptionsColors::PausePrints, *shader); break; } @@ -1320,18 +1322,15 @@ void GCodeViewer::render_shells() const // glsafe(::glDepthMask(GL_TRUE)); } +#define USE_ICON_HEXAGON 1 + void GCodeViewer::render_legend() const { - static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); - static const ImU32 ICON_BORDER_COLOR = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); - if (!m_legend_enabled) return; ImGuiWrapper& imgui = *wxGetApp().imgui(); -#define USE_ICON_HEXAGON 1 - imgui.set_next_window_pos(0.0f, 0.0f, ImGuiCond_Always); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGui::SetNextWindowBgAlpha(0.6f); @@ -1347,19 +1346,14 @@ void GCodeViewer::render_legend() const Line }; -#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR auto add_item = [this, draw_list, &imgui](EItemType type, const Color& color, const std::string& label, std::function callback = nullptr) { -#else - auto add_item = [draw_list, &imgui](EItemType type, const Color& color, const std::string& label, std::function callback = nullptr) { -#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR float icon_size = ImGui::GetTextLineHeight(); - ImVec2 pos = ImGui::GetCursorPos(); + ImVec2 pos = ImGui::GetCursorScreenPos(); switch (type) { default: case EItemType::Rect: { - draw_list->AddRect({ pos.x, pos.y }, { pos.x + icon_size, pos.y + icon_size }, ICON_BORDER_COLOR, 0.0f, 0); draw_list->AddRectFilled({ pos.x + 1.0f, pos.y + 1.0f }, { pos.x + icon_size - 1.0f, pos.y + icon_size - 1.0f }, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f })); break; @@ -1380,37 +1374,26 @@ void GCodeViewer::render_legend() const } else draw_list->AddCircleFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); - -// ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size)); -// draw_list->AddCircle(center, 0.5f * icon_size, ICON_BORDER_COLOR, 16); -// if (m_shaders_editor.shader_version == 1) { -// draw_list->AddCircleFilled(center, (0.5f * icon_size) - 2.0f, -// ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); -// float radius = ((0.5f * icon_size) - 2.0f) * (1.0f - 0.01f * static_cast(m_shaders_editor.percent_outline)); -// draw_list->AddCircleFilled(center, radius, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); -// if (m_shaders_editor.percent_center > 0) { -// radius = ((0.5f * icon_size) - 2.0f) * 0.01f * static_cast(m_shaders_editor.percent_center); -// draw_list->AddCircleFilled(center, radius, ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); -// } -// } else -// draw_list->AddCircleFilled(center, (0.5f * icon_size) - 2.0f, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); #else - draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, 0.5f * icon_size, - ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); - -// draw_list->AddCircle({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, 0.5f * icon_size, ICON_BORDER_COLOR, 16); -// draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, (0.5f * icon_size) - 2.0f, -// ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); + ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size)); + if (m_buffers[buffer_id(GCodeProcessor::EMoveType::Retract)].shader == "options_120_flat") { + draw_list->AddCircleFilled(center, 0.5f * icon_size, + ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); + float radius = 0.5f * icon_size; + draw_list->AddCircleFilled(center, radius, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); + radius = 0.5f * icon_size * 0.01f * 33.0f; + draw_list->AddCircleFilled(center, radius, ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); + } + else + draw_list->AddCircleFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR + break; } case EItemType::Hexagon: { ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size)); draw_list->AddNgonFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 6); -// draw_list->AddNgon(center, 0.5f * icon_size, ICON_BORDER_COLOR, 6); -// draw_list->AddNgonFilled(center, (0.5f * icon_size) - 2.0f, -// ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 6); break; } case EItemType::Line: @@ -1454,21 +1437,18 @@ void GCodeViewer::render_legend() const }; // extrusion paths -> title - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); switch (m_view_type) { - case EViewType::FeatureType: { imgui.text(_u8L("Feature type")); break; } - case EViewType::Height: { imgui.text(_u8L("Height (mm)")); break; } - case EViewType::Width: { imgui.text(_u8L("Width (mm)")); break; } - case EViewType::Feedrate: { imgui.text(_u8L("Speed (mm/s)")); break; } - case EViewType::FanSpeed: { imgui.text(_u8L("Fan Speed (%%)")); break; } - case EViewType::VolumetricRate: { imgui.text(_u8L("Volumetric flow rate (mm³/s)")); break; } - case EViewType::Tool: { imgui.text(_u8L("Tool")); break; } - case EViewType::ColorPrint: { imgui.text(_u8L("Color Print")); break; } - default: { break; } + case EViewType::FeatureType: { imgui.title(_u8L("Feature type")); break; } + case EViewType::Height: { imgui.title(_u8L("Height (mm)")); break; } + case EViewType::Width: { imgui.title(_u8L("Width (mm)")); break; } + case EViewType::Feedrate: { imgui.title(_u8L("Speed (mm/s)")); break; } + case EViewType::FanSpeed: { imgui.title(_u8L("Fan Speed (%%)")); break; } + case EViewType::VolumetricRate: { imgui.title(_u8L("Volumetric flow rate (mm³/s)")); break; } + case EViewType::Tool: { imgui.title(_u8L("Tool")); break; } + case EViewType::ColorPrint: { imgui.title(_u8L("Color Print")); break; } + default: { break; } } - ImGui::PopStyleColor(); - ImGui::Separator(); // extrusion paths -> items switch (m_view_type) @@ -1566,28 +1546,26 @@ void GCodeViewer::render_legend() const else { for (int i = items_cnt; i >= 0; --i) { // create label for color change item - std::string id_str = " (" + std::to_string(i + 1) + ")"; - if (i == 0) { #if USE_ICON_HEXAGON - add_item(EItemType::Hexagon, m_tool_colors[i], (boost::format(_u8L("up to %.2f mm")) % cp_values.front().first).str() + id_str); + add_item(EItemType::Hexagon, m_tool_colors[i], (boost::format(_u8L("up to %.2f mm")) % cp_values.front().first).str()); #else - add_item(EItemType::Rect, m_tool_colors[i], (boost::format(_u8L("up to %.2f mm")) % cp_values.front().first).str() + id_str); + add_item(EItemType::Rect, m_tool_colors[i], (boost::format(_u8L("up to %.2f mm")) % cp_values.front().first).str()); #endif // USE_ICON_HEXAGON break; } else if (i == items_cnt) { #if USE_ICON_HEXAGON - add_item(EItemType::Hexagon, m_tool_colors[i], (boost::format(_u8L("above %.2f mm")) % cp_values[i - 1].second).str() + id_str); + add_item(EItemType::Hexagon, m_tool_colors[i], (boost::format(_u8L("above %.2f mm")) % cp_values[i - 1].second).str()); #else - add_item(EItemType::Rect, m_tool_colors[i], (boost::format(_u8L("above %.2f mm")) % cp_values[i - 1].second).str() + id_str); + add_item(EItemType::Rect, m_tool_colors[i], (boost::format(_u8L("above %.2f mm")) % cp_values[i - 1].second).str()); #endif // USE_ICON_HEXAGON continue; } #if USE_ICON_HEXAGON - add_item(EItemType::Hexagon, m_tool_colors[i], (boost::format(_u8L("%.2f - %.2f mm")) % cp_values[i - 1].second% cp_values[i].first).str() + id_str); + add_item(EItemType::Hexagon, m_tool_colors[i], (boost::format(_u8L("%.2f - %.2f mm")) % cp_values[i - 1].second % cp_values[i].first).str()); #else - add_item(EItemType::Rect, m_tool_colors[i], (boost::format(_u8L("%.2f - %.2f mm")) % cp_values[i - 1].second% cp_values[i].first).str() + id_str); + add_item(EItemType::Rect, m_tool_colors[i], (boost::format(_u8L("%.2f - %.2f mm")) % cp_values[i - 1].second % cp_values[i].first).str()); #endif // USE_ICON_HEXAGON } } @@ -1609,15 +1587,12 @@ void GCodeViewer::render_legend() const size_t last_color_id = m_tool_colors.size() - 1; for (int i = static_cast(custom_gcode_per_print_z.size()) - 1; i >= 0; --i) { if (custom_gcode_per_print_z[i].type == ColorChange) { - // create label for color change item - std::string id_str = " (" + std::to_string(color_change_idx--) + ")"; - #if USE_ICON_HEXAGON add_item(EItemType::Hexagon, m_tool_colors[last_color_id--], #else add_item(EItemType::Rect, m_tool_colors[last_color_id--], #endif // USE_ICON_HEXAGON - (boost::format(_u8L("Color change for Extruder %d at %.2f mm")) % custom_gcode_per_print_z[i].extruder % custom_gcode_per_print_z[i].print_z).str() + id_str); + (boost::format(_u8L("Color change for Extruder %d at %.2f mm")) % custom_gcode_per_print_z[i].extruder % custom_gcode_per_print_z[i].print_z).str()); } } } @@ -1641,11 +1616,7 @@ void GCodeViewer::render_legend() const { // title ImGui::Spacing(); - ImGui::Spacing(); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); - imgui.text(_u8L("Travel")); - ImGui::PopStyleColor(); - ImGui::Separator(); + imgui.title(_u8L("Travel")); // items add_item(EItemType::Line, Travel_Colors[0], _u8L("Movement")); @@ -1657,13 +1628,18 @@ void GCodeViewer::render_legend() const } } - auto any_option_visible = [this]() { - return m_buffers[buffer_id(GCodeProcessor::EMoveType::Color_change)].visible || - m_buffers[buffer_id(GCodeProcessor::EMoveType::Custom_GCode)].visible || - m_buffers[buffer_id(GCodeProcessor::EMoveType::Pause_Print)].visible || - m_buffers[buffer_id(GCodeProcessor::EMoveType::Retract)].visible || - m_buffers[buffer_id(GCodeProcessor::EMoveType::Tool_change)].visible || - m_buffers[buffer_id(GCodeProcessor::EMoveType::Unretract)].visible; + auto any_option_available = [this]() { + auto available = [this](GCodeProcessor::EMoveType type) { + const TBuffer& buffer = m_buffers[buffer_id(type)]; + return buffer.visible && buffer.indices.count > 0; + }; + + return available(GCodeProcessor::EMoveType::Color_change) || + available(GCodeProcessor::EMoveType::Custom_GCode) || + available(GCodeProcessor::EMoveType::Pause_Print) || + available(GCodeProcessor::EMoveType::Retract) || + available(GCodeProcessor::EMoveType::Tool_change) || + available(GCodeProcessor::EMoveType::Unretract); }; auto add_option = [this, add_item](GCodeProcessor::EMoveType move_type, EOptionsColors color, const std::string& text) { @@ -1677,14 +1653,10 @@ void GCodeViewer::render_legend() const }; // options - if (any_option_visible()) { + if (any_option_available()) { // title ImGui::Spacing(); - ImGui::Spacing(); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); - imgui.text(_u8L("Options")); - ImGui::PopStyleColor(); - ImGui::Separator(); + imgui.title(_u8L("Options")); // items add_option(GCodeProcessor::EMoveType::Retract, EOptionsColors::Retractions, _u8L("Retractions")); @@ -1699,10 +1671,175 @@ void GCodeViewer::render_legend() const ImGui::PopStyleVar(); } +void GCodeViewer::render_time_estimate() const +{ + static const std::vector Columns_Headers = { + _u8L("Operation"), + _u8L("Remaining"), + _u8L("Duration") + }; + + if (!m_time_estimate_enabled) + return; + + const PrintStatistics& ps = wxGetApp().plater()->fff_print().print_statistics(); + if (ps.estimated_normal_print_time == "N/A" && ps.estimated_silent_print_time == "N/A") + return; + + int columns_count = 1; + if (ps.estimated_silent_print_time != "N/A") + ++columns_count; + + ImGuiWrapper& imgui = *wxGetApp().imgui(); + Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size(); + imgui.set_next_window_pos(static_cast(cnv_size.get_width()), static_cast(cnv_size.get_height()), ImGuiCond_Always, 1.0f, 1.0f); + ImGui::SetNextWindowSizeConstraints(ImVec2(0.0f, 0.0f), ImVec2(-1.0f, 0.5f * static_cast(cnv_size.get_height()))); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + ImGui::SetNextWindowBgAlpha(0.6f); + imgui.begin(std::string("Time_estimate"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove); + + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + float icon_size = ImGui::GetTextLineHeight(); + + using Time = std::pair; + using TimesList = std::vector>; + using Headers = std::vector; + using Offsets = std::array; + + auto add_mode = [this, &imgui, icon_size, draw_list](const std::string& mode, const std::string& time, const TimesList& times, const Headers& headers) { + auto add_partial_times = [this, &imgui, icon_size, draw_list](const TimesList& times, const Headers& headers) { + auto add_color = [this, &imgui, icon_size, draw_list](int id, Offsets& offsets, const Time& time) { + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); + std::string text = _u8L("Color"); + if (m_view_type != EViewType::ColorPrint) + text += " " + std::to_string(id); + imgui.text(text); + ImGui::PopStyleColor(); + ImGui::SameLine(); + + if (m_view_type == EViewType::ColorPrint) { + const Color& color = m_tool_colors[id - 1]; + ImVec2 pos = ImGui::GetCursorScreenPos(); +#if USE_ICON_HEXAGON + ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size)); + draw_list->AddNgonFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 6); +#else + draw_list->AddRectFilled({ pos.x + 1.0f, pos.y + 1.0f }, { pos.x + icon_size - 1.0f, pos.y + icon_size - 1.0f }, + ImGui::GetColorU32({ m_tool_colors[i][0], m_tool_colors[i][1], m_tool_colors[i][2], 1.0f })); +#endif // USE_ICON_HEXAGON + } + ImGui::SameLine(offsets[0]); + imgui.text(short_time(get_time_dhms(time.second))); + ImGui::SameLine(offsets[1]); + imgui.text(short_time(get_time_dhms(time.first))); + }; + auto calc_offsets = [this, icon_size](const TimesList& times, const Headers& headers, int color_change_count) { + Offsets ret = { ImGui::CalcTextSize(headers[0].c_str()).x, ImGui::CalcTextSize(headers[1].c_str()).x }; + for (const auto& [type, time] : times) { + std::string label; + switch (type) + { + case CustomGCode::PausePrint: + { + label = _u8L("Pause"); + break; + } + case CustomGCode::ColorChange: + { + label = _u8L("Color"); + if (m_view_type != EViewType::ColorPrint) + label += " " + std::to_string(color_change_count); + break; + } + default: { break; } + } + + ret[0] = std::max(ret[0], ImGui::CalcTextSize(label.c_str()).x); + ret[1] = std::max(ret[1], ImGui::CalcTextSize(short_time(get_time_dhms(time.second)).c_str()).x); + } + + const ImGuiStyle& style = ImGui::GetStyle(); + ret[0] += icon_size + style.ItemSpacing.x; + ret[1] += ret[0] + style.ItemSpacing.x; + return ret; + }; + + if (times.empty()) + return; + + int color_change_count = 0; + for (auto time : times) { + if (time.first == CustomGCode::ColorChange) + ++color_change_count; + } + + Offsets offsets = calc_offsets(times, headers, color_change_count); + + ImGui::Spacing(); + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); + imgui.text(headers[0]); + ImGui::SameLine(offsets[0]); + imgui.text(headers[1]); + ImGui::SameLine(offsets[1]); + imgui.text(headers[2]); + ImGui::PopStyleColor(); + + int last_color_id = color_change_count; + + for (int i = static_cast(times.size()) - 1; i >= 0; --i) { + const auto& [type, time] = times[i]; + + switch (type) + { + case CustomGCode::PausePrint: + { + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); + imgui.text(_u8L("Pause")); + ImGui::PopStyleColor(); + ImGui::SameLine(offsets[0]); + imgui.text(short_time(get_time_dhms(time.second - time.first))); + + add_color(last_color_id, offsets, time); + break; + } + case CustomGCode::ColorChange: + { + add_color(color_change_count, offsets, time); + last_color_id = color_change_count--; + break; + } + default: { break; } + } + } + }; + + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); + imgui.text(mode + ":"); + ImGui::PopStyleColor(); + ImGui::SameLine(); + imgui.text(time); + add_partial_times(times, headers); + }; + + // title + imgui.title(_u8L("Estimated printing time")); + + // times + if (ps.estimated_normal_print_time != "N/A") + add_mode(_u8L("Normal mode"), ps.estimated_normal_print_time, ps.estimated_normal_custom_gcode_print_times, Columns_Headers); + + if (ps.estimated_silent_print_time != "N/A") { + ImGui::Separator(); + add_mode(_u8L("Stealth mode"), ps.estimated_silent_print_time, ps.estimated_silent_custom_gcode_print_times, Columns_Headers); + } + + imgui.end(); + ImGui::PopStyleVar(); +} + #if ENABLE_GCODE_VIEWER_STATISTICS void GCodeViewer::render_statistics() const { - static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); static const float offset = 230.0f; ImGuiWrapper& imgui = *wxGetApp().imgui(); @@ -1711,7 +1848,7 @@ void GCodeViewer::render_statistics() const imgui.begin(std::string("GCodeViewer Statistics"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize); ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindow()); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); imgui.text(std::string("GCodeProcessor time:")); ImGui::PopStyleColor(); ImGui::SameLine(offset); @@ -1719,19 +1856,19 @@ void GCodeViewer::render_statistics() const ImGui::Separator(); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); imgui.text(std::string("Load time:")); ImGui::PopStyleColor(); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.load_time) + " ms"); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); imgui.text(std::string("Resfresh time:")); ImGui::PopStyleColor(); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.refresh_time) + " ms"); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); imgui.text(std::string("Resfresh paths time:")); ImGui::PopStyleColor(); ImGui::SameLine(offset); @@ -1739,13 +1876,13 @@ void GCodeViewer::render_statistics() const ImGui::Separator(); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); imgui.text(std::string("Multi GL_POINTS calls:")); ImGui::PopStyleColor(); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.gl_multi_points_calls_count)); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); imgui.text(std::string("Multi GL_LINE_STRIP calls:")); ImGui::PopStyleColor(); ImGui::SameLine(offset); @@ -1753,7 +1890,7 @@ void GCodeViewer::render_statistics() const ImGui::Separator(); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); imgui.text(std::string("GCodeProcessor results:")); ImGui::PopStyleColor(); ImGui::SameLine(offset); @@ -1761,13 +1898,13 @@ void GCodeViewer::render_statistics() const ImGui::Separator(); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); imgui.text(std::string("Paths CPU:")); ImGui::PopStyleColor(); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.paths_size) + " bytes"); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); imgui.text(std::string("Render paths CPU:")); ImGui::PopStyleColor(); ImGui::SameLine(offset); @@ -1775,13 +1912,13 @@ void GCodeViewer::render_statistics() const ImGui::Separator(); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); imgui.text(std::string("Vertices GPU:")); ImGui::PopStyleColor(); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.vertices_gpu_size) + " bytes"); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); imgui.text(std::string("Indices GPU:")); ImGui::PopStyleColor(); ImGui::SameLine(offset); @@ -1789,13 +1926,13 @@ void GCodeViewer::render_statistics() const ImGui::Separator(); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); imgui.text(std::string("Travel segments:")); ImGui::PopStyleColor(); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.travel_segments_count)); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); imgui.text(std::string("Extrude segments:")); ImGui::PopStyleColor(); ImGui::SameLine(offset); @@ -1816,8 +1953,6 @@ void GCodeViewer::render_shaders_editor() const } }; - static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); - ImGuiWrapper& imgui = *wxGetApp().imgui(); Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size(); @@ -1828,8 +1963,8 @@ void GCodeViewer::render_shaders_editor() const if (ImGui::CollapsingHeader("Points", ImGuiTreeNodeFlags_DefaultOpen)) { if (ImGui::TreeNode("GLSL version")) { ImGui::RadioButton("1.10 (low end PCs)", &m_shaders_editor.points.shader_version, 0); - ImGui::RadioButton("1.20 flat (billboards)", &m_shaders_editor.points.shader_version, 1); - ImGui::RadioButton("1.20 solid (spheres default)", &m_shaders_editor.points.shader_version, 2); + ImGui::RadioButton("1.20 flat (billboards) [default]", &m_shaders_editor.points.shader_version, 1); + ImGui::RadioButton("1.20 solid (spheres)", &m_shaders_editor.points.shader_version, 2); ImGui::TreePop(); } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 137ae89af7..90155c7281 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -248,7 +248,7 @@ class GCodeViewer { struct Points { - int shader_version{ 2 }; + int shader_version{ 1 }; float point_size{ 0.8f }; int percent_outline{ 0 }; int percent_center{ 33 }; @@ -341,6 +341,7 @@ private: Shells m_shells; EViewType m_view_type{ EViewType::FeatureType }; bool m_legend_enabled{ true }; + bool m_time_estimate_enabled{ true }; #if ENABLE_GCODE_VIEWER_STATISTICS mutable Statistics m_statistics; #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -396,6 +397,9 @@ public: bool is_legend_enabled() const { return m_legend_enabled; } void enable_legend(bool enable) { m_legend_enabled = enable; } + bool is_time_estimate_enabled() const { return m_time_estimate_enabled; } + void enable_time_estimate(bool enable) { m_time_estimate_enabled = enable; } + void export_toolpaths_to_obj(const char* filename) const; private: @@ -406,6 +410,7 @@ private: void render_toolpaths() const; void render_shells() const; void render_legend() const; + void render_time_estimate() const; #if ENABLE_GCODE_VIEWER_STATISTICS void render_statistics() const; #endif // ENABLE_GCODE_VIEWER_STATISTICS diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index f8ff9406f3..8c69142485 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -219,8 +219,6 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const if (!m_enabled) return; - static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); - const Size& cnv_size = canvas.get_canvas_size(); float canvas_w = (float)cnv_size.get_width(); float canvas_h = (float)cnv_size.get_height(); @@ -228,50 +226,50 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const ImGuiWrapper& imgui = *wxGetApp().imgui(); imgui.set_next_window_pos(canvas_w - imgui.get_style_scaling() * THICKNESS_BAR_WIDTH, canvas_h, ImGuiCond_Always, 1.0f, 1.0f); - imgui.begin(_(L("Variable layer height")), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse); + imgui.begin(_L("Variable layer height"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); - imgui.text(_(L("Left mouse button:"))); + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); + imgui.text(_L("Left mouse button:")); ImGui::PopStyleColor(); ImGui::SameLine(); - imgui.text(_(L("Add detail"))); + imgui.text(_L("Add detail")); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); - imgui.text(_(L("Right mouse button:"))); + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); + imgui.text(_L("Right mouse button:")); ImGui::PopStyleColor(); ImGui::SameLine(); - imgui.text(_(L("Remove detail"))); + imgui.text(_L("Remove detail")); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); - imgui.text(_(L("Shift + Left mouse button:"))); + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); + imgui.text(_L("Shift + Left mouse button:")); ImGui::PopStyleColor(); ImGui::SameLine(); - imgui.text(_(L("Reset to base"))); + imgui.text(_L("Reset to base")); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); - imgui.text(_(L("Shift + Right mouse button:"))); + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); + imgui.text(_L("Shift + Right mouse button:")); ImGui::PopStyleColor(); ImGui::SameLine(); - imgui.text(_(L("Smoothing"))); + imgui.text(_L("Smoothing")); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); - imgui.text(_(L("Mouse wheel:"))); + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); + imgui.text(_L("Mouse wheel:")); ImGui::PopStyleColor(); ImGui::SameLine(); - imgui.text(_(L("Increase/decrease edit area"))); + imgui.text(_L("Increase/decrease edit area")); ImGui::Separator(); - if (imgui.button(_(L("Adaptive")))) + if (imgui.button(_L("Adaptive"))) wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), Event(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, m_adaptive_quality)); ImGui::SameLine(); float text_align = ImGui::GetCursorPosX(); ImGui::AlignTextToFramePadding(); - imgui.text(_(L("Quality / Speed"))); + imgui.text(_L("Quality / Speed")); if (ImGui::IsItemHovered()) { ImGui::BeginTooltip(); - ImGui::TextUnformatted(_(L("Higher print quality versus higher print speed.")).ToUTF8()); + ImGui::TextUnformatted(_L("Higher print quality versus higher print speed.").ToUTF8()); ImGui::EndTooltip(); } @@ -282,13 +280,13 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const ImGui::SliderFloat("", &m_adaptive_quality, 0.0f, 1.f, "%.2f"); ImGui::Separator(); - if (imgui.button(_(L("Smooth")))) + if (imgui.button(_L("Smooth"))) wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), HeightProfileSmoothEvent(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, m_smooth_params)); ImGui::SameLine(); ImGui::SetCursorPosX(text_align); ImGui::AlignTextToFramePadding(); - imgui.text(_(L("Radius"))); + imgui.text(_L("Radius")); ImGui::SameLine(); ImGui::SetCursorPosX(widget_align); ImGui::PushItemWidth(imgui.get_style_scaling() * 120.0f); @@ -298,7 +296,7 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const ImGui::SetCursorPosX(text_align); ImGui::AlignTextToFramePadding(); - imgui.text(_(L("Keep min"))); + imgui.text(_L("Keep min")); ImGui::SameLine(); if (ImGui::GetCursorPosX() < widget_align) // because of line lenght after localization ImGui::SetCursorPosX(widget_align); @@ -307,7 +305,7 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const imgui.checkbox("##2", m_smooth_params.keep_min); ImGui::Separator(); - if (imgui.button(_(L("Reset")))) + if (imgui.button(_L("Reset"))) wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), SimpleEvent(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE)); imgui.end(); @@ -3078,8 +3076,7 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) #if ENABLE_GCODE_VIEWER case 'L': case 'l': { - if (!m_main_toolbar.is_enabled()) - { + if (!m_main_toolbar.is_enabled()) { m_gcode_viewer.enable_legend(!m_gcode_viewer.is_legend_enabled()); m_dirty = true; wxGetApp().plater()->update_preview_bottom_toolbar(); @@ -3090,13 +3087,24 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) case 'O': case 'o': { _update_camera_zoom(-1.0); break; } #if ENABLE_RENDER_PICKING_PASS - case 'T': - case 't': { + case 'P': + case 'p': { m_show_picking_texture = !m_show_picking_texture; - m_dirty = true; + m_dirty = true; break; } #endif // ENABLE_RENDER_PICKING_PASS +#if ENABLE_GCODE_VIEWER + case 'T': + case 't': { + if (!m_main_toolbar.is_enabled()) { + m_gcode_viewer.enable_time_estimate(!m_gcode_viewer.is_time_estimate_enabled()); + m_dirty = true; + wxGetApp().plater()->update_preview_bottom_toolbar(); + } + break; + } +#endif // ENABLE_GCODE_VIEWER case 'Z': #if ENABLE_GCODE_VIEWER case 'z': diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index cb47d79618..e62a81d39b 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -69,7 +69,7 @@ GLShaderProgram* GLShadersManager::get_current_shader() if (id == 0) return nullptr; - auto it = std::find_if(m_shaders.begin(), m_shaders.end(), [id](std::unique_ptr& p) { return p->get_id() == id; }); + auto it = std::find_if(m_shaders.begin(), m_shaders.end(), [id](std::unique_ptr& p) { return static_cast(p->get_id()) == id; }); return (it != m_shaders.end()) ? it->get() : nullptr; } diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 530165001f..50a820cfaa 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -323,7 +323,8 @@ bool Preview::init(wxWindow* parent, Model* model) get_option_type_string(OptionType::CustomGCodes) + "|0|" + get_option_type_string(OptionType::Shells) + "|0|" + get_option_type_string(OptionType::ToolMarker) + "|0|" + - get_option_type_string(OptionType::Legend) + "|1" + get_option_type_string(OptionType::Legend) + "|1|" + + get_option_type_string(OptionType::TimeEstimate) + "|1" ); Slic3r::GUI::create_combochecklist(m_combochecklist_options, GUI::into_u8(_L("Options")), options_items); #else @@ -1458,10 +1459,10 @@ wxString Preview::get_option_type_string(OptionType type) const case OptionType::Shells: { return _L("Shells"); } case OptionType::ToolMarker: { return _L("Tool marker"); } case OptionType::Legend: { return _L("Legend"); } + case OptionType::TimeEstimate: { return _L("Estimated printing time"); } default: { return ""; } } } - #endif // ENABLE_GCODE_VIEWER } // namespace GUI diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index bf174c2e09..ff3bf41371 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -149,7 +149,8 @@ public: CustomGCodes, Shells, ToolMarker, - Legend + Legend, + TimeEstimate }; Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process, diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index cd42857247..9aaded6e3c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -650,8 +650,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l window_width = std::max(window_width, button_width); auto draw_text_with_caption = [this, &caption_max](const wxString& caption, const wxString& text) { - static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); m_imgui->text(caption); ImGui::PopStyleColor(); ImGui::SameLine(caption_max); diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 51a9a6d4eb..2c463dc2a5 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -44,6 +44,12 @@ static const std::map font_icons = { {ImGui::MaterialIconMarker , "resin" } }; +const ImVec4 ImGuiWrapper::COL_WINDOW_BACKGROND = { 0.133f, 0.133f, 0.133f, 0.8f }; +const ImVec4 ImGuiWrapper::COL_GREY_DARK = { 0.333f, 0.333f, 0.333f, 1.0f }; +const ImVec4 ImGuiWrapper::COL_GREY_LIGHT = { 0.4f, 0.4f, 0.4f, 1.0f }; +const ImVec4 ImGuiWrapper::COL_ORANGE_DARK = { 0.757f, 0.404f, 0.216f, 1.0f }; +const ImVec4 ImGuiWrapper::COL_ORANGE_LIGHT = { 1.0f, 0.49f, 0.216f, 1.0f }; + ImGuiWrapper::ImGuiWrapper() : m_glyph_ranges(nullptr) , m_font_cjk(false) @@ -751,6 +757,22 @@ void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, co check_box(_L("Search in English"), view_params.english); } +void ImGuiWrapper::title(const std::string& str) +{ + ImGuiWindow* window = ImGui::GetCurrentWindow(); + const float frame_height = ImGui::CalcTextSize(str.c_str(), nullptr, false).y; + + ImRect frame_bb; + frame_bb.Min = { window->WorkRect.Min.x, window->DC.CursorPos.y }; + frame_bb.Max = { window->WorkRect.Max.x, window->DC.CursorPos.y + frame_height }; + + frame_bb.Min.x -= IM_FLOOR(window->WindowPadding.x * 0.5f - 1.0f); + frame_bb.Max.x += IM_FLOOR(window->WindowPadding.x * 0.5f); + + window->DrawList->AddRectFilled(frame_bb.Min, frame_bb.Max, ImGui::GetColorU32(COL_ORANGE_DARK), 0.0f, 0); + text(str); +} + void ImGuiWrapper::disabled_begin(bool disabled) { wxCHECK_RET(!m_disabled, "ImGUI: Unbalanced disabled_begin() call"); @@ -970,20 +992,10 @@ void ImGuiWrapper::init_style() { ImGuiStyle &style = ImGui::GetStyle(); - auto set_color = [&](ImGuiCol_ col, unsigned hex_color) { - style.Colors[col] = ImVec4( - ((hex_color >> 24) & 0xff) / 255.0f, - ((hex_color >> 16) & 0xff) / 255.0f, - ((hex_color >> 8) & 0xff) / 255.0f, - (hex_color & 0xff) / 255.0f); + auto set_color = [&](ImGuiCol_ entity, ImVec4 color) { + style.Colors[entity] = color; }; - static const unsigned COL_WINDOW_BACKGROND = 0x222222cc; - static const unsigned COL_GREY_DARK = 0x555555ff; - static const unsigned COL_GREY_LIGHT = 0x666666ff; - static const unsigned COL_ORANGE_DARK = 0xc16737ff; - static const unsigned COL_ORANGE_LIGHT = 0xff7d38ff; - // Window style.WindowRounding = 4.0f; set_color(ImGuiCol_WindowBg, COL_WINDOW_BACKGROND); diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index bf542e1381..f79bd3fbc8 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -80,6 +80,7 @@ public: bool undo_redo_list(const ImVec2& size, const bool is_undo, bool (*items_getter)(const bool, int, const char**), int& hovered, int& selected, int& mouse_wheel); void search_list(const ImVec2& size, bool (*items_getter)(int, const char** label, const char** tooltip), char* search_str, Search::OptionViewParameters& view_params, int& selected, bool& edited, int& mouse_wheel, bool is_localized); + void title(const std::string& str); void disabled_begin(bool disabled); void disabled_end(); @@ -89,6 +90,12 @@ public: bool want_text_input() const; bool want_any_input() const; + static const ImVec4 COL_WINDOW_BACKGROND; + static const ImVec4 COL_GREY_DARK; + static const ImVec4 COL_GREY_LIGHT; + static const ImVec4 COL_ORANGE_DARK; + static const ImVec4 COL_ORANGE_LIGHT; + private: void init_font(bool compress); void init_input(); diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index 51ba06ba45..66e5ac4878 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -183,7 +183,7 @@ void KBShortcutsDialog::fill_shortcuts() #endif // __linux__ #if ENABLE_RENDER_PICKING_PASS // Don't localize debugging texts. - { "T", "Toggle picking pass texture rendering on/off" }, + { "P", "Toggle picking pass texture rendering on/off" }, #endif // ENABLE_RENDER_PICKING_PASS }; @@ -203,7 +203,8 @@ void KBShortcutsDialog::fill_shortcuts() { L("Arrow Down"), L("Lower Layer") }, { "U", L("Upper Layer") }, { "D", L("Lower Layer") }, - { "L", L("Show/Hide Legend") } + { "L", L("Show/Hide Legend") }, + { "T", L("Show/Hide Estimated printing time") } }; m_full_shortcuts.push_back(std::make_pair(_L("Preview"), preview_shortcuts)); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index eba169dc96..59b8e56f34 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -355,6 +355,10 @@ void MainFrame::update_layout() // Set new settings switch (m_layout) { + case ESettingsLayout::Unknown: + { + break; + } case ESettingsLayout::Old: { m_plater->Reparent(m_tabpanel); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 36fa83470a..d0b52426c2 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1330,8 +1330,12 @@ void Sidebar::update_sliced_info_sizer() wxString str_color = _L("Color"); wxString str_pause = _L("Pause"); - auto fill_labels = [str_color, str_pause](const std::vector>& times, - wxString& new_label, wxString& info_text) +#if ENABLE_GCODE_VIEWER + auto fill_labels = [str_color, str_pause](const std::vector>>& times, +#else + auto fill_labels = [str_color, str_pause](const std::vector>& times, +#endif // ENABLE_GCODE_VIEWER + wxString& new_label, wxString& info_text) { int color_change_count = 0; for (auto time : times) @@ -1348,19 +1352,31 @@ void Sidebar::update_sliced_info_sizer() if (i != (int)times.size() - 1 && times[i].first == CustomGCode::PausePrint) new_label += format_wxstr(" -> %1%", str_pause); +#if ENABLE_GCODE_VIEWER + info_text += format_wxstr("\n%1% (%2%)", times[i].second.first, times[i].second.second); +#else info_text += format_wxstr("\n%1%", times[i].second); +#endif // ENABLE_GCODE_VIEWER } }; if (ps.estimated_normal_print_time != "N/A") { new_label += format_wxstr("\n - %1%", _L("normal mode")); info_text += format_wxstr("\n%1%", ps.estimated_normal_print_time); +#if ENABLE_GCODE_VIEWER + fill_labels(ps.estimated_normal_custom_gcode_print_times_str, new_label, info_text); +#else fill_labels(ps.estimated_normal_custom_gcode_print_times, new_label, info_text); +#endif // ENABLE_GCODE_VIEWER } if (ps.estimated_silent_print_time != "N/A") { new_label += format_wxstr("\n - %1%", _L("stealth mode")); info_text += format_wxstr("\n%1%", ps.estimated_silent_print_time); +#if ENABLE_GCODE_VIEWER + fill_labels(ps.estimated_silent_custom_gcode_print_times_str, new_label, info_text); +#else fill_labels(ps.estimated_silent_custom_gcode_print_times, new_label, info_text); +#endif // ENABLE_GCODE_VIEWER } p->sliced_info->SetTextAndShow(siEstimatedTime, info_text, new_label); } @@ -2709,6 +2725,9 @@ void Plater::priv::reset() if (view3D->is_layers_editing_enabled()) view3D->enable_layers_editing(false); +#if ENABLE_GCODE_VIEWER + reset_gcode_toolpaths(); +#endif // ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER_AS_STATE gcode_result.reset(); #endif // ENABLE_GCODE_VIEWER_AS_STATE @@ -2859,8 +2878,7 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool // Reset preview canvases. If the print has been invalidated, the preview canvases will be cleared. // Otherwise they will be just refreshed. #if ENABLE_GCODE_VIEWER - if (this->preview != nullptr) - { + if (this->preview != nullptr) { // If the preview is not visible, the following line just invalidates the preview, // but the G-code paths or SLA preview are calculated first once the preview is made visible. this->preview->get_canvas3d()->reset_gcode_toolpaths(); From 6fbb3db79c1a2b87a873120606bdf2bdc8cacc65 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 8 Jul 2020 14:43:14 +0200 Subject: [PATCH 145/255] Fixed build when ENABLE_GCODE_VIEWER is disabled --- src/slic3r/GUI/3DBed.cpp | 5 ++--- src/slic3r/GUI/MainFrame.cpp | 2 ++ src/slic3r/GUI/Selection.cpp | 8 ++++++++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 16ab95d6c4..ca075fb372 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -369,7 +369,6 @@ void Bed3D::calc_bounding_boxes() const m_extended_bounding_box.merge(model_bb); } #else - m_extended_bounding_box.merge(m_axes.get_total_length() * Vec3d::Ones()); m_extended_bounding_box.merge(m_axes.length + Axes::ArrowLength * Vec3d::Ones()); // extend to contain model, if any if (!m_model.get_filename().empty()) @@ -694,11 +693,11 @@ void Bed3D::render_default(bool bottom) const { // draw background glsafe(::glDepthMask(GL_FALSE)); -#if ENABLE_LAYOUT_NO_RESTART +#if ENABLE_GCODE_VIEWER glsafe(::glColor4fv(m_model_color.data())); #else glsafe(::glColor4f(0.35f, 0.35f, 0.35f, 0.4f)); -#endif // ENABLE_LAYOUT_NO_RESTART +#endif // ENABLE_GCODE_VIEWER glsafe(::glNormal3d(0.0f, 0.0f, 1.0f)); glsafe(::glVertexPointer(3, GL_FLOAT, m_triangles.get_vertex_data_size(), (GLvoid*)m_triangles.get_vertices_data())); glsafe(::glDrawArrays(GL_TRIANGLES, 0, (GLsizei)triangles_vcount)); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 59b8e56f34..0d2c17dce7 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -482,9 +482,11 @@ void MainFrame::shutdown() #endif // ENABLE_LAYOUT_NO_RESTART if (m_plater != nullptr) { +#if ENABLE_GCODE_VIEWER_AS_STATE // restore sidebar if it was hidden when switching to gcode viewer mode if (m_restore_from_gcode_viewer.collapsed_sidebar) m_plater->collapse_sidebar(false); +#endif // ENABLE_GCODE_VIEWER_AS_STATE // Stop the background thread (Windows and Linux). // Disconnect from a 3DConnextion driver (OSX). m_plater->get_mouse3d_controller().shutdown(); diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index add09a59de..f429c6a958 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -2039,11 +2039,19 @@ void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) con shader->set_uniform("uniform_color", uniform_scale ? UNIFORM_SCALE_COLOR : AXES_COLOR[axis], 4); glsafe(::glTranslated(0.0, 5.0, 0.0)); +#if ENABLE_GCODE_VIEWER m_arrow.render(); +#else + m_arrow->render(); +#endif // ENABLE_GCODE_VIEWER glsafe(::glTranslated(0.0, -10.0, 0.0)); glsafe(::glRotated(180.0, 0.0, 0.0, 1.0)); +#if ENABLE_GCODE_VIEWER m_arrow.render(); +#else + m_arrow->render(); +#endif // ENABLE_GCODE_VIEWER }; if (boost::ends_with(sidebar_field, "x") || uniform_scale) From 431cfcc671f2cf8b861814e24c5afd5c1c7ec9d7 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 9 Jul 2020 15:57:35 +0200 Subject: [PATCH 146/255] GCodeViewer -> Reworked layout of imgui dialog for estimated printing times --- src/slic3r/GUI/GCodeViewer.cpp | 254 +++++++++++++++++++------------- src/slic3r/GUI/ImGuiWrapper.cpp | 7 + 2 files changed, 160 insertions(+), 101 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 26dc765db4..3ceaf86fa2 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -40,23 +40,28 @@ static GCodeProcessor::EMoveType buffer_type(unsigned char id) { return static_cast(static_cast(GCodeProcessor::EMoveType::Retract) + id); } -std::vector> decode_colors(const std::vector & colors) { +std::array decode_color(const std::string& color) { static const float INV_255 = 1.0f / 255.0f; + std::array ret; + const char* c = color.data() + 1; + if ((color.size() == 7) && (color.front() == '#')) { + for (size_t j = 0; j < 3; ++j) { + int digit1 = hex_digit_to_int(*c++); + int digit2 = hex_digit_to_int(*c++); + if ((digit1 == -1) || (digit2 == -1)) + break; + + ret[j] = float(digit1 * 16 + digit2) * INV_255; + } + } + return ret; +} + +std::vector> decode_colors(const std::vector& colors) { std::vector> output(colors.size(), { 0.0f, 0.0f, 0.0f }); for (size_t i = 0; i < colors.size(); ++i) { - const std::string& color = colors[i]; - const char* c = color.data() + 1; - if ((color.size() == 7) && (color.front() == '#')) { - for (size_t j = 0; j < 3; ++j) { - int digit1 = hex_digit_to_int(*c++); - int digit2 = hex_digit_to_int(*c++); - if ((digit1 == -1) || (digit2 == -1)) - break; - - output[i][j] = float(digit1 * 16 + digit2) * INV_255; - } - } + output[i] = decode_color(colors[i]); } return output; } @@ -1575,6 +1580,11 @@ void GCodeViewer::render_legend() const { // extruders for (unsigned int i = 0; i < (unsigned int)extruders_count; ++i) { + // shows only extruders actually used + auto it = std::find(m_extruder_ids.begin(), m_extruder_ids.end(), static_cast(i)); + if (it == m_extruder_ids.end()) + continue; + #if USE_ICON_HEXAGON add_item(EItemType::Hexagon, m_tool_colors[i], (boost::format(_u8L("Extruder %d")) % (i + 1)).str()); #else @@ -1671,14 +1681,9 @@ void GCodeViewer::render_legend() const ImGui::PopStyleVar(); } + void GCodeViewer::render_time_estimate() const { - static const std::vector Columns_Headers = { - _u8L("Operation"), - _u8L("Remaining"), - _u8L("Duration") - }; - if (!m_time_estimate_enabled) return; @@ -1686,94 +1691,87 @@ void GCodeViewer::render_time_estimate() const if (ps.estimated_normal_print_time == "N/A" && ps.estimated_silent_print_time == "N/A") return; - int columns_count = 1; - if (ps.estimated_silent_print_time != "N/A") - ++columns_count; - ImGuiWrapper& imgui = *wxGetApp().imgui(); - Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size(); - imgui.set_next_window_pos(static_cast(cnv_size.get_width()), static_cast(cnv_size.get_height()), ImGuiCond_Always, 1.0f, 1.0f); - ImGui::SetNextWindowSizeConstraints(ImVec2(0.0f, 0.0f), ImVec2(-1.0f, 0.5f * static_cast(cnv_size.get_height()))); - ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); - ImGui::SetNextWindowBgAlpha(0.6f); - imgui.begin(std::string("Time_estimate"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove); - - ImDrawList* draw_list = ImGui::GetWindowDrawList(); - float icon_size = ImGui::GetTextLineHeight(); using Time = std::pair; using TimesList = std::vector>; - using Headers = std::vector; - using Offsets = std::array; - auto add_mode = [this, &imgui, icon_size, draw_list](const std::string& mode, const std::string& time, const TimesList& times, const Headers& headers) { - auto add_partial_times = [this, &imgui, icon_size, draw_list](const TimesList& times, const Headers& headers) { - auto add_color = [this, &imgui, icon_size, draw_list](int id, Offsets& offsets, const Time& time) { - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - std::string text = _u8L("Color"); - if (m_view_type != EViewType::ColorPrint) - text += " " + std::to_string(id); - imgui.text(text); - ImGui::PopStyleColor(); - ImGui::SameLine(); + // helper structure containig the data needed to render the items + struct Item + { + CustomGCode::Type type; + int extruder_id; + Color color; + Time time; + }; + using Items = std::vector; - if (m_view_type == EViewType::ColorPrint) { - const Color& color = m_tool_colors[id - 1]; - ImVec2 pos = ImGui::GetCursorScreenPos(); -#if USE_ICON_HEXAGON - ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size)); - draw_list->AddNgonFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 6); -#else - draw_list->AddRectFilled({ pos.x + 1.0f, pos.y + 1.0f }, { pos.x + icon_size - 1.0f, pos.y + icon_size - 1.0f }, - ImGui::GetColorU32({ m_tool_colors[i][0], m_tool_colors[i][1], m_tool_colors[i][2], 1.0f })); -#endif // USE_ICON_HEXAGON - } - ImGui::SameLine(offsets[0]); - imgui.text(short_time(get_time_dhms(time.second))); - ImGui::SameLine(offsets[1]); - imgui.text(short_time(get_time_dhms(time.first))); + auto append_mode = [this, &imgui](const std::string& time_str, const Items& items) { + auto append_partial_times = [this, &imgui](const Items& items) { + using Headers = std::vector; + const Headers headers = { + _u8L("Event"), + _u8L("Remaining"), + _u8L("Duration") }; - auto calc_offsets = [this, icon_size](const TimesList& times, const Headers& headers, int color_change_count) { + using Offsets = std::array; + auto calc_offsets = [this, &headers](const Items& items) { Offsets ret = { ImGui::CalcTextSize(headers[0].c_str()).x, ImGui::CalcTextSize(headers[1].c_str()).x }; - for (const auto& [type, time] : times) { + for (const Item& item : items) { std::string label; - switch (type) + switch (item.type) { - case CustomGCode::PausePrint: - { - label = _u8L("Pause"); - break; - } + case CustomGCode::PausePrint: { label = _u8L("Pause"); break; } case CustomGCode::ColorChange: { - label = _u8L("Color"); - if (m_view_type != EViewType::ColorPrint) - label += " " + std::to_string(color_change_count); + int extruders_count = wxGetApp().extruders_edited_cnt(); + label = (extruders_count > 1) ? _u8L("[XX] Color") : _u8L("Color"); break; } default: { break; } } ret[0] = std::max(ret[0], ImGui::CalcTextSize(label.c_str()).x); - ret[1] = std::max(ret[1], ImGui::CalcTextSize(short_time(get_time_dhms(time.second)).c_str()).x); + ret[1] = std::max(ret[1], ImGui::CalcTextSize(short_time(get_time_dhms(item.time.second)).c_str()).x); } const ImGuiStyle& style = ImGui::GetStyle(); - ret[0] += icon_size + style.ItemSpacing.x; + ret[0] += ImGui::GetTextLineHeight() + 2.0f * style.ItemSpacing.x; ret[1] += ret[0] + style.ItemSpacing.x; return ret; }; + auto append_color = [this, &imgui](int id, int extruder_id, const Color& color, Offsets& offsets, const Time& time) { + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); + int extruders_count = wxGetApp().extruders_edited_cnt(); + std::string text; + if (extruders_count > 1) + text = "[" + std::to_string(extruder_id) + "] "; + text += _u8L("Color"); + imgui.text(text); + ImGui::PopStyleColor(); + ImGui::SameLine(); - if (times.empty()) + float icon_size = ImGui::GetTextLineHeight(); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + ImVec2 pos = ImGui::GetCursorScreenPos(); + pos.x -= 0.5f * ImGui::GetStyle().ItemSpacing.x; +#if USE_ICON_HEXAGON + ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size)); + draw_list->AddNgonFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 6); +#else + draw_list->AddRectFilled({ pos.x + 1.0f, pos.y + 1.0f }, { pos.x + icon_size - 1.0f, pos.y + icon_size - 1.0f }, + ImGui::GetColorU32({ m_tool_colors[i][0], m_tool_colors[i][1], m_tool_colors[i][2], 1.0f })); +#endif // USE_ICON_HEXAGON + ImGui::SameLine(offsets[0]); + imgui.text(short_time(get_time_dhms(time.second))); + ImGui::SameLine(offsets[1]); + imgui.text(short_time(get_time_dhms(time.first))); + }; + + if (items.empty()) return; - int color_change_count = 0; - for (auto time : times) { - if (time.first == CustomGCode::ColorChange) - ++color_change_count; - } - - Offsets offsets = calc_offsets(times, headers, color_change_count); + Offsets offsets = calc_offsets(items); ImGui::Spacing(); ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); @@ -1783,13 +1781,11 @@ void GCodeViewer::render_time_estimate() const ImGui::SameLine(offsets[1]); imgui.text(headers[2]); ImGui::PopStyleColor(); + ImGui::Separator(); - int last_color_id = color_change_count; - - for (int i = static_cast(times.size()) - 1; i >= 0; --i) { - const auto& [type, time] = times[i]; - - switch (type) + unsigned int last_color_id = 0; + for (const Item& item : items) { + switch (item.type) { case CustomGCode::PausePrint: { @@ -1797,15 +1793,13 @@ void GCodeViewer::render_time_estimate() const imgui.text(_u8L("Pause")); ImGui::PopStyleColor(); ImGui::SameLine(offsets[0]); - imgui.text(short_time(get_time_dhms(time.second - time.first))); - - add_color(last_color_id, offsets, time); + imgui.text(short_time(get_time_dhms(item.time.second - item.time.first))); break; } case CustomGCode::ColorChange: { - add_color(color_change_count, offsets, time); - last_color_id = color_change_count--; + append_color(last_color_id, item.extruder_id, item.color, offsets, item.time); + ++last_color_id; break; } default: { break; } @@ -1814,24 +1808,82 @@ void GCodeViewer::render_time_estimate() const }; ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(mode + ":"); + imgui.text(_u8L("Time") + ":"); ImGui::PopStyleColor(); ImGui::SameLine(); - imgui.text(time); - add_partial_times(times, headers); + imgui.text(time_str); + append_partial_times(items); }; + auto generate_items = [this](const TimesList& times) { + std::vector items; + + std::vector custom_gcode_per_print_z = wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes; + int extruders_count = wxGetApp().extruders_edited_cnt(); + std::vector last_color(extruders_count); + for (int i = 0; i < extruders_count; ++i) { + last_color[i] = m_tool_colors[i]; + } + int last_extruder_id = 1; + for (const auto& time_rec : times) { + switch (time_rec.first) + { + case CustomGCode::PausePrint: + { + auto it = std::find_if(custom_gcode_per_print_z.begin(), custom_gcode_per_print_z.end(), [time_rec](const CustomGCode::Item& item) { return item.type == time_rec.first; }); + if (it != custom_gcode_per_print_z.end()) { + items.push_back({ CustomGCode::ColorChange, it->extruder, last_color[it->extruder - 1], time_rec.second }); + items.push_back({ time_rec.first, it->extruder, last_color[it->extruder - 1], time_rec.second }); + custom_gcode_per_print_z.erase(it); + } + break; + } + case CustomGCode::ColorChange: + { + auto it = std::find_if(custom_gcode_per_print_z.begin(), custom_gcode_per_print_z.end(), [time_rec](const CustomGCode::Item& item) { return item.type == time_rec.first; }); + if (it != custom_gcode_per_print_z.end()) { + items.push_back({ time_rec.first, it->extruder, last_color[it->extruder - 1], time_rec.second }); + last_color[it->extruder - 1] = decode_color(it->color); + last_extruder_id = it->extruder; + custom_gcode_per_print_z.erase(it); + } + else + items.push_back({ time_rec.first, last_extruder_id, last_color[last_extruder_id - 1], time_rec.second }); + + break; + } + default: { break; } + } + } + + return items; + }; + + Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size(); + imgui.set_next_window_pos(static_cast(cnv_size.get_width()), static_cast(cnv_size.get_height()), ImGuiCond_Always, 1.0f, 1.0f); + ImGui::SetNextWindowSizeConstraints(ImVec2(0.0f, 0.0f), ImVec2(-1.0f, 0.5f * static_cast(cnv_size.get_height()))); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + ImGui::SetNextWindowBgAlpha(0.6f); + imgui.begin(std::string("Time_estimate_2"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove); + // title imgui.title(_u8L("Estimated printing time")); - // times - if (ps.estimated_normal_print_time != "N/A") - add_mode(_u8L("Normal mode"), ps.estimated_normal_print_time, ps.estimated_normal_custom_gcode_print_times, Columns_Headers); - - if (ps.estimated_silent_print_time != "N/A") { - ImGui::Separator(); - add_mode(_u8L("Stealth mode"), ps.estimated_silent_print_time, ps.estimated_silent_custom_gcode_print_times, Columns_Headers); + // mode tabs + ImGui::BeginTabBar("mode_tabs"); + if (ps.estimated_normal_print_time != "N/A") { + if (ImGui::BeginTabItem(_u8L("Normal").c_str())) { + append_mode(ps.estimated_normal_print_time, generate_items(ps.estimated_normal_custom_gcode_print_times)); + ImGui::EndTabItem(); + } } + if (ps.estimated_silent_print_time != "N/A") { + if (ImGui::BeginTabItem(_u8L("Stealth").c_str())) { + append_mode(ps.estimated_silent_print_time, generate_items(ps.estimated_silent_custom_gcode_print_times)); + ImGui::EndTabItem(); + } + } + ImGui::EndTabBar(); imgui.end(); ImGui::PopStyleVar(); diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 2c463dc2a5..1253c047ef 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -1028,6 +1028,13 @@ void ImGuiWrapper::init_style() // Separator set_color(ImGuiCol_Separator, COL_ORANGE_LIGHT); + + // Tabs + set_color(ImGuiCol_Tab, COL_ORANGE_DARK); + set_color(ImGuiCol_TabHovered, COL_ORANGE_LIGHT); + set_color(ImGuiCol_TabActive, COL_ORANGE_LIGHT); + set_color(ImGuiCol_TabUnfocused, COL_GREY_DARK); + set_color(ImGuiCol_TabUnfocusedActive, COL_GREY_LIGHT); } void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) From 13a8ed0bd03aa508487dc22705f909b4563572b9 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 10 Jul 2020 13:20:03 +0200 Subject: [PATCH 147/255] GCodeViewer -> Reworked layout of color print legend to make it consistent for the single extruder and multi extruders cases --- src/slic3r/GUI/GCodeViewer.cpp | 239 ++++++++++++++++++--------------- 1 file changed, 133 insertions(+), 106 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 3ceaf86fa2..f22a691b1f 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1351,7 +1351,7 @@ void GCodeViewer::render_legend() const Line }; - auto add_item = [this, draw_list, &imgui](EItemType type, const Color& color, const std::string& label, std::function callback = nullptr) { + auto append_item = [this, draw_list, &imgui](EItemType type, const Color& color, const std::string& label, std::function callback = nullptr) { float icon_size = ImGui::GetTextLineHeight(); ImVec2 pos = ImGui::GetCursorScreenPos(); switch (type) @@ -1419,28 +1419,75 @@ void GCodeViewer::render_legend() const imgui.text(label); }; - auto add_range = [this, draw_list, &imgui, add_item](const Extrusions::Range& range, unsigned int decimals) { - auto add_range_item = [this, draw_list, &imgui, add_item](int i, float value, unsigned int decimals) { + auto append_range = [this, draw_list, &imgui, append_item](const Extrusions::Range& range, unsigned int decimals) { + auto append_range_item = [this, draw_list, &imgui, append_item](int i, float value, unsigned int decimals) { char buf[1024]; ::sprintf(buf, "%.*f", decimals, value); #if USE_ICON_HEXAGON - add_item(EItemType::Hexagon, Range_Colors[i], buf); + append_item(EItemType::Hexagon, Range_Colors[i], buf); #else - add_item(EItemType::Rect, Range_Colors[i], buf); + append_item(EItemType::Rect, Range_Colors[i], buf); #endif // USE_ICON_HEXAGON }; float step_size = range.step_size(); if (step_size == 0.0f) // single item use case - add_range_item(0, range.min, decimals); + append_range_item(0, range.min, decimals); else { for (int i = static_cast(Range_Colors.size()) - 1; i >= 0; --i) { - add_range_item(i, range.min + static_cast(i) * step_size, decimals); + append_range_item(i, range.min + static_cast(i) * step_size, decimals); } } }; + auto color_print_ranges = [this](unsigned char extruder_id, const std::vector& custom_gcode_per_print_z) { + std::vector>> ret; + ret.reserve(custom_gcode_per_print_z.size()); + + for (const auto& item : custom_gcode_per_print_z) { + if (extruder_id + 1 != static_cast(item.extruder)) + continue; + + if (item.type != ColorChange) + continue; + + auto lower_b = std::lower_bound(m_layers_zs.begin(), m_layers_zs.end(), item.print_z - Slic3r::DoubleSlider::epsilon()); + + if (lower_b == m_layers_zs.end()) + continue; + + double current_z = *lower_b; + double previous_z = lower_b == m_layers_zs.begin() ? 0.0 : *(--lower_b); + + // to avoid duplicate values, check adding values + if (ret.empty() || !(ret.back().second.first == previous_z && ret.back().second.second == current_z)) + ret.push_back({ decode_color(item.color), { previous_z, current_z } }); + } + + return ret; + }; + + auto upto_label = [](double z) { + char buf[64]; + ::sprintf(buf, "%.2f", z); + return _u8L("up to") + " " + std::string(buf) + " " + _u8L("mm"); + }; + + auto above_label = [](double z) { + char buf[64]; + ::sprintf(buf, "%.2f", z); + return _u8L("above") + " " + std::string(buf) + " " + _u8L("mm"); + }; + + auto fromto_label = [](double z1, double z2) { + char buf1[64]; + ::sprintf(buf1, "%.2f", z1); + char buf2[64]; + ::sprintf(buf2, "%.2f", z2); + return _u8L("from") + " " + std::string(buf1) + " " + _u8L("to") + " " + std::string(buf2) + " " + _u8L("mm"); + }; + // extrusion paths -> title switch (m_view_type) { @@ -1466,9 +1513,9 @@ void GCodeViewer::render_legend() const ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.3333f); #if USE_ICON_HEXAGON - add_item(EItemType::Hexagon, Extrusion_Role_Colors[static_cast(role)], _u8L(ExtrusionEntity::role_to_string(role)), [this, role]() { + append_item(EItemType::Hexagon, Extrusion_Role_Colors[static_cast(role)], _u8L(ExtrusionEntity::role_to_string(role)), [this, role]() { #else - add_item(EItemType::Rect, Extrusion_Role_Colors[static_cast(role)], _u8L(ExtrusionEntity::role_to_string(role)), [this, role]() { + append_item(EItemType::Rect, Extrusion_Role_Colors[static_cast(role)], _u8L(ExtrusionEntity::role_to_string(role)), [this, role]() { #endif // USE_ICON_HEXAGON if (role < erCount) { @@ -1485,24 +1532,19 @@ void GCodeViewer::render_legend() const } break; } - case EViewType::Height: { add_range(m_extrusions.ranges.height, 3); break; } - case EViewType::Width: { add_range(m_extrusions.ranges.width, 3); break; } - case EViewType::Feedrate: { add_range(m_extrusions.ranges.feedrate, 1); break; } - case EViewType::FanSpeed: { add_range(m_extrusions.ranges.fan_speed, 0); break; } - case EViewType::VolumetricRate: { add_range(m_extrusions.ranges.volumetric_rate, 3); break; } + case EViewType::Height: { append_range(m_extrusions.ranges.height, 3); break; } + case EViewType::Width: { append_range(m_extrusions.ranges.width, 3); break; } + case EViewType::Feedrate: { append_range(m_extrusions.ranges.feedrate, 1); break; } + case EViewType::FanSpeed: { append_range(m_extrusions.ranges.fan_speed, 0); break; } + case EViewType::VolumetricRate: { append_range(m_extrusions.ranges.volumetric_rate, 3); break; } case EViewType::Tool: { - size_t tools_count = m_tool_colors.size(); - for (size_t i = 0; i < tools_count; ++i) { - // shows only extruders actually used - auto it = std::find(m_extruder_ids.begin(), m_extruder_ids.end(), static_cast(i)); - if (it == m_extruder_ids.end()) - continue; - + // shows only extruders actually used + for (unsigned char i : m_extruder_ids) { #if USE_ICON_HEXAGON - add_item(EItemType::Hexagon, m_tool_colors[i], (boost::format(_u8L("Extruder %d")) % (i + 1)).str()); + append_item(EItemType::Hexagon, m_tool_colors[i], _u8L("Extruder") + " " + std::to_string(i + 1)); #else - add_item(EItemType::Rect, m_tool_colors[i], (boost::format(_u8L("Extruder %d")) % (i + 1)).str()); + append_item(EItemType::Rect, m_tool_colors[i], _u8L("Extruder") + " " + std::to_string(i + 1)); #endif // USE_ICON_HEXAGON } break; @@ -1512,97 +1554,85 @@ void GCodeViewer::render_legend() const const std::vector& custom_gcode_per_print_z = wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes; const int extruders_count = wxGetApp().extruders_edited_cnt(); if (extruders_count == 1) { // single extruder use case - if (custom_gcode_per_print_z.empty()) - // no data to show + std::vector>> cp_values = color_print_ranges(0, custom_gcode_per_print_z); + const int items_cnt = static_cast(cp_values.size()); + if (items_cnt == 0) { // There are no color changes, but there are some pause print or custom Gcode #if USE_ICON_HEXAGON - add_item(EItemType::Hexagon, m_tool_colors.front(), _u8L("Default print color")); + append_item(EItemType::Hexagon, m_tool_colors.front(), _u8L("Default color")); #else - add_item(EItemType::Rect, m_tool_colors.front(), _u8L("Default print color")); + append_item(EItemType::Rect, m_tool_colors.front(), _u8L("Default color")); #endif // USE_ICON_HEXAGON + } else { - std::vector> cp_values; - cp_values.reserve(custom_gcode_per_print_z.size()); - - for (auto custom_code : custom_gcode_per_print_z) { - if (custom_code.type != ColorChange) - continue; - - auto lower_b = std::lower_bound(m_layers_zs.begin(), m_layers_zs.end(), custom_code.print_z - Slic3r::DoubleSlider::epsilon()); - - if (lower_b == m_layers_zs.end()) - continue; - - double current_z = *lower_b; - double previous_z = lower_b == m_layers_zs.begin() ? 0.0 : *(--lower_b); - - // to avoid duplicate values, check adding values - if (cp_values.empty() || !(cp_values.back().first == previous_z && cp_values.back().second == current_z)) - cp_values.emplace_back(std::make_pair(previous_z, current_z)); - } - - const int items_cnt = static_cast(cp_values.size()); - if (items_cnt == 0) { // There is no one color change, but there are some pause print or custom Gcode + for (int i = items_cnt; i >= 0; --i) { + // create label for color change item + if (i == 0) { #if USE_ICON_HEXAGON - add_item(EItemType::Hexagon, m_tool_colors.front(), _u8L("Default print color")); + append_item(EItemType::Hexagon, m_tool_colors[0], upto_label(cp_values.front().second.first)); #else - add_item(EItemType::Rect, m_tool_colors.front(), _u8L("Default print color")); -#endif // USE_ICON_HEXAGON - } - else { - for (int i = items_cnt; i >= 0; --i) { - // create label for color change item - if (i == 0) { -#if USE_ICON_HEXAGON - add_item(EItemType::Hexagon, m_tool_colors[i], (boost::format(_u8L("up to %.2f mm")) % cp_values.front().first).str()); -#else - add_item(EItemType::Rect, m_tool_colors[i], (boost::format(_u8L("up to %.2f mm")) % cp_values.front().first).str()); -#endif // USE_ICON_HEXAGON - break; - } - else if (i == items_cnt) { -#if USE_ICON_HEXAGON - add_item(EItemType::Hexagon, m_tool_colors[i], (boost::format(_u8L("above %.2f mm")) % cp_values[i - 1].second).str()); -#else - add_item(EItemType::Rect, m_tool_colors[i], (boost::format(_u8L("above %.2f mm")) % cp_values[i - 1].second).str()); -#endif // USE_ICON_HEXAGON - continue; - } -#if USE_ICON_HEXAGON - add_item(EItemType::Hexagon, m_tool_colors[i], (boost::format(_u8L("%.2f - %.2f mm")) % cp_values[i - 1].second % cp_values[i].first).str()); -#else - add_item(EItemType::Rect, m_tool_colors[i], (boost::format(_u8L("%.2f - %.2f mm")) % cp_values[i - 1].second % cp_values[i].first).str()); + append_item(EItemType::Rect, m_tool_colors[0], upto_label(cp_values.front().second.first); #endif // USE_ICON_HEXAGON + break; } + else if (i == items_cnt) { +#if USE_ICON_HEXAGON + append_item(EItemType::Hexagon, cp_values[i - 1].first, above_label(cp_values[i - 1].second.second)); +#else + append_item(EItemType::Rect, cp_values[i - 1].first, above_label(cp_values[i - 1].second.second); +#endif // USE_ICON_HEXAGON + continue; + } +#if USE_ICON_HEXAGON + append_item(EItemType::Hexagon, cp_values[i - 1].first, fromto_label(cp_values[i - 1].second.second, cp_values[i].second.first)); +#else + append_item(EItemType::Rect, cp_values[i - 1].first, fromto_label(cp_values[i - 1].second.second, cp_values[i].second.first)); +#endif // USE_ICON_HEXAGON } } } else // multi extruder use case { - // extruders - for (unsigned int i = 0; i < (unsigned int)extruders_count; ++i) { - // shows only extruders actually used - auto it = std::find(m_extruder_ids.begin(), m_extruder_ids.end(), static_cast(i)); - if (it == m_extruder_ids.end()) - continue; - + // shows only extruders actually used + for (unsigned char i : m_extruder_ids) { + std::vector>> cp_values = color_print_ranges(i, custom_gcode_per_print_z); + const int items_cnt = static_cast(cp_values.size()); + if (items_cnt == 0) { // There are no color changes, but there are some pause print or custom Gcode #if USE_ICON_HEXAGON - add_item(EItemType::Hexagon, m_tool_colors[i], (boost::format(_u8L("Extruder %d")) % (i + 1)).str()); + append_item(EItemType::Hexagon, m_tool_colors[i], _u8L("Extruder") + " " + std::to_string(i + 1) + " " + _u8L("default color")); #else - add_item(EItemType::Rect, m_tool_colors[i], (boost::format(_u8L("Extruder %d")) % (i + 1)).str()); + append_item(EItemType::Rect, m_tool_colors[i], _u8L("Extruder") + " " + std::to_string(i + 1) + " " + _u8L("default color")); #endif // USE_ICON_HEXAGON - } - - // color changes - int color_change_idx = 1 + static_cast(m_tool_colors.size()) - extruders_count; - size_t last_color_id = m_tool_colors.size() - 1; - for (int i = static_cast(custom_gcode_per_print_z.size()) - 1; i >= 0; --i) { - if (custom_gcode_per_print_z[i].type == ColorChange) { + } + else { + for (int j = items_cnt; j >= 0; --j) { + // create label for color change item + std::string label = _u8L("Extruder") + " " + std::to_string(i + 1); + if (j == 0) { + label += " " + upto_label(cp_values.front().second.first); #if USE_ICON_HEXAGON - add_item(EItemType::Hexagon, m_tool_colors[last_color_id--], + append_item(EItemType::Hexagon, m_tool_colors[i], label); #else - add_item(EItemType::Rect, m_tool_colors[last_color_id--], + append_item(EItemType::Rect, m_tool_colors[i], label); #endif // USE_ICON_HEXAGON - (boost::format(_u8L("Color change for Extruder %d at %.2f mm")) % custom_gcode_per_print_z[i].extruder % custom_gcode_per_print_z[i].print_z).str()); + break; + } + else if (j == items_cnt) { + label += " " + above_label(cp_values[j - 1].second.second); +#if USE_ICON_HEXAGON + append_item(EItemType::Hexagon, cp_values[j - 1].first, label); +#else + append_item(EItemType::Rect, cp_values[j - 1].first, label); +#endif // USE_ICON_HEXAGON + continue; + } + + label += " " + fromto_label(cp_values[j - 1].second.second, cp_values[j].second.first); +#if USE_ICON_HEXAGON + append_item(EItemType::Hexagon, cp_values[j - 1].first, label); +#else + append_item(EItemType::Rect, cp_values[j - 1].first, label); +#endif // USE_ICON_HEXAGON + } } } } @@ -1629,9 +1659,9 @@ void GCodeViewer::render_legend() const imgui.title(_u8L("Travel")); // items - add_item(EItemType::Line, Travel_Colors[0], _u8L("Movement")); - add_item(EItemType::Line, Travel_Colors[1], _u8L("Extrusion")); - add_item(EItemType::Line, Travel_Colors[2], _u8L("Retraction")); + append_item(EItemType::Line, Travel_Colors[0], _u8L("Movement")); + append_item(EItemType::Line, Travel_Colors[1], _u8L("Extrusion")); + append_item(EItemType::Line, Travel_Colors[2], _u8L("Retraction")); break; } @@ -1652,13 +1682,13 @@ void GCodeViewer::render_legend() const available(GCodeProcessor::EMoveType::Unretract); }; - auto add_option = [this, add_item](GCodeProcessor::EMoveType move_type, EOptionsColors color, const std::string& text) { + auto add_option = [this, append_item](GCodeProcessor::EMoveType move_type, EOptionsColors color, const std::string& text) { const TBuffer& buffer = m_buffers[buffer_id(move_type)]; if (buffer.visible && buffer.indices.count > 0) #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR - add_item((m_shaders_editor.points.shader_version == 0) ? EItemType::Rect : EItemType::Circle, Options_Colors[static_cast(color)], text); + append_item((m_shaders_editor.points.shader_version == 0) ? EItemType::Rect : EItemType::Circle, Options_Colors[static_cast(color)], text); #else - add_item((buffer.shader == "options_110") ? EItemType::Rect : EItemType::Circle, Options_Colors[static_cast(color)], text); + append_item((buffer.shader == "options_110") ? EItemType::Rect : EItemType::Circle, Options_Colors[static_cast(color)], text); #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR }; @@ -1681,7 +1711,6 @@ void GCodeViewer::render_legend() const ImGui::PopStyleVar(); } - void GCodeViewer::render_time_estimate() const { if (!m_time_estimate_enabled) @@ -1724,8 +1753,7 @@ void GCodeViewer::render_time_estimate() const case CustomGCode::PausePrint: { label = _u8L("Pause"); break; } case CustomGCode::ColorChange: { - int extruders_count = wxGetApp().extruders_edited_cnt(); - label = (extruders_count > 1) ? _u8L("[XX] Color") : _u8L("Color"); + label = (wxGetApp().extruders_edited_cnt() > 1) ? _u8L("[XX] Color") : _u8L("Color"); break; } default: { break; } @@ -1742,9 +1770,8 @@ void GCodeViewer::render_time_estimate() const }; auto append_color = [this, &imgui](int id, int extruder_id, const Color& color, Offsets& offsets, const Time& time) { ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - int extruders_count = wxGetApp().extruders_edited_cnt(); std::string text; - if (extruders_count > 1) + if (wxGetApp().extruders_edited_cnt() > 1) text = "[" + std::to_string(extruder_id) + "] "; text += _u8L("Color"); imgui.text(text); From 755fdb5ab478042a2a7edf9318ab46defb637444 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 10 Jul 2020 15:31:56 +0200 Subject: [PATCH 148/255] GCodeViewer -> Refactoring of data shown into estimated printing time dialog --- src/slic3r/GUI/GCodeViewer.cpp | 73 +++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 31 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index f22a691b1f..aaabd62220 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1728,9 +1728,16 @@ void GCodeViewer::render_time_estimate() const // helper structure containig the data needed to render the items struct Item { - CustomGCode::Type type; + enum class EType : unsigned char + { + Print, + ColorChange, + Pause + }; + EType type; int extruder_id; - Color color; + Color color1; + Color color2; Time time; }; using Items = std::vector; @@ -1750,13 +1757,9 @@ void GCodeViewer::render_time_estimate() const std::string label; switch (item.type) { - case CustomGCode::PausePrint: { label = _u8L("Pause"); break; } - case CustomGCode::ColorChange: - { - label = (wxGetApp().extruders_edited_cnt() > 1) ? _u8L("[XX] Color") : _u8L("Color"); - break; - } - default: { break; } + case Item::EType::Print: { label = _u8L("Print"); break; } + case Item::EType::Pause: { label = _u8L("Pause"); break; } + case Item::EType::ColorChange: { label = _u8L("Color change"); break; } } ret[0] = std::max(ret[0], ImGui::CalcTextSize(label.c_str()).x); @@ -1764,17 +1767,13 @@ void GCodeViewer::render_time_estimate() const } const ImGuiStyle& style = ImGui::GetStyle(); - ret[0] += ImGui::GetTextLineHeight() + 2.0f * style.ItemSpacing.x; + ret[0] += 2.0f * (ImGui::GetTextLineHeight() + style.ItemSpacing.x); ret[1] += ret[0] + style.ItemSpacing.x; return ret; }; - auto append_color = [this, &imgui](int id, int extruder_id, const Color& color, Offsets& offsets, const Time& time) { + auto append_color = [this, &imgui](const Color& color1, const Color& color2, Offsets& offsets, const Time& time) { ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - std::string text; - if (wxGetApp().extruders_edited_cnt() > 1) - text = "[" + std::to_string(extruder_id) + "] "; - text += _u8L("Color"); - imgui.text(text); + imgui.text(_u8L("Color change")); ImGui::PopStyleColor(); ImGui::SameLine(); @@ -1784,15 +1783,18 @@ void GCodeViewer::render_time_estimate() const pos.x -= 0.5f * ImGui::GetStyle().ItemSpacing.x; #if USE_ICON_HEXAGON ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size)); - draw_list->AddNgonFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 6); + draw_list->AddNgonFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color1[0], color1[1], color1[2], 1.0f }), 6); + center.x += icon_size; + draw_list->AddNgonFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color2[0], color2[1], color2[2], 1.0f }), 6); #else draw_list->AddRectFilled({ pos.x + 1.0f, pos.y + 1.0f }, { pos.x + icon_size - 1.0f, pos.y + icon_size - 1.0f }, - ImGui::GetColorU32({ m_tool_colors[i][0], m_tool_colors[i][1], m_tool_colors[i][2], 1.0f })); + ImGui::GetColorU32({ color1[0], color1[1], color1[2], 1.0f })); + pos.x += icon_size; + draw_list->AddRectFilled({ pos.x + 1.0f, pos.y + 1.0f }, { pos.x + icon_size - 1.0f, pos.y + icon_size - 1.0f }, + ImGui::GetColorU32({ color2[0], color2[1], color2[2], 1.0f })); #endif // USE_ICON_HEXAGON ImGui::SameLine(offsets[0]); - imgui.text(short_time(get_time_dhms(time.second))); - ImGui::SameLine(offsets[1]); - imgui.text(short_time(get_time_dhms(time.first))); + imgui.text(short_time(get_time_dhms(time.second - time.first))); }; if (items.empty()) @@ -1810,11 +1812,21 @@ void GCodeViewer::render_time_estimate() const ImGui::PopStyleColor(); ImGui::Separator(); - unsigned int last_color_id = 0; for (const Item& item : items) { switch (item.type) { - case CustomGCode::PausePrint: + case Item::EType::Print: + { + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); + imgui.text(_u8L("Print")); + ImGui::PopStyleColor(); + ImGui::SameLine(offsets[0]); + imgui.text(short_time(get_time_dhms(item.time.second))); + ImGui::SameLine(offsets[1]); + imgui.text(short_time(get_time_dhms(item.time.first))); + break; + } + case Item::EType::Pause: { ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); imgui.text(_u8L("Pause")); @@ -1823,13 +1835,11 @@ void GCodeViewer::render_time_estimate() const imgui.text(short_time(get_time_dhms(item.time.second - item.time.first))); break; } - case CustomGCode::ColorChange: + case Item::EType::ColorChange: { - append_color(last_color_id, item.extruder_id, item.color, offsets, item.time); - ++last_color_id; + append_color(item.color1, item.color2, offsets, item.time); break; } - default: { break; } } } }; @@ -1859,8 +1869,8 @@ void GCodeViewer::render_time_estimate() const { auto it = std::find_if(custom_gcode_per_print_z.begin(), custom_gcode_per_print_z.end(), [time_rec](const CustomGCode::Item& item) { return item.type == time_rec.first; }); if (it != custom_gcode_per_print_z.end()) { - items.push_back({ CustomGCode::ColorChange, it->extruder, last_color[it->extruder - 1], time_rec.second }); - items.push_back({ time_rec.first, it->extruder, last_color[it->extruder - 1], time_rec.second }); + items.push_back({ Item::EType::Print, it->extruder, Color(), Color(), time_rec.second }); + items.push_back({ Item::EType::Pause, it->extruder, Color(), Color(), time_rec.second }); custom_gcode_per_print_z.erase(it); } break; @@ -1869,13 +1879,14 @@ void GCodeViewer::render_time_estimate() const { auto it = std::find_if(custom_gcode_per_print_z.begin(), custom_gcode_per_print_z.end(), [time_rec](const CustomGCode::Item& item) { return item.type == time_rec.first; }); if (it != custom_gcode_per_print_z.end()) { - items.push_back({ time_rec.first, it->extruder, last_color[it->extruder - 1], time_rec.second }); + items.push_back({ Item::EType::Print, it->extruder, Color(), Color(), time_rec.second }); + items.push_back({ Item::EType::ColorChange, it->extruder, last_color[it->extruder - 1], decode_color(it->color), time_rec.second }); last_color[it->extruder - 1] = decode_color(it->color); last_extruder_id = it->extruder; custom_gcode_per_print_z.erase(it); } else - items.push_back({ time_rec.first, last_extruder_id, last_color[last_extruder_id - 1], time_rec.second }); + items.push_back({ Item::EType::Print, last_extruder_id, Color(), Color(), time_rec.second }); break; } From 3a88e698969bdcdf5cd04225bedff96215cf5fa6 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 16 Jul 2020 11:09:21 +0200 Subject: [PATCH 149/255] ENABLE_GCODE_VIEWER -> Integration of time estimator into GCodeProcessor --- src/libslic3r/GCode.cpp | 1246 ++++++++++++------------ src/libslic3r/GCode/GCodeProcessor.cpp | 821 +++++++++++++++- src/libslic3r/GCode/GCodeProcessor.hpp | 193 +++- src/libslic3r/GCodeTimeEstimator.cpp | 16 - src/libslic3r/GCodeTimeEstimator.hpp | 4 - src/libslic3r/Print.cpp | 18 +- src/libslic3r/Print.hpp | 12 +- src/slic3r/GUI/GCodeViewer.cpp | 3 + src/slic3r/GUI/Plater.cpp | 22 +- 9 files changed, 1631 insertions(+), 704 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 7bfb73aa37..47448954c8 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -48,662 +48,684 @@ using namespace std::literals::string_view_literals; namespace Slic3r { -//! macro used to mark string used at localization, -//! return same string + //! macro used to mark string used at localization, + //! return same string #define L(s) (s) #define _(s) Slic3r::I18N::translate(s) // Only add a newline in case the current G-code does not end with a newline. -static inline void check_add_eol(std::string &gcode) -{ - if (! gcode.empty() && gcode.back() != '\n') - gcode += '\n'; -} - - -// Return true if tch_prefix is found in custom_gcode -static bool custom_gcode_changes_tool(const std::string& custom_gcode, const std::string& tch_prefix, unsigned next_extruder) -{ - bool ok = false; - size_t from_pos = 0; - size_t pos = 0; - while ((pos = custom_gcode.find(tch_prefix, from_pos)) != std::string::npos) { - if (pos+1 == custom_gcode.size()) - break; - from_pos = pos+1; - // only whitespace is allowed before the command - while (--pos < custom_gcode.size() && custom_gcode[pos] != '\n') { - if (! std::isspace(custom_gcode[pos])) - goto NEXT; - } - { - // we should also check that the extruder changes to what was expected - std::istringstream ss(custom_gcode.substr(from_pos, std::string::npos)); - unsigned num = 0; - if (ss >> num) - ok = (num == next_extruder); - } -NEXT: ; + static inline void check_add_eol(std::string& gcode) + { + if (!gcode.empty() && gcode.back() != '\n') + gcode += '\n'; } - return ok; -} -void AvoidCrossingPerimeters::init_external_mp(const Print &print) -{ - m_external_mp = Slic3r::make_unique(union_ex(this->collect_contours_all_layers(print.objects()))); -} -// Plan a travel move while minimizing the number of perimeter crossings. -// point is in unscaled coordinates, in the coordinate system of the current active object -// (set by gcodegen.set_origin()). -Polyline AvoidCrossingPerimeters::travel_to(const GCode &gcodegen, const Point &point) -{ - // If use_external, then perform the path planning in the world coordinate system (correcting for the gcodegen offset). - // Otherwise perform the path planning in the coordinate system of the active object. - bool use_external = this->use_external_mp || this->use_external_mp_once; - Point scaled_origin = use_external ? Point::new_scale(gcodegen.origin()(0), gcodegen.origin()(1)) : Point(0, 0); - Polyline result = (use_external ? m_external_mp.get() : m_layer_mp.get())-> - shortest_path(gcodegen.last_pos() + scaled_origin, point + scaled_origin); - if (use_external) - result.translate(- scaled_origin); - return result; -} - -// Collect outer contours of all objects over all layers. -// Discard objects only containing thin walls (offset would fail on an empty polygon). -// Used by avoid crossing perimeters feature. -Polygons AvoidCrossingPerimeters::collect_contours_all_layers(const PrintObjectPtrs& objects) -{ - Polygons islands; - for (const PrintObject *object : objects) { - // Reducing all the object slices into the Z projection in a logarithimc fashion. - // First reduce to half the number of layers. - std::vector polygons_per_layer((object->layers().size() + 1) / 2); - tbb::parallel_for(tbb::blocked_range(0, object->layers().size() / 2), - [&object, &polygons_per_layer](const tbb::blocked_range &range) { - for (size_t i = range.begin(); i < range.end(); ++ i) { - const Layer* layer1 = object->layers()[i * 2]; - const Layer* layer2 = object->layers()[i * 2 + 1]; - Polygons polys; - polys.reserve(layer1->lslices.size() + layer2->lslices.size()); - for (const ExPolygon &expoly : layer1->lslices) - //FIXME no holes? - polys.emplace_back(expoly.contour); - for (const ExPolygon &expoly : layer2->lslices) - //FIXME no holes? - polys.emplace_back(expoly.contour); - polygons_per_layer[i] = union_(polys); - } - }); - if (object->layers().size() & 1) { - const Layer *layer = object->layers().back(); - Polygons polys; - polys.reserve(layer->lslices.size()); - for (const ExPolygon &expoly : layer->lslices) - //FIXME no holes? - polys.emplace_back(expoly.contour); - polygons_per_layer.back() = union_(polys); - } - // Now reduce down to a single layer. - size_t cnt = polygons_per_layer.size(); - while (cnt > 1) { - tbb::parallel_for(tbb::blocked_range(0, cnt / 2), - [&polygons_per_layer](const tbb::blocked_range &range) { - for (size_t i = range.begin(); i < range.end(); ++ i) { - Polygons polys; - polys.reserve(polygons_per_layer[i * 2].size() + polygons_per_layer[i * 2 + 1].size()); - polygons_append(polys, polygons_per_layer[i * 2]); - polygons_append(polys, polygons_per_layer[i * 2 + 1]); - polygons_per_layer[i * 2] = union_(polys); - } - }); - for (size_t i = 0; i < cnt / 2; ++ i) - polygons_per_layer[i] = std::move(polygons_per_layer[i * 2]); - if (cnt & 1) - polygons_per_layer[cnt / 2] = std::move(polygons_per_layer[cnt - 1]); - cnt = (cnt + 1) / 2; - } - // And collect copies of the objects. - for (const PrintInstance &instance : object->instances()) { - // All the layers were reduced to the 1st item of polygons_per_layer. - size_t i = islands.size(); - polygons_append(islands, polygons_per_layer.front()); - for (; i < islands.size(); ++ i) - islands[i].translate(instance.shift); - } - } - return islands; -} - -std::string OozePrevention::pre_toolchange(GCode &gcodegen) -{ - std::string gcode; - - // move to the nearest standby point - if (!this->standby_points.empty()) { - // get current position in print coordinates - Vec3d writer_pos = gcodegen.writer().get_position(); - Point pos = Point::new_scale(writer_pos(0), writer_pos(1)); - - // find standby point - Point standby_point; - pos.nearest_point(this->standby_points, &standby_point); - - /* We don't call gcodegen.travel_to() because we don't need retraction (it was already - triggered by the caller) nor avoid_crossing_perimeters and also because the coordinates - of the destination point must not be transformed by origin nor current extruder offset. */ - gcode += gcodegen.writer().travel_to_xy(unscale(standby_point), - "move to standby position"); - } - - if (gcodegen.config().standby_temperature_delta.value != 0) { - // we assume that heating is always slower than cooling, so no need to block - gcode += gcodegen.writer().set_temperature - (this->_get_temp(gcodegen) + gcodegen.config().standby_temperature_delta.value, false, gcodegen.writer().extruder()->id()); - } - - return gcode; -} - -std::string OozePrevention::post_toolchange(GCode &gcodegen) -{ - return (gcodegen.config().standby_temperature_delta.value != 0) ? - gcodegen.writer().set_temperature(this->_get_temp(gcodegen), true, gcodegen.writer().extruder()->id()) : - std::string(); -} - -int -OozePrevention::_get_temp(GCode &gcodegen) -{ - return (gcodegen.layer() != NULL && gcodegen.layer()->id() == 0) - ? gcodegen.config().first_layer_temperature.get_at(gcodegen.writer().extruder()->id()) - : gcodegen.config().temperature.get_at(gcodegen.writer().extruder()->id()); -} - -std::string Wipe::wipe(GCode &gcodegen, bool toolchange) -{ - std::string gcode; - - /* Reduce feedrate a bit; travel speed is often too high to move on existing material. - Too fast = ripping of existing material; too slow = short wipe path, thus more blob. */ - double wipe_speed = gcodegen.writer().config.travel_speed.value * 0.8; - - // get the retraction length - double length = toolchange - ? gcodegen.writer().extruder()->retract_length_toolchange() - : gcodegen.writer().extruder()->retract_length(); - // Shorten the retraction length by the amount already retracted before wipe. - length *= (1. - gcodegen.writer().extruder()->retract_before_wipe()); - - if (length > 0) { - /* Calculate how long we need to travel in order to consume the required - amount of retraction. In other words, how far do we move in XY at wipe_speed - for the time needed to consume retract_length at retract_speed? */ - double wipe_dist = scale_(length / gcodegen.writer().extruder()->retract_speed() * wipe_speed); - - /* Take the stored wipe path and replace first point with the current actual position - (they might be different, for example, in case of loop clipping). */ - Polyline wipe_path; - wipe_path.append(gcodegen.last_pos()); - wipe_path.append( - this->path.points.begin() + 1, - this->path.points.end() - ); - - wipe_path.clip_end(wipe_path.length() - wipe_dist); - - // subdivide the retraction in segments - if (! wipe_path.empty()) { - for (const Line &line : wipe_path.lines()) { - double segment_length = line.length(); - /* Reduce retraction length a bit to avoid effective retraction speed to be greater than the configured one - due to rounding (TODO: test and/or better math for this) */ - double dE = length * (segment_length / wipe_dist) * 0.95; - //FIXME one shall not generate the unnecessary G1 Fxxx commands, here wipe_speed is a constant inside this cycle. - // Is it here for the cooling markers? Or should it be outside of the cycle? - gcode += gcodegen.writer().set_speed(wipe_speed*60, "", gcodegen.enable_cooling_markers() ? ";_WIPE" : ""); - gcode += gcodegen.writer().extrude_to_xy( - gcodegen.point_to_gcode(line.b), - -dE, - "wipe and retract" - ); + // Return true if tch_prefix is found in custom_gcode + static bool custom_gcode_changes_tool(const std::string& custom_gcode, const std::string& tch_prefix, unsigned next_extruder) + { + bool ok = false; + size_t from_pos = 0; + size_t pos = 0; + while ((pos = custom_gcode.find(tch_prefix, from_pos)) != std::string::npos) { + if (pos + 1 == custom_gcode.size()) + break; + from_pos = pos + 1; + // only whitespace is allowed before the command + while (--pos < custom_gcode.size() && custom_gcode[pos] != '\n') { + if (!std::isspace(custom_gcode[pos])) + goto NEXT; } - gcodegen.set_last_pos(wipe_path.points.back()); + { + // we should also check that the extruder changes to what was expected + std::istringstream ss(custom_gcode.substr(from_pos, std::string::npos)); + unsigned num = 0; + if (ss >> num) + ok = (num == next_extruder); + } + NEXT:; } - - // prevent wiping again on same path - this->reset_path(); - } - - return gcode; -} - -static inline Point wipe_tower_point_to_object_point(GCode &gcodegen, const Vec2f &wipe_tower_pt) -{ - return Point(scale_(wipe_tower_pt.x() - gcodegen.origin()(0)), scale_(wipe_tower_pt.y() - gcodegen.origin()(1))); -} - -std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::ToolChangeResult &tcr, int new_extruder_id, double z) const -{ - if (new_extruder_id != -1 && new_extruder_id != tcr.new_tool) - throw std::invalid_argument("Error: WipeTowerIntegration::append_tcr was asked to do a toolchange it didn't expect."); - - std::string gcode; - - // Toolchangeresult.gcode assumes the wipe tower corner is at the origin (except for priming lines) - // We want to rotate and shift all extrusions (gcode postprocessing) and starting and ending position - float alpha = m_wipe_tower_rotation/180.f * float(M_PI); - Vec2f start_pos = tcr.start_pos; - Vec2f end_pos = tcr.end_pos; - if (!tcr.priming) { - start_pos = Eigen::Rotation2Df(alpha) * start_pos; - start_pos += m_wipe_tower_pos; - end_pos = Eigen::Rotation2Df(alpha) * end_pos; - end_pos += m_wipe_tower_pos; + return ok; } - Vec2f wipe_tower_offset = tcr.priming ? Vec2f::Zero() : m_wipe_tower_pos; - float wipe_tower_rotation = tcr.priming ? 0.f : alpha; - - std::string tcr_rotated_gcode = post_process_wipe_tower_moves(tcr, wipe_tower_offset, wipe_tower_rotation); - - if (!tcr.priming) { - // Move over the wipe tower. - // Retract for a tool change, using the toolchange retract value and setting the priming extra length. - gcode += gcodegen.retract(true); - gcodegen.m_avoid_crossing_perimeters.use_external_mp_once = true; - gcode += gcodegen.travel_to( - wipe_tower_point_to_object_point(gcodegen, start_pos), - erMixed, - "Travel to a Wipe Tower"); - gcode += gcodegen.unretract(); + void AvoidCrossingPerimeters::init_external_mp(const Print& print) + { + m_external_mp = Slic3r::make_unique(union_ex(this->collect_contours_all_layers(print.objects()))); } - double current_z = gcodegen.writer().get_position().z(); - if (z == -1.) // in case no specific z was provided, print at current_z pos - z = current_z; - if (! is_approx(z, current_z)) { - gcode += gcodegen.writer().retract(); - gcode += gcodegen.writer().travel_to_z(z, "Travel down to the last wipe tower layer."); - gcode += gcodegen.writer().unretract(); + // Plan a travel move while minimizing the number of perimeter crossings. + // point is in unscaled coordinates, in the coordinate system of the current active object + // (set by gcodegen.set_origin()). + Polyline AvoidCrossingPerimeters::travel_to(const GCode& gcodegen, const Point& point) + { + // If use_external, then perform the path planning in the world coordinate system (correcting for the gcodegen offset). + // Otherwise perform the path planning in the coordinate system of the active object. + bool use_external = this->use_external_mp || this->use_external_mp_once; + Point scaled_origin = use_external ? Point::new_scale(gcodegen.origin()(0), gcodegen.origin()(1)) : Point(0, 0); + Polyline result = (use_external ? m_external_mp.get() : m_layer_mp.get())-> + shortest_path(gcodegen.last_pos() + scaled_origin, point + scaled_origin); + if (use_external) + result.translate(-scaled_origin); + return result; } - - // Process the end filament gcode. - std::string end_filament_gcode_str; - if (gcodegen.writer().extruder() != nullptr) { - // Process the custom end_filament_gcode in case of single_extruder_multi_material. - unsigned int old_extruder_id = gcodegen.writer().extruder()->id(); - const std::string &end_filament_gcode = gcodegen.config().end_filament_gcode.get_at(old_extruder_id); - if (gcodegen.writer().extruder() != nullptr && ! end_filament_gcode.empty()) { - end_filament_gcode_str = gcodegen.placeholder_parser_process("end_filament_gcode", end_filament_gcode, old_extruder_id); - check_add_eol(end_filament_gcode_str); + // Collect outer contours of all objects over all layers. + // Discard objects only containing thin walls (offset would fail on an empty polygon). + // Used by avoid crossing perimeters feature. + Polygons AvoidCrossingPerimeters::collect_contours_all_layers(const PrintObjectPtrs& objects) + { + Polygons islands; + for (const PrintObject* object : objects) { + // Reducing all the object slices into the Z projection in a logarithimc fashion. + // First reduce to half the number of layers. + std::vector polygons_per_layer((object->layers().size() + 1) / 2); + tbb::parallel_for(tbb::blocked_range(0, object->layers().size() / 2), + [&object, &polygons_per_layer](const tbb::blocked_range& range) { + for (size_t i = range.begin(); i < range.end(); ++i) { + const Layer* layer1 = object->layers()[i * 2]; + const Layer* layer2 = object->layers()[i * 2 + 1]; + Polygons polys; + polys.reserve(layer1->lslices.size() + layer2->lslices.size()); + for (const ExPolygon& expoly : layer1->lslices) + //FIXME no holes? + polys.emplace_back(expoly.contour); + for (const ExPolygon& expoly : layer2->lslices) + //FIXME no holes? + polys.emplace_back(expoly.contour); + polygons_per_layer[i] = union_(polys); + } + }); + if (object->layers().size() & 1) { + const Layer* layer = object->layers().back(); + Polygons polys; + polys.reserve(layer->lslices.size()); + for (const ExPolygon& expoly : layer->lslices) + //FIXME no holes? + polys.emplace_back(expoly.contour); + polygons_per_layer.back() = union_(polys); + } + // Now reduce down to a single layer. + size_t cnt = polygons_per_layer.size(); + while (cnt > 1) { + tbb::parallel_for(tbb::blocked_range(0, cnt / 2), + [&polygons_per_layer](const tbb::blocked_range& range) { + for (size_t i = range.begin(); i < range.end(); ++i) { + Polygons polys; + polys.reserve(polygons_per_layer[i * 2].size() + polygons_per_layer[i * 2 + 1].size()); + polygons_append(polys, polygons_per_layer[i * 2]); + polygons_append(polys, polygons_per_layer[i * 2 + 1]); + polygons_per_layer[i * 2] = union_(polys); + } + }); + for (size_t i = 0; i < cnt / 2; ++i) + polygons_per_layer[i] = std::move(polygons_per_layer[i * 2]); + if (cnt & 1) + polygons_per_layer[cnt / 2] = std::move(polygons_per_layer[cnt - 1]); + cnt = (cnt + 1) / 2; + } + // And collect copies of the objects. + for (const PrintInstance& instance : object->instances()) { + // All the layers were reduced to the 1st item of polygons_per_layer. + size_t i = islands.size(); + polygons_append(islands, polygons_per_layer.front()); + for (; i < islands.size(); ++i) + islands[i].translate(instance.shift); + } } + return islands; } - // Process the custom toolchange_gcode. If it is empty, provide a simple Tn command to change the filament. - // Otherwise, leave control to the user completely. - std::string toolchange_gcode_str; - if (true /*gcodegen.writer().extruder() != nullptr*/) { - const std::string& toolchange_gcode = gcodegen.config().toolchange_gcode.value; - if (!toolchange_gcode.empty()) { + std::string OozePrevention::pre_toolchange(GCode& gcodegen) + { + std::string gcode; + + // move to the nearest standby point + if (!this->standby_points.empty()) { + // get current position in print coordinates + Vec3d writer_pos = gcodegen.writer().get_position(); + Point pos = Point::new_scale(writer_pos(0), writer_pos(1)); + + // find standby point + Point standby_point; + pos.nearest_point(this->standby_points, &standby_point); + + /* We don't call gcodegen.travel_to() because we don't need retraction (it was already + triggered by the caller) nor avoid_crossing_perimeters and also because the coordinates + of the destination point must not be transformed by origin nor current extruder offset. */ + gcode += gcodegen.writer().travel_to_xy(unscale(standby_point), + "move to standby position"); + } + + if (gcodegen.config().standby_temperature_delta.value != 0) { + // we assume that heating is always slower than cooling, so no need to block + gcode += gcodegen.writer().set_temperature + (this->_get_temp(gcodegen) + gcodegen.config().standby_temperature_delta.value, false, gcodegen.writer().extruder()->id()); + } + + return gcode; + } + + std::string OozePrevention::post_toolchange(GCode& gcodegen) + { + return (gcodegen.config().standby_temperature_delta.value != 0) ? + gcodegen.writer().set_temperature(this->_get_temp(gcodegen), true, gcodegen.writer().extruder()->id()) : + std::string(); + } + + int + OozePrevention::_get_temp(GCode& gcodegen) + { + return (gcodegen.layer() != NULL && gcodegen.layer()->id() == 0) + ? gcodegen.config().first_layer_temperature.get_at(gcodegen.writer().extruder()->id()) + : gcodegen.config().temperature.get_at(gcodegen.writer().extruder()->id()); + } + + std::string Wipe::wipe(GCode& gcodegen, bool toolchange) + { + std::string gcode; + + /* Reduce feedrate a bit; travel speed is often too high to move on existing material. + Too fast = ripping of existing material; too slow = short wipe path, thus more blob. */ + double wipe_speed = gcodegen.writer().config.travel_speed.value * 0.8; + + // get the retraction length + double length = toolchange + ? gcodegen.writer().extruder()->retract_length_toolchange() + : gcodegen.writer().extruder()->retract_length(); + // Shorten the retraction length by the amount already retracted before wipe. + length *= (1. - gcodegen.writer().extruder()->retract_before_wipe()); + + if (length > 0) { + /* Calculate how long we need to travel in order to consume the required + amount of retraction. In other words, how far do we move in XY at wipe_speed + for the time needed to consume retract_length at retract_speed? */ + double wipe_dist = scale_(length / gcodegen.writer().extruder()->retract_speed() * wipe_speed); + + /* Take the stored wipe path and replace first point with the current actual position + (they might be different, for example, in case of loop clipping). */ + Polyline wipe_path; + wipe_path.append(gcodegen.last_pos()); + wipe_path.append( + this->path.points.begin() + 1, + this->path.points.end() + ); + + wipe_path.clip_end(wipe_path.length() - wipe_dist); + + // subdivide the retraction in segments + if (!wipe_path.empty()) { + for (const Line& line : wipe_path.lines()) { + double segment_length = line.length(); + /* Reduce retraction length a bit to avoid effective retraction speed to be greater than the configured one + due to rounding (TODO: test and/or better math for this) */ + double dE = length * (segment_length / wipe_dist) * 0.95; + //FIXME one shall not generate the unnecessary G1 Fxxx commands, here wipe_speed is a constant inside this cycle. + // Is it here for the cooling markers? Or should it be outside of the cycle? + gcode += gcodegen.writer().set_speed(wipe_speed * 60, "", gcodegen.enable_cooling_markers() ? ";_WIPE" : ""); + gcode += gcodegen.writer().extrude_to_xy( + gcodegen.point_to_gcode(line.b), + -dE, + "wipe and retract" + ); + } + gcodegen.set_last_pos(wipe_path.points.back()); + } + + // prevent wiping again on same path + this->reset_path(); + } + + return gcode; + } + + static inline Point wipe_tower_point_to_object_point(GCode& gcodegen, const Vec2f& wipe_tower_pt) + { + return Point(scale_(wipe_tower_pt.x() - gcodegen.origin()(0)), scale_(wipe_tower_pt.y() - gcodegen.origin()(1))); + } + + std::string WipeTowerIntegration::append_tcr(GCode& gcodegen, const WipeTower::ToolChangeResult& tcr, int new_extruder_id, double z) const + { + if (new_extruder_id != -1 && new_extruder_id != tcr.new_tool) + throw std::invalid_argument("Error: WipeTowerIntegration::append_tcr was asked to do a toolchange it didn't expect."); + + std::string gcode; + + // Toolchangeresult.gcode assumes the wipe tower corner is at the origin (except for priming lines) + // We want to rotate and shift all extrusions (gcode postprocessing) and starting and ending position + float alpha = m_wipe_tower_rotation / 180.f * float(M_PI); + Vec2f start_pos = tcr.start_pos; + Vec2f end_pos = tcr.end_pos; + if (!tcr.priming) { + start_pos = Eigen::Rotation2Df(alpha) * start_pos; + start_pos += m_wipe_tower_pos; + end_pos = Eigen::Rotation2Df(alpha) * end_pos; + end_pos += m_wipe_tower_pos; + } + + Vec2f wipe_tower_offset = tcr.priming ? Vec2f::Zero() : m_wipe_tower_pos; + float wipe_tower_rotation = tcr.priming ? 0.f : alpha; + + std::string tcr_rotated_gcode = post_process_wipe_tower_moves(tcr, wipe_tower_offset, wipe_tower_rotation); + + if (!tcr.priming) { + // Move over the wipe tower. + // Retract for a tool change, using the toolchange retract value and setting the priming extra length. + gcode += gcodegen.retract(true); + gcodegen.m_avoid_crossing_perimeters.use_external_mp_once = true; + gcode += gcodegen.travel_to( + wipe_tower_point_to_object_point(gcodegen, start_pos), + erMixed, + "Travel to a Wipe Tower"); + gcode += gcodegen.unretract(); + } + + double current_z = gcodegen.writer().get_position().z(); + if (z == -1.) // in case no specific z was provided, print at current_z pos + z = current_z; + if (!is_approx(z, current_z)) { + gcode += gcodegen.writer().retract(); + gcode += gcodegen.writer().travel_to_z(z, "Travel down to the last wipe tower layer."); + gcode += gcodegen.writer().unretract(); + } + + + // Process the end filament gcode. + std::string end_filament_gcode_str; + if (gcodegen.writer().extruder() != nullptr) { + // Process the custom end_filament_gcode in case of single_extruder_multi_material. + unsigned int old_extruder_id = gcodegen.writer().extruder()->id(); + const std::string& end_filament_gcode = gcodegen.config().end_filament_gcode.get_at(old_extruder_id); + if (gcodegen.writer().extruder() != nullptr && !end_filament_gcode.empty()) { + end_filament_gcode_str = gcodegen.placeholder_parser_process("end_filament_gcode", end_filament_gcode, old_extruder_id); + check_add_eol(end_filament_gcode_str); + } + } + + // Process the custom toolchange_gcode. If it is empty, provide a simple Tn command to change the filament. + // Otherwise, leave control to the user completely. + std::string toolchange_gcode_str; + if (true /*gcodegen.writer().extruder() != nullptr*/) { + const std::string& toolchange_gcode = gcodegen.config().toolchange_gcode.value; + if (!toolchange_gcode.empty()) { + DynamicConfig config; + int previous_extruder_id = gcodegen.writer().extruder() ? (int)gcodegen.writer().extruder()->id() : -1; + config.set_key_value("previous_extruder", new ConfigOptionInt(previous_extruder_id)); + config.set_key_value("next_extruder", new ConfigOptionInt((int)new_extruder_id)); + config.set_key_value("layer_num", new ConfigOptionInt(gcodegen.m_layer_index)); + config.set_key_value("layer_z", new ConfigOptionFloat(tcr.print_z)); + toolchange_gcode_str = gcodegen.placeholder_parser_process("toolchange_gcode", toolchange_gcode, new_extruder_id, &config); + check_add_eol(toolchange_gcode_str); + } + + std::string toolchange_command; + if (tcr.priming || (new_extruder_id >= 0 && gcodegen.writer().need_toolchange(new_extruder_id))) + toolchange_command = gcodegen.writer().toolchange(new_extruder_id); + if (!custom_gcode_changes_tool(toolchange_gcode_str, gcodegen.writer().toolchange_prefix(), new_extruder_id)) + toolchange_gcode_str += toolchange_command; + else { + // We have informed the m_writer about the current extruder_id, we can ignore the generated G-code. + } + } + + gcodegen.placeholder_parser().set("current_extruder", new_extruder_id); + + // Process the start filament gcode. + std::string start_filament_gcode_str; + const std::string& start_filament_gcode = gcodegen.config().start_filament_gcode.get_at(new_extruder_id); + if (!start_filament_gcode.empty()) { + // Process the start_filament_gcode for the active filament only. DynamicConfig config; - int previous_extruder_id = gcodegen.writer().extruder() ? (int)gcodegen.writer().extruder()->id() : -1; - config.set_key_value("previous_extruder", new ConfigOptionInt(previous_extruder_id)); - config.set_key_value("next_extruder", new ConfigOptionInt((int)new_extruder_id)); - config.set_key_value("layer_num", new ConfigOptionInt(gcodegen.m_layer_index)); - config.set_key_value("layer_z", new ConfigOptionFloat(tcr.print_z)); - toolchange_gcode_str = gcodegen.placeholder_parser_process("toolchange_gcode", toolchange_gcode, new_extruder_id, &config); - check_add_eol(toolchange_gcode_str); + config.set_key_value("filament_extruder_id", new ConfigOptionInt(new_extruder_id)); + start_filament_gcode_str = gcodegen.placeholder_parser_process("start_filament_gcode", start_filament_gcode, new_extruder_id, &config); + check_add_eol(start_filament_gcode_str); } - std::string toolchange_command; - if (tcr.priming || (new_extruder_id >= 0 && gcodegen.writer().need_toolchange(new_extruder_id))) - toolchange_command = gcodegen.writer().toolchange(new_extruder_id); - if (! custom_gcode_changes_tool(toolchange_gcode_str, gcodegen.writer().toolchange_prefix(), new_extruder_id)) - toolchange_gcode_str += toolchange_command; - else { - // We have informed the m_writer about the current extruder_id, we can ignore the generated G-code. - } - } - - gcodegen.placeholder_parser().set("current_extruder", new_extruder_id); - - // Process the start filament gcode. - std::string start_filament_gcode_str; - const std::string &start_filament_gcode = gcodegen.config().start_filament_gcode.get_at(new_extruder_id); - if (! start_filament_gcode.empty()) { - // Process the start_filament_gcode for the active filament only. + // Insert the end filament, toolchange, and start filament gcode into the generated gcode. DynamicConfig config; - config.set_key_value("filament_extruder_id", new ConfigOptionInt(new_extruder_id)); - start_filament_gcode_str = gcodegen.placeholder_parser_process("start_filament_gcode", start_filament_gcode, new_extruder_id, &config); - check_add_eol(start_filament_gcode_str); + config.set_key_value("end_filament_gcode", new ConfigOptionString(end_filament_gcode_str)); + config.set_key_value("toolchange_gcode", new ConfigOptionString(toolchange_gcode_str)); + config.set_key_value("start_filament_gcode", new ConfigOptionString(start_filament_gcode_str)); + std::string tcr_gcode, tcr_escaped_gcode = gcodegen.placeholder_parser_process("tcr_rotated_gcode", tcr_rotated_gcode, new_extruder_id, &config); + unescape_string_cstyle(tcr_escaped_gcode, tcr_gcode); + gcode += tcr_gcode; + check_add_eol(toolchange_gcode_str); + + + // A phony move to the end position at the wipe tower. + gcodegen.writer().travel_to_xy(end_pos.cast()); + gcodegen.set_last_pos(wipe_tower_point_to_object_point(gcodegen, end_pos)); + if (!is_approx(z, current_z)) { + gcode += gcodegen.writer().retract(); + gcode += gcodegen.writer().travel_to_z(current_z, "Travel back up to the topmost object layer."); + gcode += gcodegen.writer().unretract(); + } + + else { + // Prepare a future wipe. + gcodegen.m_wipe.path.points.clear(); + if (new_extruder_id >= 0) { + // Start the wipe at the current position. + gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, end_pos)); + // Wipe end point: Wipe direction away from the closer tower edge to the further tower edge. + gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, + Vec2f((std::abs(m_left - end_pos.x()) < std::abs(m_right - end_pos.x())) ? m_right : m_left, + end_pos.y()))); + } + } + + // Let the planner know we are traveling between objects. + gcodegen.m_avoid_crossing_perimeters.use_external_mp_once = true; + return gcode; } - // Insert the end filament, toolchange, and start filament gcode into the generated gcode. - DynamicConfig config; - config.set_key_value("end_filament_gcode", new ConfigOptionString(end_filament_gcode_str)); - config.set_key_value("toolchange_gcode", new ConfigOptionString(toolchange_gcode_str)); - config.set_key_value("start_filament_gcode", new ConfigOptionString(start_filament_gcode_str)); - std::string tcr_gcode, tcr_escaped_gcode = gcodegen.placeholder_parser_process("tcr_rotated_gcode", tcr_rotated_gcode, new_extruder_id, &config); - unescape_string_cstyle(tcr_escaped_gcode, tcr_gcode); - gcode += tcr_gcode; - check_add_eol(toolchange_gcode_str); + // This function postprocesses gcode_original, rotates and moves all G1 extrusions and returns resulting gcode + // Starting position has to be supplied explicitely (otherwise it would fail in case first G1 command only contained one coordinate) + std::string WipeTowerIntegration::post_process_wipe_tower_moves(const WipeTower::ToolChangeResult& tcr, const Vec2f& translation, float angle) const + { + Vec2f extruder_offset = m_extruder_offsets[tcr.initial_tool].cast(); + std::istringstream gcode_str(tcr.gcode); + std::string gcode_out; + std::string line; + Vec2f pos = tcr.start_pos; + Vec2f transformed_pos = pos; + Vec2f old_pos(-1000.1f, -1000.1f); - // A phony move to the end position at the wipe tower. - gcodegen.writer().travel_to_xy(end_pos.cast()); - gcodegen.set_last_pos(wipe_tower_point_to_object_point(gcodegen, end_pos)); - if (! is_approx(z, current_z)) { - gcode += gcodegen.writer().retract(); - gcode += gcodegen.writer().travel_to_z(current_z, "Travel back up to the topmost object layer."); - gcode += gcodegen.writer().unretract(); + while (gcode_str) { + std::getline(gcode_str, line); // we read the gcode line by line + + // All G1 commands should be translated and rotated. X and Y coords are + // only pushed to the output when they differ from last time. + // WT generator can override this by appending the never_skip_tag + if (line.find("G1 ") == 0) { + bool never_skip = false; + auto it = line.find(WipeTower::never_skip_tag()); + if (it != std::string::npos) { + // remove the tag and remember we saw it + never_skip = true; + line.erase(it, it + WipeTower::never_skip_tag().size()); + } + std::ostringstream line_out; + std::istringstream line_str(line); + line_str >> std::noskipws; // don't skip whitespace + char ch = 0; + while (line_str >> ch) { + if (ch == 'X' || ch == 'Y') + line_str >> (ch == 'X' ? pos.x() : pos.y()); + else + line_out << ch; + } + + transformed_pos = Eigen::Rotation2Df(angle) * pos + translation; + + if (transformed_pos != old_pos || never_skip) { + line = line_out.str(); + std::ostringstream oss; + oss << std::fixed << std::setprecision(3) << "G1 "; + if (transformed_pos.x() != old_pos.x() || never_skip) + oss << " X" << transformed_pos.x() - extruder_offset.x(); + if (transformed_pos.y() != old_pos.y() || never_skip) + oss << " Y" << transformed_pos.y() - extruder_offset.y(); + oss << " "; + line.replace(line.find("G1 "), 3, oss.str()); + old_pos = transformed_pos; + } + } + + gcode_out += line + "\n"; + + // If this was a toolchange command, we should change current extruder offset + if (line == "[toolchange_gcode]") { + extruder_offset = m_extruder_offsets[tcr.new_tool].cast(); + + // If the extruder offset changed, add an extra move so everything is continuous + if (extruder_offset != m_extruder_offsets[tcr.initial_tool].cast()) { + std::ostringstream oss; + oss << std::fixed << std::setprecision(3) + << "G1 X" << transformed_pos.x() - extruder_offset.x() + << " Y" << transformed_pos.y() - extruder_offset.y() + << "\n"; + gcode_out += oss.str(); + } + } + } + return gcode_out; } - else { + + std::string WipeTowerIntegration::prime(GCode& gcodegen) + { + assert(m_layer_idx == 0); + std::string gcode; + + + // Disable linear advance for the wipe tower operations. + //gcode += (gcodegen.config().gcode_flavor == gcfRepRap ? std::string("M572 D0 S0\n") : std::string("M900 K0\n")); + + for (const WipeTower::ToolChangeResult& tcr : m_priming) { + if (!tcr.extrusions.empty()) + gcode += append_tcr(gcodegen, tcr, tcr.new_tool); + + + // Let the tool change be executed by the wipe tower class. + // Inform the G-code writer about the changes done behind its back. + //gcode += tcr.gcode; + // Let the m_writer know the current extruder_id, but ignore the generated G-code. + // unsigned int current_extruder_id = tcr.extrusions.back().tool; + // gcodegen.writer().toolchange(current_extruder_id); + // gcodegen.placeholder_parser().set("current_extruder", current_extruder_id); + + } + + // A phony move to the end position at the wipe tower. + /* gcodegen.writer().travel_to_xy(Vec2d(m_priming.back().end_pos.x, m_priming.back().end_pos.y)); + gcodegen.set_last_pos(wipe_tower_point_to_object_point(gcodegen, m_priming.back().end_pos)); // Prepare a future wipe. gcodegen.m_wipe.path.points.clear(); - if (new_extruder_id >= 0) { - // Start the wipe at the current position. - gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, end_pos)); - // Wipe end point: Wipe direction away from the closer tower edge to the further tower edge. - gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, - Vec2f((std::abs(m_left - end_pos.x()) < std::abs(m_right - end_pos.x())) ? m_right : m_left, - end_pos.y()))); + // Start the wipe at the current position. + gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, m_priming.back().end_pos)); + // Wipe end point: Wipe direction away from the closer tower edge to the further tower edge. + gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, + WipeTower::xy((std::abs(m_left - m_priming.back().end_pos.x) < std::abs(m_right - m_priming.back().end_pos.x)) ? m_right : m_left, + m_priming.back().end_pos.y)));*/ + + return gcode; + } + + std::string WipeTowerIntegration::tool_change(GCode& gcodegen, int extruder_id, bool finish_layer) + { + std::string gcode; + assert(m_layer_idx >= 0); + if (!m_brim_done || gcodegen.writer().need_toolchange(extruder_id) || finish_layer) { + if (m_layer_idx < (int)m_tool_changes.size()) { + if (!(size_t(m_tool_change_idx) < m_tool_changes[m_layer_idx].size())) + throw std::runtime_error("Wipe tower generation failed, possibly due to empty first layer."); + + + // Calculate where the wipe tower layer will be printed. -1 means that print z will not change, + // resulting in a wipe tower with sparse layers. + double wipe_tower_z = -1; + bool ignore_sparse = false; + if (gcodegen.config().wipe_tower_no_sparse_layers.value) { + wipe_tower_z = m_last_wipe_tower_print_z; + ignore_sparse = (m_brim_done && m_tool_changes[m_layer_idx].size() == 1 && m_tool_changes[m_layer_idx].front().initial_tool == m_tool_changes[m_layer_idx].front().new_tool); + if (m_tool_change_idx == 0 && !ignore_sparse) + wipe_tower_z = m_last_wipe_tower_print_z + m_tool_changes[m_layer_idx].front().layer_height; + } + + if (!ignore_sparse) { + gcode += append_tcr(gcodegen, m_tool_changes[m_layer_idx][m_tool_change_idx++], extruder_id, wipe_tower_z); + m_last_wipe_tower_print_z = wipe_tower_z; + } + } + m_brim_done = true; } + return gcode; } - // Let the planner know we are traveling between objects. - gcodegen.m_avoid_crossing_perimeters.use_external_mp_once = true; - return gcode; -} - -// This function postprocesses gcode_original, rotates and moves all G1 extrusions and returns resulting gcode -// Starting position has to be supplied explicitely (otherwise it would fail in case first G1 command only contained one coordinate) -std::string WipeTowerIntegration::post_process_wipe_tower_moves(const WipeTower::ToolChangeResult& tcr, const Vec2f& translation, float angle) const -{ - Vec2f extruder_offset = m_extruder_offsets[tcr.initial_tool].cast(); - - std::istringstream gcode_str(tcr.gcode); - std::string gcode_out; - std::string line; - Vec2f pos = tcr.start_pos; - Vec2f transformed_pos = pos; - Vec2f old_pos(-1000.1f, -1000.1f); - - while (gcode_str) { - std::getline(gcode_str, line); // we read the gcode line by line - - // All G1 commands should be translated and rotated. X and Y coords are - // only pushed to the output when they differ from last time. - // WT generator can override this by appending the never_skip_tag - if (line.find("G1 ") == 0) { - bool never_skip = false; - auto it = line.find(WipeTower::never_skip_tag()); - if (it != std::string::npos) { - // remove the tag and remember we saw it - never_skip = true; - line.erase(it, it+WipeTower::never_skip_tag().size()); - } - std::ostringstream line_out; - std::istringstream line_str(line); - line_str >> std::noskipws; // don't skip whitespace - char ch = 0; - while (line_str >> ch) { - if (ch == 'X' || ch =='Y') - line_str >> (ch == 'X' ? pos.x() : pos.y()); - else - line_out << ch; - } - - transformed_pos = Eigen::Rotation2Df(angle) * pos + translation; - - if (transformed_pos != old_pos || never_skip) { - line = line_out.str(); - std::ostringstream oss; - oss << std::fixed << std::setprecision(3) << "G1 "; - if (transformed_pos.x() != old_pos.x() || never_skip) - oss << " X" << transformed_pos.x() - extruder_offset.x(); - if (transformed_pos.y() != old_pos.y() || never_skip) - oss << " Y" << transformed_pos.y() - extruder_offset.y(); - oss << " "; - line.replace(line.find("G1 "), 3, oss.str()); - old_pos = transformed_pos; - } - } - - gcode_out += line + "\n"; - - // If this was a toolchange command, we should change current extruder offset - if (line == "[toolchange_gcode]") { - extruder_offset = m_extruder_offsets[tcr.new_tool].cast(); - - // If the extruder offset changed, add an extra move so everything is continuous - if (extruder_offset != m_extruder_offsets[tcr.initial_tool].cast()) { - std::ostringstream oss; - oss << std::fixed << std::setprecision(3) - << "G1 X" << transformed_pos.x() - extruder_offset.x() - << " Y" << transformed_pos.y() - extruder_offset.y() - << "\n"; - gcode_out += oss.str(); - } - } + // Print is finished. Now it remains to unload the filament safely with ramming over the wipe tower. + std::string WipeTowerIntegration::finalize(GCode& gcodegen) + { + std::string gcode; + if (std::abs(gcodegen.writer().get_position()(2) - m_final_purge.print_z) > EPSILON) + gcode += gcodegen.change_layer(m_final_purge.print_z); + gcode += append_tcr(gcodegen, m_final_purge, -1); + return gcode; } - return gcode_out; -} - - -std::string WipeTowerIntegration::prime(GCode &gcodegen) -{ - assert(m_layer_idx == 0); - std::string gcode; - - - // Disable linear advance for the wipe tower operations. - //gcode += (gcodegen.config().gcode_flavor == gcfRepRap ? std::string("M572 D0 S0\n") : std::string("M900 K0\n")); - - for (const WipeTower::ToolChangeResult& tcr : m_priming) { - if (!tcr.extrusions.empty()) - gcode += append_tcr(gcodegen, tcr, tcr.new_tool); - - - // Let the tool change be executed by the wipe tower class. - // Inform the G-code writer about the changes done behind its back. - //gcode += tcr.gcode; - // Let the m_writer know the current extruder_id, but ignore the generated G-code. - // unsigned int current_extruder_id = tcr.extrusions.back().tool; - // gcodegen.writer().toolchange(current_extruder_id); - // gcodegen.placeholder_parser().set("current_extruder", current_extruder_id); - - } - - // A phony move to the end position at the wipe tower. - /* gcodegen.writer().travel_to_xy(Vec2d(m_priming.back().end_pos.x, m_priming.back().end_pos.y)); - gcodegen.set_last_pos(wipe_tower_point_to_object_point(gcodegen, m_priming.back().end_pos)); - // Prepare a future wipe. - gcodegen.m_wipe.path.points.clear(); - // Start the wipe at the current position. - gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, m_priming.back().end_pos)); - // Wipe end point: Wipe direction away from the closer tower edge to the further tower edge. - gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, - WipeTower::xy((std::abs(m_left - m_priming.back().end_pos.x) < std::abs(m_right - m_priming.back().end_pos.x)) ? m_right : m_left, - m_priming.back().end_pos.y)));*/ - - return gcode; -} - -std::string WipeTowerIntegration::tool_change(GCode &gcodegen, int extruder_id, bool finish_layer) -{ - std::string gcode; - assert(m_layer_idx >= 0); - if (! m_brim_done || gcodegen.writer().need_toolchange(extruder_id) || finish_layer) { - if (m_layer_idx < (int)m_tool_changes.size()) { - if (! (size_t(m_tool_change_idx) < m_tool_changes[m_layer_idx].size())) - throw std::runtime_error("Wipe tower generation failed, possibly due to empty first layer."); - - - // Calculate where the wipe tower layer will be printed. -1 means that print z will not change, - // resulting in a wipe tower with sparse layers. - double wipe_tower_z = -1; - bool ignore_sparse = false; - if (gcodegen.config().wipe_tower_no_sparse_layers.value) { - wipe_tower_z = m_last_wipe_tower_print_z; - ignore_sparse = (m_brim_done && m_tool_changes[m_layer_idx].size() == 1 && m_tool_changes[m_layer_idx].front().initial_tool == m_tool_changes[m_layer_idx].front().new_tool); - if (m_tool_change_idx == 0 && ! ignore_sparse) - wipe_tower_z = m_last_wipe_tower_print_z + m_tool_changes[m_layer_idx].front().layer_height; - } - - if (! ignore_sparse) { - gcode += append_tcr(gcodegen, m_tool_changes[m_layer_idx][m_tool_change_idx++], extruder_id, wipe_tower_z); - m_last_wipe_tower_print_z = wipe_tower_z; - } - } - m_brim_done = true; - } - return gcode; -} - -// Print is finished. Now it remains to unload the filament safely with ramming over the wipe tower. -std::string WipeTowerIntegration::finalize(GCode &gcodegen) -{ - std::string gcode; - if (std::abs(gcodegen.writer().get_position()(2) - m_final_purge.print_z) > EPSILON) - gcode += gcodegen.change_layer(m_final_purge.print_z); - gcode += append_tcr(gcodegen, m_final_purge, -1); - return gcode; -} #if ENABLE_GCODE_VIEWER -const std::vector ColorPrintColors::Colors = { "#C0392B", "#E67E22", "#F1C40F", "#27AE60", "#1ABC9C", "#2980B9", "#9B59B6" }; + const std::vector ColorPrintColors::Colors = { "#C0392B", "#E67E22", "#F1C40F", "#27AE60", "#1ABC9C", "#2980B9", "#9B59B6" }; #endif // ENABLE_GCODE_VIEWER #define EXTRUDER_CONFIG(OPT) m_config.OPT.get_at(m_writer.extruder()->id()) -// Collect pairs of object_layer + support_layer sorted by print_z. -// object_layer & support_layer are considered to be on the same print_z, if they are not further than EPSILON. -std::vector GCode::collect_layers_to_print(const PrintObject &object) -{ - std::vector layers_to_print; - layers_to_print.reserve(object.layers().size() + object.support_layers().size()); + // Collect pairs of object_layer + support_layer sorted by print_z. + // object_layer & support_layer are considered to be on the same print_z, if they are not further than EPSILON. + std::vector GCode::collect_layers_to_print(const PrintObject& object) + { + std::vector layers_to_print; + layers_to_print.reserve(object.layers().size() + object.support_layers().size()); - // Calculate a minimum support layer height as a minimum over all extruders, but not smaller than 10um. - // This is the same logic as in support generator. - //FIXME should we use the printing extruders instead? - double gap_over_supports = object.config().support_material_contact_distance; - // FIXME should we test object.config().support_material_synchronize_layers ? Currently the support layers are synchronized with object layers iff soluble supports. - assert(! object.config().support_material || gap_over_supports != 0. || object.config().support_material_synchronize_layers); - if (gap_over_supports != 0.) { - gap_over_supports = std::max(0., gap_over_supports); - // Not a soluble support, - double support_layer_height_min = 1000000.; - for (auto lh : object.print()->config().min_layer_height.values) - support_layer_height_min = std::min(support_layer_height_min, std::max(0.01, lh)); - gap_over_supports += support_layer_height_min; - } + // Calculate a minimum support layer height as a minimum over all extruders, but not smaller than 10um. + // This is the same logic as in support generator. + //FIXME should we use the printing extruders instead? + double gap_over_supports = object.config().support_material_contact_distance; + // FIXME should we test object.config().support_material_synchronize_layers ? Currently the support layers are synchronized with object layers iff soluble supports. + assert(!object.config().support_material || gap_over_supports != 0. || object.config().support_material_synchronize_layers); + if (gap_over_supports != 0.) { + gap_over_supports = std::max(0., gap_over_supports); + // Not a soluble support, + double support_layer_height_min = 1000000.; + for (auto lh : object.print()->config().min_layer_height.values) + support_layer_height_min = std::min(support_layer_height_min, std::max(0.01, lh)); + gap_over_supports += support_layer_height_min; + } - // Pair the object layers with the support layers by z. - size_t idx_object_layer = 0; - size_t idx_support_layer = 0; - const LayerToPrint* last_extrusion_layer = nullptr; - while (idx_object_layer < object.layers().size() || idx_support_layer < object.support_layers().size()) { - LayerToPrint layer_to_print; - layer_to_print.object_layer = (idx_object_layer < object.layers().size()) ? object.layers()[idx_object_layer ++] : nullptr; - layer_to_print.support_layer = (idx_support_layer < object.support_layers().size()) ? object.support_layers()[idx_support_layer ++] : nullptr; - if (layer_to_print.object_layer && layer_to_print.support_layer) { - if (layer_to_print.object_layer->print_z < layer_to_print.support_layer->print_z - EPSILON) { - layer_to_print.support_layer = nullptr; - -- idx_support_layer; - } else if (layer_to_print.support_layer->print_z < layer_to_print.object_layer->print_z - EPSILON) { - layer_to_print.object_layer = nullptr; - -- idx_object_layer; + // Pair the object layers with the support layers by z. + size_t idx_object_layer = 0; + size_t idx_support_layer = 0; + const LayerToPrint* last_extrusion_layer = nullptr; + while (idx_object_layer < object.layers().size() || idx_support_layer < object.support_layers().size()) { + LayerToPrint layer_to_print; + layer_to_print.object_layer = (idx_object_layer < object.layers().size()) ? object.layers()[idx_object_layer++] : nullptr; + layer_to_print.support_layer = (idx_support_layer < object.support_layers().size()) ? object.support_layers()[idx_support_layer++] : nullptr; + if (layer_to_print.object_layer && layer_to_print.support_layer) { + if (layer_to_print.object_layer->print_z < layer_to_print.support_layer->print_z - EPSILON) { + layer_to_print.support_layer = nullptr; + --idx_support_layer; + } + else if (layer_to_print.support_layer->print_z < layer_to_print.object_layer->print_z - EPSILON) { + layer_to_print.object_layer = nullptr; + --idx_object_layer; + } + } + + layers_to_print.emplace_back(layer_to_print); + + // In case there are extrusions on this layer, check there is a layer to lay it on. + if ((layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions()) + // Allow empty support layers, as the support generator may produce no extrusions for non-empty support regions. + || (layer_to_print.support_layer /* && layer_to_print.support_layer->has_extrusions() */)) { + double support_contact_z = (last_extrusion_layer && last_extrusion_layer->support_layer) + ? gap_over_supports + : 0.; + double maximal_print_z = (last_extrusion_layer ? last_extrusion_layer->print_z() : 0.) + + layer_to_print.layer()->height + + support_contact_z; + // Negative support_contact_z is not taken into account, it can result in false positives in cases + // where previous layer has object extrusions too (https://github.com/prusa3d/PrusaSlicer/issues/2752) + + // Only check this layer in case it has some extrusions. + bool has_extrusions = (layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions()) + || (layer_to_print.support_layer && layer_to_print.support_layer->has_extrusions()); + + if (has_extrusions && layer_to_print.print_z() > maximal_print_z + 2. * EPSILON) + throw std::runtime_error(_(L("Empty layers detected, the output would not be printable.")) + "\n\n" + + _(L("Object name")) + ": " + object.model_object()->name + "\n" + _(L("Print z")) + ": " + + std::to_string(layers_to_print.back().print_z()) + "\n\n" + _(L("This is " + "usually caused by negligibly small extrusions or by a faulty model. Try to repair " + "the model or change its orientation on the bed."))); + // Remember last layer with extrusions. + last_extrusion_layer = &layers_to_print.back(); } } - layers_to_print.emplace_back(layer_to_print); - - // In case there are extrusions on this layer, check there is a layer to lay it on. - if ((layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions()) - // Allow empty support layers, as the support generator may produce no extrusions for non-empty support regions. - || (layer_to_print.support_layer /* && layer_to_print.support_layer->has_extrusions() */)) { - double support_contact_z = (last_extrusion_layer && last_extrusion_layer->support_layer) - ? gap_over_supports - : 0.; - double maximal_print_z = (last_extrusion_layer ? last_extrusion_layer->print_z() : 0.) - + layer_to_print.layer()->height - + support_contact_z; - // Negative support_contact_z is not taken into account, it can result in false positives in cases - // where previous layer has object extrusions too (https://github.com/prusa3d/PrusaSlicer/issues/2752) - - // Only check this layer in case it has some extrusions. - bool has_extrusions = (layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions()) - || (layer_to_print.support_layer && layer_to_print.support_layer->has_extrusions()); - - if (has_extrusions && layer_to_print.print_z() > maximal_print_z + 2. * EPSILON) - throw std::runtime_error(_(L("Empty layers detected, the output would not be printable.")) + "\n\n" + - _(L("Object name")) + ": " + object.model_object()->name + "\n" + _(L("Print z")) + ": " + - std::to_string(layers_to_print.back().print_z()) + "\n\n" + _(L("This is " - "usually caused by negligibly small extrusions or by a faulty model. Try to repair " - "the model or change its orientation on the bed."))); - // Remember last layer with extrusions. - last_extrusion_layer = &layers_to_print.back(); - } + return layers_to_print; } - return layers_to_print; -} + // Prepare for non-sequential printing of multiple objects: Support resp. object layers with nearly identical print_z + // will be printed for all objects at once. + // Return a list of items. + std::vector>> GCode::collect_layers_to_print(const Print& print) + { + struct OrderingItem { + coordf_t print_z; + size_t object_idx; + size_t layer_idx; + }; -// Prepare for non-sequential printing of multiple objects: Support resp. object layers with nearly identical print_z -// will be printed for all objects at once. -// Return a list of items. -std::vector>> GCode::collect_layers_to_print(const Print &print) -{ - struct OrderingItem { - coordf_t print_z; - size_t object_idx; - size_t layer_idx; - }; - - std::vector> per_object(print.objects().size(), std::vector()); - std::vector ordering; - for (size_t i = 0; i < print.objects().size(); ++i) { - per_object[i] = collect_layers_to_print(*print.objects()[i]); - OrderingItem ordering_item; - ordering_item.object_idx = i; - ordering.reserve(ordering.size() + per_object[i].size()); - const LayerToPrint &front = per_object[i].front(); - for (const LayerToPrint <p : per_object[i]) { - ordering_item.print_z = ltp.print_z(); - ordering_item.layer_idx = <p - &front; - ordering.emplace_back(ordering_item); + std::vector> per_object(print.objects().size(), std::vector()); + std::vector ordering; + for (size_t i = 0; i < print.objects().size(); ++i) { + per_object[i] = collect_layers_to_print(*print.objects()[i]); + OrderingItem ordering_item; + ordering_item.object_idx = i; + ordering.reserve(ordering.size() + per_object[i].size()); + const LayerToPrint& front = per_object[i].front(); + for (const LayerToPrint& ltp : per_object[i]) { + ordering_item.print_z = ltp.print_z(); + ordering_item.layer_idx = <p - &front; + ordering.emplace_back(ordering_item); + } } - } - std::sort(ordering.begin(), ordering.end(), [](const OrderingItem &oi1, const OrderingItem &oi2) { return oi1.print_z < oi2.print_z; }); + std::sort(ordering.begin(), ordering.end(), [](const OrderingItem& oi1, const OrderingItem& oi2) { return oi1.print_z < oi2.print_z; }); - std::vector>> layers_to_print; - // Merge numerically very close Z values. - for (size_t i = 0; i < ordering.size();) { - // Find the last layer with roughly the same print_z. - size_t j = i + 1; - coordf_t zmax = ordering[i].print_z + EPSILON; - for (; j < ordering.size() && ordering[j].print_z <= zmax; ++ j) ; - // Merge into layers_to_print. - std::pair> merged; - // Assign an average print_z to the set of layers with nearly equal print_z. - merged.first = 0.5 * (ordering[i].print_z + ordering[j-1].print_z); - merged.second.assign(print.objects().size(), LayerToPrint()); - for (; i < j; ++i) { - const OrderingItem &oi = ordering[i]; - assert(merged.second[oi.object_idx].layer() == nullptr); - merged.second[oi.object_idx] = std::move(per_object[oi.object_idx][oi.layer_idx]); + std::vector>> layers_to_print; + // Merge numerically very close Z values. + for (size_t i = 0; i < ordering.size();) { + // Find the last layer with roughly the same print_z. + size_t j = i + 1; + coordf_t zmax = ordering[i].print_z + EPSILON; + for (; j < ordering.size() && ordering[j].print_z <= zmax; ++j); + // Merge into layers_to_print. + std::pair> merged; + // Assign an average print_z to the set of layers with nearly equal print_z. + merged.first = 0.5 * (ordering[i].print_z + ordering[j - 1].print_z); + merged.second.assign(print.objects().size(), LayerToPrint()); + for (; i < j; ++i) { + const OrderingItem& oi = ordering[i]; + assert(merged.second[oi.object_idx].layer() == nullptr); + merged.second[oi.object_idx] = std::move(per_object[oi.object_idx][oi.layer_idx]); + } + layers_to_print.emplace_back(std::move(merged)); } - layers_to_print.emplace_back(std::move(merged)); - } - return layers_to_print; -} + return layers_to_print; + } #if ENABLE_GCODE_VIEWER +// free functions called by GCode::do_export() +namespace DoExport { + static void update_print_stats_estimated_times( + const GCodeProcessor& processor, + const bool silent_time_estimator_enabled, + PrintStatistics& print_statistics) + { + print_statistics.estimated_normal_print_time = processor.get_time_dhm(GCodeProcessor::ETimeMode::Normal); + print_statistics.estimated_normal_custom_gcode_print_times = processor.get_custom_gcode_times(GCodeProcessor::ETimeMode::Normal, true); + if (silent_time_estimator_enabled) { + print_statistics.estimated_silent_print_time = processor.get_time_dhm(GCodeProcessor::ETimeMode::Stealth); + print_statistics.estimated_silent_custom_gcode_print_times = processor.get_custom_gcode_times(GCodeProcessor::ETimeMode::Stealth, true); + } + else { + print_statistics.estimated_silent_print_time = "N/A"; + print_statistics.estimated_silent_custom_gcode_print_times.clear(); + } + } + +} // namespace DoExport + void GCode::do_export(Print* print, const char* path, GCodeProcessor::Result* result, ThumbnailsGeneratorCallback thumbnail_cb) #else void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_data, ThumbnailsGeneratorCallback thumbnail_cb) @@ -768,6 +790,8 @@ void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_ m_processor.process_file(path_tmp); if (result != nullptr) *result = std::move(m_processor.extract_result()); + + DoExport::update_print_stats_estimated_times(m_processor, m_silent_time_estimator_enabled, print->m_print_statistics); #endif // ENABLE_GCODE_VIEWER GCodeTimeEstimator::PostProcessData normal_data = m_normal_time_estimator.get_post_process_data(); @@ -883,10 +907,11 @@ namespace DoExport { } #if ENABLE_GCODE_VIEWER - static void init_gcode_processor(const PrintConfig& config, GCodeProcessor& processor) + static void init_gcode_processor(const PrintConfig& config, GCodeProcessor& processor, bool silent_time_estimator_enabled) { processor.reset(); processor.apply_config(config); + processor.enable_stealth_time_estimator(silent_time_estimator_enabled); } #else static void init_gcode_analyzer(const PrintConfig &config, GCodeAnalyzer &analyzer) @@ -1036,7 +1061,7 @@ namespace DoExport { } // Fill in print_statistics and return formatted string containing filament statistics to be inserted into G-code comment section. - static std::string update_print_stats_and_format_filament_stats( + static std::string update_print_stats_and_format_filament_stats( const GCodeTimeEstimator &normal_time_estimator, const GCodeTimeEstimator &silent_time_estimator, const bool silent_time_estimator_enabled, @@ -1044,20 +1069,19 @@ namespace DoExport { const WipeTowerData &wipe_tower_data, const std::vector &extruders, PrintStatistics &print_statistics) - { + { std::string filament_stats_string_out; print_statistics.clear(); - print_statistics.estimated_normal_print_time = normal_time_estimator.get_time_dhm/*s*/(); - print_statistics.estimated_silent_print_time = silent_time_estimator_enabled ? silent_time_estimator.get_time_dhm/*s*/() : "N/A"; #if ENABLE_GCODE_VIEWER + print_statistics.estimated_normal_print_time_str = normal_time_estimator.get_time_dhm/*s*/(); + print_statistics.estimated_silent_print_time_str = silent_time_estimator_enabled ? silent_time_estimator.get_time_dhm/*s*/() : "N/A"; print_statistics.estimated_normal_custom_gcode_print_times_str = normal_time_estimator.get_custom_gcode_times_dhm(true); - print_statistics.estimated_normal_custom_gcode_print_times = normal_time_estimator.get_custom_gcode_times(true); - if (silent_time_estimator_enabled) { + if (silent_time_estimator_enabled) print_statistics.estimated_silent_custom_gcode_print_times_str = silent_time_estimator.get_custom_gcode_times_dhm(true); - print_statistics.estimated_silent_custom_gcode_print_times = silent_time_estimator.get_custom_gcode_times(true); - } #else + print_statistics.estimated_normal_print_time = normal_time_estimator.get_time_dhm/*s*/(); + print_statistics.estimated_silent_print_time = silent_time_estimator_enabled ? silent_time_estimator.get_time_dhm/*s*/() : "N/A"; print_statistics.estimated_normal_custom_gcode_print_times = normal_time_estimator.get_custom_gcode_times_dhm(true); if (silent_time_estimator_enabled) print_statistics.estimated_silent_custom_gcode_print_times = silent_time_estimator.get_custom_gcode_times_dhm(true); @@ -1156,7 +1180,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu // modifies the following: m_normal_time_estimator, m_silent_time_estimator, m_silent_time_estimator_enabled); #if ENABLE_GCODE_VIEWER - DoExport::init_gcode_processor(print.config(), m_processor); + DoExport::init_gcode_processor(print.config(), m_processor, m_silent_time_estimator_enabled); #else DoExport::init_gcode_analyzer(print.config(), m_analyzer); #endif // ENABLE_GCODE_VIEWER diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 14f29b56b6..7174e5e36d 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -1,9 +1,11 @@ #include "libslic3r/libslic3r.h" +#include "libslic3r/Utils.hpp" #include "GCodeProcessor.hpp" #include #include +#include #if ENABLE_GCODE_VIEWER @@ -14,20 +16,65 @@ static const float INCHES_TO_MM = 25.4f; static const float MMMIN_TO_MMSEC = 1.0f / 60.0f; -static bool is_valid_extrusion_role(int value) -{ - return ((int)Slic3r::erNone <= value) && (value <= (int)Slic3r::erMixed); -} +static const float DEFAULT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 namespace Slic3r { -const std::string GCodeProcessor::Extrusion_Role_Tag = "_PROCESSOR_EXTRUSION_ROLE:"; -const std::string GCodeProcessor::Width_Tag = "_PROCESSOR_WIDTH:"; -const std::string GCodeProcessor::Height_Tag = "_PROCESSOR_HEIGHT:"; -const std::string GCodeProcessor::Mm3_Per_Mm_Tag = "_PROCESSOR_MM3_PER_MM:"; -const std::string GCodeProcessor::Color_Change_Tag = "_PROCESSOR_COLOR_CHANGE"; -const std::string GCodeProcessor::Pause_Print_Tag = "_PROCESSOR_PAUSE_PRINT"; -const std::string GCodeProcessor::Custom_Code_Tag = "_PROCESSOR_CUSTOM_CODE"; +const std::string GCodeProcessor::Extrusion_Role_Tag = "PrusaSlicer__EXTRUSION_ROLE:"; +const std::string GCodeProcessor::Width_Tag = "PrusaSlicer__WIDTH:"; +const std::string GCodeProcessor::Height_Tag = "PrusaSlicer__HEIGHT:"; +const std::string GCodeProcessor::Mm3_Per_Mm_Tag = "PrusaSlicer__MM3_PER_MM:"; +const std::string GCodeProcessor::Color_Change_Tag = "PrusaSlicer__COLOR_CHANGE"; +const std::string GCodeProcessor::Pause_Print_Tag = "PrusaSlicer__PAUSE_PRINT"; +const std::string GCodeProcessor::Custom_Code_Tag = "PrusaSlicer__CUSTOM_CODE"; + +static bool is_valid_extrusion_role(int value) +{ + return (static_cast(erNone) <= value) && (value <= static_cast(erMixed)); +} + +static void set_option_value(ConfigOptionFloats& option, size_t id, float value) +{ + if (id < option.values.size()) + option.values[id] = static_cast(value); +}; + +static float get_option_value(const ConfigOptionFloats& option, size_t id) +{ + return option.values.empty() ? 0.0f : + ((id < option.values.size()) ? static_cast(option.values[id]) : static_cast(option.values.back())); +} + +static float estimated_acceleration_distance(float initial_rate, float target_rate, float acceleration) +{ + return (acceleration == 0.0f) ? 0.0f : (sqr(target_rate) - sqr(initial_rate)) / (2.0f * acceleration); +} + +static float intersection_distance(float initial_rate, float final_rate, float acceleration, float distance) +{ + return (acceleration == 0.0f) ? 0.0f : (2.0f * acceleration * distance - sqr(initial_rate) + sqr(final_rate)) / (4.0f * acceleration); +} + +static float speed_from_distance(float initial_feedrate, float distance, float acceleration) +{ + // to avoid invalid negative numbers due to numerical errors + float value = std::max(0.0f, sqr(initial_feedrate) + 2.0f * acceleration * distance); + return ::sqrt(value); +} + +// Calculates the maximum allowable speed at this point when you must be able to reach target_velocity using the +// acceleration within the allotted distance. +static float max_allowable_speed(float acceleration, float target_velocity, float distance) +{ + // to avoid invalid negative numbers due to numerical errors + float value = std::max(0.0f, sqr(target_velocity) - 2.0f * acceleration * distance); + return std::sqrt(value); +} + +static float acceleration_time_from_distance(float initial_feedrate, float distance, float acceleration) +{ + return (acceleration != 0.0f) ? (speed_from_distance(initial_feedrate, distance, acceleration) - initial_feedrate) / acceleration : 0.0f; +} void GCodeProcessor::CachedPosition::reset() { @@ -41,6 +88,208 @@ void GCodeProcessor::CpColor::reset() current = 0; } +float GCodeProcessor::Trapezoid::acceleration_time(float entry_feedrate, float acceleration) const +{ + return acceleration_time_from_distance(entry_feedrate, accelerate_until, acceleration); +} + +float GCodeProcessor::Trapezoid::cruise_time() const +{ + return (cruise_feedrate != 0.0f) ? cruise_distance() / cruise_feedrate : 0.0f; +} + +float GCodeProcessor::Trapezoid::deceleration_time(float distance, float acceleration) const +{ + return acceleration_time_from_distance(cruise_feedrate, (distance - decelerate_after), -acceleration); +} + +float GCodeProcessor::Trapezoid::cruise_distance() const +{ + return decelerate_after - accelerate_until; +} + +void GCodeProcessor::TimeBlock::calculate_trapezoid() +{ + trapezoid.cruise_feedrate = feedrate_profile.cruise; + + float accelerate_distance = std::max(0.0f, estimated_acceleration_distance(feedrate_profile.entry, feedrate_profile.cruise, acceleration)); + float decelerate_distance = std::max(0.0f, estimated_acceleration_distance(feedrate_profile.cruise, feedrate_profile.exit, -acceleration)); + float cruise_distance = distance - accelerate_distance - decelerate_distance; + + // Not enough space to reach the nominal feedrate. + // This means no cruising, and we'll have to use intersection_distance() to calculate when to abort acceleration + // and start braking in order to reach the exit_feedrate exactly at the end of this block. + if (cruise_distance < 0.0f) { + accelerate_distance = std::clamp(intersection_distance(feedrate_profile.entry, feedrate_profile.exit, acceleration, distance), 0.0f, distance); + cruise_distance = 0.0f; + trapezoid.cruise_feedrate = speed_from_distance(feedrate_profile.entry, accelerate_distance, acceleration); + } + + trapezoid.accelerate_until = accelerate_distance; + trapezoid.decelerate_after = accelerate_distance + cruise_distance; +} + +float GCodeProcessor::TimeBlock::time() const +{ + return trapezoid.acceleration_time(feedrate_profile.entry, acceleration) + + trapezoid.cruise_time() + + trapezoid.deceleration_time(distance, acceleration); +} + +void GCodeProcessor::TimeMachine::State::reset() +{ + feedrate = 0.0f; + safe_feedrate = 0.0f; + axis_feedrate = { 0.0f, 0.0f, 0.0f, 0.0f }; + abs_axis_feedrate = { 0.0f, 0.0f, 0.0f, 0.0f }; +} + +void GCodeProcessor::TimeMachine::CustomGCodeTime::reset() +{ + needed = false; + cache = 0.0f; + times = std::vector>(); +} + +void GCodeProcessor::TimeMachine::reset() +{ + enabled = false; + acceleration = 0.0f; + extrude_factor_override_percentage = 1.0f; + time = 0.0f; + curr.reset(); + prev.reset(); + gcode_time.reset(); + blocks = std::vector(); +} + +void GCodeProcessor::TimeMachine::simulate_st_synchronize(float additional_time) +{ + if (!enabled) + return; + + time += additional_time; + gcode_time.cache += additional_time; + calculate_time(); +} + +static void planner_forward_pass_kernel(GCodeProcessor::TimeBlock& prev, GCodeProcessor::TimeBlock& curr) +{ + // If the previous block is an acceleration block, but it is not long enough to complete the + // full speed change within the block, we need to adjust the entry speed accordingly. Entry + // speeds have already been reset, maximized, and reverse planned by reverse planner. + // If nominal length is true, max junction speed is guaranteed to be reached. No need to recheck. + if (!prev.flags.nominal_length) { + if (prev.feedrate_profile.entry < curr.feedrate_profile.entry) { + float entry_speed = std::min(curr.feedrate_profile.entry, max_allowable_speed(-prev.acceleration, prev.feedrate_profile.entry, prev.distance)); + + // Check for junction speed change + if (curr.feedrate_profile.entry != entry_speed) { + curr.feedrate_profile.entry = entry_speed; + curr.flags.recalculate = true; + } + } + } +} + +void planner_reverse_pass_kernel(GCodeProcessor::TimeBlock& curr, GCodeProcessor::TimeBlock& next) +{ + // If entry speed is already at the maximum entry speed, no need to recheck. Block is cruising. + // If not, block in state of acceleration or deceleration. Reset entry speed to maximum and + // check for maximum allowable speed reductions to ensure maximum possible planned speed. + if (curr.feedrate_profile.entry != curr.max_entry_speed) { + // If nominal length true, max junction speed is guaranteed to be reached. Only compute + // for max allowable speed if block is decelerating and nominal length is false. + if (!curr.flags.nominal_length && curr.max_entry_speed > next.feedrate_profile.entry) + curr.feedrate_profile.entry = std::min(curr.max_entry_speed, max_allowable_speed(-curr.acceleration, next.feedrate_profile.entry, curr.distance)); + else + curr.feedrate_profile.entry = curr.max_entry_speed; + + curr.flags.recalculate = true; + } +} + +static void recalculate_trapezoids(std::vector& blocks) +{ + GCodeProcessor::TimeBlock* curr = nullptr; + GCodeProcessor::TimeBlock* next = nullptr; + + for (size_t i = 0; i < blocks.size(); ++i) { + GCodeProcessor::TimeBlock& b = blocks[i]; + + curr = next; + next = &b; + + if (curr != nullptr) { + // Recalculate if current block entry or exit junction speed has changed. + if (curr->flags.recalculate || next->flags.recalculate) { + // NOTE: Entry and exit factors always > 0 by all previous logic operations. + GCodeProcessor::TimeBlock block = *curr; + block.feedrate_profile.exit = next->feedrate_profile.entry; + block.calculate_trapezoid(); + curr->trapezoid = block.trapezoid; + curr->flags.recalculate = false; // Reset current only to ensure next trapezoid is computed + } + } + } + + // Last/newest block in buffer. Always recalculated. + if (next != nullptr) { + GCodeProcessor::TimeBlock block = *next; + block.feedrate_profile.exit = next->safe_feedrate; + block.calculate_trapezoid(); + next->trapezoid = block.trapezoid; + next->flags.recalculate = false; + } +} + +void GCodeProcessor::TimeMachine::calculate_time(size_t keep_last_n_blocks) +{ + if (!enabled || blocks.size() < 2) + return; + + assert(keep_last_n_blocks <= blocks.size()); + + // forward_pass + for (size_t i = 0; i + 1 < blocks.size(); ++i) { + planner_forward_pass_kernel(blocks[i], blocks[i + 1]); + } + + // reverse_pass + for (int i = static_cast(blocks.size()) - 1; i > 0; --i) + planner_reverse_pass_kernel(blocks[i - 1], blocks[i]); + + recalculate_trapezoids(blocks); + + size_t n_blocks_process = blocks.size() - keep_last_n_blocks; +// m_g1_times.reserve(m_g1_times.size() + n_blocks_process); + for (size_t i = 0; i < n_blocks_process; ++i) { + float block_time = blocks[i].time(); + time += block_time; + gcode_time.cache += block_time; + +// if (block.g1_line_id >= 0) +// m_g1_times.emplace_back(block.g1_line_id, time); + } + + if (keep_last_n_blocks) + blocks.erase(blocks.begin(), blocks.begin() + n_blocks_process); + else + blocks.clear(); +} + +void GCodeProcessor::TimeProcessor::reset() +{ + extruder_unloaded = true; + machine_limits = MachineEnvelopeConfig(); + filament_load_times = std::vector(); + filament_unload_times = std::vector(); + for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + machines[i].reset(); + } + machines[static_cast(ETimeMode::Normal)].enabled = true; +} + unsigned int GCodeProcessor::s_result_id = 0; void GCodeProcessor::apply_config(const PrintConfig& config) @@ -61,6 +310,28 @@ void GCodeProcessor::apply_config(const PrintConfig& config) for (size_t id = 0; id < extruders_count; ++id) { m_extruders_color[id] = static_cast(id); } + + m_time_processor.machine_limits = reinterpret_cast(config); + // Filament load / unload times are not specific to a firmware flavor. Let anybody use it if they find it useful. + // As of now the fields are shown at the UI dialog in the same combo box as the ramming values, so they + // are considered to be active for the single extruder multi-material printers only. + m_time_processor.filament_load_times.clear(); + for (double d : config.filament_load_time.values) { + m_time_processor.filament_load_times.push_back(static_cast(d)); + } + m_time_processor.filament_unload_times.clear(); + for (double d : config.filament_unload_time.values) { + m_time_processor.filament_unload_times.push_back(static_cast(d)); + } + for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + float max_acceleration = get_option_value(m_time_processor.machine_limits.machine_max_acceleration_extruding, i); + m_time_processor.machines[i].acceleration = (max_acceleration > 0.0f) ? max_acceleration : DEFAULT_ACCELERATION; + } +} + +void GCodeProcessor::enable_stealth_time_estimator(bool enabled) +{ + m_time_processor.machines[static_cast(ETimeMode::Stealth)].enabled = enabled; } void GCodeProcessor::reset() @@ -71,9 +342,9 @@ void GCodeProcessor::reset() m_extruder_offsets = std::vector(1, Vec3f::Zero()); m_flavor = gcfRepRap; - std::fill(m_start_position.begin(), m_start_position.end(), 0.0f); - std::fill(m_end_position.begin(), m_end_position.end(), 0.0f); - std::fill(m_origin.begin(), m_origin.end(), 0.0f); + m_start_position = { 0.0f, 0.0f, 0.0f, 0.0f }; + m_end_position = { 0.0f, 0.0f, 0.0f, 0.0f }; + m_origin = { 0.0f, 0.0f, 0.0f, 0.0f }; m_cached_position.reset(); m_feedrate = 0.0f; @@ -87,6 +358,8 @@ void GCodeProcessor::reset() m_extruders_color = ExtrudersColor(); m_cp_color.reset(); + m_time_processor.reset(); + m_result.reset(); m_result.id = ++s_result_id; } @@ -101,11 +374,43 @@ void GCodeProcessor::process_file(const std::string& filename) m_result.moves.emplace_back(MoveVertex()); m_parser.parse_file(filename, [this](GCodeReader& reader, const GCodeReader::GCodeLine& line) { process_gcode_line(line); }); + // process the remaining time blocks + for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + TimeMachine& machine = m_time_processor.machines[i]; + TimeMachine::CustomGCodeTime& gcode_time = machine.gcode_time; + machine.calculate_time(); + if (gcode_time.needed && gcode_time.cache != 0.0f) + gcode_time.times.push_back({ CustomGCode::ColorChange, gcode_time.cache }); + } + #if ENABLE_GCODE_VIEWER_STATISTICS m_result.time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); #endif // ENABLE_GCODE_VIEWER_STATISTICS } +std::string GCodeProcessor::get_time_dhm(ETimeMode mode) const +{ + std::string ret = "N/A"; + if (mode < ETimeMode::Count) + ret = short_time(get_time_dhms(m_time_processor.machines[static_cast(mode)].time)); + return ret; +} + +std::vector>> GCodeProcessor::get_custom_gcode_times(ETimeMode mode, bool include_remaining) const +{ + std::vector>> ret; + if (mode < ETimeMode::Count) { + const TimeMachine& machine = m_time_processor.machines[static_cast(mode)]; + float total_time = 0.0f; + for (const auto& [type, time] : machine.gcode_time.times) { + float remaining = include_remaining ? machine.time - total_time : 0.0f; + ret.push_back({ type, { time, remaining } }); + total_time += time; + } + } + return ret; +} + void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) { /* std::cout << line.raw() << std::endl; */ @@ -126,6 +431,8 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) case 1: { process_G1(line); break; } // Move case 10: { process_G10(line); break; } // Retract case 11: { process_G11(line); break; } // Unretract + case 20: { process_G20(line); break; } // Set Units to Inches + case 21: { process_G21(line); break; } // Set Units to Millimeters case 22: { process_G22(line); break; } // Firmware controlled retract case 23: { process_G23(line); break; } // Firmware controlled unretract case 90: { process_G90(line); break; } // Set to Absolute Positioning @@ -139,6 +446,7 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) { switch (::atoi(&cmd[1])) { + case 1: { process_M1(line); break; } // Sleep or Conditional stop case 82: { process_M82(line); break; } // Set extruder to absolute mode case 83: { process_M83(line); break; } // Set extruder to relative mode case 106: { process_M106(line); break; } // Set fan speed @@ -146,8 +454,15 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) case 108: { process_M108(line); break; } // Set tool (Sailfish) case 132: { process_M132(line); break; } // Recall stored home offsets case 135: { process_M135(line); break; } // Set tool (MakerWare) + case 201: { process_M201(line); break; } // Set max printing acceleration + case 203: { process_M203(line); break; } // Set maximum feedrate + case 204: { process_M204(line); break; } // Set default acceleration + case 205: { process_M205(line); break; } // Advanced settings + case 221: { process_M221(line); break; } // Set extrude factor override percentage case 401: { process_M401(line); break; } // Repetier: Store x, y and z position case 402: { process_M402(line); break; } // Repetier: Go to stored position + case 566: { process_M566(line); break; } // Set allowable instantaneous speed change + case 702: { process_M702(line); break; } // Unload the current filament into the MK3 MMU2 unit at the end of print. default: { break; } } break; @@ -160,8 +475,7 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) default: { break; } } } - else - { + else { std::string comment = line.comment(); if (comment.length() > 1) // process tags embedded into comments @@ -179,8 +493,7 @@ void GCodeProcessor::process_tags(const std::string& comment) int role = std::stoi(comment.substr(pos + Extrusion_Role_Tag.length())); if (is_valid_extrusion_role(role)) m_extrusion_role = static_cast(role); - else - { + else { // todo: show some error ? } } @@ -247,11 +560,12 @@ void GCodeProcessor::process_tags(const std::string& comment) if (m_cp_color.counter == UCHAR_MAX) m_cp_color.counter = 0; - if (m_extruder_id == extruder_id) - { + if (m_extruder_id == extruder_id) { m_cp_color.current = m_extruders_color[extruder_id]; store_move_vertex(EMoveType::Color_change); } + + process_custom_gcode_time(CustomGCode::ColorChange); } catch (...) { @@ -265,6 +579,7 @@ void GCodeProcessor::process_tags(const std::string& comment) pos = comment.find(Pause_Print_Tag); if (pos != comment.npos) { store_move_vertex(EMoveType::Pause_Print); + process_custom_gcode_time(CustomGCode::PausePrint); return; } @@ -306,12 +621,14 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) type = EMoveType::Travel; else type = EMoveType::Retract; - } else if (delta_pos[E] > 0.0f) { + } + else if (delta_pos[E] > 0.0f) { if (delta_pos[X] == 0.0f && delta_pos[Y] == 0.0f && delta_pos[Z] == 0.0f) type = EMoveType::Unretract; else if ((delta_pos[X] != 0.0f) || (delta_pos[Y] != 0.0f)) type = EMoveType::Extrude; - } else if (delta_pos[X] != 0.0f || delta_pos[Y] != 0.0f || delta_pos[Z] != 0.0f) + } + else if (delta_pos[X] != 0.0f || delta_pos[Y] != 0.0f || delta_pos[Z] != 0.0f) type = EMoveType::Travel; #if ENABLE_GCODE_VIEWER_AS_STATE @@ -351,7 +668,165 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) if (max_abs_delta == 0.0f) return; - // store g1 move + // time estimate section + auto move_length = [](const AxisCoords& delta_pos) { + float sq_xyz_length = sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z]); + return (sq_xyz_length > 0.0f) ? std::sqrt(sq_xyz_length) : std::abs(delta_pos[E]); + }; + + auto is_extruder_only_move = [](const AxisCoords& delta_pos) { + return (delta_pos[X] == 0.0f) && (delta_pos[Y] == 0.0f) && (delta_pos[Z] == 0.0f) && (delta_pos[E] != 0.0f); + }; + + float distance = move_length(delta_pos); + assert(distance != 0.0f); + float inv_distance = 1.0f / distance; + + for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + TimeMachine& machine = m_time_processor.machines[i]; + if (!machine.enabled) + continue; + + TimeMachine::State& curr = machine.curr; + TimeMachine::State& prev = machine.prev; + std::vector& blocks = machine.blocks; + + curr.feedrate = (delta_pos[E] == 0.0f) ? + minimum_travel_feedrate(static_cast(i), m_feedrate) : + minimum_feedrate(static_cast(i), m_feedrate); + + TimeBlock block; + block.distance = distance; + + // calculates block cruise feedrate + float min_feedrate_factor = 1.0f; + for (unsigned char a = X; a <= E; ++a) { + curr.axis_feedrate[a] = curr.feedrate * delta_pos[a] * inv_distance; + if (a == E) + curr.axis_feedrate[a] *= machine.extrude_factor_override_percentage; + + curr.abs_axis_feedrate[a] = std::abs(curr.axis_feedrate[a]); + if (curr.abs_axis_feedrate[a] != 0.0f) { + float axis_max_feedrate = get_axis_max_feedrate(static_cast(i), static_cast(a)); + if (axis_max_feedrate != 0.0f) + min_feedrate_factor = std::min(min_feedrate_factor, axis_max_feedrate / curr.abs_axis_feedrate[a]); + } + } + + block.feedrate_profile.cruise = min_feedrate_factor * curr.feedrate; + + if (min_feedrate_factor < 1.0f) { + for (unsigned char a = X; a <= E; ++a) { + curr.axis_feedrate[a] *= min_feedrate_factor; + curr.abs_axis_feedrate[a] *= min_feedrate_factor; + } + } + + // calculates block acceleration + float acceleration = is_extruder_only_move(delta_pos) ? + get_retract_acceleration(static_cast(i)) : + get_acceleration(static_cast(i)); + + for (unsigned char a = X; a <= E; ++a) { + float axis_max_acceleration = get_axis_max_acceleration(static_cast(i), static_cast(a)); + if (acceleration * std::abs(delta_pos[a]) * inv_distance > axis_max_acceleration) + acceleration = axis_max_acceleration; + } + + block.acceleration = acceleration; + + // calculates block exit feedrate + curr.safe_feedrate = block.feedrate_profile.cruise; + + for (unsigned char a = X; a <= E; ++a) { + float axis_max_jerk = get_axis_max_jerk(static_cast(i), static_cast(a)); + if (curr.abs_axis_feedrate[a] > axis_max_jerk) + curr.safe_feedrate = std::min(curr.safe_feedrate, axis_max_jerk); + } + + block.feedrate_profile.exit = curr.safe_feedrate; + + static const float PREVIOUS_FEEDRATE_THRESHOLD = 0.0001f; + + // calculates block entry feedrate + float vmax_junction = curr.safe_feedrate; + if (!blocks.empty() && prev.feedrate > PREVIOUS_FEEDRATE_THRESHOLD) { + bool prev_speed_larger = prev.feedrate > block.feedrate_profile.cruise; + float smaller_speed_factor = prev_speed_larger ? (block.feedrate_profile.cruise / prev.feedrate) : (prev.feedrate / block.feedrate_profile.cruise); + // Pick the smaller of the nominal speeds. Higher speed shall not be achieved at the junction during coasting. + vmax_junction = prev_speed_larger ? block.feedrate_profile.cruise : prev.feedrate; + + float v_factor = 1.0f; + bool limited = false; + + for (unsigned char a = X; a <= E; ++a) { + // Limit an axis. We have to differentiate coasting from the reversal of an axis movement, or a full stop. + float v_exit = prev.axis_feedrate[a]; + float v_entry = curr.axis_feedrate[a]; + + if (prev_speed_larger) + v_exit *= smaller_speed_factor; + + if (limited) { + v_exit *= v_factor; + v_entry *= v_factor; + } + + // Calculate the jerk depending on whether the axis is coasting in the same direction or reversing a direction. + float jerk = + (v_exit > v_entry) ? + (((v_entry > 0.0f) || (v_exit < 0.0f)) ? + // coasting + (v_exit - v_entry) : + // axis reversal + std::max(v_exit, -v_entry)) : + // v_exit <= v_entry + (((v_entry < 0.0f) || (v_exit > 0.0f)) ? + // coasting + (v_entry - v_exit) : + // axis reversal + std::max(-v_exit, v_entry)); + + float axis_max_jerk = get_axis_max_jerk(static_cast(i), static_cast(a)); + if (jerk > axis_max_jerk) { + v_factor *= axis_max_jerk / jerk; + limited = true; + } + } + + if (limited) + vmax_junction *= v_factor; + + // Now the transition velocity is known, which maximizes the shared exit / entry velocity while + // respecting the jerk factors, it may be possible, that applying separate safe exit / entry velocities will achieve faster prints. + float vmax_junction_threshold = vmax_junction * 0.99f; + + // Not coasting. The machine will stop and start the movements anyway, better to start the segment from start. + if ((prev.safe_feedrate > vmax_junction_threshold) && (curr.safe_feedrate > vmax_junction_threshold)) + vmax_junction = curr.safe_feedrate; + } + + float v_allowable = max_allowable_speed(-acceleration, curr.safe_feedrate, block.distance); + block.feedrate_profile.entry = std::min(vmax_junction, v_allowable); + + block.max_entry_speed = vmax_junction; + block.flags.nominal_length = (block.feedrate_profile.cruise <= v_allowable); + block.flags.recalculate = true; + block.safe_feedrate = curr.safe_feedrate; + + // calculates block trapezoid + block.calculate_trapezoid(); + + // updates previous + prev = curr; + + blocks.push_back(block); + + if (blocks.size() > TimeProcessor::Planner::refresh_threshold) + machine.calculate_time(TimeProcessor::Planner::queue_size); + } + + // store move store_move_vertex(move_type(delta_pos)); } @@ -367,6 +842,16 @@ void GCodeProcessor::process_G11(const GCodeReader::GCodeLine& line) store_move_vertex(EMoveType::Unretract); } +void GCodeProcessor::process_G20(const GCodeReader::GCodeLine& line) +{ + m_units = EUnits::Inches; +} + +void GCodeProcessor::process_G21(const GCodeReader::GCodeLine& line) +{ + m_units = EUnits::Millimeters; +} + void GCodeProcessor::process_G22(const GCodeReader::GCodeLine& line) { // stores retract move @@ -391,32 +876,34 @@ void GCodeProcessor::process_G91(const GCodeReader::GCodeLine& line) void GCodeProcessor::process_G92(const GCodeReader::GCodeLine& line) { - float lengthsScaleFactor = (m_units == EUnits::Inches) ? INCHES_TO_MM : 1.0f; - bool anyFound = false; + float lengths_scale_factor = (m_units == EUnits::Inches) ? INCHES_TO_MM : 1.0f; + bool any_found = false; if (line.has_x()) { - m_origin[X] = m_end_position[X] - line.x() * lengthsScaleFactor; - anyFound = true; + m_origin[X] = m_end_position[X] - line.x() * lengths_scale_factor; + any_found = true; } if (line.has_y()) { - m_origin[Y] = m_end_position[Y] - line.y() * lengthsScaleFactor; - anyFound = true; + m_origin[Y] = m_end_position[Y] - line.y() * lengths_scale_factor; + any_found = true; } if (line.has_z()) { - m_origin[Z] = m_end_position[Z] - line.z() * lengthsScaleFactor; - anyFound = true; + m_origin[Z] = m_end_position[Z] - line.z() * lengths_scale_factor; + any_found = true; } if (line.has_e()) { // extruder coordinate can grow to the point where its float representation does not allow for proper addition with small increments, // we set the value taken from the G92 line as the new current position for it - m_end_position[E] = line.e() * lengthsScaleFactor; - anyFound = true; + m_end_position[E] = line.e() * lengths_scale_factor; + any_found = true; } + else + simulate_st_synchronize(); - if (!anyFound && !line.has_unknown_axis()) { + if (!any_found && !line.has_unknown_axis()) { // The G92 may be called for axes that PrusaSlicer does not recognize, for example see GH issue #3510, // where G92 A0 B0 is called although the extruder axis is till E. for (unsigned char a = X; a <= E; ++a) { @@ -425,6 +912,11 @@ void GCodeProcessor::process_G92(const GCodeReader::GCodeLine& line) } } +void GCodeProcessor::process_M1(const GCodeReader::GCodeLine& line) +{ + simulate_st_synchronize(); +} + void GCodeProcessor::process_M82(const GCodeReader::GCodeLine& line) { m_e_local_positioning_type = EPositioningType::Absolute; @@ -501,6 +993,117 @@ void GCodeProcessor::process_M135(const GCodeReader::GCodeLine& line) process_T(cmd.substr(pos)); } +void GCodeProcessor::process_M201(const GCodeReader::GCodeLine& line) +{ + // see http://reprap.org/wiki/G-code#M201:_Set_max_printing_acceleration + float factor = (m_flavor != gcfRepRap && m_units == EUnits::Inches) ? INCHES_TO_MM : 1.0f; + + for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + if (line.has_x()) + set_option_value(m_time_processor.machine_limits.machine_max_acceleration_x, i, line.x() * factor); + + if (line.has_y() && i < m_time_processor.machine_limits.machine_max_acceleration_y.values.size()) + set_option_value(m_time_processor.machine_limits.machine_max_acceleration_y, i, line.y() * factor); + + if (line.has_z() && i < m_time_processor.machine_limits.machine_max_acceleration_z.values.size()) + set_option_value(m_time_processor.machine_limits.machine_max_acceleration_z, i, line.z() * factor); + + if (line.has_e() && i < m_time_processor.machine_limits.machine_max_acceleration_e.values.size()) + set_option_value(m_time_processor.machine_limits.machine_max_acceleration_e, i, line.e() * factor); + } +} + +void GCodeProcessor::process_M203(const GCodeReader::GCodeLine& line) +{ + // see http://reprap.org/wiki/G-code#M203:_Set_maximum_feedrate + if (m_flavor == gcfRepetier) + return; + + // see http://reprap.org/wiki/G-code#M203:_Set_maximum_feedrate + // http://smoothieware.org/supported-g-codes + float factor = (m_flavor == gcfMarlin || m_flavor == gcfSmoothie) ? 1.0f : MMMIN_TO_MMSEC; + + for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + if (line.has_x()) + set_option_value(m_time_processor.machine_limits.machine_max_feedrate_x, i, line.x() * factor); + + if (line.has_y()) + set_option_value(m_time_processor.machine_limits.machine_max_feedrate_y, i, line.y() * factor); + + if (line.has_z()) + set_option_value(m_time_processor.machine_limits.machine_max_feedrate_z, i, line.z() * factor); + + if (line.has_e()) + set_option_value(m_time_processor.machine_limits.machine_max_feedrate_e, i, line.e() * factor); + } +} + +void GCodeProcessor::process_M204(const GCodeReader::GCodeLine& line) +{ + float value; + for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + if (line.has_value('S', value)) { + // Legacy acceleration format. This format is used by the legacy Marlin, MK2 or MK3 firmware, + // and it is also generated by Slic3r to control acceleration per extrusion type + // (there is a separate acceleration settings in Slicer for perimeter, first layer etc). + set_acceleration(static_cast(i), value); + if (line.has_value('T', value)) + set_option_value(m_time_processor.machine_limits.machine_max_acceleration_retracting, i, value); + } + else { + // New acceleration format, compatible with the upstream Marlin. + if (line.has_value('P', value)) + set_acceleration(static_cast(i), value); + if (line.has_value('R', value)) + set_option_value(m_time_processor.machine_limits.machine_max_acceleration_retracting, i, value); + if (line.has_value('T', value)) { + // Interpret the T value as the travel acceleration in the new Marlin format. + //FIXME Prusa3D firmware currently does not support travel acceleration value independent from the extruding acceleration value. + // set_travel_acceleration(value); + } + } + } +} + +void GCodeProcessor::process_M205(const GCodeReader::GCodeLine& line) +{ + for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + if (line.has_x()) { + float max_jerk = line.x(); + set_option_value(m_time_processor.machine_limits.machine_max_jerk_x, i, max_jerk); + set_option_value(m_time_processor.machine_limits.machine_max_jerk_y, i, max_jerk); + } + + if (line.has_y()) + set_option_value(m_time_processor.machine_limits.machine_max_jerk_y, i, line.y()); + + if (line.has_z()) + set_option_value(m_time_processor.machine_limits.machine_max_jerk_z, i, line.z()); + + if (line.has_e()) + set_option_value(m_time_processor.machine_limits.machine_max_jerk_e, i, line.e()); + + float value; + if (line.has_value('S', value)) + set_option_value(m_time_processor.machine_limits.machine_min_extruding_rate, i, value); + + if (line.has_value('T', value)) + set_option_value(m_time_processor.machine_limits.machine_min_travel_rate, i, value); + } +} + +void GCodeProcessor::process_M221(const GCodeReader::GCodeLine& line) +{ + float value_s; + float value_t; + if (line.has_value('S', value_s) && !line.has_value('T', value_t)) { + value_s *= 0.01f; + for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + m_time_processor.machines[i].extrude_factor_override_percentage = value_s; + } + } +} + void GCodeProcessor::process_M401(const GCodeReader::GCodeLine& line) { if (m_flavor != gcfRepetier) @@ -544,6 +1147,34 @@ void GCodeProcessor::process_M402(const GCodeReader::GCodeLine& line) m_feedrate = p; } +void GCodeProcessor::process_M566(const GCodeReader::GCodeLine& line) +{ + for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + if (line.has_x()) + set_option_value(m_time_processor.machine_limits.machine_max_jerk_x, i, line.x() * MMMIN_TO_MMSEC); + + if (line.has_y()) + set_option_value(m_time_processor.machine_limits.machine_max_jerk_y, i, line.y() * MMMIN_TO_MMSEC); + + if (line.has_z()) + set_option_value(m_time_processor.machine_limits.machine_max_jerk_z, i, line.z() * MMMIN_TO_MMSEC); + + if (line.has_e()) + set_option_value(m_time_processor.machine_limits.machine_max_jerk_e, i, line.e() * MMMIN_TO_MMSEC); + } +} + +void GCodeProcessor::process_M702(const GCodeReader::GCodeLine& line) +{ + if (line.has('C')) { + // MK3 MMU2 specific M code: + // M702 C is expected to be sent by the custom end G-code when finalizing a print. + // The MK3 unit shall unload and park the active filament into the MMU2 unit. + m_time_processor.extruder_unloaded = true; + simulate_st_synchronize(get_filament_unload_time(m_extruder_id)); + } +} + void GCodeProcessor::process_T(const GCodeReader::GCodeLine& line) { process_T(line.cmd()); @@ -560,8 +1191,16 @@ void GCodeProcessor::process_T(const std::string& command) if (id >= extruders_count) BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid toolchange, maybe from a custom gcode."; else { + unsigned char old_extruder_id = m_extruder_id; m_extruder_id = id; m_cp_color.current = m_extruders_color[id]; + // Specific to the MK3 MMU2: + // The initial value of extruder_unloaded is set to true indicating + // that the filament is parked in the MMU2 unit and there is nothing to be unloaded yet. + float extra_time = get_filament_unload_time(static_cast(old_extruder_id)); + m_time_processor.extruder_unloaded = false; + extra_time += get_filament_load_time(static_cast(m_extruder_id)); + simulate_st_synchronize(extra_time); } // store tool change move @@ -593,6 +1232,120 @@ void GCodeProcessor::store_move_vertex(EMoveType type) m_result.moves.emplace_back(vertex); } +float GCodeProcessor::minimum_feedrate(ETimeMode mode, float feedrate) const +{ + if (m_time_processor.machine_limits.machine_min_extruding_rate.empty()) + return feedrate; + + return std::max(feedrate, get_option_value(m_time_processor.machine_limits.machine_min_extruding_rate, static_cast(mode))); +} + +float GCodeProcessor::minimum_travel_feedrate(ETimeMode mode, float feedrate) const +{ + if (m_time_processor.machine_limits.machine_min_travel_rate.empty()) + return feedrate; + + return std::max(feedrate, get_option_value(m_time_processor.machine_limits.machine_min_travel_rate, static_cast(mode))); +} + +float GCodeProcessor::get_axis_max_feedrate(ETimeMode mode, Axis axis) const +{ + switch (axis) + { + case X: { return get_option_value(m_time_processor.machine_limits.machine_max_feedrate_x, static_cast(mode)); } + case Y: { return get_option_value(m_time_processor.machine_limits.machine_max_feedrate_y, static_cast(mode)); } + case Z: { return get_option_value(m_time_processor.machine_limits.machine_max_feedrate_z, static_cast(mode)); } + case E: { return get_option_value(m_time_processor.machine_limits.machine_max_feedrate_e, static_cast(mode)); } + default: { return 0.0f; } + } +} + +float GCodeProcessor::get_axis_max_acceleration(ETimeMode mode, Axis axis) const +{ + switch (axis) + { + case X: { return get_option_value(m_time_processor.machine_limits.machine_max_acceleration_x, static_cast(mode)); } + case Y: { return get_option_value(m_time_processor.machine_limits.machine_max_acceleration_y, static_cast(mode)); } + case Z: { return get_option_value(m_time_processor.machine_limits.machine_max_acceleration_z, static_cast(mode)); } + case E: { return get_option_value(m_time_processor.machine_limits.machine_max_acceleration_e, static_cast(mode)); } + default: { return 0.0f; } + } +} + +float GCodeProcessor::get_axis_max_jerk(ETimeMode mode, Axis axis) const +{ + switch (axis) + { + case X: { return get_option_value(m_time_processor.machine_limits.machine_max_jerk_x, static_cast(mode)); } + case Y: { return get_option_value(m_time_processor.machine_limits.machine_max_jerk_y, static_cast(mode)); } + case Z: { return get_option_value(m_time_processor.machine_limits.machine_max_jerk_z, static_cast(mode)); } + case E: { return get_option_value(m_time_processor.machine_limits.machine_max_jerk_e, static_cast(mode)); } + default: { return 0.0f; } + } +} + +float GCodeProcessor::get_retract_acceleration(ETimeMode mode) const +{ + return get_option_value(m_time_processor.machine_limits.machine_max_acceleration_retracting, static_cast(mode)); +} + +float GCodeProcessor::get_acceleration(ETimeMode mode) const +{ + size_t id = static_cast(mode); + return (id < m_time_processor.machines.size()) ? m_time_processor.machines[id].acceleration : DEFAULT_ACCELERATION; +} + +void GCodeProcessor::set_acceleration(ETimeMode mode, float value) +{ + size_t id = static_cast(mode); + if (id < m_time_processor.machines.size()) { + float max_acceleration = get_option_value(m_time_processor.machine_limits.machine_max_acceleration_extruding, id); + m_time_processor.machines[id].acceleration = (max_acceleration == 0.0f) ? value : std::min(value, max_acceleration); + } +} + +float GCodeProcessor::get_filament_load_time(size_t extruder_id) +{ + return (m_time_processor.filament_load_times.empty() || m_time_processor.extruder_unloaded) ? + 0.0f : + ((extruder_id < m_time_processor.filament_load_times.size()) ? + m_time_processor.filament_load_times[extruder_id] : m_time_processor.filament_load_times.front()); +} + +float GCodeProcessor::get_filament_unload_time(size_t extruder_id) +{ + return (m_time_processor.filament_unload_times.empty() || m_time_processor.extruder_unloaded) ? + 0.0f : + ((extruder_id < m_time_processor.filament_unload_times.size()) ? + m_time_processor.filament_unload_times[extruder_id] : m_time_processor.filament_unload_times.front()); +} + +void GCodeProcessor::process_custom_gcode_time(CustomGCode::Type code) +{ + for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + TimeMachine& machine = m_time_processor.machines[i]; + if (!machine.enabled) + continue; + + TimeMachine::CustomGCodeTime& gcode_time = machine.gcode_time; + gcode_time.needed = true; + //FIXME this simulates st_synchronize! is it correct? + // The estimated time may be longer than the real print time. + machine.simulate_st_synchronize(); + if (gcode_time.cache != 0.0f) { + gcode_time.times.push_back({ code, gcode_time.cache }); + gcode_time.cache = 0.0f; + } + } +} + +void GCodeProcessor::simulate_st_synchronize(float additional_time) +{ + for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + m_time_processor.machines[i].simulate_st_synchronize(additional_time); + } +} + } /* namespace Slic3r */ #endif // ENABLE_GCODE_VIEWER diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 3f596c9c2b..9878eea9dd 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -5,6 +5,8 @@ #include "libslic3r/GCodeReader.hpp" #include "libslic3r/Point.hpp" #include "libslic3r/ExtrusionEntity.hpp" +#include "libslic3r/PrintConfig.hpp" +#include "libslic3r/CustomGCode.hpp" #include #include @@ -41,7 +43,7 @@ namespace Slic3r { struct CachedPosition { AxisCoords position; // mm - float feedrate; // mm/s + float feedrate; // mm/s void reset(); }; @@ -54,6 +56,118 @@ namespace Slic3r { void reset(); }; + public: + struct FeedrateProfile + { + float entry{ 0.0f }; // mm/s + float cruise{ 0.0f }; // mm/s + float exit{ 0.0f }; // mm/s + }; + + struct Trapezoid + { + float accelerate_until{ 0.0f }; // mm + float decelerate_after{ 0.0f }; // mm + float cruise_feedrate{ 0.0f }; // mm/sec + + float acceleration_time(float entry_feedrate, float acceleration) const; + float cruise_time() const; + float deceleration_time(float distance, float acceleration) const; + float cruise_distance() const; + }; + + struct TimeBlock + { + struct Flags + { + bool recalculate{ false }; + bool nominal_length{ false }; + }; + + float distance{ 0.0f }; // mm + float acceleration{ 0.0f }; // mm/s^2 + float max_entry_speed{ 0.0f }; // mm/s + float safe_feedrate{ 0.0f }; // mm/s + Flags flags; + FeedrateProfile feedrate_profile; + Trapezoid trapezoid; + + // Calculates this block's trapezoid + void calculate_trapezoid(); + + float time() const; + }; + + enum class ETimeMode : unsigned char + { + Normal, + Stealth, + Count + }; + + private: + struct TimeMachine + { + struct State + { + float feedrate; // mm/s + float safe_feedrate; // mm/s + AxisCoords axis_feedrate; // mm/s + AxisCoords abs_axis_feedrate; // mm/s + + void reset(); + }; + + struct CustomGCodeTime + { + bool needed; + float cache; + std::vector> times; + + void reset(); + }; + + bool enabled; + float acceleration; // mm/s^2 + float extrude_factor_override_percentage; + float time; // s + State curr; + State prev; + CustomGCodeTime gcode_time; + std::vector blocks; + + void reset(); + + // Simulates firmware st_synchronize() call + void simulate_st_synchronize(float additional_time = 0.0f); + void calculate_time(size_t keep_last_n_blocks = 0); + }; + + struct TimeProcessor + { + struct Planner + { + // Size of the firmware planner queue. The old 8-bit Marlins usually just managed 16 trapezoidal blocks. + // Let's be conservative and plan for newer boards with more memory. + static constexpr size_t queue_size = 64; + // The firmware recalculates last planner_queue_size trapezoidal blocks each time a new block is added. + // We are not simulating the firmware exactly, we calculate a sequence of blocks once a reasonable number of blocks accumulate. + static constexpr size_t refresh_threshold = queue_size * 4; + }; + + // extruder_id is currently used to correctly calculate filament load / unload times into the total print time. + // This is currently only really used by the MK3 MMU2: + // extruder_unloaded = true means no filament is loaded yet, all the filaments are parked in the MK3 MMU2 unit. + bool extruder_unloaded; + MachineEnvelopeConfig machine_limits; + // Additional load / unload times for a filament exchange sequence. + std::vector filament_load_times; + std::vector filament_unload_times; + std::array(ETimeMode::Count)> machines; + + void reset(); + }; + public: enum class EMoveType : unsigned char { @@ -85,21 +199,6 @@ namespace Slic3r { float time{ 0.0f }; // s float volumetric_rate() const { return feedrate * mm3_per_mm; } - - std::string to_string() const - { - std::string str = std::to_string((int)type); - str += ", " + std::to_string((int)extrusion_role); - str += ", " + Slic3r::to_string((Vec3d)position.cast()); - str += ", " + std::to_string(extruder_id); - str += ", " + std::to_string(cp_color_id); - str += ", " + std::to_string(feedrate); - str += ", " + std::to_string(width); - str += ", " + std::to_string(height); - str += ", " + std::to_string(mm3_per_mm); - str += ", " + std::to_string(fan_speed); - return str; - } }; struct Result @@ -124,13 +223,13 @@ namespace Slic3r { GCodeFlavor m_flavor; AxisCoords m_start_position; // mm - AxisCoords m_end_position; // mm - AxisCoords m_origin; // mm + AxisCoords m_end_position; // mm + AxisCoords m_origin; // mm CachedPosition m_cached_position; - float m_feedrate; // mm/s - float m_width; // mm - float m_height; // mm + float m_feedrate; // mm/s + float m_width; // mm + float m_height; // mm float m_mm3_per_mm; float m_fan_speed; // percentage ExtrusionRole m_extrusion_role; @@ -138,6 +237,8 @@ namespace Slic3r { ExtrudersColor m_extruders_color; CpColor m_cp_color; + TimeProcessor m_time_processor; + Result m_result; static unsigned int s_result_id; @@ -145,6 +246,7 @@ namespace Slic3r { GCodeProcessor() { reset(); } void apply_config(const PrintConfig& config); + void enable_stealth_time_estimator(bool enabled); void reset(); const Result& get_result() const { return m_result; } @@ -153,6 +255,9 @@ namespace Slic3r { // Process the gcode contained in the file with the given filename void process_file(const std::string& filename); + std::string get_time_dhm(ETimeMode mode) const; + std::vector>> get_custom_gcode_times(ETimeMode mode, bool include_remaining) const; + private: void process_gcode_line(const GCodeReader::GCodeLine& line); @@ -169,6 +274,12 @@ namespace Slic3r { // Unretract void process_G11(const GCodeReader::GCodeLine& line); + // Set Units to Inches + void process_G20(const GCodeReader::GCodeLine& line); + + // Set Units to Millimeters + void process_G21(const GCodeReader::GCodeLine& line); + // Firmware controlled Retract void process_G22(const GCodeReader::GCodeLine& line); @@ -184,6 +295,9 @@ namespace Slic3r { // Set Position void process_G92(const GCodeReader::GCodeLine& line); + // Sleep or Conditional stop + void process_M1(const GCodeReader::GCodeLine& line); + // Set extruder to absolute mode void process_M82(const GCodeReader::GCodeLine& line); @@ -205,17 +319,54 @@ namespace Slic3r { // Set tool (MakerWare) void process_M135(const GCodeReader::GCodeLine& line); + // Set max printing acceleration + void process_M201(const GCodeReader::GCodeLine& line); + + // Set maximum feedrate + void process_M203(const GCodeReader::GCodeLine& line); + + // Set default acceleration + void process_M204(const GCodeReader::GCodeLine& line); + + // Advanced settings + void process_M205(const GCodeReader::GCodeLine& line); + + // Set extrude factor override percentage + void process_M221(const GCodeReader::GCodeLine& line); + // Repetier: Store x, y and z position void process_M401(const GCodeReader::GCodeLine& line); // Repetier: Go to stored position void process_M402(const GCodeReader::GCodeLine& line); + // Set allowable instantaneous speed change + void process_M566(const GCodeReader::GCodeLine& line); + + // Unload the current filament into the MK3 MMU2 unit at the end of print. + void process_M702(const GCodeReader::GCodeLine& line); + // Processes T line (Select Tool) void process_T(const GCodeReader::GCodeLine& line); void process_T(const std::string& command); void store_move_vertex(EMoveType type); + + float minimum_feedrate(ETimeMode mode, float feedrate) const; + float minimum_travel_feedrate(ETimeMode mode, float feedrate) const; + float get_axis_max_feedrate(ETimeMode mode, Axis axis) const; + float get_axis_max_acceleration(ETimeMode mode, Axis axis) const; + float get_axis_max_jerk(ETimeMode mode, Axis axis) const; + float get_retract_acceleration(ETimeMode mode) const; + float get_acceleration(ETimeMode mode) const; + void set_acceleration(ETimeMode mode, float value); + float get_filament_load_time(size_t extruder_id); + float get_filament_unload_time(size_t extruder_id); + + void process_custom_gcode_time(CustomGCode::Type code); + + // Simulates firmware st_synchronize() call + void simulate_st_synchronize(float additional_time = 0.0f); }; } /* namespace Slic3r */ diff --git a/src/libslic3r/GCodeTimeEstimator.cpp b/src/libslic3r/GCodeTimeEstimator.cpp index d67db84819..bc3adefc08 100644 --- a/src/libslic3r/GCodeTimeEstimator.cpp +++ b/src/libslic3r/GCodeTimeEstimator.cpp @@ -678,21 +678,6 @@ namespace Slic3r { return _get_time_minutes(get_time()); } -#if ENABLE_GCODE_VIEWER - std::vector>> GCodeTimeEstimator::get_custom_gcode_times(bool include_remaining) const - { - std::vector>> ret; - - float total_time = 0.0f; - for (const auto& [type, time] : m_custom_gcode_times) { - float remaining = include_remaining ? m_time - total_time : 0.0f; - ret.push_back({ type, { time, remaining } }); - total_time += time; - } - - return ret; - } -#else std::vector> GCodeTimeEstimator::get_custom_gcode_times() const { return m_custom_gcode_times; @@ -736,7 +721,6 @@ namespace Slic3r { } return ret; } -#endif // ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER std::vector>> GCodeTimeEstimator::get_custom_gcode_times_dhm(bool include_remaining) const diff --git a/src/libslic3r/GCodeTimeEstimator.hpp b/src/libslic3r/GCodeTimeEstimator.hpp index cfa12b40be..ce6b2f4af0 100644 --- a/src/libslic3r/GCodeTimeEstimator.hpp +++ b/src/libslic3r/GCodeTimeEstimator.hpp @@ -358,9 +358,6 @@ namespace Slic3r { std::string get_time_minutes() const; // Returns the estimated time, in seconds, for each custom gcode -#if ENABLE_GCODE_VIEWER - std::vector>> get_custom_gcode_times(bool include_remaining) const; -#else std::vector> get_custom_gcode_times() const; // Returns the estimated time, in format DDd HHh MMm SSs, for each color @@ -370,7 +367,6 @@ namespace Slic3r { // Returns the estimated time, in minutes (integer), for each color // If include_remaining==true the strings will be formatted as: "time for color (remaining time at color start)" std::vector get_color_times_minutes(bool include_remaining) const; -#endif // ENABLE_GCODE_VIEWER // Returns the estimated time, in format DDd HHh MMm, for each custom_gcode // If include_remaining==true the strings will be formatted as: "time for custom_gcode (remaining time at color start)" diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 5a1a9868d7..34fab6f307 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -2190,18 +2190,24 @@ std::string Print::output_filename(const std::string &filename_base) const DynamicConfig PrintStatistics::config() const { DynamicConfig config; +#if ENABLE_GCODE_VIEWER + config.set_key_value("print_time", new ConfigOptionString(this->estimated_normal_print_time_str)); + config.set_key_value("normal_print_time", new ConfigOptionString(this->estimated_normal_print_time_str)); + config.set_key_value("silent_print_time", new ConfigOptionString(this->estimated_silent_print_time_str)); +#else std::string normal_print_time = short_time(this->estimated_normal_print_time); std::string silent_print_time = short_time(this->estimated_silent_print_time); config.set_key_value("print_time", new ConfigOptionString(normal_print_time)); config.set_key_value("normal_print_time", new ConfigOptionString(normal_print_time)); config.set_key_value("silent_print_time", new ConfigOptionString(silent_print_time)); - config.set_key_value("used_filament", new ConfigOptionFloat (this->total_used_filament / 1000.)); - config.set_key_value("extruded_volume", new ConfigOptionFloat (this->total_extruded_volume)); - config.set_key_value("total_cost", new ConfigOptionFloat (this->total_cost)); +#endif // ENABLE_GCODE_VIEWER + config.set_key_value("used_filament", new ConfigOptionFloat(this->total_used_filament / 1000.)); + config.set_key_value("extruded_volume", new ConfigOptionFloat(this->total_extruded_volume)); + config.set_key_value("total_cost", new ConfigOptionFloat(this->total_cost)); config.set_key_value("total_toolchanges", new ConfigOptionInt(this->total_toolchanges)); - config.set_key_value("total_weight", new ConfigOptionFloat (this->total_weight)); - config.set_key_value("total_wipe_tower_cost", new ConfigOptionFloat (this->total_wipe_tower_cost)); - config.set_key_value("total_wipe_tower_filament", new ConfigOptionFloat (this->total_wipe_tower_filament)); + config.set_key_value("total_weight", new ConfigOptionFloat(this->total_weight)); + config.set_key_value("total_wipe_tower_cost", new ConfigOptionFloat(this->total_wipe_tower_cost)); + config.set_key_value("total_wipe_tower_filament", new ConfigOptionFloat(this->total_wipe_tower_filament)); return config; } diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index eb9a4fb4b7..b46ec42174 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -303,14 +303,18 @@ private: struct PrintStatistics { PrintStatistics() { clear(); } +#if ENABLE_GCODE_VIEWER std::string estimated_normal_print_time; std::string estimated_silent_print_time; -#if ENABLE_GCODE_VIEWER + std::string estimated_normal_print_time_str; + std::string estimated_silent_print_time_str; std::vector>> estimated_normal_custom_gcode_print_times; std::vector>> estimated_silent_custom_gcode_print_times; std::vector>> estimated_normal_custom_gcode_print_times_str; std::vector>> estimated_silent_custom_gcode_print_times_str; #else + std::string estimated_normal_print_time; + std::string estimated_silent_print_time; std::vector> estimated_normal_custom_gcode_print_times; std::vector> estimated_silent_custom_gcode_print_times; #endif // ENABLE_GCODE_VIEWER @@ -331,14 +335,12 @@ struct PrintStatistics std::string finalize_output_path(const std::string &path_in) const; void clear() { - estimated_normal_print_time.clear(); - estimated_silent_print_time.clear(); #if ENABLE_GCODE_VIEWER estimated_normal_custom_gcode_print_times_str.clear(); estimated_silent_custom_gcode_print_times_str.clear(); - estimated_normal_custom_gcode_print_times.clear(); - estimated_silent_custom_gcode_print_times.clear(); #else + estimated_normal_print_time.clear(); + estimated_silent_print_time.clear(); estimated_normal_custom_gcode_print_times.clear(); estimated_silent_custom_gcode_print_times.clear(); #endif //ENABLE_GCODE_VIEWER diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index aaabd62220..27b0db83f5 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1720,6 +1720,9 @@ void GCodeViewer::render_time_estimate() const if (ps.estimated_normal_print_time == "N/A" && ps.estimated_silent_print_time == "N/A") return; + if (ps.estimated_normal_print_time.empty() && ps.estimated_silent_print_time.empty()) + return; + ImGuiWrapper& imgui = *wxGetApp().imgui(); using Time = std::pair; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 0981740ebf..9c22a6d60a 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1322,7 +1322,11 @@ void Sidebar::update_sliced_info_sizer() wxString::Format("%.2f", ps.total_cost); p->sliced_info->SetTextAndShow(siCost, info_text, new_label); +#if ENABLE_GCODE_VIEWER + if (ps.estimated_normal_print_time_str == "N/A" && ps.estimated_silent_print_time_str == "N/A") +#else if (ps.estimated_normal_print_time == "N/A" && ps.estimated_silent_print_time == "N/A") +#endif // ENABLE_GCODE_VIEWER p->sliced_info->SetTextAndShow(siEstimatedTime, "N/A"); else { new_label = _L("Estimated printing time") +":"; @@ -1360,21 +1364,25 @@ void Sidebar::update_sliced_info_sizer() } }; +#if ENABLE_GCODE_VIEWER + if (ps.estimated_normal_print_time_str != "N/A") { + new_label += format_wxstr("\n - %1%", _L("normal mode")); + info_text += format_wxstr("\n%1%", ps.estimated_normal_print_time_str); + fill_labels(ps.estimated_normal_custom_gcode_print_times_str, new_label, info_text); + } + if (ps.estimated_silent_print_time_str != "N/A") { + new_label += format_wxstr("\n - %1%", _L("stealth mode")); + info_text += format_wxstr("\n%1%", ps.estimated_silent_print_time_str); + fill_labels(ps.estimated_silent_custom_gcode_print_times_str, new_label, info_text); +#else if (ps.estimated_normal_print_time != "N/A") { new_label += format_wxstr("\n - %1%", _L("normal mode")); info_text += format_wxstr("\n%1%", ps.estimated_normal_print_time); -#if ENABLE_GCODE_VIEWER - fill_labels(ps.estimated_normal_custom_gcode_print_times_str, new_label, info_text); -#else fill_labels(ps.estimated_normal_custom_gcode_print_times, new_label, info_text); -#endif // ENABLE_GCODE_VIEWER } if (ps.estimated_silent_print_time != "N/A") { new_label += format_wxstr("\n - %1%", _L("stealth mode")); info_text += format_wxstr("\n%1%", ps.estimated_silent_print_time); -#if ENABLE_GCODE_VIEWER - fill_labels(ps.estimated_silent_custom_gcode_print_times_str, new_label, info_text); -#else fill_labels(ps.estimated_silent_custom_gcode_print_times, new_label, info_text); #endif // ENABLE_GCODE_VIEWER } From f7164db68e760c9df9a937b5b3674c9f8bcd3be8 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 17 Jul 2020 08:27:23 +0200 Subject: [PATCH 150/255] GCodeViewer -> Added estimated printing times for move types --- src/libslic3r/GCode.cpp | 28 +---- src/libslic3r/GCode/GCodeProcessor.cpp | 51 ++++++++- src/libslic3r/GCode/GCodeProcessor.hpp | 36 +++--- src/libslic3r/Print.hpp | 19 +++- src/slic3r/GUI/GCodeViewer.cpp | 148 ++++++++++++++++++------- 5 files changed, 195 insertions(+), 87 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 47448954c8..9e365f9558 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -705,27 +705,6 @@ namespace Slic3r { } #if ENABLE_GCODE_VIEWER -// free functions called by GCode::do_export() -namespace DoExport { - static void update_print_stats_estimated_times( - const GCodeProcessor& processor, - const bool silent_time_estimator_enabled, - PrintStatistics& print_statistics) - { - print_statistics.estimated_normal_print_time = processor.get_time_dhm(GCodeProcessor::ETimeMode::Normal); - print_statistics.estimated_normal_custom_gcode_print_times = processor.get_custom_gcode_times(GCodeProcessor::ETimeMode::Normal, true); - if (silent_time_estimator_enabled) { - print_statistics.estimated_silent_print_time = processor.get_time_dhm(GCodeProcessor::ETimeMode::Stealth); - print_statistics.estimated_silent_custom_gcode_print_times = processor.get_custom_gcode_times(GCodeProcessor::ETimeMode::Stealth, true); - } - else { - print_statistics.estimated_silent_print_time = "N/A"; - print_statistics.estimated_silent_custom_gcode_print_times.clear(); - } - } - -} // namespace DoExport - void GCode::do_export(Print* print, const char* path, GCodeProcessor::Result* result, ThumbnailsGeneratorCallback thumbnail_cb) #else void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_data, ThumbnailsGeneratorCallback thumbnail_cb) @@ -787,11 +766,12 @@ void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_ } #if ENABLE_GCODE_VIEWER + print->m_print_statistics.clear_time_estimates(); m_processor.process_file(path_tmp); - if (result != nullptr) + if (result != nullptr) { *result = std::move(m_processor.extract_result()); - - DoExport::update_print_stats_estimated_times(m_processor, m_silent_time_estimator_enabled, print->m_print_statistics); + m_processor.update_print_stats_estimated_times(print->m_print_statistics); + } #endif // ENABLE_GCODE_VIEWER GCodeTimeEstimator::PostProcessData normal_data = m_normal_time_estimator.get_post_process_data(); diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 7174e5e36d..7f8efc53fc 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -1,5 +1,6 @@ #include "libslic3r/libslic3r.h" #include "libslic3r/Utils.hpp" +#include "libslic3r/Print.hpp" #include "GCodeProcessor.hpp" #include @@ -161,6 +162,7 @@ void GCodeProcessor::TimeMachine::reset() prev.reset(); gcode_time.reset(); blocks = std::vector(); + std::fill(moves_time.begin(), moves_time.end(), 0.0f); } void GCodeProcessor::TimeMachine::simulate_st_synchronize(float additional_time) @@ -264,9 +266,11 @@ void GCodeProcessor::TimeMachine::calculate_time(size_t keep_last_n_blocks) size_t n_blocks_process = blocks.size() - keep_last_n_blocks; // m_g1_times.reserve(m_g1_times.size() + n_blocks_process); for (size_t i = 0; i < n_blocks_process; ++i) { - float block_time = blocks[i].time(); + const TimeBlock& block = blocks[i]; + float block_time = block.time(); time += block_time; gcode_time.cache += block_time; + moves_time[static_cast(block.move_type)] += block_time; // if (block.g1_line_id >= 0) // m_g1_times.emplace_back(block.g1_line_id, time); @@ -388,12 +392,31 @@ void GCodeProcessor::process_file(const std::string& filename) #endif // ENABLE_GCODE_VIEWER_STATISTICS } +void GCodeProcessor::update_print_stats_estimated_times(PrintStatistics& print_statistics) +{ + print_statistics.estimated_normal_print_time = get_time(GCodeProcessor::ETimeMode::Normal); + print_statistics.estimated_normal_custom_gcode_print_times = get_custom_gcode_times(GCodeProcessor::ETimeMode::Normal, true); + print_statistics.estimated_normal_moves_times = get_moves_time(GCodeProcessor::ETimeMode::Normal); + if (m_time_processor.machines[static_cast(GCodeProcessor::ETimeMode::Stealth)].enabled) { + print_statistics.estimated_silent_print_time = get_time(GCodeProcessor::ETimeMode::Stealth); + print_statistics.estimated_silent_custom_gcode_print_times = get_custom_gcode_times(GCodeProcessor::ETimeMode::Stealth, true); + print_statistics.estimated_silent_moves_times = get_moves_time(GCodeProcessor::ETimeMode::Stealth); + } + else { + print_statistics.estimated_silent_print_time = 0.0f; + print_statistics.estimated_silent_custom_gcode_print_times.clear(); + print_statistics.estimated_silent_moves_times.clear(); + } +} + +float GCodeProcessor::get_time(ETimeMode mode) const +{ + return (mode < ETimeMode::Count) ? m_time_processor.machines[static_cast(mode)].time : 0.0f; +} + std::string GCodeProcessor::get_time_dhm(ETimeMode mode) const { - std::string ret = "N/A"; - if (mode < ETimeMode::Count) - ret = short_time(get_time_dhms(m_time_processor.machines[static_cast(mode)].time)); - return ret; + return (mode < ETimeMode::Count) ? short_time(get_time_dhms(m_time_processor.machines[static_cast(mode)].time)) : std::string("N/A"); } std::vector>> GCodeProcessor::get_custom_gcode_times(ETimeMode mode, bool include_remaining) const @@ -411,6 +434,19 @@ std::vector>> GCodeProcesso return ret; } +std::vector> GCodeProcessor::get_moves_time(ETimeMode mode) const +{ + std::vector> ret; + if (mode < ETimeMode::Count) { + for (size_t i = 0; i < m_time_processor.machines[static_cast(mode)].moves_time.size(); ++i) { + float time = m_time_processor.machines[static_cast(mode)].moves_time[i]; + if (time > 0.0f) + ret.push_back({ static_cast(i), time }); + } + } + return ret; +} + void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) { /* std::cout << line.raw() << std::endl; */ @@ -668,6 +704,8 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) if (max_abs_delta == 0.0f) return; + EMoveType type = move_type(delta_pos); + // time estimate section auto move_length = [](const AxisCoords& delta_pos) { float sq_xyz_length = sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z]); @@ -696,6 +734,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) minimum_feedrate(static_cast(i), m_feedrate); TimeBlock block; + block.move_type = type; block.distance = distance; // calculates block cruise feedrate @@ -827,7 +866,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) } // store move - store_move_vertex(move_type(delta_pos)); + store_move_vertex(type); } void GCodeProcessor::process_G10(const GCodeReader::GCodeLine& line) diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 9878eea9dd..214ed3d911 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -13,6 +13,8 @@ namespace Slic3r { + struct PrintStatistics; + class GCodeProcessor { public: @@ -57,6 +59,20 @@ namespace Slic3r { }; public: + enum class EMoveType : unsigned char + { + Noop, + Retract, + Unretract, + Tool_change, + Color_change, + Pause_Print, + Custom_GCode, + Travel, + Extrude, + Count + }; + struct FeedrateProfile { float entry{ 0.0f }; // mm/s @@ -84,6 +100,7 @@ namespace Slic3r { bool nominal_length{ false }; }; + EMoveType move_type{ EMoveType::Noop }; float distance{ 0.0f }; // mm float acceleration{ 0.0f }; // mm/s^2 float max_entry_speed{ 0.0f }; // mm/s @@ -135,6 +152,7 @@ namespace Slic3r { State prev; CustomGCodeTime gcode_time; std::vector blocks; + std::array(EMoveType::Count)> moves_time; void reset(); @@ -169,20 +187,6 @@ namespace Slic3r { }; public: - enum class EMoveType : unsigned char - { - Noop, - Retract, - Unretract, - Tool_change, - Color_change, - Pause_Print, - Custom_GCode, - Travel, - Extrude, - Count - }; - struct MoveVertex { EMoveType type{ EMoveType::Noop }; @@ -255,9 +259,13 @@ namespace Slic3r { // Process the gcode contained in the file with the given filename void process_file(const std::string& filename); + void update_print_stats_estimated_times(PrintStatistics& print_statistics); + float get_time(ETimeMode mode) const; std::string get_time_dhm(ETimeMode mode) const; std::vector>> get_custom_gcode_times(ETimeMode mode, bool include_remaining) const; + std::vector> get_moves_time(ETimeMode mode) const; + private: void process_gcode_line(const GCodeReader::GCodeLine& line); diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 4a0657061a..748411cd77 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -304,14 +304,16 @@ struct PrintStatistics { PrintStatistics() { clear(); } #if ENABLE_GCODE_VIEWER - std::string estimated_normal_print_time; - std::string estimated_silent_print_time; + float estimated_normal_print_time; + float estimated_silent_print_time; std::string estimated_normal_print_time_str; std::string estimated_silent_print_time_str; std::vector>> estimated_normal_custom_gcode_print_times; std::vector>> estimated_silent_custom_gcode_print_times; std::vector>> estimated_normal_custom_gcode_print_times_str; std::vector>> estimated_silent_custom_gcode_print_times_str; + std::vector> estimated_normal_moves_times; + std::vector> estimated_silent_moves_times; #else std::string estimated_normal_print_time; std::string estimated_silent_print_time; @@ -336,6 +338,8 @@ struct PrintStatistics void clear() { #if ENABLE_GCODE_VIEWER + estimated_normal_print_time_str.clear(); + estimated_silent_print_time_str.clear(); estimated_normal_custom_gcode_print_times_str.clear(); estimated_silent_custom_gcode_print_times_str.clear(); #else @@ -353,6 +357,17 @@ struct PrintStatistics total_wipe_tower_filament = 0.; filament_stats.clear(); } + +#if ENABLE_GCODE_VIEWER + void clear_time_estimates() { + estimated_normal_print_time = 0.0f; + estimated_silent_print_time = 0.0f; + estimated_normal_custom_gcode_print_times.clear(); + estimated_silent_custom_gcode_print_times.clear(); + estimated_normal_moves_times.clear(); + estimated_silent_moves_times.clear(); + } +#endif //ENABLE_GCODE_VIEWER }; typedef std::vector PrintObjectPtrs; diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 27b0db83f5..db95c2b224 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1717,19 +1717,16 @@ void GCodeViewer::render_time_estimate() const return; const PrintStatistics& ps = wxGetApp().plater()->fff_print().print_statistics(); - if (ps.estimated_normal_print_time == "N/A" && ps.estimated_silent_print_time == "N/A") - return; - - if (ps.estimated_normal_print_time.empty() && ps.estimated_silent_print_time.empty()) + if (ps.estimated_normal_print_time <= 0.0f && ps.estimated_silent_print_time <= 0.0f) return; ImGuiWrapper& imgui = *wxGetApp().imgui(); - using Time = std::pair; - using TimesList = std::vector>; + using Times = std::pair; + using TimesList = std::vector>; - // helper structure containig the data needed to render the items - struct Item + // helper structure containig the data needed to render the time items + struct PartialTime { enum class EType : unsigned char { @@ -1741,12 +1738,13 @@ void GCodeViewer::render_time_estimate() const int extruder_id; Color color1; Color color2; - Time time; + Times times; }; - using Items = std::vector; + using PartialTimes = std::vector; - auto append_mode = [this, &imgui](const std::string& time_str, const Items& items) { - auto append_partial_times = [this, &imgui](const Items& items) { + auto append_mode = [this, &imgui](float total_time, const PartialTimes& items, + const std::vector>& moves_time) { + auto append_partial_times = [this, &imgui](const PartialTimes& items) { using Headers = std::vector; const Headers headers = { _u8L("Event"), @@ -1754,19 +1752,19 @@ void GCodeViewer::render_time_estimate() const _u8L("Duration") }; using Offsets = std::array; - auto calc_offsets = [this, &headers](const Items& items) { + auto calc_offsets = [this, &headers](const PartialTimes& items) { Offsets ret = { ImGui::CalcTextSize(headers[0].c_str()).x, ImGui::CalcTextSize(headers[1].c_str()).x }; - for (const Item& item : items) { + for (const PartialTime& item : items) { std::string label; switch (item.type) { - case Item::EType::Print: { label = _u8L("Print"); break; } - case Item::EType::Pause: { label = _u8L("Pause"); break; } - case Item::EType::ColorChange: { label = _u8L("Color change"); break; } + case PartialTime::EType::Print: { label = _u8L("Print"); break; } + case PartialTime::EType::Pause: { label = _u8L("Pause"); break; } + case PartialTime::EType::ColorChange: { label = _u8L("Color change"); break; } } ret[0] = std::max(ret[0], ImGui::CalcTextSize(label.c_str()).x); - ret[1] = std::max(ret[1], ImGui::CalcTextSize(short_time(get_time_dhms(item.time.second)).c_str()).x); + ret[1] = std::max(ret[1], ImGui::CalcTextSize(short_time(get_time_dhms(item.times.second)).c_str()).x); } const ImGuiStyle& style = ImGui::GetStyle(); @@ -1774,7 +1772,7 @@ void GCodeViewer::render_time_estimate() const ret[1] += ret[0] + style.ItemSpacing.x; return ret; }; - auto append_color = [this, &imgui](const Color& color1, const Color& color2, Offsets& offsets, const Time& time) { + auto append_color = [this, &imgui](const Color& color1, const Color& color2, Offsets& offsets, const Times& times) { ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); imgui.text(_u8L("Color change")); ImGui::PopStyleColor(); @@ -1797,7 +1795,7 @@ void GCodeViewer::render_time_estimate() const ImGui::GetColorU32({ color2[0], color2[1], color2[2], 1.0f })); #endif // USE_ICON_HEXAGON ImGui::SameLine(offsets[0]); - imgui.text(short_time(get_time_dhms(time.second - time.first))); + imgui.text(short_time(get_time_dhms(times.second - times.first))); }; if (items.empty()) @@ -1815,48 +1813,116 @@ void GCodeViewer::render_time_estimate() const ImGui::PopStyleColor(); ImGui::Separator(); - for (const Item& item : items) { + for (const PartialTime& item : items) { switch (item.type) { - case Item::EType::Print: + case PartialTime::EType::Print: { ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); imgui.text(_u8L("Print")); ImGui::PopStyleColor(); ImGui::SameLine(offsets[0]); - imgui.text(short_time(get_time_dhms(item.time.second))); + imgui.text(short_time(get_time_dhms(item.times.second))); ImGui::SameLine(offsets[1]); - imgui.text(short_time(get_time_dhms(item.time.first))); + imgui.text(short_time(get_time_dhms(item.times.first))); break; } - case Item::EType::Pause: + case PartialTime::EType::Pause: { ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); imgui.text(_u8L("Pause")); ImGui::PopStyleColor(); ImGui::SameLine(offsets[0]); - imgui.text(short_time(get_time_dhms(item.time.second - item.time.first))); + imgui.text(short_time(get_time_dhms(item.times.second - item.times.first))); break; } - case Item::EType::ColorChange: + case PartialTime::EType::ColorChange: { - append_color(item.color1, item.color2, offsets, item.time); + append_color(item.color1, item.color2, offsets, item.times); break; } } } }; + auto append_move_times = [this, &imgui](float total_time, const std::vector>& moves_time) { + using Headers = std::vector; + const Headers headers = { + _u8L("Type"), + _u8L("Time"), + _u8L("Percentage") + }; + auto move_type_label = [](GCodeProcessor::EMoveType type) { + switch (type) + { + case GCodeProcessor::EMoveType::Noop: { return _u8L("Noop"); } + case GCodeProcessor::EMoveType::Retract: { return _u8L("Retraction"); } + case GCodeProcessor::EMoveType::Unretract: { return _u8L("Unretraction"); } + case GCodeProcessor::EMoveType::Tool_change: { return _u8L("Tool change"); } + case GCodeProcessor::EMoveType::Color_change: { return _u8L("Color change"); } + case GCodeProcessor::EMoveType::Pause_Print: { return _u8L("Pause print"); } + case GCodeProcessor::EMoveType::Custom_GCode: { return _u8L("Custom GCode"); } + case GCodeProcessor::EMoveType::Travel: { return _u8L("Travel"); } + case GCodeProcessor::EMoveType::Extrude: { return _u8L("Extrusion"); } + default: { return _u8L("Unknown"); } + } + }; + using Offsets = std::array; + auto calc_offsets = [this, &headers, move_type_label](const std::vector>& moves_time) { + Offsets ret = { ImGui::CalcTextSize(headers[0].c_str()).x, ImGui::CalcTextSize(headers[1].c_str()).x }; + for (const auto& [type, time] : moves_time) { + ret[0] = std::max(ret[0], ImGui::CalcTextSize(move_type_label(type).c_str()).x); + ret[1] = std::max(ret[1], ImGui::CalcTextSize(short_time(get_time_dhms(time)).c_str()).x); + } + + const ImGuiStyle& style = ImGui::GetStyle(); + ret[0] += 2.0f * style.ItemSpacing.x; + ret[1] += ret[0] + style.ItemSpacing.x; + return ret; + }; + + + if (moves_time.empty()) + return; + + if (!ImGui::CollapsingHeader(_u8L("Moves Time").c_str())) + return; + + Offsets offsets = calc_offsets(moves_time); + + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); + imgui.text(headers[0]); + ImGui::SameLine(offsets[0]); + imgui.text(headers[1]); + ImGui::SameLine(offsets[1]); + imgui.text(headers[2]); + ImGui::PopStyleColor(); + ImGui::Separator(); + + for (const auto& [type, time] : moves_time) { + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); + imgui.text(move_type_label(type)); + ImGui::PopStyleColor(); + ImGui::SameLine(offsets[0]); + imgui.text(short_time(get_time_dhms(time))); + ImGui::SameLine(offsets[1]); + char buf[64]; + ::sprintf(buf, "%.2f%%", 100.0f * time / total_time); + ImGui::TextUnformatted(buf); + } + }; + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); imgui.text(_u8L("Time") + ":"); ImGui::PopStyleColor(); ImGui::SameLine(); - imgui.text(time_str); + imgui.text(short_time(get_time_dhms(total_time))); append_partial_times(items); + append_move_times(total_time, moves_time); }; - auto generate_items = [this](const TimesList& times) { - std::vector items; + auto generate_partial_times = [this](const TimesList& times) { + PartialTimes items; std::vector custom_gcode_per_print_z = wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes; int extruders_count = wxGetApp().extruders_edited_cnt(); @@ -1872,8 +1938,8 @@ void GCodeViewer::render_time_estimate() const { auto it = std::find_if(custom_gcode_per_print_z.begin(), custom_gcode_per_print_z.end(), [time_rec](const CustomGCode::Item& item) { return item.type == time_rec.first; }); if (it != custom_gcode_per_print_z.end()) { - items.push_back({ Item::EType::Print, it->extruder, Color(), Color(), time_rec.second }); - items.push_back({ Item::EType::Pause, it->extruder, Color(), Color(), time_rec.second }); + items.push_back({ PartialTime::EType::Print, it->extruder, Color(), Color(), time_rec.second }); + items.push_back({ PartialTime::EType::Pause, it->extruder, Color(), Color(), time_rec.second }); custom_gcode_per_print_z.erase(it); } break; @@ -1882,14 +1948,14 @@ void GCodeViewer::render_time_estimate() const { auto it = std::find_if(custom_gcode_per_print_z.begin(), custom_gcode_per_print_z.end(), [time_rec](const CustomGCode::Item& item) { return item.type == time_rec.first; }); if (it != custom_gcode_per_print_z.end()) { - items.push_back({ Item::EType::Print, it->extruder, Color(), Color(), time_rec.second }); - items.push_back({ Item::EType::ColorChange, it->extruder, last_color[it->extruder - 1], decode_color(it->color), time_rec.second }); + items.push_back({ PartialTime::EType::Print, it->extruder, Color(), Color(), time_rec.second }); + items.push_back({ PartialTime::EType::ColorChange, it->extruder, last_color[it->extruder - 1], decode_color(it->color), time_rec.second }); last_color[it->extruder - 1] = decode_color(it->color); last_extruder_id = it->extruder; custom_gcode_per_print_z.erase(it); } else - items.push_back({ Item::EType::Print, last_extruder_id, Color(), Color(), time_rec.second }); + items.push_back({ PartialTime::EType::Print, last_extruder_id, Color(), Color(), time_rec.second }); break; } @@ -1905,22 +1971,22 @@ void GCodeViewer::render_time_estimate() const ImGui::SetNextWindowSizeConstraints(ImVec2(0.0f, 0.0f), ImVec2(-1.0f, 0.5f * static_cast(cnv_size.get_height()))); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGui::SetNextWindowBgAlpha(0.6f); - imgui.begin(std::string("Time_estimate_2"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove); + imgui.begin(std::string("Time_estimate"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove); // title imgui.title(_u8L("Estimated printing time")); // mode tabs ImGui::BeginTabBar("mode_tabs"); - if (ps.estimated_normal_print_time != "N/A") { + if (ps.estimated_normal_print_time > 0.0f) { if (ImGui::BeginTabItem(_u8L("Normal").c_str())) { - append_mode(ps.estimated_normal_print_time, generate_items(ps.estimated_normal_custom_gcode_print_times)); + append_mode(ps.estimated_normal_print_time, generate_partial_times(ps.estimated_normal_custom_gcode_print_times), ps.estimated_normal_moves_times); ImGui::EndTabItem(); } } - if (ps.estimated_silent_print_time != "N/A") { + if (ps.estimated_silent_print_time > 0.0f) { if (ImGui::BeginTabItem(_u8L("Stealth").c_str())) { - append_mode(ps.estimated_silent_print_time, generate_items(ps.estimated_silent_custom_gcode_print_times)); + append_mode(ps.estimated_silent_print_time, generate_partial_times(ps.estimated_silent_custom_gcode_print_times), ps.estimated_silent_moves_times); ImGui::EndTabItem(); } } From b03ae392c5020828e8e96f44f635f77f045ca073 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 17 Jul 2020 10:50:16 +0200 Subject: [PATCH 151/255] GCodeViewer -> Added estimated printing times for extrusion roles --- src/libslic3r/GCode/GCodeProcessor.cpp | 19 +++ src/libslic3r/GCode/GCodeProcessor.hpp | 3 + src/libslic3r/Print.hpp | 4 + src/slic3r/GUI/GCodeViewer.cpp | 172 +++++++++++++++++-------- 4 files changed, 144 insertions(+), 54 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 7f8efc53fc..67ed7c699b 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -163,6 +163,7 @@ void GCodeProcessor::TimeMachine::reset() gcode_time.reset(); blocks = std::vector(); std::fill(moves_time.begin(), moves_time.end(), 0.0f); + std::fill(roles_time.begin(), roles_time.end(), 0.0f); } void GCodeProcessor::TimeMachine::simulate_st_synchronize(float additional_time) @@ -271,6 +272,7 @@ void GCodeProcessor::TimeMachine::calculate_time(size_t keep_last_n_blocks) time += block_time; gcode_time.cache += block_time; moves_time[static_cast(block.move_type)] += block_time; + roles_time[static_cast(block.role)] += block_time; // if (block.g1_line_id >= 0) // m_g1_times.emplace_back(block.g1_line_id, time); @@ -397,15 +399,18 @@ void GCodeProcessor::update_print_stats_estimated_times(PrintStatistics& print_s print_statistics.estimated_normal_print_time = get_time(GCodeProcessor::ETimeMode::Normal); print_statistics.estimated_normal_custom_gcode_print_times = get_custom_gcode_times(GCodeProcessor::ETimeMode::Normal, true); print_statistics.estimated_normal_moves_times = get_moves_time(GCodeProcessor::ETimeMode::Normal); + print_statistics.estimated_normal_roles_times = get_roles_time(GCodeProcessor::ETimeMode::Normal); if (m_time_processor.machines[static_cast(GCodeProcessor::ETimeMode::Stealth)].enabled) { print_statistics.estimated_silent_print_time = get_time(GCodeProcessor::ETimeMode::Stealth); print_statistics.estimated_silent_custom_gcode_print_times = get_custom_gcode_times(GCodeProcessor::ETimeMode::Stealth, true); print_statistics.estimated_silent_moves_times = get_moves_time(GCodeProcessor::ETimeMode::Stealth); + print_statistics.estimated_silent_roles_times = get_roles_time(GCodeProcessor::ETimeMode::Stealth); } else { print_statistics.estimated_silent_print_time = 0.0f; print_statistics.estimated_silent_custom_gcode_print_times.clear(); print_statistics.estimated_silent_moves_times.clear(); + print_statistics.estimated_silent_roles_times.clear(); } } @@ -447,6 +452,19 @@ std::vector> GCodeProcessor::get_mov return ret; } +std::vector> GCodeProcessor::get_roles_time(ETimeMode mode) const +{ + std::vector> ret; + if (mode < ETimeMode::Count) { + for (size_t i = 0; i < m_time_processor.machines[static_cast(mode)].roles_time.size(); ++i) { + float time = m_time_processor.machines[static_cast(mode)].roles_time[i]; + if (time > 0.0f) + ret.push_back({ static_cast(i), time }); + } + } + return ret; +} + void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) { /* std::cout << line.raw() << std::endl; */ @@ -735,6 +753,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) TimeBlock block; block.move_type = type; + block.role = m_extrusion_role; block.distance = distance; // calculates block cruise feedrate diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 214ed3d911..d19d363f95 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -101,6 +101,7 @@ namespace Slic3r { }; EMoveType move_type{ EMoveType::Noop }; + ExtrusionRole role{ erNone }; float distance{ 0.0f }; // mm float acceleration{ 0.0f }; // mm/s^2 float max_entry_speed{ 0.0f }; // mm/s @@ -153,6 +154,7 @@ namespace Slic3r { CustomGCodeTime gcode_time; std::vector blocks; std::array(EMoveType::Count)> moves_time; + std::array(ExtrusionRole::erCount)> roles_time; void reset(); @@ -265,6 +267,7 @@ namespace Slic3r { std::vector>> get_custom_gcode_times(ETimeMode mode, bool include_remaining) const; std::vector> get_moves_time(ETimeMode mode) const; + std::vector> get_roles_time(ETimeMode mode) const; private: void process_gcode_line(const GCodeReader::GCodeLine& line); diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 748411cd77..e2b7ab5467 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -314,6 +314,8 @@ struct PrintStatistics std::vector>> estimated_silent_custom_gcode_print_times_str; std::vector> estimated_normal_moves_times; std::vector> estimated_silent_moves_times; + std::vector> estimated_normal_roles_times; + std::vector> estimated_silent_roles_times; #else std::string estimated_normal_print_time; std::string estimated_silent_print_time; @@ -366,6 +368,8 @@ struct PrintStatistics estimated_silent_custom_gcode_print_times.clear(); estimated_normal_moves_times.clear(); estimated_silent_moves_times.clear(); + estimated_normal_roles_times.clear(); + estimated_silent_roles_times.clear(); } #endif //ENABLE_GCODE_VIEWER }; diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index db95c2b224..df29af67b8 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1724,6 +1724,8 @@ void GCodeViewer::render_time_estimate() const using Times = std::pair; using TimesList = std::vector>; + using Headers = std::vector; + using ColumnOffsets = std::array; // helper structure containig the data needed to render the time items struct PartialTime @@ -1743,17 +1745,14 @@ void GCodeViewer::render_time_estimate() const using PartialTimes = std::vector; auto append_mode = [this, &imgui](float total_time, const PartialTimes& items, - const std::vector>& moves_time) { - auto append_partial_times = [this, &imgui](const PartialTimes& items) { - using Headers = std::vector; - const Headers headers = { - _u8L("Event"), - _u8L("Remaining"), - _u8L("Duration") - }; - using Offsets = std::array; + const Headers& partial_times_headers, + const std::vector>& moves_time, + const Headers& moves_headers, + const std::vector>& roles_time, + const Headers& roles_headers) { + auto append_partial_times = [this, &imgui](const PartialTimes& items, const Headers& headers) { auto calc_offsets = [this, &headers](const PartialTimes& items) { - Offsets ret = { ImGui::CalcTextSize(headers[0].c_str()).x, ImGui::CalcTextSize(headers[1].c_str()).x }; + ColumnOffsets ret = { ImGui::CalcTextSize(headers[0].c_str()).x, ImGui::CalcTextSize(headers[1].c_str()).x }; for (const PartialTime& item : items) { std::string label; switch (item.type) @@ -1772,7 +1771,7 @@ void GCodeViewer::render_time_estimate() const ret[1] += ret[0] + style.ItemSpacing.x; return ret; }; - auto append_color = [this, &imgui](const Color& color1, const Color& color2, Offsets& offsets, const Times& times) { + auto append_color = [this, &imgui](const Color& color1, const Color& color2, ColumnOffsets& offsets, const Times& times) { ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); imgui.text(_u8L("Color change")); ImGui::PopStyleColor(); @@ -1801,7 +1800,7 @@ void GCodeViewer::render_time_estimate() const if (items.empty()) return; - Offsets offsets = calc_offsets(items); + ColumnOffsets offsets = calc_offsets(items); ImGui::Spacing(); ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); @@ -1845,42 +1844,25 @@ void GCodeViewer::render_time_estimate() const } }; - auto append_move_times = [this, &imgui](float total_time, const std::vector>& moves_time) { - using Headers = std::vector; - const Headers headers = { - _u8L("Type"), - _u8L("Time"), - _u8L("Percentage") - }; - auto move_type_label = [](GCodeProcessor::EMoveType type) { - switch (type) - { - case GCodeProcessor::EMoveType::Noop: { return _u8L("Noop"); } - case GCodeProcessor::EMoveType::Retract: { return _u8L("Retraction"); } - case GCodeProcessor::EMoveType::Unretract: { return _u8L("Unretraction"); } - case GCodeProcessor::EMoveType::Tool_change: { return _u8L("Tool change"); } - case GCodeProcessor::EMoveType::Color_change: { return _u8L("Color change"); } - case GCodeProcessor::EMoveType::Pause_Print: { return _u8L("Pause print"); } - case GCodeProcessor::EMoveType::Custom_GCode: { return _u8L("Custom GCode"); } - case GCodeProcessor::EMoveType::Travel: { return _u8L("Travel"); } - case GCodeProcessor::EMoveType::Extrude: { return _u8L("Extrusion"); } - default: { return _u8L("Unknown"); } - } - }; - using Offsets = std::array; - auto calc_offsets = [this, &headers, move_type_label](const std::vector>& moves_time) { - Offsets ret = { ImGui::CalcTextSize(headers[0].c_str()).x, ImGui::CalcTextSize(headers[1].c_str()).x }; - for (const auto& [type, time] : moves_time) { - ret[0] = std::max(ret[0], ImGui::CalcTextSize(move_type_label(type).c_str()).x); - ret[1] = std::max(ret[1], ImGui::CalcTextSize(short_time(get_time_dhms(time)).c_str()).x); - } - - const ImGuiStyle& style = ImGui::GetStyle(); - ret[0] += 2.0f * style.ItemSpacing.x; - ret[1] += ret[0] + style.ItemSpacing.x; - return ret; - }; + auto move_type_label = [](GCodeProcessor::EMoveType type) { + switch (type) + { + case GCodeProcessor::EMoveType::Noop: { return _u8L("Noop"); } + case GCodeProcessor::EMoveType::Retract: { return _u8L("Retraction"); } + case GCodeProcessor::EMoveType::Unretract: { return _u8L("Unretraction"); } + case GCodeProcessor::EMoveType::Tool_change: { return _u8L("Tool change"); } + case GCodeProcessor::EMoveType::Color_change: { return _u8L("Color change"); } + case GCodeProcessor::EMoveType::Pause_Print: { return _u8L("Pause print"); } + case GCodeProcessor::EMoveType::Custom_GCode: { return _u8L("Custom GCode"); } + case GCodeProcessor::EMoveType::Travel: { return _u8L("Travel"); } + case GCodeProcessor::EMoveType::Extrude: { return _u8L("Extrusion"); } + default: { return _u8L("Unknown"); } + } + }; + auto append_move_times = [this, &imgui, move_type_label](float total_time, + const std::vector>& moves_time, + const Headers& headers, const ColumnOffsets& offsets) { if (moves_time.empty()) return; @@ -1888,8 +1870,6 @@ void GCodeViewer::render_time_estimate() const if (!ImGui::CollapsingHeader(_u8L("Moves Time").c_str())) return; - Offsets offsets = calc_offsets(moves_time); - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); imgui.text(headers[0]); ImGui::SameLine(offsets[0]); @@ -1899,7 +1879,10 @@ void GCodeViewer::render_time_estimate() const ImGui::PopStyleColor(); ImGui::Separator(); - for (const auto& [type, time] : moves_time) { + std::vector> sorted_moves_time(moves_time); + std::sort(sorted_moves_time.begin(), sorted_moves_time.end(), [](const auto& p1, const auto& p2) { return p2.second < p1.second; }); + + for (const auto& [type, time] : sorted_moves_time) { ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); imgui.text(move_type_label(type)); ImGui::PopStyleColor(); @@ -1912,13 +1895,72 @@ void GCodeViewer::render_time_estimate() const } }; + auto append_role_times = [this, &imgui](float total_time, + const std::vector>& roles_time, + const Headers& headers, const ColumnOffsets& offsets) { + + if (roles_time.empty()) + return; + + if (!ImGui::CollapsingHeader(_u8L("Features Time").c_str())) + return; + + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); + imgui.text(headers[0]); + ImGui::SameLine(offsets[0]); + imgui.text(headers[1]); + ImGui::SameLine(offsets[1]); + imgui.text(headers[2]); + ImGui::PopStyleColor(); + ImGui::Separator(); + + std::vector> sorted_roles_time(roles_time); + std::sort(sorted_roles_time.begin(), sorted_roles_time.end(), [](const auto& p1, const auto& p2) { return p2.second < p1.second; }); + + for (const auto& [role, time] : sorted_roles_time) { + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); + imgui.text(_u8L(ExtrusionEntity::role_to_string(role))); + ImGui::PopStyleColor(); + ImGui::SameLine(offsets[0]); + imgui.text(short_time(get_time_dhms(time))); + ImGui::SameLine(offsets[1]); + char buf[64]; + ::sprintf(buf, "%.2f%%", 100.0f * time / total_time); + ImGui::TextUnformatted(buf); + } + }; + + auto calc_common_offsets = [move_type_label]( + const std::vector>& moves_time, const Headers& moves_headers, + const std::vector>& roles_time, const Headers& roles_headers) { + ColumnOffsets ret = { std::max(ImGui::CalcTextSize(moves_headers[0].c_str()).x, ImGui::CalcTextSize(roles_headers[0].c_str()).x), + std::max(ImGui::CalcTextSize(moves_headers[1].c_str()).x, ImGui::CalcTextSize(roles_headers[1].c_str()).x) }; + + for (const auto& [type, time] : moves_time) { + ret[0] = std::max(ret[0], ImGui::CalcTextSize(move_type_label(type).c_str()).x); + ret[1] = std::max(ret[1], ImGui::CalcTextSize(short_time(get_time_dhms(time)).c_str()).x); + } + + for (const auto& [role, time] : roles_time) { + ret[0] = std::max(ret[0], ImGui::CalcTextSize(_u8L(ExtrusionEntity::role_to_string(role)).c_str()).x); + ret[1] = std::max(ret[1], ImGui::CalcTextSize(short_time(get_time_dhms(time)).c_str()).x); + } + + const ImGuiStyle& style = ImGui::GetStyle(); + ret[0] += 2.0f * style.ItemSpacing.x; + ret[1] += ret[0] + style.ItemSpacing.x; + return ret; + }; + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); imgui.text(_u8L("Time") + ":"); ImGui::PopStyleColor(); ImGui::SameLine(); imgui.text(short_time(get_time_dhms(total_time))); - append_partial_times(items); - append_move_times(total_time, moves_time); + append_partial_times(items, partial_times_headers); + ColumnOffsets common_offsets = calc_common_offsets(moves_time, moves_headers, roles_time, roles_headers); + append_move_times(total_time, moves_time, moves_headers, common_offsets); + append_role_times(total_time, roles_time, roles_headers, common_offsets); }; auto generate_partial_times = [this](const TimesList& times) { @@ -1966,6 +2008,22 @@ void GCodeViewer::render_time_estimate() const return items; }; + const Headers partial_times_headers = { + _u8L("Event"), + _u8L("Remaining"), + _u8L("Duration") + }; + const Headers moves_headers = { + _u8L("Type"), + _u8L("Time"), + _u8L("Percentage") + }; + const Headers roles_headers = { + _u8L("Feature"), + _u8L("Time"), + _u8L("Percentage") + }; + Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size(); imgui.set_next_window_pos(static_cast(cnv_size.get_width()), static_cast(cnv_size.get_height()), ImGuiCond_Always, 1.0f, 1.0f); ImGui::SetNextWindowSizeConstraints(ImVec2(0.0f, 0.0f), ImVec2(-1.0f, 0.5f * static_cast(cnv_size.get_height()))); @@ -1980,13 +2038,19 @@ void GCodeViewer::render_time_estimate() const ImGui::BeginTabBar("mode_tabs"); if (ps.estimated_normal_print_time > 0.0f) { if (ImGui::BeginTabItem(_u8L("Normal").c_str())) { - append_mode(ps.estimated_normal_print_time, generate_partial_times(ps.estimated_normal_custom_gcode_print_times), ps.estimated_normal_moves_times); + append_mode(ps.estimated_normal_print_time, + generate_partial_times(ps.estimated_normal_custom_gcode_print_times), partial_times_headers, + ps.estimated_normal_moves_times, moves_headers, + ps.estimated_normal_roles_times, roles_headers); ImGui::EndTabItem(); } } if (ps.estimated_silent_print_time > 0.0f) { if (ImGui::BeginTabItem(_u8L("Stealth").c_str())) { - append_mode(ps.estimated_silent_print_time, generate_partial_times(ps.estimated_silent_custom_gcode_print_times), ps.estimated_silent_moves_times); + append_mode(ps.estimated_silent_print_time, + generate_partial_times(ps.estimated_silent_custom_gcode_print_times), partial_times_headers, + ps.estimated_silent_moves_times, moves_headers, + ps.estimated_silent_roles_times, roles_headers); ImGui::EndTabItem(); } } From 0df1d117804264f7b9f30f9f7e5a6367314f1cd5 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 17 Jul 2020 11:08:34 +0200 Subject: [PATCH 152/255] GCodeViewer -> Attempt to fix rendering of toolpaths on Mac --- src/slic3r/GUI/GCodeViewer.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index df29af67b8..27bd8b6727 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1221,7 +1221,13 @@ void GCodeViewer::render_toolpaths() const glsafe(::glEnable(GL_POINT_SPRITE)); for (const RenderPath& path : buffer.render_paths) { +#ifdef __APPLE__ + for (size_t i = 0; i < path.sizes.size(); ++i) { + glsafe(::glDrawElements(GL_POINTS, (GLsizei)path.sizes[i], GL_UNSIGNED_INT, (const void*)path.offsets[i])); + } +#else glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); +#endif // __APPLE__ #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -1235,7 +1241,13 @@ void GCodeViewer::render_toolpaths() const for (const RenderPath& path : buffer.render_paths) { shader.set_uniform("uniform_color", path.color); +#ifdef __APPLE__ + for (size_t i = 0; i < path.sizes.size(); ++i) { + glsafe(::glDrawElements(GL_LINES, (GLsizei)path.sizes[i], GL_UNSIGNED_INT, (const void*)path.offsets[i])); + } +#else glsafe(::glMultiDrawElements(GL_LINES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); +#endif // __APPLE__ #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_line_strip_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS From a35f72442e3d44156f88efa58d16222a6a0b7ee0 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 17 Jul 2020 12:10:55 +0200 Subject: [PATCH 153/255] GCodeViewer -> 2nd attempt to fix rendering of toolpaths on Mac --- src/slic3r/GUI/GCodeViewer.cpp | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 27bd8b6727..0ab43a98c7 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1221,13 +1221,7 @@ void GCodeViewer::render_toolpaths() const glsafe(::glEnable(GL_POINT_SPRITE)); for (const RenderPath& path : buffer.render_paths) { -#ifdef __APPLE__ - for (size_t i = 0; i < path.sizes.size(); ++i) { - glsafe(::glDrawElements(GL_POINTS, (GLsizei)path.sizes[i], GL_UNSIGNED_INT, (const void*)path.offsets[i])); - } -#else glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); -#endif // __APPLE__ #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -1241,13 +1235,7 @@ void GCodeViewer::render_toolpaths() const for (const RenderPath& path : buffer.render_paths) { shader.set_uniform("uniform_color", path.color); -#ifdef __APPLE__ - for (size_t i = 0; i < path.sizes.size(); ++i) { - glsafe(::glDrawElements(GL_LINES, (GLsizei)path.sizes[i], GL_UNSIGNED_INT, (const void*)path.offsets[i])); - } -#else glsafe(::glMultiDrawElements(GL_LINES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); -#endif // __APPLE__ #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_line_strip_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -1255,7 +1243,11 @@ void GCodeViewer::render_toolpaths() const }; auto line_width = [zoom]() { - return (zoom < 5.0) ? 1.0 : (1.0 + 5.0 * (zoom - 5.0) / (100.0 - 5.0)); +#ifdef WIN32 + return (zoom < 5.0) ? 1.0 : (1.0 + 5.0 * (zoom - 5.0) / (100.0 - 5.0)); +#else + return 3.0f; +#endif // WIN32 }; glsafe(::glCullFace(GL_BACK)); From 087c83c95877bc0c09ef55ba24919436617b5d7a Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 17 Jul 2020 14:58:58 +0200 Subject: [PATCH 154/255] GCodeViewer -> 3rd attempt to fix rendering of toolpaths on Mac --- src/slic3r/GUI/GCodeViewer.cpp | 43 +++++++++++++++++----------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 0ab43a98c7..a697306cfd 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1232,8 +1232,7 @@ void GCodeViewer::render_toolpaths() const }; auto render_as_lines = [this](const TBuffer& buffer, GLShaderProgram& shader) { - for (const RenderPath& path : buffer.render_paths) - { + for (const RenderPath& path : buffer.render_paths) { shader.set_uniform("uniform_color", path.color); glsafe(::glMultiDrawElements(GL_LINES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS @@ -1242,16 +1241,11 @@ void GCodeViewer::render_toolpaths() const } }; - auto line_width = [zoom]() { -#ifdef WIN32 + auto line_width = [](double zoom) { return (zoom < 5.0) ? 1.0 : (1.0 + 5.0 * (zoom - 5.0) / (100.0 - 5.0)); -#else - return 3.0f; -#endif // WIN32 }; - glsafe(::glCullFace(GL_BACK)); - glsafe(::glLineWidth(static_cast(line_width()))); + glsafe(::glLineWidth(static_cast(line_width(zoom)))); unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); unsigned char end_id = buffer_id(GCodeProcessor::EMoveType::Count); @@ -1269,8 +1263,12 @@ void GCodeViewer::render_toolpaths() const shader->start_using(); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.vertices.id)); - glsafe(::glVertexAttribPointer(0, buffer.vertices.vertex_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)0)); - glsafe(::glEnableVertexAttribArray(0)); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + glsafe(::glVertexPointer(buffer.vertices.vertex_size_floats(), GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)0)); + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); +// glsafe(::glVertexAttribPointer(0, buffer.vertices.vertex_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)0)); +// glsafe(::glEnableVertexAttribArray(0)); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.indices.id)); @@ -1286,26 +1284,27 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Extrude: case GCodeProcessor::EMoveType::Travel: { - std::array light_intensity; #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR - light_intensity[0] = m_shaders_editor.lines.lights.ambient; - light_intensity[1] = m_shaders_editor.lines.lights.top_diffuse; - light_intensity[2] = m_shaders_editor.lines.lights.front_diffuse; - light_intensity[3] = m_shaders_editor.lines.lights.global; + std::array light_intensity = { + m_shaders_editor.lines.lights.ambient, + m_shaders_editor.lines.lights.top_diffuse, + m_shaders_editor.lines.lights.front_diffuse, + m_shaders_editor.lines.lights.global }; #else - light_intensity[0] = 0.25f; - light_intensity[1] = 0.7f; - light_intensity[2] = 0.75f; - light_intensity[3] = 0.75f; + std::array light_intensity = { 0.25f, 0.7f, 0.75f, 0.75f }; #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR shader->set_uniform("light_intensity", light_intensity); - render_as_lines(buffer, *shader); break; + render_as_lines(buffer, *shader); + break; } } glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - glsafe(::glDisableVertexAttribArray(0)); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); +// glsafe(::glDisableVertexAttribArray(0)); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); shader->stop_using(); From afd9429e6d9b56a26db85270f498cf287e45864d Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 17 Jul 2020 15:18:29 +0200 Subject: [PATCH 155/255] Code cleanup --- src/slic3r/GUI/GCodeViewer.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index a697306cfd..3edf0d907c 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1263,12 +1263,8 @@ void GCodeViewer::render_toolpaths() const shader->start_using(); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.vertices.id)); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glVertexPointer(buffer.vertices.vertex_size_floats(), GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)0)); glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); -// glsafe(::glVertexAttribPointer(0, buffer.vertices.vertex_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)0)); -// glsafe(::glEnableVertexAttribArray(0)); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.indices.id)); @@ -1301,10 +1297,7 @@ void GCodeViewer::render_toolpaths() const glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); -// glsafe(::glDisableVertexAttribArray(0)); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); shader->stop_using(); From 51f0fd8912ef2f368c20e99d41131f2e7f87e16b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 20 Jul 2020 09:45:49 +0200 Subject: [PATCH 156/255] GCodeViewer -> Added visualization of percentage in estimated printing time dialog --- src/libslic3r/Print.hpp | 2 + src/slic3r/GUI/GCodeViewer.cpp | 88 +++++++++++++++------------------ src/slic3r/GUI/ImGuiWrapper.cpp | 4 +- src/slic3r/GUI/MainFrame.cpp | 4 ++ 4 files changed, 48 insertions(+), 50 deletions(-) diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index e2b7ab5467..7a0ecdf170 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -340,6 +340,7 @@ struct PrintStatistics void clear() { #if ENABLE_GCODE_VIEWER + clear_time_estimates(); estimated_normal_print_time_str.clear(); estimated_silent_print_time_str.clear(); estimated_normal_custom_gcode_print_times_str.clear(); @@ -461,6 +462,7 @@ public: const Polygon& first_layer_convex_hull() const { return m_first_layer_convex_hull; } const PrintStatistics& print_statistics() const { return m_print_statistics; } + PrintStatistics& print_statistics() { return m_print_statistics; } // Wipe tower support. bool has_wipe_tower() const; diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 3edf0d907c..07cfb396e8 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1740,14 +1740,25 @@ void GCodeViewer::render_time_estimate() const }; using PartialTimes = std::vector; - auto append_mode = [this, &imgui](float total_time, const PartialTimes& items, + auto append_headers = [&imgui](const Headers& headers, const ColumnOffsets& offsets) { + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); + imgui.text(headers[0]); + ImGui::SameLine(offsets[0]); + imgui.text(headers[1]); + ImGui::SameLine(offsets[1]); + imgui.text(headers[2]); + ImGui::PopStyleColor(); + ImGui::Separator(); + }; + + auto append_mode = [this, &imgui, append_headers](float total_time, const PartialTimes& items, const Headers& partial_times_headers, const std::vector>& moves_time, const Headers& moves_headers, const std::vector>& roles_time, const Headers& roles_headers) { - auto append_partial_times = [this, &imgui](const PartialTimes& items, const Headers& headers) { - auto calc_offsets = [this, &headers](const PartialTimes& items) { + auto append_partial_times = [this, &imgui, append_headers](const PartialTimes& items, const Headers& headers) { + auto calc_offsets = [this, &headers](const PartialTimes& items) { ColumnOffsets ret = { ImGui::CalcTextSize(headers[0].c_str()).x, ImGui::CalcTextSize(headers[1].c_str()).x }; for (const PartialTime& item : items) { std::string label; @@ -1799,14 +1810,7 @@ void GCodeViewer::render_time_estimate() const ColumnOffsets offsets = calc_offsets(items); ImGui::Spacing(); - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(headers[0]); - ImGui::SameLine(offsets[0]); - imgui.text(headers[1]); - ImGui::SameLine(offsets[1]); - imgui.text(headers[2]); - ImGui::PopStyleColor(); - ImGui::Separator(); + append_headers(headers, offsets); for (const PartialTime& item : items) { switch (item.type) @@ -1856,7 +1860,26 @@ void GCodeViewer::render_time_estimate() const } }; - auto append_move_times = [this, &imgui, move_type_label](float total_time, + auto append_time_item = [&imgui] (const std::string& label, float time, float percentage, const ImVec4& color, const ColumnOffsets& offsets) { + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); + imgui.text(label); + ImGui::PopStyleColor(); + ImGui::SameLine(offsets[0]); + imgui.text(short_time(get_time_dhms(time))); + ImGui::SameLine(offsets[1]); + char buf[64]; + ::sprintf(buf, "%.2f%%", 100.0f * percentage); + ImGuiWindow* window = ImGui::GetCurrentWindow(); + ImRect frame_bb; + frame_bb.Min = { ImGui::GetCursorScreenPos().x, window->DC.CursorPos.y }; + frame_bb.Max = { frame_bb.Min.x + percentage * (window->WorkRect.Max.x - frame_bb.Min.x), window->DC.CursorPos.y + ImGui::CalcTextSize(buf, nullptr, false).y }; + frame_bb.Min.x -= IM_FLOOR(window->WindowPadding.x * 0.5f - 1.0f); + frame_bb.Max.x += IM_FLOOR(window->WindowPadding.x * 0.5f); + window->DrawList->AddRectFilled(frame_bb.Min, frame_bb.Max, ImGui::GetColorU32({ color.x, color.y, color.z, 1.0f }), 0.0f, 0); + ImGui::TextUnformatted(buf); + }; + + auto append_move_times = [this, &imgui, move_type_label, append_headers, append_time_item](float total_time, const std::vector>& moves_time, const Headers& headers, const ColumnOffsets& offsets) { @@ -1866,32 +1889,17 @@ void GCodeViewer::render_time_estimate() const if (!ImGui::CollapsingHeader(_u8L("Moves Time").c_str())) return; - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(headers[0]); - ImGui::SameLine(offsets[0]); - imgui.text(headers[1]); - ImGui::SameLine(offsets[1]); - imgui.text(headers[2]); - ImGui::PopStyleColor(); - ImGui::Separator(); + append_headers(headers, offsets); std::vector> sorted_moves_time(moves_time); std::sort(sorted_moves_time.begin(), sorted_moves_time.end(), [](const auto& p1, const auto& p2) { return p2.second < p1.second; }); for (const auto& [type, time] : sorted_moves_time) { - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(move_type_label(type)); - ImGui::PopStyleColor(); - ImGui::SameLine(offsets[0]); - imgui.text(short_time(get_time_dhms(time))); - ImGui::SameLine(offsets[1]); - char buf[64]; - ::sprintf(buf, "%.2f%%", 100.0f * time / total_time); - ImGui::TextUnformatted(buf); + append_time_item(move_type_label(type), time, time / total_time, ImGuiWrapper::COL_ORANGE_LIGHT, offsets); } }; - auto append_role_times = [this, &imgui](float total_time, + auto append_role_times = [this, &imgui, append_headers, append_time_item](float total_time, const std::vector>& roles_time, const Headers& headers, const ColumnOffsets& offsets) { @@ -1901,28 +1909,14 @@ void GCodeViewer::render_time_estimate() const if (!ImGui::CollapsingHeader(_u8L("Features Time").c_str())) return; - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(headers[0]); - ImGui::SameLine(offsets[0]); - imgui.text(headers[1]); - ImGui::SameLine(offsets[1]); - imgui.text(headers[2]); - ImGui::PopStyleColor(); - ImGui::Separator(); + append_headers(headers, offsets); std::vector> sorted_roles_time(roles_time); std::sort(sorted_roles_time.begin(), sorted_roles_time.end(), [](const auto& p1, const auto& p2) { return p2.second < p1.second; }); for (const auto& [role, time] : sorted_roles_time) { - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(_u8L(ExtrusionEntity::role_to_string(role))); - ImGui::PopStyleColor(); - ImGui::SameLine(offsets[0]); - imgui.text(short_time(get_time_dhms(time))); - ImGui::SameLine(offsets[1]); - char buf[64]; - ::sprintf(buf, "%.2f%%", 100.0f * time / total_time); - ImGui::TextUnformatted(buf); + Color color = Extrusion_Role_Colors[static_cast(role)]; + append_time_item(_u8L(ExtrusionEntity::role_to_string(role)), time, time / total_time, { 0.666f * color[0], 0.666f * color[1], 0.666f * color[2], 1.0f}, offsets); } }; diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 1253c047ef..b4e8c6d0f9 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -760,12 +760,10 @@ void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, co void ImGuiWrapper::title(const std::string& str) { ImGuiWindow* window = ImGui::GetCurrentWindow(); - const float frame_height = ImGui::CalcTextSize(str.c_str(), nullptr, false).y; ImRect frame_bb; frame_bb.Min = { window->WorkRect.Min.x, window->DC.CursorPos.y }; - frame_bb.Max = { window->WorkRect.Max.x, window->DC.CursorPos.y + frame_height }; - + frame_bb.Max = { window->WorkRect.Max.x, window->DC.CursorPos.y + ImGui::CalcTextSize(str.c_str(), nullptr, false).y }; frame_bb.Min.x -= IM_FLOOR(window->WindowPadding.x * 0.5f - 1.0f); frame_bb.Max.x += IM_FLOOR(window->WindowPadding.x * 0.5f); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index eda980a93b..d917e82b4d 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -1428,6 +1428,8 @@ void MainFrame::set_mode(EMode mode) select_tab(0); #endif // ENABLE_LAYOUT_NO_RESTART + m_plater->fff_print().print_statistics().clear_time_estimates(); + m_plater->reset(); m_plater->reset_gcode_toolpaths(); @@ -1471,6 +1473,8 @@ void MainFrame::set_mode(EMode mode) update_layout(); #endif // ENABLE_LAYOUT_NO_RESTART + m_plater->fff_print().print_statistics().clear_time_estimates(); + m_plater->reset(); m_plater->reset_last_loaded_gcode(); m_plater->reset_gcode_toolpaths(); From 4700579589377f8036ec442913e3b4b6a273987b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 20 Jul 2020 12:25:00 +0200 Subject: [PATCH 157/255] GCodeViewer -> Estimated printing time dialog hidden by defaul --- src/slic3r/GUI/GCodeViewer.cpp | 8 ++++++ src/slic3r/GUI/GCodeViewer.hpp | 4 +-- src/slic3r/GUI/GLCanvas3D.hpp | 1 + src/slic3r/GUI/Plater.cpp | 45 +++++++++++++++++++--------------- 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 07cfb396e8..2d2bb512d9 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -495,6 +495,14 @@ void GCodeViewer::set_layers_z_range(const std::array& layers_z_range wxGetApp().plater()->update_preview_moves_slider(); } +void GCodeViewer::enable_time_estimate(bool enable) +{ + m_time_estimate_enabled = enable; + wxGetApp().update_ui_from_settings(); + wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); + wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); +} + void GCodeViewer::export_toolpaths_to_obj(const char* filename) const { if (filename == nullptr) diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 90155c7281..564b625699 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -341,7 +341,7 @@ private: Shells m_shells; EViewType m_view_type{ EViewType::FeatureType }; bool m_legend_enabled{ true }; - bool m_time_estimate_enabled{ true }; + bool m_time_estimate_enabled{ false }; #if ENABLE_GCODE_VIEWER_STATISTICS mutable Statistics m_statistics; #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -398,7 +398,7 @@ public: void enable_legend(bool enable) { m_legend_enabled = enable; } bool is_time_estimate_enabled() const { return m_time_estimate_enabled; } - void enable_time_estimate(bool enable) { m_time_estimate_enabled = enable; } + void enable_time_estimate(bool enable); void export_toolpaths_to_obj(const char* filename) const; diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 782a9425d7..0b5a357fdb 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -558,6 +558,7 @@ public: void reset_gcode_toolpaths() { m_gcode_viewer.reset(); } const GCodeViewer::SequentialView& get_gcode_sequential_view() const { return m_gcode_viewer.get_sequential_view(); } void update_gcode_sequential_view_current(unsigned int first, unsigned int last) { m_gcode_viewer.update_sequential_view_current(first, last); } + bool is_time_estimate_enabled() const { return m_gcode_viewer.is_time_estimate_enabled(); } #endif // ENABLE_GCODE_VIEWER void toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index db19ff39b6..39003e9aaa 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1323,13 +1323,14 @@ void Sidebar::update_sliced_info_sizer() p->sliced_info->SetTextAndShow(siCost, info_text, new_label); #if ENABLE_GCODE_VIEWER - if (ps.estimated_normal_print_time_str == "N/A" && ps.estimated_silent_print_time_str == "N/A") + if (p->plater->get_current_canvas3D()->is_time_estimate_enabled() || (ps.estimated_normal_print_time_str == "N/A" && ps.estimated_silent_print_time_str == "N/A")) #else + if (ps.estimated_normal_print_time == "N/A" && ps.estimated_silent_print_time == "N/A") #endif // ENABLE_GCODE_VIEWER p->sliced_info->SetTextAndShow(siEstimatedTime, "N/A"); else { - new_label = _L("Estimated printing time") +":"; + new_label = _L("Estimated printing time") + ":"; info_text = ""; wxString str_color = _L("Color"); wxString str_pause = _L("Pause"); @@ -1340,29 +1341,29 @@ void Sidebar::update_sliced_info_sizer() auto fill_labels = [str_color, str_pause](const std::vector>& times, #endif // ENABLE_GCODE_VIEWER wxString& new_label, wxString& info_text) - { - int color_change_count = 0; - for (auto time : times) - if (time.first == CustomGCode::ColorChange) - color_change_count++; - - for (int i = (int)times.size() - 1; i >= 0; --i) { - if (i == 0 || times[i - 1].first == CustomGCode::PausePrint) - new_label += format_wxstr("\n - %1%%2%", str_color + " ", color_change_count); - else if (times[i - 1].first == CustomGCode::ColorChange) - new_label += format_wxstr("\n - %1%%2%", str_color + " ", color_change_count--); + int color_change_count = 0; + for (auto time : times) + if (time.first == CustomGCode::ColorChange) + color_change_count++; - if (i != (int)times.size() - 1 && times[i].first == CustomGCode::PausePrint) - new_label += format_wxstr(" -> %1%", str_pause); + for (int i = (int)times.size() - 1; i >= 0; --i) + { + if (i == 0 || times[i - 1].first == CustomGCode::PausePrint) + new_label += format_wxstr("\n - %1%%2%", str_color + " ", color_change_count); + else if (times[i - 1].first == CustomGCode::ColorChange) + new_label += format_wxstr("\n - %1%%2%", str_color + " ", color_change_count--); + + if (i != (int)times.size() - 1 && times[i].first == CustomGCode::PausePrint) + new_label += format_wxstr(" -> %1%", str_pause); #if ENABLE_GCODE_VIEWER - info_text += format_wxstr("\n%1% (%2%)", times[i].second.first, times[i].second.second); + info_text += format_wxstr("\n%1% (%2%)", times[i].second.first, times[i].second.second); #else - info_text += format_wxstr("\n%1%", times[i].second); + info_text += format_wxstr("\n%1%", times[i].second); #endif // ENABLE_GCODE_VIEWER - } - }; + } + }; #if ENABLE_GCODE_VIEWER if (ps.estimated_normal_print_time_str != "N/A") { @@ -1386,7 +1387,7 @@ void Sidebar::update_sliced_info_sizer() fill_labels(ps.estimated_silent_custom_gcode_print_times, new_label, info_text); #endif // ENABLE_GCODE_VIEWER } - p->sliced_info->SetTextAndShow(siEstimatedTime, info_text, new_label); + p->sliced_info->SetTextAndShow(siEstimatedTime, info_text, new_label); } // if there is a wipe tower, insert number of toolchanges info into the array: @@ -2180,6 +2181,10 @@ void Plater::priv::select_view_3D(const std::string& name) set_current_panel(view3D); else if (name == "Preview") set_current_panel(preview); + +#if ENABLE_GCODE_VIEWER + wxGetApp().update_ui_from_settings(); +#endif // ENABLE_GCODE_VIEWER } void Plater::priv::select_next_view_3D() From dc59e86d2c10fac0e58694a37ff77f72790da0eb Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 21 Jul 2020 09:34:54 +0200 Subject: [PATCH 158/255] ENABLE_GCODE_VIEWER -> Partial refactoring in preparation for removal of old time estimator --- src/libslic3r/GCode.cpp | 2 ++ src/libslic3r/GCodeTimeEstimator.cpp | 2 ++ src/libslic3r/GCodeTimeEstimator.hpp | 2 ++ src/libslic3r/Print.cpp | 6 ++++++ src/libslic3r/Print.hpp | 6 ++++++ src/libslic3r/Technologies.hpp | 1 + src/slic3r/GUI/Plater.cpp | 27 +++++++++++++++++++++++++++ 7 files changed, 46 insertions(+) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 56cf357b7a..a4f25fa14c 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1065,11 +1065,13 @@ namespace DoExport { print_statistics.clear(); #if ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR print_statistics.estimated_normal_print_time_str = normal_time_estimator.get_time_dhm/*s*/(); print_statistics.estimated_silent_print_time_str = silent_time_estimator_enabled ? silent_time_estimator.get_time_dhm/*s*/() : "N/A"; print_statistics.estimated_normal_custom_gcode_print_times_str = normal_time_estimator.get_custom_gcode_times_dhm(true); if (silent_time_estimator_enabled) print_statistics.estimated_silent_custom_gcode_print_times_str = silent_time_estimator.get_custom_gcode_times_dhm(true); +#endif // ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR #else print_statistics.estimated_normal_print_time = normal_time_estimator.get_time_dhm/*s*/(); print_statistics.estimated_silent_print_time = silent_time_estimator_enabled ? silent_time_estimator.get_time_dhm/*s*/() : "N/A"; diff --git a/src/libslic3r/GCodeTimeEstimator.cpp b/src/libslic3r/GCodeTimeEstimator.cpp index bc3adefc08..4bfe322ce2 100644 --- a/src/libslic3r/GCodeTimeEstimator.cpp +++ b/src/libslic3r/GCodeTimeEstimator.cpp @@ -723,6 +723,7 @@ namespace Slic3r { } #if ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR std::vector>> GCodeTimeEstimator::get_custom_gcode_times_dhm(bool include_remaining) const { std::vector>> ret; @@ -737,6 +738,7 @@ namespace Slic3r { return ret; } +#endif // ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR #else std::vector> GCodeTimeEstimator::get_custom_gcode_times_dhm(bool include_remaining) const { diff --git a/src/libslic3r/GCodeTimeEstimator.hpp b/src/libslic3r/GCodeTimeEstimator.hpp index ce6b2f4af0..3b92f02692 100644 --- a/src/libslic3r/GCodeTimeEstimator.hpp +++ b/src/libslic3r/GCodeTimeEstimator.hpp @@ -371,7 +371,9 @@ namespace Slic3r { // Returns the estimated time, in format DDd HHh MMm, for each custom_gcode // If include_remaining==true the strings will be formatted as: "time for custom_gcode (remaining time at color start)" #if ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR std::vector>> get_custom_gcode_times_dhm(bool include_remaining) const; +#endif // ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR #else std::vector> get_custom_gcode_times_dhm(bool include_remaining) const; #endif // ENABLE_GCODE_VIEWER diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 34fab6f307..a48d6f602f 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -2191,9 +2191,15 @@ DynamicConfig PrintStatistics::config() const { DynamicConfig config; #if ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR config.set_key_value("print_time", new ConfigOptionString(this->estimated_normal_print_time_str)); config.set_key_value("normal_print_time", new ConfigOptionString(this->estimated_normal_print_time_str)); config.set_key_value("silent_print_time", new ConfigOptionString(this->estimated_silent_print_time_str)); +#else + config.set_key_value("print_time", new ConfigOptionString(short_time(get_time_dhms(this->estimated_normal_print_time)))); + config.set_key_value("normal_print_time", new ConfigOptionString(short_time(get_time_dhms(this->estimated_normal_print_time)))); + config.set_key_value("silent_print_time", new ConfigOptionString(short_time(get_time_dhms(this->estimated_silent_print_time)))); +#endif // ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR #else std::string normal_print_time = short_time(this->estimated_normal_print_time); std::string silent_print_time = short_time(this->estimated_silent_print_time); diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 7a0ecdf170..064145a2e7 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -306,12 +306,16 @@ struct PrintStatistics #if ENABLE_GCODE_VIEWER float estimated_normal_print_time; float estimated_silent_print_time; +#if ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR std::string estimated_normal_print_time_str; std::string estimated_silent_print_time_str; +#endif // ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR std::vector>> estimated_normal_custom_gcode_print_times; std::vector>> estimated_silent_custom_gcode_print_times; +#if ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR std::vector>> estimated_normal_custom_gcode_print_times_str; std::vector>> estimated_silent_custom_gcode_print_times_str; +#endif // ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR std::vector> estimated_normal_moves_times; std::vector> estimated_silent_moves_times; std::vector> estimated_normal_roles_times; @@ -341,10 +345,12 @@ struct PrintStatistics void clear() { #if ENABLE_GCODE_VIEWER clear_time_estimates(); +#if ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR estimated_normal_print_time_str.clear(); estimated_silent_print_time_str.clear(); estimated_normal_custom_gcode_print_times_str.clear(); estimated_silent_custom_gcode_print_times_str.clear(); +#endif // ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR #else estimated_normal_print_time.clear(); estimated_silent_print_time.clear(); diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index b04e78c4ed..06d217812b 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -62,6 +62,7 @@ #define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_SHADERS_EDITOR (0 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_AS_STATE (1 && ENABLE_GCODE_VIEWER) +#define ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR (1 && ENABLE_GCODE_VIEWER) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 39003e9aaa..f4c017adde 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1323,7 +1323,11 @@ void Sidebar::update_sliced_info_sizer() p->sliced_info->SetTextAndShow(siCost, info_text, new_label); #if ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR if (p->plater->get_current_canvas3D()->is_time_estimate_enabled() || (ps.estimated_normal_print_time_str == "N/A" && ps.estimated_silent_print_time_str == "N/A")) +#else + if (p->plater->get_current_canvas3D()->is_time_estimate_enabled() || (ps.estimated_normal_print_time <= 0.0f && ps.estimated_silent_print_time <= 0.0f)) +#endif // ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR #else if (ps.estimated_normal_print_time == "N/A" && ps.estimated_silent_print_time == "N/A") @@ -1336,7 +1340,11 @@ void Sidebar::update_sliced_info_sizer() wxString str_pause = _L("Pause"); #if ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR auto fill_labels = [str_color, str_pause](const std::vector>>& times, +#else + auto fill_labels = [str_color, str_pause](const std::vector>>& times, +#endif // ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR #else auto fill_labels = [str_color, str_pause](const std::vector>& times, #endif // ENABLE_GCODE_VIEWER @@ -1358,7 +1366,11 @@ void Sidebar::update_sliced_info_sizer() new_label += format_wxstr(" -> %1%", str_pause); #if ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR info_text += format_wxstr("\n%1% (%2%)", times[i].second.first, times[i].second.second); +#else + info_text += format_wxstr("\n%1% (%2%)", short_time(get_time_dhms(times[i].second.first)), short_time(get_time_dhms(times[i].second.second))); +#endif // ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR #else info_text += format_wxstr("\n%1%", times[i].second); #endif // ENABLE_GCODE_VIEWER @@ -1366,6 +1378,7 @@ void Sidebar::update_sliced_info_sizer() }; #if ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR if (ps.estimated_normal_print_time_str != "N/A") { new_label += format_wxstr("\n - %1%", _L("normal mode")); info_text += format_wxstr("\n%1%", ps.estimated_normal_print_time_str); @@ -1375,6 +1388,17 @@ void Sidebar::update_sliced_info_sizer() new_label += format_wxstr("\n - %1%", _L("stealth mode")); info_text += format_wxstr("\n%1%", ps.estimated_silent_print_time_str); fill_labels(ps.estimated_silent_custom_gcode_print_times_str, new_label, info_text); +#else + if (ps.estimated_normal_print_time > 0.0f) { + new_label += format_wxstr("\n - %1%", _L("normal mode")); + info_text += format_wxstr("\n%1%", short_time(get_time_dhms(ps.estimated_normal_print_time))); + fill_labels(ps.estimated_normal_custom_gcode_print_times, new_label, info_text); + } + if (ps.estimated_silent_print_time > 0.0f) { + new_label += format_wxstr("\n - %1%", _L("stealth mode")); + info_text += format_wxstr("\n%1%", short_time(get_time_dhms(ps.estimated_silent_print_time))); + fill_labels(ps.estimated_silent_custom_gcode_print_times, new_label, info_text); +#endif // ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR #else if (ps.estimated_normal_print_time != "N/A") { new_label += format_wxstr("\n - %1%", _L("normal mode")); @@ -1397,6 +1421,9 @@ void Sidebar::update_sliced_info_sizer() p->sliced_info->SetTextAndShow(siMateril_unit, "N/A"); } } +#if ENABLE_GCODE_VIEWER + Layout(); +#endif // ENABLE_GCODE_VIEWER } void Sidebar::show_sliced_info_sizer(const bool show) From 42677107a57a0ad7319d856dcfcdc520148d8924 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 21 Jul 2020 16:00:03 +0200 Subject: [PATCH 159/255] ENABLE_GCODE_VIEWER -> Fixed scene update when opening a gcode file --- src/slic3r/GUI/Plater.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index f4c017adde..ef113b7b96 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4650,6 +4650,7 @@ void Plater::load_gcode(const wxString& filename) // cleanup view before to start loading/processing p->gcode_result.reset(); + reset_gcode_toolpaths(); p->preview->reload_print(false); p->get_current_canvas3D()->render(); From 8f90fe16095225062c6a738bebc994714778023d Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 22 Jul 2020 10:37:25 +0200 Subject: [PATCH 160/255] Code cleanup and small refactoring --- src/libslic3r/GCode.cpp | 146 ++----------------------- src/libslic3r/GCode/GCodeProcessor.cpp | 15 +-- 2 files changed, 16 insertions(+), 145 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index d492acf2e8..8a835e07d5 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -579,7 +579,6 @@ namespace Slic3r { #define EXTRUDER_CONFIG(OPT) m_config.OPT.get_at(m_writer.extruder()->id()) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Collect pairs of object_layer + support_layer sorted by print_z. // object_layer & support_layer are considered to be on the same print_z, if they are not further than EPSILON. std::vector GCode::collect_layers_to_print(const PrintObject& object) @@ -663,127 +662,6 @@ std::vector GCode::collect_layers_to_print(const PrintObjec return layers_to_print; } - -// // Collect pairs of object_layer + support_layer sorted by print_z. -// // object_layer & support_layer are considered to be on the same print_z, if they are not further than EPSILON. -// std::vector GCode::collect_layers_to_print(const PrintObject& object) -// { -// std::vector layers_to_print; -// layers_to_print.reserve(object.layers().size() + object.support_layers().size()); -// -// // Calculate a minimum support layer height as a minimum over all extruders, but not smaller than 10um. -// // This is the same logic as in support generator. -// //FIXME should we use the printing extruders instead? -// double gap_over_supports = object.config().support_material_contact_distance; -// // FIXME should we test object.config().support_material_synchronize_layers ? Currently the support layers are synchronized with object layers iff soluble supports. -// assert(!object.config().support_material || gap_over_supports != 0. || object.config().support_material_synchronize_layers); -// if (gap_over_supports != 0.) { -// gap_over_supports = std::max(0., gap_over_supports); -// // Not a soluble support, -// double support_layer_height_min = 1000000.; -// for (auto lh : object.print()->config().min_layer_height.values) -// support_layer_height_min = std::min(support_layer_height_min, std::max(0.01, lh)); -// gap_over_supports += support_layer_height_min; -// } -// -// // Pair the object layers with the support layers by z. -// size_t idx_object_layer = 0; -// size_t idx_support_layer = 0; -// const LayerToPrint* last_extrusion_layer = nullptr; -// while (idx_object_layer < object.layers().size() || idx_support_layer < object.support_layers().size()) { -// LayerToPrint layer_to_print; -// layer_to_print.object_layer = (idx_object_layer < object.layers().size()) ? object.layers()[idx_object_layer++] : nullptr; -// layer_to_print.support_layer = (idx_support_layer < object.support_layers().size()) ? object.support_layers()[idx_support_layer++] : nullptr; -// if (layer_to_print.object_layer && layer_to_print.support_layer) { -// if (layer_to_print.object_layer->print_z < layer_to_print.support_layer->print_z - EPSILON) { -// layer_to_print.support_layer = nullptr; -// --idx_support_layer; -// } -// else if (layer_to_print.support_layer->print_z < layer_to_print.object_layer->print_z - EPSILON) { -// layer_to_print.object_layer = nullptr; -// --idx_object_layer; -// } -// } -// -//<<<<<<< HEAD -// layers_to_print.emplace_back(layer_to_print); -// -// // Check that there are extrusions on the very first layer. -// if (layers_to_print.size() == 1u) { -// if ((layer_to_print.object_layer && !layer_to_print.object_layer->has_extrusions()) -// || (layer_to_print.support_layer && !layer_to_print.support_layer->has_extrusions())) -// throw std::runtime_error(_(L("There is an object with no extrusions on the first layer."))); -//======= -// layers_to_print.emplace_back(layer_to_print); -// -// bool has_extrusions = (layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions()) -// || (layer_to_print.support_layer && layer_to_print.support_layer->has_extrusions()); -// -// // Check that there are extrusions on the very first layer. -// if (layers_to_print.size() == 1u) { -// if (! has_extrusions) -// throw std::runtime_error(_(L("There is an object with no extrusions on the first layer."))); -// } -// -// // In case there are extrusions on this layer, check there is a layer to lay it on. -// if ((layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions()) -// // Allow empty support layers, as the support generator may produce no extrusions for non-empty support regions. -// || (layer_to_print.support_layer /* && layer_to_print.support_layer->has_extrusions() */)) { -// double support_contact_z = (last_extrusion_layer && last_extrusion_layer->support_layer) -// ? gap_over_supports -// : 0.; -// double maximal_print_z = (last_extrusion_layer ? last_extrusion_layer->print_z() : 0.) -// + layer_to_print.layer()->height -// + support_contact_z; -// // Negative support_contact_z is not taken into account, it can result in false positives in cases -// // where previous layer has object extrusions too (https://github.com/prusa3d/PrusaSlicer/issues/2752) -// -// if (has_extrusions && layer_to_print.print_z() > maximal_print_z + 2. * EPSILON) { -// const_cast(object.print())->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL, -// _(L("Empty layers detected, the output would not be printable.")) + "\n\n" + -// _(L("Object name")) + ": " + object.model_object()->name + "\n" + _(L("Print z")) + ": " + -// std::to_string(layers_to_print.back().print_z()) + "\n\n" + _(L("This is " -// "usually caused by negligibly small extrusions or by a faulty model. Try to repair " -// "the model or change its orientation on the bed."))); -//>>>>>>> b587289c141022323753fa1810552964de0b1356 -// } -// -// // In case there are extrusions on this layer, check there is a layer to lay it on. -// if ((layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions()) -// // Allow empty support layers, as the support generator may produce no extrusions for non-empty support regions. -// || (layer_to_print.support_layer /* && layer_to_print.support_layer->has_extrusions() */)) { -// double support_contact_z = (last_extrusion_layer && last_extrusion_layer->support_layer) -// ? gap_over_supports -// : 0.; -// double maximal_print_z = (last_extrusion_layer ? last_extrusion_layer->print_z() : 0.) -// + layer_to_print.layer()->height -// + support_contact_z; -// // Negative support_contact_z is not taken into account, it can result in false positives in cases -// // where previous layer has object extrusions too (https://github.com/prusa3d/PrusaSlicer/issues/2752) -// -// // Only check this layer in case it has some extrusions. -// bool has_extrusions = (layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions()) -// || (layer_to_print.support_layer && layer_to_print.support_layer->has_extrusions()); -// -// if (has_extrusions && layer_to_print.print_z() > maximal_print_z + 2. * EPSILON) { -// const_cast(object.print())->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL, -// _(L("Empty layers detected, the output would not be printable.")) + "\n\n" + -// _(L("Object name")) + ": " + object.model_object()->name + "\n" + _(L("Print z")) + ": " + -// std::to_string(layers_to_print.back().print_z()) + "\n\n" + _(L("This is " -// "usually caused by negligibly small extrusions or by a faulty model. Try to repair " -// "the model or change its orientation on the bed."))); -// } -// -// // Remember last layer with extrusions. -// if (has_extrusions) -// last_extrusion_layer = &layers_to_print.back(); -// } -// } -// -// return layers_to_print; -// } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - // Prepare for non-sequential printing of multiple objects: Support resp. object layers with nearly identical print_z // will be printed for all objects at once. // Return a list of items. @@ -3332,36 +3210,34 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, // adds analyzer tags and updates analyzer's tracking data #if !ENABLE_GCODE_VIEWER - if (m_enable_analyzer) - { + if (m_enable_analyzer) { #endif // !ENABLE_GCODE_VIEWER - // PrusaMultiMaterial::Writer may generate GCodeAnalyzer::Height_Tag and GCodeAnalyzer::Width_Tag lines without updating m_last_height and m_last_width - // so, if the last role was erWipeTower we force export of GCodeAnalyzer::Height_Tag and GCodeAnalyzer::Width_Tag lines #if ENABLE_GCODE_VIEWER + // PrusaMultiMaterial::Writer may generate GCodeProcessor::Height_Tag and GCodeProcessor::Width_Tag lines without updating m_last_height and m_last_width + // so, if the last role was erWipeTower we force export of GCodeProcessor::Height_Tag and GCodeProcessor::Width_Tag lines bool last_was_wipe_tower = (m_last_processor_extrusion_role == erWipeTower); #else + // PrusaMultiMaterial::Writer may generate GCodeAnalyzer::Height_Tag and GCodeAnalyzer::Width_Tag lines without updating m_last_height and m_last_width + // so, if the last role was erWipeTower we force export of GCodeAnalyzer::Height_Tag and GCodeAnalyzer::Width_Tag lines bool last_was_wipe_tower = (m_last_analyzer_extrusion_role == erWipeTower); #endif // ENABLE_GCODE_VIEWER char buf[64]; #if ENABLE_GCODE_VIEWER - if (path.role() != m_last_processor_extrusion_role) - { + if (path.role() != m_last_processor_extrusion_role) { m_last_processor_extrusion_role = path.role(); sprintf(buf, ";%s%d\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), int(m_last_processor_extrusion_role)); gcode += buf; } #else - if (path.role() != m_last_analyzer_extrusion_role) - { + if (path.role() != m_last_analyzer_extrusion_role) { m_last_analyzer_extrusion_role = path.role(); sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), int(m_last_analyzer_extrusion_role)); gcode += buf; } #endif // ENABLE_GCODE_VIEWER - if (last_was_wipe_tower || (m_last_mm3_per_mm != path.mm3_per_mm)) - { + if (last_was_wipe_tower || (m_last_mm3_per_mm != path.mm3_per_mm)) { m_last_mm3_per_mm = path.mm3_per_mm; #if ENABLE_GCODE_VIEWER sprintf(buf, ";%s%f\n", GCodeProcessor::Mm3_Per_Mm_Tag.c_str(), m_last_mm3_per_mm); @@ -3372,8 +3248,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, #endif // ENABLE_GCODE_VIEWER } - if (last_was_wipe_tower || (m_last_width != path.width)) - { + if (last_was_wipe_tower || (m_last_width != path.width)) { m_last_width = path.width; #if ENABLE_GCODE_VIEWER sprintf(buf, ";%s%f\n", GCodeProcessor::Width_Tag.c_str(), m_last_width); @@ -3384,8 +3259,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, #endif // ENABLE_GCODE_VIEWER } - if (last_was_wipe_tower || (m_last_height != path.height)) - { + if (last_was_wipe_tower || (m_last_height != path.height)) { m_last_height = path.height; #if ENABLE_GCODE_VIEWER sprintf(buf, ";%s%f\n", GCodeProcessor::Height_Tag.c_str(), m_last_height); diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 67ed7c699b..83cbb876ef 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -671,15 +671,12 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) EMoveType 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) - type = EMoveType::Travel; - else - type = EMoveType::Retract; - } + type = (delta_pos[X] != 0.0f || delta_pos[Y] != 0.0f || delta_pos[Z] != 0.0f) ? EMoveType::Travel : 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) type = EMoveType::Unretract; - else if ((delta_pos[X] != 0.0f) || (delta_pos[Y] != 0.0f)) + else if (delta_pos[X] != 0.0f || delta_pos[Y] != 0.0f) type = EMoveType::Extrude; } else if (delta_pos[X] != 0.0f || delta_pos[Y] != 0.0f || delta_pos[Z] != 0.0f) @@ -730,8 +727,8 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) return (sq_xyz_length > 0.0f) ? std::sqrt(sq_xyz_length) : std::abs(delta_pos[E]); }; - auto is_extruder_only_move = [](const AxisCoords& delta_pos) { - return (delta_pos[X] == 0.0f) && (delta_pos[Y] == 0.0f) && (delta_pos[Z] == 0.0f) && (delta_pos[E] != 0.0f); + auto is_extrusion_only_move = [](const AxisCoords& delta_pos) { + return delta_pos[X] == 0.0f && delta_pos[Y] == 0.0f && delta_pos[Z] == 0.0f && delta_pos[E] != 0.0f; }; float distance = move_length(delta_pos); @@ -781,7 +778,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) } // calculates block acceleration - float acceleration = is_extruder_only_move(delta_pos) ? + float acceleration = is_extrusion_only_move(delta_pos) ? get_retract_acceleration(static_cast(i)) : get_acceleration(static_cast(i)); From 14366800e2feac3ce075a317e0895e43411dfc4c Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 27 Jul 2020 15:45:29 +0200 Subject: [PATCH 161/255] GCodeProcessor -> Added parsing of 3d part generated gcodes --- src/libslic3r/GCode/GCodeProcessor.cpp | 311 +++++++++++++++++++++++++ src/libslic3r/GCode/GCodeProcessor.hpp | 23 ++ src/slic3r/GUI/Plater.cpp | 1 + 3 files changed, 335 insertions(+) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 83cbb876ef..42d1c07575 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -296,6 +296,14 @@ void GCodeProcessor::TimeProcessor::reset() machines[static_cast(ETimeMode::Normal)].enabled = true; } +const std::vector> GCodeProcessor::Producers = { + { EProducer::PrusaSlicer, "PrusaSlicer" }, + { EProducer::Cura, "Cura" }, + { EProducer::Simplify3D, "Simplify3D" }, + { EProducer::CraftWare, "CraftWare" }, + { EProducer::ideaMaker, "ideaMaker" } +}; + unsigned int GCodeProcessor::s_result_id = 0; void GCodeProcessor::apply_config(const PrintConfig& config) @@ -364,6 +372,9 @@ void GCodeProcessor::reset() m_extruders_color = ExtrudersColor(); m_cp_color.reset(); + m_producer = EProducer::Unknown; + m_producers_enabled = false; + m_time_processor.reset(); m_result.reset(); @@ -539,6 +550,13 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) void GCodeProcessor::process_tags(const std::string& comment) { + if (m_producers_enabled && m_producer == EProducer::Unknown && detect_producer(comment)) + return; + else if (m_producers_enabled && m_producer != EProducer::Unknown) { + if (process_producers_tags(comment)) + return; + } + // extrusion role tag size_t pos = comment.find(Extrusion_Role_Tag); if (pos != comment.npos) { @@ -645,6 +663,299 @@ void GCodeProcessor::process_tags(const std::string& comment) } } +bool GCodeProcessor::process_producers_tags(const std::string& comment) +{ + switch (m_producer) + { + case EProducer::PrusaSlicer: { return process_prusaslicer_tags(comment); } + case EProducer::Cura: { return process_cura_tags(comment); } + case EProducer::Simplify3D: { return process_simplify3d_tags(comment); } + case EProducer::CraftWare: { return process_craftware_tags(comment); } + case EProducer::ideaMaker: { return process_ideamaker_tags(comment); } + default: { return false; } + } +} + +bool GCodeProcessor::process_prusaslicer_tags(const std::string& comment) +{ + std::cout << comment << "\n"; + return false; +} + +bool GCodeProcessor::process_cura_tags(const std::string& comment) +{ + // TYPE -> extrusion role + std::string tag = "TYPE:"; + size_t pos = comment.find(tag); + if (pos != comment.npos) { + std::string type = comment.substr(pos + tag.length()); + if (type == "SKIRT") + m_extrusion_role = erSkirt; + else if (type == "WALL-OUTER") + m_extrusion_role = erExternalPerimeter; + else if (type == "WALL-INNER") + m_extrusion_role = erPerimeter; + else if (type == "SKIN") + m_extrusion_role = erSolidInfill; + else if (type == "FILL") + m_extrusion_role = erInternalInfill; + else if (type == "SUPPORT") + m_extrusion_role = erSupportMaterial; + else if (type == "SUPPORT-INTERFACE") + m_extrusion_role = erSupportMaterialInterface; + else if (type == "PRIME-TOWER") + m_extrusion_role = erWipeTower; + else { + m_extrusion_role = erNone; + BOOST_LOG_TRIVIAL(warning) << "GCodeProcessor found unknown extrusion role: " << type; + } + + return true; + } + + return false; +} + +bool GCodeProcessor::process_simplify3d_tags(const std::string& comment) +{ + // extrusion roles + + // ; skirt + size_t pos = comment.find(" skirt"); + if (pos == 0) { + m_extrusion_role = erSkirt; + return true; + } + + // ; outer perimeter + pos = comment.find(" outer perimeter"); + if (pos == 0) { + m_extrusion_role = erExternalPerimeter; + return true; + } + + // ; inner perimeter + pos = comment.find(" inner perimeter"); + if (pos == 0) { + m_extrusion_role = erPerimeter; + return true; + } + + // ; gap fill + pos = comment.find(" gap fill"); + if (pos == 0) { + m_extrusion_role = erGapFill; + return true; + } + + // ; infill + pos = comment.find(" infill"); + if (pos == 0) { + m_extrusion_role = erInternalInfill; + return true; + } + + // ; solid layer + pos = comment.find(" solid layer"); + if (pos == 0) { + m_extrusion_role = erNone; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return true; + } + + // ; bridge + pos = comment.find(" bridge"); + if (pos == 0) { + m_extrusion_role = erBridgeInfill; + return true; + } + + // ; support + pos = comment.find(" support"); + if (pos == 0) { + m_extrusion_role = erSupportMaterial; + return true; + } + + // ; prime pillar + pos = comment.find(" prime pillar"); + if (pos == 0) { + m_extrusion_role = erWipeTower; + return true; + } + + // ; ooze shield + pos = comment.find(" ooze shield"); + if (pos == 0) { + m_extrusion_role = erNone; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return true; + } + + // ; raft + pos = comment.find(" raft"); + if (pos == 0) { + m_extrusion_role = erSkirt; + return true; + } + + // geometry + + // ; tool + std::string tag = " tool"; + pos = comment.find(tag); + if (pos == 0) { + std::string data = comment.substr(pos + tag.length()); + std::string h_tag = "H"; + size_t h_start = data.find(h_tag); + size_t h_end = data.find_first_of(' ', h_start); + std::string w_tag = "W"; + size_t w_start = data.find(w_tag); + size_t w_end = data.find_first_of(' ', w_start); + if (h_start != data.npos) { + try + { + std::string test = data.substr(h_start + 1, (h_end != data.npos) ? h_end - h_start - 1 : h_end); + m_height = std::stof(data.substr(h_start + 1, (h_end != data.npos) ? h_end - h_start - 1 : h_end)); + } + catch (...) + { + BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ")."; + } + } + if (w_start != data.npos) { + try + { + std::string test = data.substr(w_start + 1, (w_end != data.npos) ? w_end - w_start - 1 : w_end); + m_width = std::stof(data.substr(w_start + 1, (w_end != data.npos) ? w_end - w_start - 1 : w_end)); + } + catch (...) + { + BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ")."; + } + } + + return true; + } + + std::cout << comment << "\n"; + return false; +} + +bool GCodeProcessor::process_craftware_tags(const std::string& comment) +{ + // segType -> extrusion role + std::string tag = "segType:"; + size_t pos = comment.find(tag); + if (pos != comment.npos) { + std::string type = comment.substr(pos + tag.length()); + if (type == "Skirt") + m_extrusion_role = erSkirt; + else if (type == "Perimeter") + m_extrusion_role = erExternalPerimeter; + else if (type == "HShell") + m_extrusion_role = erNone; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + else if (type == "InnerHair") + m_extrusion_role = erNone; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + else if (type == "Loop") + m_extrusion_role = erNone; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + else if (type == "Infill") + m_extrusion_role = erInternalInfill; + else if (type == "Raft") + m_extrusion_role = erSkirt; + else if (type == "Support") + m_extrusion_role = erSupportMaterial; + else if (type == "SupportTouch") + m_extrusion_role = erSupportMaterial; + else if (type == "SoftSupport") + m_extrusion_role = erSupportMaterialInterface; + else if (type == "Pillar") + m_extrusion_role = erWipeTower; + else { + m_extrusion_role = erNone; + BOOST_LOG_TRIVIAL(warning) << "GCodeProcessor found unknown extrusion role: " << type; + } + + return true; + } + + return false; +} + +bool GCodeProcessor::process_ideamaker_tags(const std::string& comment) +{ + // TYPE -> extrusion role + std::string tag = "TYPE:"; + size_t pos = comment.find(tag); + if (pos != comment.npos) { + std::string type = comment.substr(pos + tag.length()); + if (type == "RAFT") + m_extrusion_role = erSkirt; + else if (type == "WALL-OUTER") + m_extrusion_role = erExternalPerimeter; + else if (type == "WALL-INNER") + m_extrusion_role = erPerimeter; + else if (type == "SOLID-FILL") + m_extrusion_role = erSolidInfill; + else if (type == "FILL") + m_extrusion_role = erInternalInfill; + else if (type == "BRIDGE") + m_extrusion_role = erBridgeInfill; + else if (type == "SUPPORT") + m_extrusion_role = erSupportMaterial; + else { + m_extrusion_role = erNone; + BOOST_LOG_TRIVIAL(warning) << "GCodeProcessor found unknown extrusion role: " << type; + } + return true; + } + + // geometry + + // width + tag = "WIDTH:"; + pos = comment.find(tag); + if (pos != comment.npos) { + try + { + m_width = std::stof(comment.substr(pos + tag.length())); + } + catch (...) + { + BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ")."; + } + return true; + } + + // height + tag = "HEIGHT:"; + pos = comment.find(tag); + if (pos != comment.npos) { + try + { + m_height = std::stof(comment.substr(pos + tag.length())); + } + catch (...) + { + BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ")."; + } + return true; + } + + return false; +} + +bool GCodeProcessor::detect_producer(const std::string& comment) +{ + for (const auto& [id, search_string] : Producers) { + size_t pos = comment.find(search_string); + if (pos != comment.npos) { + m_producer = id; + BOOST_LOG_TRIVIAL(info) << "Detected gcode producer: " << search_string; + return true; + } + } + return false; +} + void GCodeProcessor::process_G0(const GCodeReader::GCodeLine& line) { process_G1(line); diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index d19d363f95..9507adf4d5 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -243,6 +243,20 @@ namespace Slic3r { ExtrudersColor m_extruders_color; CpColor m_cp_color; + enum class EProducer + { + Unknown, + PrusaSlicer, + Cura, + Simplify3D, + CraftWare, + ideaMaker + }; + + static const std::vector> Producers; + EProducer m_producer; + bool m_producers_enabled; + TimeProcessor m_time_processor; Result m_result; @@ -253,6 +267,7 @@ namespace Slic3r { void apply_config(const PrintConfig& config); void enable_stealth_time_estimator(bool enabled); + void enable_producers(bool enabled) { m_producers_enabled = enabled; } void reset(); const Result& get_result() const { return m_result; } @@ -274,6 +289,14 @@ namespace Slic3r { // Process tags embedded into comments void process_tags(const std::string& comment); + bool process_producers_tags(const std::string& comment); + bool process_prusaslicer_tags(const std::string& comment); + bool process_cura_tags(const std::string& comment); + bool process_simplify3d_tags(const std::string& comment); + bool process_craftware_tags(const std::string& comment); + bool process_ideamaker_tags(const std::string& comment); + + bool detect_producer(const std::string& comment); // Move void process_G0(const GCodeReader::GCodeLine& line); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 8a5863616e..193ac8e0c1 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4662,6 +4662,7 @@ void Plater::load_gcode(const wxString& filename) // process gcode GCodeProcessor processor; // processor.apply_config(config); + processor.enable_producers(true); processor.process_file(filename.ToUTF8().data()); p->gcode_result = std::move(processor.extract_result()); From d9228ee82cc541f997da7a731893c44a59023445 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 28 Jul 2020 09:48:55 +0200 Subject: [PATCH 162/255] GCodeProcessor -> Human readable extrusion roles in gcode --- src/libslic3r/ExtrusionEntity.cpp | 36 ++++++++++++++++++++++++++ src/libslic3r/ExtrusionEntity.hpp | 1 + src/libslic3r/GCode.cpp | 6 ++--- src/libslic3r/GCode/GCodeProcessor.cpp | 23 ++++------------ src/libslic3r/GCode/WipeTower.cpp | 2 +- 5 files changed, 46 insertions(+), 22 deletions(-) diff --git a/src/libslic3r/ExtrusionEntity.cpp b/src/libslic3r/ExtrusionEntity.cpp index d629a3c89b..b2c5e1350f 100644 --- a/src/libslic3r/ExtrusionEntity.cpp +++ b/src/libslic3r/ExtrusionEntity.cpp @@ -331,4 +331,40 @@ std::string ExtrusionEntity::role_to_string(ExtrusionRole role) return ""; } +ExtrusionRole ExtrusionEntity::string_to_role(const std::string& role) +{ + if (role == L("Perimeter")) + return erPerimeter; + else if (role == L("External perimeter")) + return erExternalPerimeter; + else if (role == L("Overhang perimeter")) + return erOverhangPerimeter; + else if (role == L("Internal infill")) + return erInternalInfill; + else if (role == L("Solid infill")) + return erSolidInfill; + else if (role == L("Top solid infill")) + return erTopSolidInfill; + else if (role == L("Ironing")) + return erIroning; + else if (role == L("Bridge infill")) + return erBridgeInfill; + else if (role == L("Gap fill")) + return erGapFill; + else if (role == L("Skirt")) + return erSkirt; + else if (role == L("Support material")) + return erSupportMaterial; + else if (role == L("Support material interface")) + return erSupportMaterialInterface; + else if (role == L("Wipe tower")) + return erWipeTower; + else if (role == L("Custom")) + return erCustom; + else if (role == L("Mixed")) + return erMixed; + else + return erNone; +} + } diff --git a/src/libslic3r/ExtrusionEntity.hpp b/src/libslic3r/ExtrusionEntity.hpp index 879f564b6c..3d7e581128 100644 --- a/src/libslic3r/ExtrusionEntity.hpp +++ b/src/libslic3r/ExtrusionEntity.hpp @@ -106,6 +106,7 @@ public: virtual double total_volume() const = 0; static std::string role_to_string(ExtrusionRole role); + static ExtrusionRole string_to_role(const std::string& role); }; typedef std::vector ExtrusionEntitiesPtr; diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 8a835e07d5..742498baf8 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1388,7 +1388,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu #if ENABLE_GCODE_VIEWER // adds tag for processor - _write_format(file, ";%s%d\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), erCustom); + _write_format(file, ";%s%s\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), ExtrusionEntity::role_to_string(erCustom).c_str()); #else if (m_enable_analyzer) // adds tag for analyzer @@ -1546,7 +1546,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu #if ENABLE_GCODE_VIEWER // adds tag for processor - _write_format(file, ";%s%d\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), erCustom); + _write_format(file, ";%s%s\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), ExtrusionEntity::role_to_string(erCustom).c_str()); #else if (m_enable_analyzer) // adds tag for analyzer @@ -3226,7 +3226,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, #if ENABLE_GCODE_VIEWER if (path.role() != m_last_processor_extrusion_role) { m_last_processor_extrusion_role = path.role(); - sprintf(buf, ";%s%d\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), int(m_last_processor_extrusion_role)); + sprintf(buf, ";%s%s\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), ExtrusionEntity::role_to_string(m_last_processor_extrusion_role).c_str()); gcode += buf; } #else diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 42d1c07575..44598d2408 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -21,13 +21,13 @@ static const float DEFAULT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 namespace Slic3r { -const std::string GCodeProcessor::Extrusion_Role_Tag = "PrusaSlicer__EXTRUSION_ROLE:"; +const std::string GCodeProcessor::Extrusion_Role_Tag = "ExtrType:"; const std::string GCodeProcessor::Width_Tag = "PrusaSlicer__WIDTH:"; const std::string GCodeProcessor::Height_Tag = "PrusaSlicer__HEIGHT:"; const std::string GCodeProcessor::Mm3_Per_Mm_Tag = "PrusaSlicer__MM3_PER_MM:"; -const std::string GCodeProcessor::Color_Change_Tag = "PrusaSlicer__COLOR_CHANGE"; -const std::string GCodeProcessor::Pause_Print_Tag = "PrusaSlicer__PAUSE_PRINT"; -const std::string GCodeProcessor::Custom_Code_Tag = "PrusaSlicer__CUSTOM_CODE"; +const std::string GCodeProcessor::Color_Change_Tag = "COLOR_CHANGE"; +const std::string GCodeProcessor::Pause_Print_Tag = "PAUSE_PRINT"; +const std::string GCodeProcessor::Custom_Code_Tag = "CUSTOM_CODE"; static bool is_valid_extrusion_role(int value) { @@ -560,20 +560,7 @@ void GCodeProcessor::process_tags(const std::string& comment) // extrusion role tag size_t pos = comment.find(Extrusion_Role_Tag); if (pos != comment.npos) { - try - { - int role = std::stoi(comment.substr(pos + Extrusion_Role_Tag.length())); - if (is_valid_extrusion_role(role)) - m_extrusion_role = static_cast(role); - else { - // todo: show some error ? - } - } - catch (...) - { - BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Extrusion Role (" << comment << ")."; - } - + m_extrusion_role = ExtrusionEntity::string_to_role(comment.substr(pos + Extrusion_Role_Tag.length())); return; } diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index 73ac36dc41..e4f995aba1 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -64,7 +64,7 @@ public: #endif // ENABLE_GCODE_VIEWER m_gcode += buf; #if ENABLE_GCODE_VIEWER - sprintf(buf, ";%s%d\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), erWipeTower); + sprintf(buf, ";%s%s\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), ExtrusionEntity::role_to_string(erWipeTower).c_str()); #else sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), erWipeTower); #endif // ENABLE_GCODE_VIEWER From 11cf9a87f143dcc18c82779ce63a7cdf768521e4 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 29 Jul 2020 10:04:10 +0200 Subject: [PATCH 163/255] GCodeProcessor -> Calculate mm3 per mm on the fly --- src/libslic3r/GCode.cpp | 8 ++------ src/libslic3r/GCode.hpp | 7 ++++++- src/libslic3r/GCode/GCodeProcessor.cpp | 28 ++++++++++++-------------- src/libslic3r/GCode/GCodeProcessor.hpp | 2 +- src/libslic3r/GCode/WipeTower.cpp | 26 ++++++++++++------------ 5 files changed, 35 insertions(+), 36 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 742498baf8..ced52207d0 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1178,7 +1178,6 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu // resets analyzer's tracking data #if ENABLE_GCODE_VIEWER - m_last_mm3_per_mm = 0.0f; m_last_width = 0.0f; m_last_height = 0.0f; #else @@ -3237,16 +3236,13 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } #endif // ENABLE_GCODE_VIEWER +#if !ENABLE_GCODE_VIEWER if (last_was_wipe_tower || (m_last_mm3_per_mm != path.mm3_per_mm)) { m_last_mm3_per_mm = path.mm3_per_mm; -#if ENABLE_GCODE_VIEWER - sprintf(buf, ";%s%f\n", GCodeProcessor::Mm3_Per_Mm_Tag.c_str(), m_last_mm3_per_mm); - gcode += buf; -#else sprintf(buf, ";%s%f\n", GCodeAnalyzer::Mm3_Per_Mm_Tag.c_str(), m_last_mm3_per_mm); gcode += buf; -#endif // ENABLE_GCODE_VIEWER } +#endif // !ENABLE_GCODE_VIEWER if (last_was_wipe_tower || (m_last_width != path.width)) { m_last_width = path.width; diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 2732427620..443c25bb2f 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -173,7 +173,6 @@ public: m_last_pos_defined(false), m_last_extrusion_role(erNone), #if ENABLE_GCODE_VIEWER - m_last_mm3_per_mm(0.0f), m_last_width(0.0f), m_last_height(0.0f), #else @@ -378,10 +377,16 @@ private: double m_volumetric_speed; // Support for the extrusion role markers. Which marker is active? ExtrusionRole m_last_extrusion_role; +#if ENABLE_GCODE_VIEWER + // Support for G-Code Processor + float m_last_width; + float m_last_height; +#else // Support for G-Code Analyzer double m_last_mm3_per_mm; float m_last_width; float m_last_height; +#endif // ENABLE_GCODE_VIEWER Point m_last_pos; bool m_last_pos_defined; diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 44598d2408..ef9c64880d 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -24,7 +24,6 @@ namespace Slic3r { const std::string GCodeProcessor::Extrusion_Role_Tag = "ExtrType:"; const std::string GCodeProcessor::Width_Tag = "PrusaSlicer__WIDTH:"; const std::string GCodeProcessor::Height_Tag = "PrusaSlicer__HEIGHT:"; -const std::string GCodeProcessor::Mm3_Per_Mm_Tag = "PrusaSlicer__MM3_PER_MM:"; const std::string GCodeProcessor::Color_Change_Tag = "COLOR_CHANGE"; const std::string GCodeProcessor::Pause_Print_Tag = "PAUSE_PRINT"; const std::string GCodeProcessor::Custom_Code_Tag = "CUSTOM_CODE"; @@ -325,6 +324,10 @@ void GCodeProcessor::apply_config(const PrintConfig& config) m_extruders_color[id] = static_cast(id); } + for (double diam : config.filament_diameter.values) { + m_filament_diameters.push_back(static_cast(diam)); + } + m_time_processor.machine_limits = reinterpret_cast(config); // Filament load / unload times are not specific to a firmware flavor. Let anybody use it if they find it useful. // As of now the fields are shown at the UI dialog in the same combo box as the ramming values, so they @@ -370,6 +373,7 @@ void GCodeProcessor::reset() m_extrusion_role = erNone; m_extruder_id = 0; m_extruders_color = ExtrudersColor(); + m_filament_diameters = std::vector(); m_cp_color.reset(); m_producer = EProducer::Unknown; @@ -592,20 +596,6 @@ void GCodeProcessor::process_tags(const std::string& comment) return; } - // mm3 per mm tag - pos = comment.find(Mm3_Per_Mm_Tag); - if (pos != comment.npos) { - try - { - m_mm3_per_mm = std::stof(comment.substr(pos + Mm3_Per_Mm_Tag.length())); - } - catch (...) - { - BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Mm3_Per_Mm (" << comment << ")."; - } - return; - } - // color change tag pos = comment.find(Color_Change_Tag); if (pos != comment.npos) { @@ -1019,6 +1009,14 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) EMoveType type = move_type(delta_pos); + if (type == EMoveType::Extrude) { + if (delta_pos[E] > 0.0f) { + float ds = std::sqrt(sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z])); + if (ds > 0.0f && static_cast(m_extruder_id) < m_filament_diameters.size()) + m_mm3_per_mm = round_nearest(delta_pos[E] * static_cast(M_PI) * sqr(static_cast(m_filament_diameters[m_extruder_id])) / (4.0f * ds), 3); + } + } + // time estimate section auto move_length = [](const AxisCoords& delta_pos) { float sq_xyz_length = sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z]); diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 9507adf4d5..d59fc7bb9b 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -21,7 +21,6 @@ namespace Slic3r { static const std::string Extrusion_Role_Tag; static const std::string Width_Tag; static const std::string Height_Tag; - static const std::string Mm3_Per_Mm_Tag; static const std::string Color_Change_Tag; static const std::string Pause_Print_Tag; static const std::string Custom_Code_Tag; @@ -241,6 +240,7 @@ namespace Slic3r { ExtrusionRole m_extrusion_role; unsigned char m_extruder_id; ExtrudersColor m_extruders_color; + std::vector m_filament_diameters; CpColor m_cp_color; enum class EProducer diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index e4f995aba1..c20009a487 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -84,19 +84,17 @@ public: return *this; } - WipeTowerWriter& change_analyzer_mm3_per_mm(float len, float e) { - static const float area = float(M_PI) * 1.75f * 1.75f / 4.f; - float mm3_per_mm = (len == 0.f ? 0.f : area * e / len); - // adds tag for analyzer: - char buf[64]; -#if ENABLE_GCODE_VIEWER - sprintf(buf, ";%s%f\n", GCodeProcessor::Mm3_Per_Mm_Tag.c_str(), mm3_per_mm); -#else - sprintf(buf, ";%s%f\n", GCodeAnalyzer::Mm3_Per_Mm_Tag.c_str(), mm3_per_mm); -#endif // ENABLE_GCODE_VIEWER - m_gcode += buf; - return *this; +#if !ENABLE_GCODE_VIEWER + WipeTowerWriter& change_analyzer_mm3_per_mm(float len, float e) { + static const float area = float(M_PI) * 1.75f * 1.75f / 4.f; + float mm3_per_mm = (len == 0.f ? 0.f : area * e / len); + // adds tag for analyzer: + char buf[64]; + sprintf(buf, ";%s%f\n", GCodeAnalyzer::Mm3_Per_Mm_Tag.c_str(), mm3_per_mm); + m_gcode += buf; + return *this; } +#endif // !ENABLE_GCODE_VIEWER WipeTowerWriter& set_initial_position(const Vec2f &pos, float width = 0.f, float depth = 0.f, float internal_angle = 0.f) { m_wipe_tower_width = width; @@ -169,8 +167,10 @@ public: Vec2f rot(this->rotate(Vec2f(x,y))); // this is where we want to go if (! m_preview_suppressed && e > 0.f && len > 0.f) { +#if !ENABLE_GCODE_VIEWER change_analyzer_mm3_per_mm(len, e); - // Width of a squished extrusion, corrected for the roundings of the squished extrusions. +#endif // !ENABLE_GCODE_VIEWER + // Width of a squished extrusion, corrected for the roundings of the squished extrusions. // This is left zero if it is a travel move. float width = e * m_filpar[0].filament_area / (len * m_layer_height); // Correct for the roundings of a squished extrusion. From 16e282110d2fc8ce503c0635397ad0e8300c78c3 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 29 Jul 2020 11:13:48 +0200 Subject: [PATCH 164/255] GCodeProcessor -> Load config data from gcode files generated by PrusaSlicer --- src/libslic3r/GCode/GCodeProcessor.cpp | 45 +++++++++++++++++++++++--- src/libslic3r/GCode/GCodeProcessor.hpp | 1 + src/libslic3r/GCodeReader.cpp | 5 +++ src/libslic3r/GCodeReader.hpp | 6 ++++ 4 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index ef9c64880d..ae414ad441 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -346,6 +346,18 @@ void GCodeProcessor::apply_config(const PrintConfig& config) } } +void GCodeProcessor::apply_config(const DynamicPrintConfig& config) +{ + m_parser.apply_config(config); + + const ConfigOptionFloats* filament_diameters = config.option("filament_diameter"); + if (filament_diameters != nullptr) { + for (double diam : filament_diameters->values) { + m_filament_diameters.push_back(static_cast(diam)); + } + } +} + void GCodeProcessor::enable_stealth_time_estimator(bool enabled) { m_time_processor.machines[static_cast(ETimeMode::Stealth)].enabled = enabled; @@ -391,6 +403,28 @@ void GCodeProcessor::process_file(const std::string& filename) auto start_time = std::chrono::high_resolution_clock::now(); #endif // ENABLE_GCODE_VIEWER_STATISTICS + // pre-processing + // parse the gcode file to detect its producer + if (m_producers_enabled) { + m_parser.parse_file(filename, [this](GCodeReader& reader, const GCodeReader::GCodeLine& line) { + std::string cmd = line.cmd(); + if (cmd.length() == 0) { + std::string comment = line.comment(); + if (comment.length() > 1 && detect_producer(comment)) + m_parser.quit_parsing_file(); + } + }); + + // if the gcode was produced by PrusaSlicer, + // extract the config from it + if (m_producer == EProducer::PrusaSlicer) { + DynamicPrintConfig config; + config.apply(FullPrintConfig::defaults()); + config.load_from_gcode_file(filename); + apply_config(config); + } + } + m_result.id = ++s_result_id; m_result.moves.emplace_back(MoveVertex()); m_parser.parse_file(filename, [this](GCodeReader& reader, const GCodeReader::GCodeLine& line) { process_gcode_line(line); }); @@ -554,11 +588,12 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) void GCodeProcessor::process_tags(const std::string& comment) { - if (m_producers_enabled && m_producer == EProducer::Unknown && detect_producer(comment)) - return; - else if (m_producers_enabled && m_producer != EProducer::Unknown) { - if (process_producers_tags(comment)) - return; + // producers tags + if (m_producers_enabled) { + if (m_producer != EProducer::Unknown) { + if (process_producers_tags(comment)) + return; + } } // extrusion role tag diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index d59fc7bb9b..b2d702f7f3 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -266,6 +266,7 @@ namespace Slic3r { GCodeProcessor() { reset(); } void apply_config(const PrintConfig& config); + void apply_config(const DynamicPrintConfig& config); void enable_stealth_time_estimator(bool enabled); void enable_producers(bool enabled) { m_producers_enabled = enabled; } void reset(); diff --git a/src/libslic3r/GCodeReader.cpp b/src/libslic3r/GCodeReader.cpp index e68bc5ad29..ab77b01413 100644 --- a/src/libslic3r/GCodeReader.cpp +++ b/src/libslic3r/GCodeReader.cpp @@ -115,7 +115,12 @@ void GCodeReader::parse_file(const std::string &file, callback_t callback) { std::ifstream f(file); std::string line; +#if ENABLE_GCODE_VIEWER + m_parsing_file = true; + while (m_parsing_file && std::getline(f, line)) +#else while (std::getline(f, line)) +#endif // ENABLE_GCODE_VIEWER this->parse_line(line, callback); } diff --git a/src/libslic3r/GCodeReader.hpp b/src/libslic3r/GCodeReader.hpp index 9503ddcc16..7e0793cd9b 100644 --- a/src/libslic3r/GCodeReader.hpp +++ b/src/libslic3r/GCodeReader.hpp @@ -107,6 +107,9 @@ public: { GCodeLine gline; this->parse_line(line.c_str(), gline, callback); } void parse_file(const std::string &file, callback_t callback); +#if ENABLE_GCODE_VIEWER + void quit_parsing_file() { m_parsing_file = false; } +#endif // ENABLE_GCODE_VIEWER float& x() { return m_position[X]; } float x() const { return m_position[X]; } @@ -145,6 +148,9 @@ private: char m_extrusion_axis; float m_position[NUM_AXES]; bool m_verbose; +#if ENABLE_GCODE_VIEWER + bool m_parsing_file{ false }; +#endif // ENABLE_GCODE_VIEWER }; } /* namespace Slic3r */ From 9d4344a78ce56ecf722e946f2c1796a9e1df96e8 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 29 Jul 2020 12:47:42 +0200 Subject: [PATCH 165/255] GCodeProcessor/GCodeViewer -> Extract bed shape from gcode files generated by PrusaSlicer --- src/libslic3r/GCode/GCodeProcessor.cpp | 4 ++++ src/libslic3r/GCode/GCodeProcessor.hpp | 20 ++++++++++++++++++-- src/slic3r/GUI/GCodeViewer.cpp | 22 ++++++++++++++-------- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index ae414ad441..beb340a5da 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -356,6 +356,10 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config) m_filament_diameters.push_back(static_cast(diam)); } } + + const ConfigOptionPoints* bed_shape = config.option("bed_shape"); + if (bed_shape != nullptr) + m_result.bed_shape = bed_shape->values; } void GCodeProcessor::enable_stealth_time_estimator(bool enabled) diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index b2d702f7f3..1def93e74b 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -210,11 +210,27 @@ namespace Slic3r { { unsigned int id; std::vector moves; +#if ENABLE_GCODE_VIEWER_AS_STATE + Pointfs bed_shape; +#endif // ENABLE_GCODE_VIEWER_AS_STATE #if ENABLE_GCODE_VIEWER_STATISTICS long long time{ 0 }; - void reset() { time = 0; moves = std::vector(); } + void reset() + { + time = 0; + moves = std::vector(); +#if ENABLE_GCODE_VIEWER_AS_STATE + bed_shape = Pointfs(); +#endif // ENABLE_GCODE_VIEWER_AS_STATE + } #else - void reset() { moves = std::vector(); } + void reset() + { + moves = std::vector(); +#if ENABLE_GCODE_VIEWER_AS_STATE + bed_shape = Pointfs(); +#endif // ENABLE_GCODE_VIEWER_AS_STATE + } #endif // ENABLE_GCODE_VIEWER_STATISTICS }; diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 418223503b..817e7e650c 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -323,14 +323,20 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& #if ENABLE_GCODE_VIEWER_AS_STATE if (wxGetApp().mainframe->get_mode() == MainFrame::EMode::GCodeViewer) { - // adjust printbed size in dependence of toolpaths bbox - const double margin = 10.0; - Vec2d min(m_paths_bounding_box.min(0) - margin, m_paths_bounding_box.min(1) - margin); - Vec2d max(m_paths_bounding_box.max(0) + margin, m_paths_bounding_box.max(1) + margin); - Pointfs bed_shape = { { min(0), min(1) }, - { max(0), min(1) }, - { max(0), max(1) }, - { min(0), max(1) } }; + Pointfs bed_shape; + if (!gcode_result.bed_shape.empty()) + // bed shape detected in the gcode + bed_shape = gcode_result.bed_shape; + else { + // adjust printbed size in dependence of toolpaths bbox + const double margin = 10.0; + Vec2d min(m_paths_bounding_box.min(0) - margin, m_paths_bounding_box.min(1) - margin); + Vec2d max(m_paths_bounding_box.max(0) + margin, m_paths_bounding_box.max(1) + margin); + bed_shape = { { min(0), min(1) }, + { max(0), min(1) }, + { max(0), max(1) }, + { min(0), max(1) } }; + } wxGetApp().plater()->set_bed_shape(bed_shape, "", ""); } #endif // ENABLE_GCODE_VIEWER_AS_STATE From 54a434063167a87b9d57665b604b15914e190630 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 29 Jul 2020 13:05:16 +0200 Subject: [PATCH 166/255] GCodeViewer -> Hexagonal icons as default --- src/slic3r/GUI/GCodeViewer.cpp | 57 +--------------------------------- 1 file changed, 1 insertion(+), 56 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 817e7e650c..fed9a30d57 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1348,8 +1348,6 @@ void GCodeViewer::render_shells() const // glsafe(::glDepthMask(GL_TRUE)); } -#define USE_ICON_HEXAGON 1 - void GCodeViewer::render_legend() const { if (!m_legend_enabled) @@ -1444,11 +1442,7 @@ void GCodeViewer::render_legend() const auto append_range_item = [this, draw_list, &imgui, append_item](int i, float value, unsigned int decimals) { char buf[1024]; ::sprintf(buf, "%.*f", decimals, value); -#if USE_ICON_HEXAGON append_item(EItemType::Hexagon, Range_Colors[i], buf); -#else - append_item(EItemType::Rect, Range_Colors[i], buf); -#endif // USE_ICON_HEXAGON }; float step_size = range.step_size(); @@ -1533,13 +1527,8 @@ void GCodeViewer::render_legend() const if (!visible) ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.3333f); -#if USE_ICON_HEXAGON append_item(EItemType::Hexagon, Extrusion_Role_Colors[static_cast(role)], _u8L(ExtrusionEntity::role_to_string(role)), [this, role]() { -#else - append_item(EItemType::Rect, Extrusion_Role_Colors[static_cast(role)], _u8L(ExtrusionEntity::role_to_string(role)), [this, role]() { -#endif // USE_ICON_HEXAGON - if (role < erCount) - { + if (role < erCount) { m_extrusions.role_visibility_flags = is_visible(role) ? m_extrusions.role_visibility_flags & ~(1 << role) : m_extrusions.role_visibility_flags | (1 << role); // update buffers' render paths refresh_render_paths(false, false); @@ -1562,11 +1551,7 @@ void GCodeViewer::render_legend() const { // shows only extruders actually used for (unsigned char i : m_extruder_ids) { -#if USE_ICON_HEXAGON append_item(EItemType::Hexagon, m_tool_colors[i], _u8L("Extruder") + " " + std::to_string(i + 1)); -#else - append_item(EItemType::Rect, m_tool_colors[i], _u8L("Extruder") + " " + std::to_string(i + 1)); -#endif // USE_ICON_HEXAGON } break; } @@ -1578,36 +1563,20 @@ void GCodeViewer::render_legend() const std::vector>> cp_values = color_print_ranges(0, custom_gcode_per_print_z); const int items_cnt = static_cast(cp_values.size()); if (items_cnt == 0) { // There are no color changes, but there are some pause print or custom Gcode -#if USE_ICON_HEXAGON append_item(EItemType::Hexagon, m_tool_colors.front(), _u8L("Default color")); -#else - append_item(EItemType::Rect, m_tool_colors.front(), _u8L("Default color")); -#endif // USE_ICON_HEXAGON } else { for (int i = items_cnt; i >= 0; --i) { // create label for color change item if (i == 0) { -#if USE_ICON_HEXAGON append_item(EItemType::Hexagon, m_tool_colors[0], upto_label(cp_values.front().second.first)); -#else - append_item(EItemType::Rect, m_tool_colors[0], upto_label(cp_values.front().second.first); -#endif // USE_ICON_HEXAGON break; } else if (i == items_cnt) { -#if USE_ICON_HEXAGON append_item(EItemType::Hexagon, cp_values[i - 1].first, above_label(cp_values[i - 1].second.second)); -#else - append_item(EItemType::Rect, cp_values[i - 1].first, above_label(cp_values[i - 1].second.second); -#endif // USE_ICON_HEXAGON continue; } -#if USE_ICON_HEXAGON append_item(EItemType::Hexagon, cp_values[i - 1].first, fromto_label(cp_values[i - 1].second.second, cp_values[i].second.first)); -#else - append_item(EItemType::Rect, cp_values[i - 1].first, fromto_label(cp_values[i - 1].second.second, cp_values[i].second.first)); -#endif // USE_ICON_HEXAGON } } } @@ -1618,11 +1587,7 @@ void GCodeViewer::render_legend() const std::vector>> cp_values = color_print_ranges(i, custom_gcode_per_print_z); const int items_cnt = static_cast(cp_values.size()); if (items_cnt == 0) { // There are no color changes, but there are some pause print or custom Gcode -#if USE_ICON_HEXAGON append_item(EItemType::Hexagon, m_tool_colors[i], _u8L("Extruder") + " " + std::to_string(i + 1) + " " + _u8L("default color")); -#else - append_item(EItemType::Rect, m_tool_colors[i], _u8L("Extruder") + " " + std::to_string(i + 1) + " " + _u8L("default color")); -#endif // USE_ICON_HEXAGON } else { for (int j = items_cnt; j >= 0; --j) { @@ -1630,29 +1595,17 @@ void GCodeViewer::render_legend() const std::string label = _u8L("Extruder") + " " + std::to_string(i + 1); if (j == 0) { label += " " + upto_label(cp_values.front().second.first); -#if USE_ICON_HEXAGON append_item(EItemType::Hexagon, m_tool_colors[i], label); -#else - append_item(EItemType::Rect, m_tool_colors[i], label); -#endif // USE_ICON_HEXAGON break; } else if (j == items_cnt) { label += " " + above_label(cp_values[j - 1].second.second); -#if USE_ICON_HEXAGON append_item(EItemType::Hexagon, cp_values[j - 1].first, label); -#else - append_item(EItemType::Rect, cp_values[j - 1].first, label); -#endif // USE_ICON_HEXAGON continue; } label += " " + fromto_label(cp_values[j - 1].second.second, cp_values[j].second.first); -#if USE_ICON_HEXAGON append_item(EItemType::Hexagon, cp_values[j - 1].first, label); -#else - append_item(EItemType::Rect, cp_values[j - 1].first, label); -#endif // USE_ICON_HEXAGON } } } @@ -1826,18 +1779,10 @@ void GCodeViewer::render_time_estimate() const ImDrawList* draw_list = ImGui::GetWindowDrawList(); ImVec2 pos = ImGui::GetCursorScreenPos(); pos.x -= 0.5f * ImGui::GetStyle().ItemSpacing.x; -#if USE_ICON_HEXAGON ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size)); draw_list->AddNgonFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color1[0], color1[1], color1[2], 1.0f }), 6); center.x += icon_size; draw_list->AddNgonFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color2[0], color2[1], color2[2], 1.0f }), 6); -#else - draw_list->AddRectFilled({ pos.x + 1.0f, pos.y + 1.0f }, { pos.x + icon_size - 1.0f, pos.y + icon_size - 1.0f }, - ImGui::GetColorU32({ color1[0], color1[1], color1[2], 1.0f })); - pos.x += icon_size; - draw_list->AddRectFilled({ pos.x + 1.0f, pos.y + 1.0f }, { pos.x + icon_size - 1.0f, pos.y + icon_size - 1.0f }, - ImGui::GetColorU32({ color2[0], color2[1], color2[2], 1.0f })); -#endif // USE_ICON_HEXAGON ImGui::SameLine(offsets[0]); imgui.text(short_time(get_time_dhms(times.second - times.first))); }; From 0348986bda0e20c26a99a452be5402146303680c Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 29 Jul 2020 14:20:01 +0200 Subject: [PATCH 167/255] Follow-up of 9d4344a78ce56ecf722e946f2c1796a9e1df96e8 -> ensure printbed always rendered as custom in gcode preview mode --- src/libslic3r/GCode/GCodeProcessor.cpp | 1 - src/slic3r/GUI/3DBed.cpp | 41 +++++++++++++++----------- src/slic3r/GUI/3DBed.hpp | 2 +- src/slic3r/GUI/GCodeViewer.cpp | 2 +- src/slic3r/GUI/MainFrame.cpp | 2 +- src/slic3r/GUI/Plater.cpp | 13 ++++---- src/slic3r/GUI/Plater.hpp | 2 +- 7 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index beb340a5da..7a6b1ecb42 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -694,7 +694,6 @@ bool GCodeProcessor::process_producers_tags(const std::string& comment) bool GCodeProcessor::process_prusaslicer_tags(const std::string& comment) { - std::cout << comment << "\n"; return false; } diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index ca075fb372..9d16bead71 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -255,7 +255,7 @@ Bed3D::Bed3D() { } -bool Bed3D::set_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model) +bool Bed3D::set_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom) { auto check_texture = [](const std::string& texture) { return !texture.empty() && (boost::algorithm::iends_with(texture, ".png") || boost::algorithm::iends_with(texture, ".svg")) && boost::filesystem::exists(texture); @@ -265,30 +265,39 @@ bool Bed3D::set_shape(const Pointfs& shape, const std::string& custom_texture, c return !model.empty() && boost::algorithm::iends_with(model, ".stl") && boost::filesystem::exists(model); }; - auto [new_type, system_model, system_texture] = detect_type(shape); + EType type; + std::string model; + std::string texture; + if (force_as_custom) + type = Custom; + else { + auto [new_type, system_model, system_texture] = detect_type(shape); + type = new_type; + model = system_model; + texture = system_texture; + } - std::string texture_filename = custom_texture.empty() ? system_texture : custom_texture; + std::string texture_filename = custom_texture.empty() ? texture : custom_texture; if (!check_texture(texture_filename)) texture_filename.clear(); - std::string model_filename = custom_model.empty() ? system_model : custom_model; + std::string model_filename = custom_model.empty() ? model : custom_model; if (!check_model(model_filename)) model_filename.clear(); - if ((m_shape == shape) && (m_type == new_type) && (m_texture_filename == texture_filename) && (m_model_filename == model_filename)) + if (m_shape == shape && m_type == type && m_texture_filename == texture_filename && m_model_filename == model_filename) // No change, no need to update the UI. return false; m_shape = shape; m_texture_filename = texture_filename; m_model_filename = model_filename; - m_type = new_type; + m_type = type; calc_bounding_boxes(); ExPolygon poly; - for (const Vec2d& p : m_shape) - { + for (const Vec2d& p : m_shape) { poly.contour.append(Point(scale_(p(0)), scale_(p(1)))); } @@ -435,19 +444,15 @@ static std::string system_print_bed_texture(const Preset &preset) std::tuple Bed3D::detect_type(const Pointfs& shape) const { auto bundle = wxGetApp().preset_bundle; - if (bundle != nullptr) - { + if (bundle != nullptr) { const Preset* curr = &bundle->printers.get_selected_preset(); - while (curr != nullptr) - { - if (curr->config.has("bed_shape")) - { - if (shape == dynamic_cast(curr->config.option("bed_shape"))->values) - { + while (curr != nullptr) { + if (curr->config.has("bed_shape")) { + if (shape == dynamic_cast(curr->config.option("bed_shape"))->values) { std::string model_filename = system_print_bed_model(*curr); std::string texture_filename = system_print_bed_texture(*curr); if (!model_filename.empty() && !texture_filename.empty()) - return std::make_tuple(System, model_filename, texture_filename); + return { System, model_filename, texture_filename }; } } @@ -455,7 +460,7 @@ std::tuple Bed3D::detect_type(const Poin } } - return std::make_tuple(Custom, "", ""); + return { Custom, "", "" }; } void Bed3D::render_axes() const diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp index b9e952c4a4..fbfc3078c1 100644 --- a/src/slic3r/GUI/3DBed.hpp +++ b/src/slic3r/GUI/3DBed.hpp @@ -144,7 +144,7 @@ public: const Pointfs& get_shape() const { return m_shape; } // Return true if the bed shape changed, so the calee will update the UI. - bool set_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model); + bool set_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false); const BoundingBoxf3& get_bounding_box(bool extended) const { return extended ? m_extended_bounding_box : m_bounding_box; diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index fed9a30d57..af3d8d901c 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -337,7 +337,7 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& { max(0), max(1) }, { min(0), max(1) } }; } - wxGetApp().plater()->set_bed_shape(bed_shape, "", ""); + wxGetApp().plater()->set_bed_shape(bed_shape, "", "", true); } #endif // ENABLE_GCODE_VIEWER_AS_STATE } diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index c43563c8bf..0d527f48b3 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -1490,7 +1490,7 @@ void MainFrame::set_mode(EMode mode) m_plater->select_view("iso"); // switch printbed - m_plater->set_bed_shape({ { 0.0, 0.0 }, { 200.0, 0.0 }, { 200.0, 200.0 }, { 0.0, 200.0 } }, "", ""); + m_plater->set_bed_shape({ { 0.0, 0.0 }, { 200.0, 0.0 }, { 200.0, 200.0 }, { 0.0, 200.0 } }, "", "", true); // switch menubar SetMenuBar(m_gcodeviewer_menubar); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 193ac8e0c1..43cf27e30f 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1867,7 +1867,7 @@ struct Plater::priv // triangulate the bed and store the triangles into m_bed.m_triangles, // fills the m_bed.m_grid_lines and sets m_bed.m_origin. // Sets m_bed.m_polygon to limit the object placement. - void set_bed_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model); + void set_bed_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false); bool can_delete() const; bool can_delete_all() const; @@ -4182,11 +4182,10 @@ bool Plater::priv::can_reload_from_disk() const return !paths.empty(); } -void Plater::priv::set_bed_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model) +void Plater::priv::set_bed_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom) { - bool new_shape = bed.set_shape(shape, custom_texture, custom_model); - if (new_shape) - { + bool new_shape = bed.set_shape(shape, custom_texture, custom_model, force_as_custom); + if (new_shape) { if (view3D) view3D->bed_shape_changed(); if (preview) preview->bed_shape_changed(); } @@ -5456,9 +5455,9 @@ void Plater::set_bed_shape() const } #if ENABLE_GCODE_VIEWER_AS_STATE -void Plater::set_bed_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model) const +void Plater::set_bed_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom) const { - p->set_bed_shape(shape, custom_texture, custom_model); + p->set_bed_shape(shape, custom_texture, custom_model, force_as_custom); } #endif // ENABLE_GCODE_VIEWER_AS_STATE diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 085ed0e69c..59d595bbe4 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -363,7 +363,7 @@ public: void set_bed_shape() const; #if ENABLE_GCODE_VIEWER_AS_STATE - void set_bed_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model) const; + void set_bed_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false) const; #endif // ENABLE_GCODE_VIEWER_AS_STATE // ROII wrapper for suppressing the Undo / Redo snapshot to be taken. From 39d08441cc4bf103bfc240e8609935aded72ffa7 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 29 Jul 2020 15:40:28 +0200 Subject: [PATCH 168/255] ENABLE_GCODE_VIEWER_AS_STATE -> Fixed collapse toolbar showing-up when presing [T] in gcode preview mode --- src/slic3r/GUI/GLCanvas3D.cpp | 5 +++++ src/slic3r/GUI/GLToolbar.cpp | 13 +------------ src/slic3r/GUI/GLToolbar.hpp | 4 ++-- src/slic3r/GUI/MainFrame.cpp | 6 +++++- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 2c13c752e6..175eecd8bd 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4295,8 +4295,13 @@ void GLCanvas3D::update_ui_from_settings() } #endif // ENABLE_RETINA_GL +#if ENABLE_GCODE_VIEWER_AS_STATE + if (wxGetApp().mainframe != nullptr && wxGetApp().mainframe->get_mode() != MainFrame::EMode::GCodeViewer) + wxGetApp().plater()->get_collapse_toolbar().set_enabled(wxGetApp().app_config->get("show_collapse_button") == "1"); +#else bool enable_collapse = wxGetApp().app_config->get("show_collapse_button") == "1"; wxGetApp().plater()->get_collapse_toolbar().set_enabled(enable_collapse); +#endif // ENABLE_GCODE_VIEWER_AS_STATE } diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index 4ab282b066..46371b037a 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -230,24 +230,13 @@ void GLToolbar::set_icons_size(float size) void GLToolbar::set_scale(float scale) { - if (m_layout.scale != scale) - { + if (m_layout.scale != scale) { m_layout.scale = scale; m_layout.dirty = true; m_icons_texture_dirty = true; } } -bool GLToolbar::is_enabled() const -{ - return m_enabled; -} - -void GLToolbar::set_enabled(bool enable) -{ - m_enabled = enable;//true; etFIXME -} - bool GLToolbar::add_item(const GLToolbarItem::Data& data) { GLToolbarItem* item = new GLToolbarItem(GLToolbarItem::Action, data); diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index 41c2735c9a..74e18de975 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -276,8 +276,8 @@ public: void set_icons_size(float size); void set_scale(float scale); - bool is_enabled() const; - void set_enabled(bool enable); + bool is_enabled() const { return m_enabled; } + void set_enabled(bool enable) { m_enabled = enable; } bool add_item(const GLToolbarItem::Data& data); bool add_separator(); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 0d527f48b3..7d6acad069 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -279,8 +279,12 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S update_ui_from_settings(); // FIXME (?) - if (m_plater != nullptr) + if (m_plater != nullptr) { +#if ENABLE_GCODE_VIEWER_AS_STATE + m_plater->get_collapse_toolbar().set_enabled(wxGetApp().app_config->get("show_collapse_button") == "1"); +#endif // ENABLE_GCODE_VIEWER_AS_STATE m_plater->show_action_buttons(true); + } } #if ENABLE_LAYOUT_NO_RESTART From 534e8bb909a7533020256104b220e93842e8ad02 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 30 Jul 2020 13:49:57 +0200 Subject: [PATCH 169/255] ENABLE_GCODE_VIEWER -> Export to gcode layer z and layer height at each layer change --- src/libslic3r/GCode.cpp | 42 +++++++++++++++++--------- src/libslic3r/GCode.hpp | 12 +++----- src/libslic3r/GCode/GCodeProcessor.cpp | 2 +- 3 files changed, 34 insertions(+), 22 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index ced52207d0..2dea4fb22b 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1180,6 +1180,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu #if ENABLE_GCODE_VIEWER m_last_width = 0.0f; m_last_height = 0.0f; + m_last_layer_z = 0.0f; #else m_last_mm3_per_mm = GCodeAnalyzer::Default_mm3_per_mm; m_last_width = GCodeAnalyzer::Default_Width; @@ -2067,6 +2068,20 @@ void GCode::process_layer( std::string gcode; +#if ENABLE_GCODE_VIEWER + // export layer z + char buf[64]; + sprintf(buf, ";Z%g\n", print_z); + gcode += buf; + // export layer height + float height = first_layer ? static_cast(print_z) : static_cast(print_z) - m_last_layer_z; + sprintf(buf, ";%s%g\n", GCodeProcessor::Height_Tag.c_str(), height); + gcode += buf; + // update caches + m_last_layer_z = static_cast(print_z); + m_last_height = height; +#endif // ENABLE_GCODE_VIEWER + // Set new layer - this will change Z and force a retraction if retract_layer_change is enabled. if (! print.config().before_layer_gcode.value.empty()) { DynamicConfig config; @@ -3207,7 +3222,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } } - // adds analyzer tags and updates analyzer's tracking data + // adds processor tags and updates processor tracking data #if !ENABLE_GCODE_VIEWER if (m_enable_analyzer) { #endif // !ENABLE_GCODE_VIEWER @@ -3234,40 +3249,39 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), int(m_last_analyzer_extrusion_role)); gcode += buf; } -#endif // ENABLE_GCODE_VIEWER -#if !ENABLE_GCODE_VIEWER if (last_was_wipe_tower || (m_last_mm3_per_mm != path.mm3_per_mm)) { m_last_mm3_per_mm = path.mm3_per_mm; sprintf(buf, ";%s%f\n", GCodeAnalyzer::Mm3_Per_Mm_Tag.c_str(), m_last_mm3_per_mm); gcode += buf; } -#endif // !ENABLE_GCODE_VIEWER +#endif // ENABLE_GCODE_VIEWER - if (last_was_wipe_tower || (m_last_width != path.width)) { + if (last_was_wipe_tower || m_last_width != path.width) { m_last_width = path.width; #if ENABLE_GCODE_VIEWER - sprintf(buf, ";%s%f\n", GCodeProcessor::Width_Tag.c_str(), m_last_width); - gcode += buf; + sprintf(buf, ";%s%g\n", GCodeProcessor::Width_Tag.c_str(), m_last_width); #else sprintf(buf, ";%s%f\n", GCodeAnalyzer::Width_Tag.c_str(), m_last_width); - gcode += buf; #endif // ENABLE_GCODE_VIEWER + gcode += buf; } - if (last_was_wipe_tower || (m_last_height != path.height)) { - m_last_height = path.height; + #if ENABLE_GCODE_VIEWER - sprintf(buf, ";%s%f\n", GCodeProcessor::Height_Tag.c_str(), m_last_height); + if (last_was_wipe_tower || std::abs(m_last_height - path.height) > EPSILON) { + m_last_height = path.height; + sprintf(buf, ";%s%g\n", GCodeProcessor::Height_Tag.c_str(), m_last_height); gcode += buf; + } #else + if (last_was_wipe_tower || m_last_height != path.height) { + m_last_height = path.height; sprintf(buf, ";%s%f\n", GCodeAnalyzer::Height_Tag.c_str(), m_last_height); gcode += buf; -#endif // ENABLE_GCODE_VIEWER } -#if !ENABLE_GCODE_VIEWER } -#endif // !ENABLE_GCODE_VIEWER +#endif // ENABLE_GCODE_VIEWER std::string comment; if (m_enable_cooling_markers) { diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 443c25bb2f..69f98bfa52 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -172,14 +172,11 @@ public: m_volumetric_speed(0), m_last_pos_defined(false), m_last_extrusion_role(erNone), -#if ENABLE_GCODE_VIEWER - m_last_width(0.0f), - m_last_height(0.0f), -#else +#if !ENABLE_GCODE_VIEWER m_last_mm3_per_mm(GCodeAnalyzer::Default_mm3_per_mm), m_last_width(GCodeAnalyzer::Default_Width), m_last_height(GCodeAnalyzer::Default_Height), -#endif // ENABLE_GCODE_VIEWER +#endif // !ENABLE_GCODE_VIEWER m_brim_done(false), m_second_layer_things_done(false), m_normal_time_estimator(GCodeTimeEstimator::Normal), @@ -379,8 +376,9 @@ private: ExtrusionRole m_last_extrusion_role; #if ENABLE_GCODE_VIEWER // Support for G-Code Processor - float m_last_width; - float m_last_height; + float m_last_width{ 0.0f }; + float m_last_height{ 0.0f }; + float m_last_layer_z{ 0.0f }; #else // Support for G-Code Analyzer double m_last_mm3_per_mm; diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 7a6b1ecb42..c10552482d 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -23,7 +23,7 @@ namespace Slic3r { const std::string GCodeProcessor::Extrusion_Role_Tag = "ExtrType:"; const std::string GCodeProcessor::Width_Tag = "PrusaSlicer__WIDTH:"; -const std::string GCodeProcessor::Height_Tag = "PrusaSlicer__HEIGHT:"; +const std::string GCodeProcessor::Height_Tag = "Height:"; const std::string GCodeProcessor::Color_Change_Tag = "COLOR_CHANGE"; const std::string GCodeProcessor::Pause_Print_Tag = "PAUSE_PRINT"; const std::string GCodeProcessor::Custom_Code_Tag = "CUSTOM_CODE"; From 2dee3abea033e57fe79fd986799726b38ac80483 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 30 Jul 2020 14:15:00 +0200 Subject: [PATCH 170/255] Revert titles in legend dialog to previous format --- src/slic3r/GUI/ImGuiWrapper.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 00d69b4ccb..6aef521667 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -762,16 +762,10 @@ void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, co void ImGuiWrapper::title(const std::string& str) { - ImGuiWindow* window = ImGui::GetCurrentWindow(); - - ImRect frame_bb; - frame_bb.Min = { window->WorkRect.Min.x, window->DC.CursorPos.y }; - frame_bb.Max = { window->WorkRect.Max.x, window->DC.CursorPos.y + ImGui::CalcTextSize(str.c_str(), nullptr, false).y }; - frame_bb.Min.x -= IM_FLOOR(window->WindowPadding.x * 0.5f - 1.0f); - frame_bb.Max.x += IM_FLOOR(window->WindowPadding.x * 0.5f); - - window->DrawList->AddRectFilled(frame_bb.Min, frame_bb.Max, ImGui::GetColorU32(COL_ORANGE_DARK), 0.0f, 0); + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); text(str); + ImGui::PopStyleColor(); + ImGui::Separator(); } void ImGuiWrapper::disabled_begin(bool disabled) From 1532920d81411f07ecb80edf6dbb6396fce73fab Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 3 Aug 2020 08:46:32 +0200 Subject: [PATCH 171/255] GCodeProcessor -> Extended import of config data from gcode saved by PrusaSlicer --- src/libslic3r/GCode/GCodeProcessor.cpp | 207 ++++++++++++++++++++++--- src/libslic3r/GCode/GCodeProcessor.hpp | 8 +- src/slic3r/GUI/GCodeViewer.cpp | 17 +- src/slic3r/GUI/KBShortcutsDialog.cpp | 6 + 4 files changed, 205 insertions(+), 33 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index c10552482d..f3e07da881 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -24,9 +24,9 @@ namespace Slic3r { const std::string GCodeProcessor::Extrusion_Role_Tag = "ExtrType:"; const std::string GCodeProcessor::Width_Tag = "PrusaSlicer__WIDTH:"; const std::string GCodeProcessor::Height_Tag = "Height:"; -const std::string GCodeProcessor::Color_Change_Tag = "COLOR_CHANGE"; -const std::string GCodeProcessor::Pause_Print_Tag = "PAUSE_PRINT"; -const std::string GCodeProcessor::Custom_Code_Tag = "CUSTOM_CODE"; +const std::string GCodeProcessor::Color_Change_Tag = "Color change"; +const std::string GCodeProcessor::Pause_Print_Tag = "Pause print"; +const std::string GCodeProcessor::Custom_Code_Tag = "Custom gcode"; static bool is_valid_extrusion_role(int value) { @@ -297,7 +297,7 @@ void GCodeProcessor::TimeProcessor::reset() const std::vector> GCodeProcessor::Producers = { { EProducer::PrusaSlicer, "PrusaSlicer" }, - { EProducer::Cura, "Cura" }, + { EProducer::Cura, "Cura_SteamEngine" }, { EProducer::Simplify3D, "Simplify3D" }, { EProducer::CraftWare, "CraftWare" }, { EProducer::ideaMaker, "ideaMaker" } @@ -314,32 +314,34 @@ void GCodeProcessor::apply_config(const PrintConfig& config) size_t extruders_count = config.nozzle_diameter.values.size(); m_extruder_offsets.resize(extruders_count); - for (size_t id = 0; id < extruders_count; ++id) { - Vec2f offset = config.extruder_offset.get_at(id).cast(); - m_extruder_offsets[id] = Vec3f(offset(0), offset(1), 0.0f); + for (size_t i = 0; i < extruders_count; ++i) { + Vec2f offset = config.extruder_offset.get_at(i).cast(); + m_extruder_offsets[i] = { offset(0), offset(1), 0.0f }; } - m_extruders_color.resize(extruders_count); - for (size_t id = 0; id < extruders_count; ++id) { - m_extruders_color[id] = static_cast(id); + m_extruder_colors.resize(extruders_count); + for (size_t i = 0; i < extruders_count; ++i) { + m_extruder_colors[i] = static_cast(i); } - for (double diam : config.filament_diameter.values) { - m_filament_diameters.push_back(static_cast(diam)); + m_filament_diameters.resize(config.filament_diameter.values.size()); + for (size_t i = 0; i < config.filament_diameter.values.size(); ++i) { + m_filament_diameters[i] = static_cast(config.filament_diameter.values[i]); } m_time_processor.machine_limits = reinterpret_cast(config); // Filament load / unload times are not specific to a firmware flavor. Let anybody use it if they find it useful. // As of now the fields are shown at the UI dialog in the same combo box as the ramming values, so they // are considered to be active for the single extruder multi-material printers only. - m_time_processor.filament_load_times.clear(); - for (double d : config.filament_load_time.values) { - m_time_processor.filament_load_times.push_back(static_cast(d)); + m_time_processor.filament_load_times.resize(config.filament_load_time.values.size()); + for (size_t i = 0; i < config.filament_load_time.values.size(); ++i) { + m_time_processor.filament_load_times[i] = static_cast(config.filament_load_time.values[i]); } - m_time_processor.filament_unload_times.clear(); - for (double d : config.filament_unload_time.values) { - m_time_processor.filament_unload_times.push_back(static_cast(d)); + m_time_processor.filament_unload_times.resize(config.filament_unload_time.values.size()); + for (size_t i = 0; i < config.filament_unload_time.values.size(); ++i) { + m_time_processor.filament_unload_times[i] = static_cast(config.filament_unload_time.values[i]); } + for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { float max_acceleration = get_option_value(m_time_processor.machine_limits.machine_max_acceleration_extruding, i); m_time_processor.machines[i].acceleration = (max_acceleration > 0.0f) ? max_acceleration : DEFAULT_ACCELERATION; @@ -350,6 +352,14 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config) { m_parser.apply_config(config); + const ConfigOptionEnum* gcode_flavor = config.option>("gcode_flavor"); + if (gcode_flavor != nullptr) + m_flavor = gcode_flavor->value; + + const ConfigOptionPoints* bed_shape = config.option("bed_shape"); + if (bed_shape != nullptr) + m_result.bed_shape = bed_shape->values; + const ConfigOptionFloats* filament_diameters = config.option("filament_diameter"); if (filament_diameters != nullptr) { for (double diam : filament_diameters->values) { @@ -357,9 +367,127 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config) } } - const ConfigOptionPoints* bed_shape = config.option("bed_shape"); - if (bed_shape != nullptr) - m_result.bed_shape = bed_shape->values; + const ConfigOptionPoints* extruder_offset = config.option("extruder_offset"); + if (extruder_offset != nullptr) { + m_extruder_offsets.resize(extruder_offset->values.size()); + for (size_t i = 0; i < extruder_offset->values.size(); ++i) { + Vec2f offset = extruder_offset->values[i].cast(); + m_extruder_offsets[i] = { offset(0), offset(1), 0.0f }; + } + } + + // ensure at least one (default) color is defined + std::string default_color = "#FF8000"; + m_result.extruder_colors = std::vector(1, default_color); + const ConfigOptionStrings* extruder_colour = config.option("extruder_colour"); + if (extruder_colour != nullptr) { + // takes colors from config + m_result.extruder_colors = extruder_colour->values; + // try to replace missing values with filament colors + const ConfigOptionStrings* filament_colour = config.option("filament_colour"); + if (filament_colour != nullptr && filament_colour->values.size() == m_result.extruder_colors.size()) { + for (size_t i = 0; i < m_result.extruder_colors.size(); ++i) { + if (m_result.extruder_colors[i].empty()) + m_result.extruder_colors[i] = filament_colour->values[i]; + } + } + } + + // replace missing values with default + for (size_t i = 0; i < m_result.extruder_colors.size(); ++i) { + if (m_result.extruder_colors[i].empty()) + m_result.extruder_colors[i] = default_color; + } + + m_extruder_colors.resize(m_result.extruder_colors.size()); + for (size_t i = 0; i < m_result.extruder_colors.size(); ++i) { + m_extruder_colors[i] = static_cast(i); + } + + const ConfigOptionFloats* filament_load_time = config.option("filament_load_time"); + if (filament_load_time != nullptr) { + m_time_processor.filament_load_times.resize(filament_load_time->values.size()); + for (size_t i = 0; i < filament_load_time->values.size(); ++i) { + m_time_processor.filament_load_times[i] = static_cast(filament_load_time->values[i]); + } + } + + const ConfigOptionFloats* filament_unload_time = config.option("filament_unload_time"); + if (filament_unload_time != nullptr) { + m_time_processor.filament_unload_times.resize(filament_unload_time->values.size()); + for (size_t i = 0; i < filament_unload_time->values.size(); ++i) { + m_time_processor.filament_unload_times[i] = static_cast(filament_unload_time->values[i]); + } + } + + const ConfigOptionFloats* machine_max_acceleration_x = config.option("machine_max_acceleration_x"); + if (machine_max_acceleration_x != nullptr) + m_time_processor.machine_limits.machine_max_acceleration_x.values = machine_max_acceleration_x->values; + + const ConfigOptionFloats* machine_max_acceleration_y = config.option("machine_max_acceleration_y"); + if (machine_max_acceleration_y != nullptr) + m_time_processor.machine_limits.machine_max_acceleration_y.values = machine_max_acceleration_y->values; + + const ConfigOptionFloats* machine_max_acceleration_z = config.option("machine_max_acceleration_z"); + if (machine_max_acceleration_z != nullptr) + m_time_processor.machine_limits.machine_max_acceleration_z.values = machine_max_acceleration_z->values; + + const ConfigOptionFloats* machine_max_acceleration_e = config.option("machine_max_acceleration_e"); + if (machine_max_acceleration_e != nullptr) + m_time_processor.machine_limits.machine_max_acceleration_e.values = machine_max_acceleration_e->values; + + const ConfigOptionFloats* machine_max_feedrate_x = config.option("machine_max_feedrate_x"); + if (machine_max_feedrate_x != nullptr) + m_time_processor.machine_limits.machine_max_feedrate_x.values = machine_max_feedrate_x->values; + + const ConfigOptionFloats* machine_max_feedrate_y = config.option("machine_max_feedrate_y"); + if (machine_max_feedrate_y != nullptr) + m_time_processor.machine_limits.machine_max_feedrate_y.values = machine_max_feedrate_y->values; + + const ConfigOptionFloats* machine_max_feedrate_z = config.option("machine_max_feedrate_z"); + if (machine_max_feedrate_z != nullptr) + m_time_processor.machine_limits.machine_max_feedrate_z.values = machine_max_feedrate_z->values; + + const ConfigOptionFloats* machine_max_feedrate_e = config.option("machine_max_feedrate_e"); + if (machine_max_feedrate_e != nullptr) + m_time_processor.machine_limits.machine_max_feedrate_e.values = machine_max_feedrate_e->values; + + const ConfigOptionFloats* machine_max_jerk_x = config.option("machine_max_jerk_x"); + if (machine_max_jerk_x != nullptr) + m_time_processor.machine_limits.machine_max_jerk_x.values = machine_max_jerk_x->values; + + const ConfigOptionFloats* machine_max_jerk_y = config.option("machine_max_jerk_y"); + if (machine_max_jerk_y != nullptr) + m_time_processor.machine_limits.machine_max_jerk_y.values = machine_max_jerk_y->values; + + const ConfigOptionFloats* machine_max_jerk_z = config.option("machine_max_jerkz"); + if (machine_max_jerk_z != nullptr) + m_time_processor.machine_limits.machine_max_jerk_z.values = machine_max_jerk_z->values; + + const ConfigOptionFloats* machine_max_jerk_e = config.option("machine_max_jerk_e"); + if (machine_max_jerk_e != nullptr) + m_time_processor.machine_limits.machine_max_jerk_e.values = machine_max_jerk_e->values; + + const ConfigOptionFloats* machine_max_acceleration_extruding = config.option("machine_max_acceleration_extruding"); + if (machine_max_acceleration_extruding != nullptr) + m_time_processor.machine_limits.machine_max_acceleration_extruding.values = machine_max_acceleration_extruding->values; + + const ConfigOptionFloats* machine_max_acceleration_retracting = config.option("machine_max_acceleration_retracting"); + if (machine_max_acceleration_retracting != nullptr) + m_time_processor.machine_limits.machine_max_acceleration_retracting.values = machine_max_acceleration_retracting->values; + + const ConfigOptionFloats* machine_min_extruding_rate = config.option("machine_min_extruding_rate"); + if (machine_min_extruding_rate != nullptr) + m_time_processor.machine_limits.machine_min_extruding_rate.values = machine_min_extruding_rate->values; + + const ConfigOptionFloats* machine_min_travel_rate = config.option("machine_min_travel_rate"); + if (machine_min_travel_rate != nullptr) + m_time_processor.machine_limits.machine_min_travel_rate.values = machine_min_travel_rate->values; + + for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + float max_acceleration = get_option_value(m_time_processor.machine_limits.machine_max_acceleration_extruding, i); + m_time_processor.machines[i].acceleration = (max_acceleration > 0.0f) ? max_acceleration : DEFAULT_ACCELERATION; + } } void GCodeProcessor::enable_stealth_time_estimator(bool enabled) @@ -388,7 +516,7 @@ void GCodeProcessor::reset() m_extrusion_role = erNone; m_extruder_id = 0; - m_extruders_color = ExtrudersColor(); + m_extruder_colors = ExtruderColors(); m_filament_diameters = std::vector(); m_cp_color.reset(); @@ -643,13 +771,13 @@ void GCodeProcessor::process_tags(const std::string& comment) { unsigned char extruder_id = (pos == comment.npos) ? 0 : static_cast(std::stoi(comment.substr(pos + 1))); - m_extruders_color[extruder_id] = static_cast(m_extruder_offsets.size()) + m_cp_color.counter; // color_change position in list of color for preview + m_extruder_colors[extruder_id] = static_cast(m_extruder_offsets.size()) + m_cp_color.counter; // color_change position in list of color for preview ++m_cp_color.counter; if (m_cp_color.counter == UCHAR_MAX) m_cp_color.counter = 0; if (m_extruder_id == extruder_id) { - m_cp_color.current = m_extruders_color[extruder_id]; + m_cp_color.current = m_extruder_colors[extruder_id]; store_move_vertex(EMoveType::Color_change); } @@ -728,6 +856,35 @@ bool GCodeProcessor::process_cura_tags(const std::string& comment) return true; } + // flavor + tag = "FLAVOR:"; + pos = comment.find(tag); + if (pos != comment.npos) { + std::string flavor = comment.substr(pos + tag.length()); + if (flavor == "BFB") + m_flavor = gcfMarlin; // << ??????????????????????? + else if (flavor == "Mach3") + m_flavor = gcfMach3; + else if (flavor == "Makerbot") + m_flavor = gcfMakerWare; + else if (flavor == "UltiGCode") + m_flavor = gcfMarlin; // << ??????????????????????? + else if (flavor == "Marlin(Volumetric)") + m_flavor = gcfMarlin; // << ??????????????????????? + else if (flavor == "Griffin") + m_flavor = gcfMarlin; // << ??????????????????????? + else if (flavor == "Repetier") + m_flavor = gcfRepetier; + else if (flavor == "RepRap") + m_flavor = gcfRepRap; + else if (flavor == "Marlin") + m_flavor = gcfMarlin; + else + BOOST_LOG_TRIVIAL(warning) << "GCodeProcessor found unknown flavor: " << flavor; + + return true; + } + return false; } @@ -1582,7 +1739,7 @@ void GCodeProcessor::process_T(const std::string& command) else { unsigned char old_extruder_id = m_extruder_id; m_extruder_id = id; - m_cp_color.current = m_extruders_color[id]; + m_cp_color.current = m_extruder_colors[id]; // Specific to the MK3 MMU2: // The initial value of extruder_unloaded is set to true indicating // that the filament is parked in the MMU2 unit and there is nothing to be unloaded yet. diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 1def93e74b..bad04100ef 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -10,6 +10,7 @@ #include #include +#include namespace Slic3r { @@ -27,7 +28,7 @@ namespace Slic3r { private: using AxisCoords = std::array; - using ExtrudersColor = std::vector; + using ExtruderColors = std::vector; enum class EUnits : unsigned char { @@ -212,6 +213,7 @@ namespace Slic3r { std::vector moves; #if ENABLE_GCODE_VIEWER_AS_STATE Pointfs bed_shape; + std::vector extruder_colors; #endif // ENABLE_GCODE_VIEWER_AS_STATE #if ENABLE_GCODE_VIEWER_STATISTICS long long time{ 0 }; @@ -221,6 +223,7 @@ namespace Slic3r { moves = std::vector(); #if ENABLE_GCODE_VIEWER_AS_STATE bed_shape = Pointfs(); + extruder_colors = std::vector(); #endif // ENABLE_GCODE_VIEWER_AS_STATE } #else @@ -229,6 +232,7 @@ namespace Slic3r { moves = std::vector(); #if ENABLE_GCODE_VIEWER_AS_STATE bed_shape = Pointfs(); + extruder_colors = std::vector(); #endif // ENABLE_GCODE_VIEWER_AS_STATE } #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -255,7 +259,7 @@ namespace Slic3r { float m_fan_speed; // percentage ExtrusionRole m_extrusion_role; unsigned char m_extruder_id; - ExtrudersColor m_extruders_color; + ExtruderColors m_extruder_colors; std::vector m_filament_diameters; CpColor m_cp_color; diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index af3d8d901c..8d4fb6f4cb 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -43,13 +43,13 @@ static GCodeProcessor::EMoveType buffer_type(unsigned char id) { std::array decode_color(const std::string& color) { static const float INV_255 = 1.0f / 255.0f; - std::array ret; + std::array ret = { 0.0f, 0.0f, 0.0f }; const char* c = color.data() + 1; - if ((color.size() == 7) && (color.front() == '#')) { + if (color.size() == 7 && color.front() == '#') { for (size_t j = 0; j < 3; ++j) { int digit1 = hex_digit_to_int(*c++); int digit2 = hex_digit_to_int(*c++); - if ((digit1 == -1) || (digit2 == -1)) + if (digit1 == -1 || digit2 == -1) break; ret[j] = float(digit1 * 16 + digit2) * INV_255; @@ -351,8 +351,14 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: if (m_vertices_count == 0) return; - // update tool colors - m_tool_colors = decode_colors(str_tool_colors); +#if ENABLE_GCODE_VIEWER_AS_STATE + if (m_view_type == EViewType::Tool && !gcode_result.extruder_colors.empty()) + // update tool colors from config stored in the gcode + m_tool_colors = decode_colors(gcode_result.extruder_colors); + else +#endif // ENABLE_GCODE_VIEWER_AS_STATE + // update tool colors + m_tool_colors = decode_colors(str_tool_colors); // update ranges for coloring / legend m_extrusions.reset_ranges(); @@ -1708,7 +1714,6 @@ void GCodeViewer::render_time_estimate() const } #endif // ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG - using Times = std::pair; using TimesList = std::vector>; using Headers = std::vector; diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index 66e5ac4878..fc6bc98914 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -204,7 +204,13 @@ void KBShortcutsDialog::fill_shortcuts() { "U", L("Upper Layer") }, { "D", L("Lower Layer") }, { "L", L("Show/Hide Legend") }, +#if ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG + { "T", L("Show Estimated printing time") } +#else { "T", L("Show/Hide Estimated printing time") } +#endif // ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG +#endif // ENABLE_GCODE_VIEWER }; m_full_shortcuts.push_back(std::make_pair(_L("Preview"), preview_shortcuts)); From 5249b3e018f84d232a578e4992844da3ce1ba6fc Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 3 Aug 2020 13:57:10 +0200 Subject: [PATCH 172/255] ENABLE_GCODE_VIEWER -> Estimated print time statistics moved from PrintStatistics to GCodeProcessor --- src/libslic3r/GCode.cpp | 5 +- src/libslic3r/GCode/GCodeProcessor.cpp | 41 ++- src/libslic3r/GCode/GCodeProcessor.hpp | 68 +++-- src/libslic3r/Print.hpp | 24 -- src/slic3r/GUI/GCodeViewer.cpp | 334 +++++++++++-------------- src/slic3r/GUI/GCodeViewer.hpp | 9 +- src/slic3r/GUI/MainFrame.cpp | 4 - 7 files changed, 227 insertions(+), 258 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 2dea4fb22b..880572b2bb 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -775,12 +775,9 @@ void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_ } #if ENABLE_GCODE_VIEWER - print->m_print_statistics.clear_time_estimates(); m_processor.process_file(path_tmp); - if (result != nullptr) { + if (result != nullptr) *result = std::move(m_processor.extract_result()); - m_processor.update_print_stats_estimated_times(print->m_print_statistics); - } #endif // ENABLE_GCODE_VIEWER GCodeTimeEstimator::PostProcessData normal_data = m_normal_time_estimator.get_post_process_data(); diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index f3e07da881..5d9644457d 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -570,31 +570,13 @@ void GCodeProcessor::process_file(const std::string& filename) gcode_time.times.push_back({ CustomGCode::ColorChange, gcode_time.cache }); } + update_estimated_times_stats(); + #if ENABLE_GCODE_VIEWER_STATISTICS m_result.time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); #endif // ENABLE_GCODE_VIEWER_STATISTICS } -void GCodeProcessor::update_print_stats_estimated_times(PrintStatistics& print_statistics) -{ - print_statistics.estimated_normal_print_time = get_time(GCodeProcessor::ETimeMode::Normal); - print_statistics.estimated_normal_custom_gcode_print_times = get_custom_gcode_times(GCodeProcessor::ETimeMode::Normal, true); - print_statistics.estimated_normal_moves_times = get_moves_time(GCodeProcessor::ETimeMode::Normal); - print_statistics.estimated_normal_roles_times = get_roles_time(GCodeProcessor::ETimeMode::Normal); - if (m_time_processor.machines[static_cast(GCodeProcessor::ETimeMode::Stealth)].enabled) { - print_statistics.estimated_silent_print_time = get_time(GCodeProcessor::ETimeMode::Stealth); - print_statistics.estimated_silent_custom_gcode_print_times = get_custom_gcode_times(GCodeProcessor::ETimeMode::Stealth, true); - print_statistics.estimated_silent_moves_times = get_moves_time(GCodeProcessor::ETimeMode::Stealth); - print_statistics.estimated_silent_roles_times = get_roles_time(GCodeProcessor::ETimeMode::Stealth); - } - else { - print_statistics.estimated_silent_print_time = 0.0f; - print_statistics.estimated_silent_custom_gcode_print_times.clear(); - print_statistics.estimated_silent_moves_times.clear(); - print_statistics.estimated_silent_roles_times.clear(); - } -} - float GCodeProcessor::get_time(ETimeMode mode) const { return (mode < ETimeMode::Count) ? m_time_processor.machines[static_cast(mode)].time : 0.0f; @@ -620,7 +602,7 @@ std::vector>> GCodeProcesso return ret; } -std::vector> GCodeProcessor::get_moves_time(ETimeMode mode) const +std::vector> GCodeProcessor::get_moves_time(ETimeMode mode) const { std::vector> ret; if (mode < ETimeMode::Count) { @@ -1892,6 +1874,23 @@ void GCodeProcessor::simulate_st_synchronize(float additional_time) } } +void GCodeProcessor::update_estimated_times_stats() +{ + auto update_mode = [this](GCodeProcessor::ETimeMode mode) { + PrintEstimatedTimeStatistics::Mode& data = m_result.time_statistics.modes[static_cast(mode)]; + data.time = get_time(mode); + data.custom_gcode_times = get_custom_gcode_times(mode, true); + data.moves_times = get_moves_time(mode); + data.roles_times = get_roles_time(mode); + }; + + update_mode(GCodeProcessor::ETimeMode::Normal); + if (m_time_processor.machines[static_cast(GCodeProcessor::ETimeMode::Stealth)].enabled) + update_mode(GCodeProcessor::ETimeMode::Stealth); + else + m_result.time_statistics.modes[static_cast(GCodeProcessor::ETimeMode::Stealth)].reset(); +} + } /* namespace Slic3r */ #endif // ENABLE_GCODE_VIEWER diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index bad04100ef..526300e55a 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -14,7 +14,54 @@ namespace Slic3r { - struct PrintStatistics; + enum class EMoveType : unsigned char + { + Noop, + Retract, + Unretract, + Tool_change, + Color_change, + Pause_Print, + Custom_GCode, + Travel, + Extrude, + Count + }; + + struct PrintEstimatedTimeStatistics + { + enum class ETimeMode : unsigned char + { + Normal, + Stealth, + Count + }; + + struct Mode + { + float time; + std::vector>> custom_gcode_times; + std::vector> moves_times; + std::vector> roles_times; + + void reset() { + time = 0.0f; + custom_gcode_times.clear(); + moves_times.clear(); + roles_times.clear(); + } + }; + + std::array(ETimeMode::Count)> modes; + + PrintEstimatedTimeStatistics() { reset(); } + + void reset() { + for (auto m : modes) { + m.reset(); + } + } + }; class GCodeProcessor { @@ -59,20 +106,6 @@ namespace Slic3r { }; public: - enum class EMoveType : unsigned char - { - Noop, - Retract, - Unretract, - Tool_change, - Color_change, - Pause_Print, - Custom_GCode, - Travel, - Extrude, - Count - }; - struct FeedrateProfile { float entry{ 0.0f }; // mm/s @@ -215,6 +248,8 @@ namespace Slic3r { Pointfs bed_shape; std::vector extruder_colors; #endif // ENABLE_GCODE_VIEWER_AS_STATE + PrintEstimatedTimeStatistics time_statistics; + #if ENABLE_GCODE_VIEWER_STATISTICS long long time{ 0 }; void reset() @@ -297,7 +332,6 @@ namespace Slic3r { // Process the gcode contained in the file with the given filename void process_file(const std::string& filename); - void update_print_stats_estimated_times(PrintStatistics& print_statistics); float get_time(ETimeMode mode) const; std::string get_time_dhm(ETimeMode mode) const; std::vector>> get_custom_gcode_times(ETimeMode mode, bool include_remaining) const; @@ -422,6 +456,8 @@ namespace Slic3r { // Simulates firmware st_synchronize() call void simulate_st_synchronize(float additional_time = 0.0f); + + void update_estimated_times_stats(); }; } /* namespace Slic3r */ diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 22af935d3e..62c00aa88d 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -304,22 +304,12 @@ struct PrintStatistics { PrintStatistics() { clear(); } #if ENABLE_GCODE_VIEWER - float estimated_normal_print_time; - float estimated_silent_print_time; #if ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR std::string estimated_normal_print_time_str; std::string estimated_silent_print_time_str; -#endif // ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR - std::vector>> estimated_normal_custom_gcode_print_times; - std::vector>> estimated_silent_custom_gcode_print_times; -#if ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR std::vector>> estimated_normal_custom_gcode_print_times_str; std::vector>> estimated_silent_custom_gcode_print_times_str; #endif // ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR - std::vector> estimated_normal_moves_times; - std::vector> estimated_silent_moves_times; - std::vector> estimated_normal_roles_times; - std::vector> estimated_silent_roles_times; #else std::string estimated_normal_print_time; std::string estimated_silent_print_time; @@ -344,7 +334,6 @@ struct PrintStatistics void clear() { #if ENABLE_GCODE_VIEWER - clear_time_estimates(); #if ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR estimated_normal_print_time_str.clear(); estimated_silent_print_time_str.clear(); @@ -366,19 +355,6 @@ struct PrintStatistics total_wipe_tower_filament = 0.; filament_stats.clear(); } - -#if ENABLE_GCODE_VIEWER - void clear_time_estimates() { - estimated_normal_print_time = 0.0f; - estimated_silent_print_time = 0.0f; - estimated_normal_custom_gcode_print_times.clear(); - estimated_silent_custom_gcode_print_times.clear(); - estimated_normal_moves_times.clear(); - estimated_silent_moves_times.clear(); - estimated_normal_roles_times.clear(); - estimated_silent_roles_times.clear(); - } -#endif //ENABLE_GCODE_VIEWER }; typedef std::vector PrintObjectPtrs; diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 8d4fb6f4cb..4faa0486ff 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -32,12 +32,12 @@ namespace Slic3r { namespace GUI { -static unsigned char buffer_id(GCodeProcessor::EMoveType type) { - return static_cast(type) - static_cast(GCodeProcessor::EMoveType::Retract); +static unsigned char buffer_id(EMoveType type) { + return static_cast(type) - static_cast(EMoveType::Retract); } -static GCodeProcessor::EMoveType buffer_type(unsigned char id) { - return static_cast(static_cast(GCodeProcessor::EMoveType::Retract) + id); +static EMoveType buffer_type(unsigned char id) { + return static_cast(static_cast(EMoveType::Retract) + id); } std::array decode_color(const std::string& color) { @@ -92,19 +92,19 @@ bool GCodeViewer::Path::matches(const GCodeProcessor::MoveVertex& move) const { switch (move.type) { - case GCodeProcessor::EMoveType::Tool_change: - case GCodeProcessor::EMoveType::Color_change: - case GCodeProcessor::EMoveType::Pause_Print: - case GCodeProcessor::EMoveType::Custom_GCode: - case GCodeProcessor::EMoveType::Retract: - case GCodeProcessor::EMoveType::Unretract: - case GCodeProcessor::EMoveType::Extrude: + case EMoveType::Tool_change: + case EMoveType::Color_change: + case EMoveType::Pause_Print: + case EMoveType::Custom_GCode: + case EMoveType::Retract: + case EMoveType::Unretract: + case EMoveType::Extrude: { return type == move.type && role == move.extrusion_role && height == move.height && width == move.width && feedrate == move.feedrate && fan_speed == move.fan_speed && volumetric_rate == move.volumetric_rate() && extruder_id == move.extruder_id && cp_color_id == move.cp_color_id; } - case GCodeProcessor::EMoveType::Travel: + case EMoveType::Travel: { return type == move.type && feedrate == move.feedrate && extruder_id == move.extruder_id && cp_color_id == move.cp_color_id; } @@ -198,9 +198,7 @@ void GCodeViewer::SequentialView::Marker::render() const ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGui::SetNextWindowBgAlpha(0.25f); imgui.begin(std::string("ToolPosition"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(_u8L("Tool position") + ":"); - ImGui::PopStyleColor(); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Tool position") + ":"); ImGui::SameLine(); char buf[1024]; sprintf(buf, "X: %.2f, Y: %.2f, Z: %.2f", m_world_position(0), m_world_position(1), m_world_position(2)); @@ -274,18 +272,18 @@ bool GCodeViewer::init() switch (buffer_type(i)) { default: { break; } - case GCodeProcessor::EMoveType::Tool_change: - case GCodeProcessor::EMoveType::Color_change: - case GCodeProcessor::EMoveType::Pause_Print: - case GCodeProcessor::EMoveType::Custom_GCode: - case GCodeProcessor::EMoveType::Retract: - case GCodeProcessor::EMoveType::Unretract: + case EMoveType::Tool_change: + case EMoveType::Color_change: + case EMoveType::Pause_Print: + case EMoveType::Custom_GCode: + case EMoveType::Retract: + case EMoveType::Unretract: { m_buffers[i].vertices.format = VBuffer::EFormat::Position; break; } - case GCodeProcessor::EMoveType::Extrude: - case GCodeProcessor::EMoveType::Travel: + case EMoveType::Extrude: + case EMoveType::Travel: { m_buffers[i].vertices.format = VBuffer::EFormat::PositionNormal; break; @@ -293,7 +291,7 @@ bool GCodeViewer::init() } } - set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Extrude, true); + set_toolpath_move_type_visible(EMoveType::Extrude, true); m_sequential_view.marker.init(); init_shaders(); @@ -340,6 +338,8 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& wxGetApp().plater()->set_bed_shape(bed_shape, "", "", true); } #endif // ENABLE_GCODE_VIEWER_AS_STATE + + m_time_statistics = gcode_result.time_statistics; } void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors) @@ -371,7 +371,7 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: switch (curr.type) { - case GCodeProcessor::EMoveType::Extrude: + case EMoveType::Extrude: { m_extrusions.ranges.height.update_from(curr.height); m_extrusions.ranges.width.update_from(curr.width); @@ -379,7 +379,7 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: m_extrusions.ranges.volumetric_rate.update_from(curr.volumetric_rate()); [[fallthrough]]; } - case GCodeProcessor::EMoveType::Travel: + case EMoveType::Travel: { if (m_buffers[buffer_id(curr.type)].visible) m_extrusions.ranges.feedrate.update_from(curr.feedrate); @@ -415,6 +415,7 @@ void GCodeViewer::reset() m_layers_zs = std::vector(); m_layers_z_range = { 0.0, 0.0 }; m_roles = std::vector(); + m_time_statistics.reset(); #if ENABLE_GCODE_VIEWER_STATISTICS m_statistics.reset_all(); @@ -452,13 +453,13 @@ void GCodeViewer::render() const #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR } -bool GCodeViewer::is_toolpath_move_type_visible(GCodeProcessor::EMoveType type) const +bool GCodeViewer::is_toolpath_move_type_visible(EMoveType type) const { size_t id = static_cast(buffer_id(type)); return (id < m_buffers.size()) ? m_buffers[id].visible : false; } -void GCodeViewer::set_toolpath_move_type_visible(GCodeProcessor::EMoveType type, bool visible) +void GCodeViewer::set_toolpath_move_type_visible(EMoveType type, bool visible) { size_t id = static_cast(buffer_id(type)); if (id < m_buffers.size()) @@ -472,13 +473,13 @@ unsigned int GCodeViewer::get_options_visibility_flags() const }; unsigned int flags = 0; - flags = set_flag(flags, static_cast(Preview::OptionType::Travel), is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Travel)); - flags = set_flag(flags, static_cast(Preview::OptionType::Retractions), is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Retract)); - flags = set_flag(flags, static_cast(Preview::OptionType::Unretractions), is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Unretract)); - flags = set_flag(flags, static_cast(Preview::OptionType::ToolChanges), is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Tool_change)); - flags = set_flag(flags, static_cast(Preview::OptionType::ColorChanges), is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Color_change)); - flags = set_flag(flags, static_cast(Preview::OptionType::PausePrints), is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Pause_Print)); - flags = set_flag(flags, static_cast(Preview::OptionType::CustomGCodes), is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Custom_GCode)); + flags = set_flag(flags, static_cast(Preview::OptionType::Travel), is_toolpath_move_type_visible(EMoveType::Travel)); + flags = set_flag(flags, static_cast(Preview::OptionType::Retractions), is_toolpath_move_type_visible(EMoveType::Retract)); + flags = set_flag(flags, static_cast(Preview::OptionType::Unretractions), is_toolpath_move_type_visible(EMoveType::Unretract)); + flags = set_flag(flags, static_cast(Preview::OptionType::ToolChanges), is_toolpath_move_type_visible(EMoveType::Tool_change)); + flags = set_flag(flags, static_cast(Preview::OptionType::ColorChanges), is_toolpath_move_type_visible(EMoveType::Color_change)); + flags = set_flag(flags, static_cast(Preview::OptionType::PausePrints), is_toolpath_move_type_visible(EMoveType::Pause_Print)); + flags = set_flag(flags, static_cast(Preview::OptionType::CustomGCodes), is_toolpath_move_type_visible(EMoveType::Custom_GCode)); flags = set_flag(flags, static_cast(Preview::OptionType::Shells), m_shells.visible); flags = set_flag(flags, static_cast(Preview::OptionType::ToolMarker), m_sequential_view.marker.is_visible()); flags = set_flag(flags, static_cast(Preview::OptionType::Legend), is_legend_enabled()); @@ -494,13 +495,13 @@ void GCodeViewer::set_options_visibility_from_flags(unsigned int flags) return (flags & (1 << flag)) != 0; }; - set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Travel, is_flag_set(static_cast(Preview::OptionType::Travel))); - set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Retract, is_flag_set(static_cast(Preview::OptionType::Retractions))); - set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Unretract, is_flag_set(static_cast(Preview::OptionType::Unretractions))); - set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Tool_change, is_flag_set(static_cast(Preview::OptionType::ToolChanges))); - set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Color_change, is_flag_set(static_cast(Preview::OptionType::ColorChanges))); - set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Pause_Print, is_flag_set(static_cast(Preview::OptionType::PausePrints))); - set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Custom_GCode, is_flag_set(static_cast(Preview::OptionType::CustomGCodes))); + set_toolpath_move_type_visible(EMoveType::Travel, is_flag_set(static_cast(Preview::OptionType::Travel))); + set_toolpath_move_type_visible(EMoveType::Retract, is_flag_set(static_cast(Preview::OptionType::Retractions))); + set_toolpath_move_type_visible(EMoveType::Unretract, is_flag_set(static_cast(Preview::OptionType::Unretractions))); + set_toolpath_move_type_visible(EMoveType::Tool_change, is_flag_set(static_cast(Preview::OptionType::ToolChanges))); + set_toolpath_move_type_visible(EMoveType::Color_change, is_flag_set(static_cast(Preview::OptionType::ColorChanges))); + set_toolpath_move_type_visible(EMoveType::Pause_Print, is_flag_set(static_cast(Preview::OptionType::PausePrints))); + set_toolpath_move_type_visible(EMoveType::Custom_GCode, is_flag_set(static_cast(Preview::OptionType::CustomGCodes))); m_shells.visible = is_flag_set(static_cast(Preview::OptionType::Shells)); m_sequential_view.marker.set_visible(is_flag_set(static_cast(Preview::OptionType::ToolMarker))); enable_legend(is_flag_set(static_cast(Preview::OptionType::Legend))); @@ -537,7 +538,7 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const wxBusyCursor busy; // the data needed is contained into the Extrude TBuffer - const TBuffer& buffer = m_buffers[buffer_id(GCodeProcessor::EMoveType::Extrude)]; + const TBuffer& buffer = m_buffers[buffer_id(EMoveType::Extrude)]; if (buffer.vertices.id == 0 || buffer.indices.id == 0) return; @@ -805,21 +806,21 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const void GCodeViewer::init_shaders() { - unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); - unsigned char end_id = buffer_id(GCodeProcessor::EMoveType::Count); + unsigned char begin_id = buffer_id(EMoveType::Retract); + unsigned char end_id = buffer_id(EMoveType::Count); bool is_glsl_120 = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20); for (unsigned char i = begin_id; i < end_id; ++i) { switch (buffer_type(i)) { - case GCodeProcessor::EMoveType::Tool_change: { m_buffers[i].shader = is_glsl_120 ? "options_120_flat" : "options_110"; break; } - case GCodeProcessor::EMoveType::Color_change: { m_buffers[i].shader = is_glsl_120 ? "options_120_flat" : "options_110"; break; } - case GCodeProcessor::EMoveType::Pause_Print: { m_buffers[i].shader = is_glsl_120 ? "options_120_flat" : "options_110"; break; } - case GCodeProcessor::EMoveType::Custom_GCode: { m_buffers[i].shader = is_glsl_120 ? "options_120_flat" : "options_110"; break; } - case GCodeProcessor::EMoveType::Retract: { m_buffers[i].shader = is_glsl_120 ? "options_120_flat" : "options_110"; break; } - case GCodeProcessor::EMoveType::Unretract: { m_buffers[i].shader = is_glsl_120 ? "options_120_flat" : "options_110"; break; } - case GCodeProcessor::EMoveType::Extrude: { m_buffers[i].shader = "toolpaths"; break; } - case GCodeProcessor::EMoveType::Travel: { m_buffers[i].shader = "toolpaths"; break; } + case EMoveType::Tool_change: { m_buffers[i].shader = is_glsl_120 ? "options_120_flat" : "options_110"; break; } + case EMoveType::Color_change: { m_buffers[i].shader = is_glsl_120 ? "options_120_flat" : "options_110"; break; } + case EMoveType::Pause_Print: { m_buffers[i].shader = is_glsl_120 ? "options_120_flat" : "options_110"; break; } + case EMoveType::Custom_GCode: { m_buffers[i].shader = is_glsl_120 ? "options_120_flat" : "options_110"; break; } + case EMoveType::Retract: { m_buffers[i].shader = is_glsl_120 ? "options_120_flat" : "options_110"; break; } + case EMoveType::Unretract: { m_buffers[i].shader = is_glsl_120 ? "options_120_flat" : "options_110"; break; } + case EMoveType::Extrude: { m_buffers[i].shader = "toolpaths"; break; } + case EMoveType::Travel: { m_buffers[i].shader = "toolpaths"; break; } default: { break; } } } @@ -846,14 +847,17 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) m_paths_bounding_box.merge(move.position.cast()); else { #endif // ENABLE_GCODE_VIEWER_AS_STATE - if (move.type == GCodeProcessor::EMoveType::Extrude && move.width != 0.0f && move.height != 0.0f) + if (move.type == EMoveType::Extrude && move.width != 0.0f && move.height != 0.0f) m_paths_bounding_box.merge(move.position.cast()); #if ENABLE_GCODE_VIEWER_AS_STATE } #endif // ENABLE_GCODE_VIEWER_AS_STATE } - // max bounding box + // add origin + m_paths_bounding_box.merge(Vec3d::Zero()); + + // max bounding box (account for tool marker) m_max_bounding_box = m_paths_bounding_box; m_max_bounding_box.merge(m_paths_bounding_box.max + m_sequential_view.marker.get_bounding_box().size()[2] * Vec3d::UnitZ()); @@ -875,12 +879,12 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) switch (curr.type) { - case GCodeProcessor::EMoveType::Tool_change: - case GCodeProcessor::EMoveType::Color_change: - case GCodeProcessor::EMoveType::Pause_Print: - case GCodeProcessor::EMoveType::Custom_GCode: - case GCodeProcessor::EMoveType::Retract: - case GCodeProcessor::EMoveType::Unretract: + case EMoveType::Tool_change: + case EMoveType::Color_change: + case EMoveType::Pause_Print: + case EMoveType::Custom_GCode: + case EMoveType::Retract: + case EMoveType::Unretract: { for (int j = 0; j < 3; ++j) { buffer_vertices.push_back(curr.position[j]); @@ -889,8 +893,8 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) buffer_indices.push_back(static_cast(buffer_indices.size())); break; } - case GCodeProcessor::EMoveType::Extrude: - case GCodeProcessor::EMoveType::Travel: + case EMoveType::Extrude: + case EMoveType::Travel: { // x component of the normal to the current segment (the normal is parallel to the XY plane) float normal_x = (curr.position - prev.position).normalized()[1]; @@ -979,7 +983,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) // layers zs / roles / extruder ids / cp color ids -> extract from result for (size_t i = 0; i < m_vertices_count; ++i) { const GCodeProcessor::MoveVertex& move = gcode_result.moves[i]; - if (move.type == GCodeProcessor::EMoveType::Extrude) + if (move.type == EMoveType::Extrude) m_layers_zs.emplace_back(static_cast(move.position[2])); m_extruder_ids.emplace_back(move.extruder_id); @@ -1127,14 +1131,14 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool for (size_t i = 0; i < buffer.paths.size(); ++i) { const Path& path = buffer.paths[i]; - if (path.type == GCodeProcessor::EMoveType::Travel) { + if (path.type == EMoveType::Travel) { if (!is_travel_in_z_range(i)) continue; } else if (!is_in_z_range(path)) continue; - if (path.type == GCodeProcessor::EMoveType::Extrude && !is_visible(path)) + if (path.type == EMoveType::Extrude && !is_visible(path)) continue; // store valid path @@ -1156,7 +1160,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool for (const Path& path : buffer.paths) { if (path.first.s_id <= m_sequential_view.current.last && m_sequential_view.current.last <= path.last.s_id) { size_t offset = m_sequential_view.current.last - path.first.s_id; - if (offset > 0 && (path.type == GCodeProcessor::EMoveType::Travel || path.type == GCodeProcessor::EMoveType::Extrude)) + if (offset > 0 && (path.type == EMoveType::Travel || path.type == EMoveType::Extrude)) offset = 1 + 2 * (offset - 1); offset += path.first.i_id; @@ -1182,8 +1186,8 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool Color color; switch (path.type) { - case GCodeProcessor::EMoveType::Extrude: { color = extrusion_color(path); break; } - case GCodeProcessor::EMoveType::Travel: { color = (m_view_type == EViewType::Feedrate || m_view_type == EViewType::Tool || m_view_type == EViewType::ColorPrint) ? extrusion_color(path) : travel_color(path); break; } + case EMoveType::Extrude: { color = extrusion_color(path); break; } + case EMoveType::Travel: { color = (m_view_type == EViewType::Feedrate || m_view_type == EViewType::Tool || m_view_type == EViewType::ColorPrint) ? extrusion_color(path) : travel_color(path); break; } default: { color = { 0.0f, 0.0f, 0.0f }; break; } } @@ -1195,7 +1199,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool } unsigned int size = std::min(m_sequential_view.current.last, path.last.s_id) - std::max(m_sequential_view.current.first, path.first.s_id) + 1; - if (path.type == GCodeProcessor::EMoveType::Extrude || path.type == GCodeProcessor::EMoveType::Travel) + if (path.type == EMoveType::Extrude || path.type == EMoveType::Travel) size = 2 * (size - 1); it->sizes.push_back(size); @@ -1278,8 +1282,8 @@ void GCodeViewer::render_toolpaths() const glsafe(::glLineWidth(static_cast(line_width(zoom)))); - unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); - unsigned char end_id = buffer_id(GCodeProcessor::EMoveType::Count); + unsigned char begin_id = buffer_id(EMoveType::Retract); + unsigned char end_id = buffer_id(EMoveType::Count); for (unsigned char i = begin_id; i < end_id; ++i) { const TBuffer& buffer = m_buffers[i]; @@ -1302,14 +1306,14 @@ void GCodeViewer::render_toolpaths() const switch (buffer_type(i)) { default: { break; } - case GCodeProcessor::EMoveType::Tool_change: { render_as_points(buffer, EOptionsColors::ToolChanges, *shader); break; } - case GCodeProcessor::EMoveType::Color_change: { render_as_points(buffer, EOptionsColors::ColorChanges, *shader); break; } - case GCodeProcessor::EMoveType::Pause_Print: { render_as_points(buffer, EOptionsColors::PausePrints, *shader); break; } - case GCodeProcessor::EMoveType::Custom_GCode: { render_as_points(buffer, EOptionsColors::CustomGCodes, *shader); break; } - case GCodeProcessor::EMoveType::Retract: { render_as_points(buffer, EOptionsColors::Retractions, *shader); break; } - case GCodeProcessor::EMoveType::Unretract: { render_as_points(buffer, EOptionsColors::Unretractions, *shader); break; } - case GCodeProcessor::EMoveType::Extrude: - case GCodeProcessor::EMoveType::Travel: + case EMoveType::Tool_change: { render_as_points(buffer, EOptionsColors::ToolChanges, *shader); break; } + case EMoveType::Color_change: { render_as_points(buffer, EOptionsColors::ColorChanges, *shader); break; } + case EMoveType::Pause_Print: { render_as_points(buffer, EOptionsColors::PausePrints, *shader); break; } + case EMoveType::Custom_GCode: { render_as_points(buffer, EOptionsColors::CustomGCodes, *shader); break; } + case EMoveType::Retract: { render_as_points(buffer, EOptionsColors::Retractions, *shader); break; } + case EMoveType::Unretract: { render_as_points(buffer, EOptionsColors::Unretractions, *shader); break; } + case EMoveType::Extrude: + case EMoveType::Travel: { #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR std::array light_intensity = { @@ -1406,7 +1410,7 @@ void GCodeViewer::render_legend() const draw_list->AddCircleFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); #else ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size)); - if (m_buffers[buffer_id(GCodeProcessor::EMoveType::Retract)].shader == "options_120_flat") { + if (m_buffers[buffer_id(EMoveType::Retract)].shader == "options_120_flat") { draw_list->AddCircleFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); float radius = 0.5f * icon_size; @@ -1623,7 +1627,7 @@ void GCodeViewer::render_legend() const } // travel paths - if (m_buffers[buffer_id(GCodeProcessor::EMoveType::Travel)].visible) { + if (m_buffers[buffer_id(EMoveType::Travel)].visible) { switch (m_view_type) { case EViewType::Feedrate: @@ -1649,20 +1653,20 @@ void GCodeViewer::render_legend() const } auto any_option_available = [this]() { - auto available = [this](GCodeProcessor::EMoveType type) { + auto available = [this](EMoveType type) { const TBuffer& buffer = m_buffers[buffer_id(type)]; return buffer.visible && buffer.indices.count > 0; }; - return available(GCodeProcessor::EMoveType::Color_change) || - available(GCodeProcessor::EMoveType::Custom_GCode) || - available(GCodeProcessor::EMoveType::Pause_Print) || - available(GCodeProcessor::EMoveType::Retract) || - available(GCodeProcessor::EMoveType::Tool_change) || - available(GCodeProcessor::EMoveType::Unretract); + return available(EMoveType::Color_change) || + available(EMoveType::Custom_GCode) || + available(EMoveType::Pause_Print) || + available(EMoveType::Retract) || + available(EMoveType::Tool_change) || + available(EMoveType::Unretract); }; - auto add_option = [this, append_item](GCodeProcessor::EMoveType move_type, EOptionsColors color, const std::string& text) { + auto add_option = [this, append_item](EMoveType move_type, EOptionsColors color, const std::string& text) { const TBuffer& buffer = m_buffers[buffer_id(move_type)]; if (buffer.visible && buffer.indices.count > 0) #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR @@ -1679,12 +1683,12 @@ void GCodeViewer::render_legend() const imgui.title(_u8L("Options")); // items - add_option(GCodeProcessor::EMoveType::Retract, EOptionsColors::Retractions, _u8L("Retractions")); - add_option(GCodeProcessor::EMoveType::Unretract, EOptionsColors::Unretractions, _u8L("Unretractions")); - add_option(GCodeProcessor::EMoveType::Tool_change, EOptionsColors::ToolChanges, _u8L("Tool changes")); - add_option(GCodeProcessor::EMoveType::Color_change, EOptionsColors::ColorChanges, _u8L("Color changes")); - add_option(GCodeProcessor::EMoveType::Pause_Print, EOptionsColors::PausePrints, _u8L("Pause prints")); - add_option(GCodeProcessor::EMoveType::Custom_GCode, EOptionsColors::CustomGCodes, _u8L("Custom GCodes")); + add_option(EMoveType::Retract, EOptionsColors::Retractions, _u8L("Retractions")); + add_option(EMoveType::Unretract, EOptionsColors::Unretractions, _u8L("Unretractions")); + add_option(EMoveType::Tool_change, EOptionsColors::ToolChanges, _u8L("Tool changes")); + add_option(EMoveType::Color_change, EOptionsColors::ColorChanges, _u8L("Color changes")); + add_option(EMoveType::Pause_Print, EOptionsColors::PausePrints, _u8L("Pause prints")); + add_option(EMoveType::Custom_GCode, EOptionsColors::CustomGCodes, _u8L("Custom GCodes")); } imgui.end(); @@ -1700,10 +1704,6 @@ void GCodeViewer::render_time_estimate() const return; } - const PrintStatistics& ps = wxGetApp().plater()->fff_print().print_statistics(); - if (ps.estimated_normal_print_time <= 0.0f && ps.estimated_silent_print_time <= 0.0f) - return; - ImGuiWrapper& imgui = *wxGetApp().imgui(); #if ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG @@ -1737,19 +1737,17 @@ void GCodeViewer::render_time_estimate() const using PartialTimes = std::vector; auto append_headers = [&imgui](const Headers& headers, const ColumnOffsets& offsets) { - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(headers[0]); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, headers[0]); ImGui::SameLine(offsets[0]); - imgui.text(headers[1]); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, headers[1]); ImGui::SameLine(offsets[1]); - imgui.text(headers[2]); - ImGui::PopStyleColor(); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, headers[2]); ImGui::Separator(); }; auto append_mode = [this, &imgui, append_headers](float total_time, const PartialTimes& items, const Headers& partial_times_headers, - const std::vector>& moves_time, + const std::vector>& moves_time, const Headers& moves_headers, const std::vector>& roles_time, const Headers& roles_headers) { @@ -1775,9 +1773,7 @@ void GCodeViewer::render_time_estimate() const return ret; }; auto append_color = [this, &imgui](const Color& color1, const Color& color2, ColumnOffsets& offsets, const Times& times) { - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(_u8L("Color change")); - ImGui::PopStyleColor(); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Color change")); ImGui::SameLine(); float icon_size = ImGui::GetTextLineHeight(); @@ -1805,9 +1801,7 @@ void GCodeViewer::render_time_estimate() const { case PartialTime::EType::Print: { - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(_u8L("Print")); - ImGui::PopStyleColor(); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Print")); ImGui::SameLine(offsets[0]); imgui.text(short_time(get_time_dhms(item.times.second))); ImGui::SameLine(offsets[1]); @@ -1816,9 +1810,7 @@ void GCodeViewer::render_time_estimate() const } case PartialTime::EType::Pause: { - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(_u8L("Pause")); - ImGui::PopStyleColor(); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Pause")); ImGui::SameLine(offsets[0]); imgui.text(short_time(get_time_dhms(item.times.second - item.times.first))); break; @@ -1832,26 +1824,24 @@ void GCodeViewer::render_time_estimate() const } }; - auto move_type_label = [](GCodeProcessor::EMoveType type) { + auto move_type_label = [](EMoveType type) { switch (type) { - case GCodeProcessor::EMoveType::Noop: { return _u8L("Noop"); } - case GCodeProcessor::EMoveType::Retract: { return _u8L("Retraction"); } - case GCodeProcessor::EMoveType::Unretract: { return _u8L("Unretraction"); } - case GCodeProcessor::EMoveType::Tool_change: { return _u8L("Tool change"); } - case GCodeProcessor::EMoveType::Color_change: { return _u8L("Color change"); } - case GCodeProcessor::EMoveType::Pause_Print: { return _u8L("Pause print"); } - case GCodeProcessor::EMoveType::Custom_GCode: { return _u8L("Custom GCode"); } - case GCodeProcessor::EMoveType::Travel: { return _u8L("Travel"); } - case GCodeProcessor::EMoveType::Extrude: { return _u8L("Extrusion"); } - default: { return _u8L("Unknown"); } + case EMoveType::Noop: { return _u8L("Noop"); } + case EMoveType::Retract: { return _u8L("Retraction"); } + case EMoveType::Unretract: { return _u8L("Unretraction"); } + case EMoveType::Tool_change: { return _u8L("Tool change"); } + case EMoveType::Color_change: { return _u8L("Color change"); } + case EMoveType::Pause_Print: { return _u8L("Pause print"); } + case EMoveType::Custom_GCode: { return _u8L("Custom GCode"); } + case EMoveType::Travel: { return _u8L("Travel"); } + case EMoveType::Extrude: { return _u8L("Extrusion"); } + default: { return _u8L("Unknown"); } } }; auto append_time_item = [&imgui] (const std::string& label, float time, float percentage, const ImVec4& color, const ColumnOffsets& offsets) { - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(label); - ImGui::PopStyleColor(); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, label); ImGui::SameLine(offsets[0]); imgui.text(short_time(get_time_dhms(time))); ImGui::SameLine(offsets[1]); @@ -1868,7 +1858,7 @@ void GCodeViewer::render_time_estimate() const }; auto append_move_times = [this, &imgui, move_type_label, append_headers, append_time_item](float total_time, - const std::vector>& moves_time, + const std::vector>& moves_time, const Headers& headers, const ColumnOffsets& offsets) { if (moves_time.empty()) @@ -1879,7 +1869,7 @@ void GCodeViewer::render_time_estimate() const append_headers(headers, offsets); - std::vector> sorted_moves_time(moves_time); + std::vector> sorted_moves_time(moves_time); std::sort(sorted_moves_time.begin(), sorted_moves_time.end(), [](const auto& p1, const auto& p2) { return p2.second < p1.second; }); for (const auto& [type, time] : sorted_moves_time) { @@ -1909,7 +1899,7 @@ void GCodeViewer::render_time_estimate() const }; auto calc_common_offsets = [move_type_label]( - const std::vector>& moves_time, const Headers& moves_headers, + const std::vector>& moves_time, const Headers& moves_headers, const std::vector>& roles_time, const Headers& roles_headers) { ColumnOffsets ret = { std::max(ImGui::CalcTextSize(moves_headers[0].c_str()).x, ImGui::CalcTextSize(roles_headers[0].c_str()).x), std::max(ImGui::CalcTextSize(moves_headers[1].c_str()).x, ImGui::CalcTextSize(roles_headers[1].c_str()).x) }; @@ -1930,9 +1920,7 @@ void GCodeViewer::render_time_estimate() const return ret; }; - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(_u8L("Time") + ":"); - ImGui::PopStyleColor(); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Time") + ":"); ImGui::SameLine(); imgui.text(short_time(get_time_dhms(total_time))); append_partial_times(items, partial_times_headers); @@ -2032,21 +2020,23 @@ void GCodeViewer::render_time_estimate() const // mode tabs ImGui::BeginTabBar("mode_tabs"); - if (ps.estimated_normal_print_time > 0.0f) { + const PrintEstimatedTimeStatistics::Mode& normal_mode = m_time_statistics.modes[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Normal)]; + if (normal_mode.time > 0.0f) { if (ImGui::BeginTabItem(_u8L("Normal").c_str())) { - append_mode(ps.estimated_normal_print_time, - generate_partial_times(ps.estimated_normal_custom_gcode_print_times), partial_times_headers, - ps.estimated_normal_moves_times, moves_headers, - ps.estimated_normal_roles_times, roles_headers); + append_mode(normal_mode.time, + generate_partial_times(normal_mode.custom_gcode_times), partial_times_headers, + normal_mode.moves_times, moves_headers, + normal_mode.roles_times, roles_headers); ImGui::EndTabItem(); } } - if (ps.estimated_silent_print_time > 0.0f) { + const PrintEstimatedTimeStatistics::Mode& stealth_mode = m_time_statistics.modes[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Stealth)]; + if (stealth_mode.time > 0.0f) { if (ImGui::BeginTabItem(_u8L("Stealth").c_str())) { - append_mode(ps.estimated_silent_print_time, - generate_partial_times(ps.estimated_silent_custom_gcode_print_times), partial_times_headers, - ps.estimated_silent_moves_times, moves_headers, - ps.estimated_silent_roles_times, roles_headers); + append_mode(stealth_mode.time, + generate_partial_times(stealth_mode.custom_gcode_times), partial_times_headers, + stealth_mode.moves_times, moves_headers, + stealth_mode.roles_times, roles_headers); ImGui::EndTabItem(); } } @@ -2082,93 +2072,67 @@ void GCodeViewer::render_statistics() const imgui.begin(std::string("GCodeViewer Statistics"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize); ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindow()); - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(std::string("GCodeProcessor time:")); - ImGui::PopStyleColor(); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, std::string("GCodeProcessor time:")); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.results_time) + " ms"); ImGui::Separator(); - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(std::string("Load time:")); - ImGui::PopStyleColor(); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, std::string("Load time:")); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.load_time) + " ms"); - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(std::string("Resfresh time:")); - ImGui::PopStyleColor(); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, std::string("Refresh time:")); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.refresh_time) + " ms"); - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(std::string("Resfresh paths time:")); - ImGui::PopStyleColor(); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, std::string("Refresh paths time:")); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.refresh_paths_time) + " ms"); ImGui::Separator(); - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(std::string("Multi GL_POINTS calls:")); - ImGui::PopStyleColor(); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, std::string("Multi GL_POINTS calls:")); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.gl_multi_points_calls_count)); - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(std::string("Multi GL_LINE_STRIP calls:")); - ImGui::PopStyleColor(); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, std::string("Multi GL_LINE_STRIP calls:")); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.gl_multi_line_strip_calls_count)); ImGui::Separator(); - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(std::string("GCodeProcessor results:")); - ImGui::PopStyleColor(); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, std::string("GCodeProcessor results:")); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.results_size) + " bytes"); ImGui::Separator(); - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(std::string("Paths CPU:")); - ImGui::PopStyleColor(); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, std::string("Paths CPU:")); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.paths_size) + " bytes"); - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(std::string("Render paths CPU:")); - ImGui::PopStyleColor(); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, std::string("Render paths CPU:")); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.render_paths_size) + " bytes"); ImGui::Separator(); - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(std::string("Vertices GPU:")); - ImGui::PopStyleColor(); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, std::string("Vertices GPU:")); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.vertices_gpu_size) + " bytes"); - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(std::string("Indices GPU:")); - ImGui::PopStyleColor(); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, std::string("Vertices GPU:")); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.indices_gpu_size) + " bytes"); ImGui::Separator(); - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(std::string("Travel segments:")); - ImGui::PopStyleColor(); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, std::string("Vertices GPU:")); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.travel_segments_count)); - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); - imgui.text(std::string("Extrude segments:")); - ImGui::PopStyleColor(); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, std::string("Extrude segments:")); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.extrude_segments_count)); @@ -2242,7 +2206,7 @@ void GCodeViewer::render_shaders_editor() const bool GCodeViewer::is_travel_in_z_range(size_t id) const { - const TBuffer& buffer = m_buffers[buffer_id(GCodeProcessor::EMoveType::Travel)]; + const TBuffer& buffer = m_buffers[buffer_id(EMoveType::Travel)]; if (id >= buffer.paths.size()) return false; diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 3b50062fbc..0a32a97e67 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -88,7 +88,7 @@ class GCodeViewer Vec3f position{ Vec3f::Zero() }; }; - GCodeProcessor::EMoveType type{ GCodeProcessor::EMoveType::Noop }; + EMoveType type{ EMoveType::Noop }; ExtrusionRole role{ erNone }; Endpoint first; Endpoint last; @@ -326,7 +326,7 @@ public: private: unsigned int m_last_result_id{ 0 }; size_t m_vertices_count{ 0 }; - mutable std::vector m_buffers{ static_cast(GCodeProcessor::EMoveType::Extrude) }; + mutable std::vector m_buffers{ static_cast(EMoveType::Extrude) }; // bounding box of toolpaths BoundingBoxf3 m_paths_bounding_box; // bounding box of toolpaths + marker tools @@ -341,6 +341,7 @@ private: Shells m_shells; EViewType m_view_type{ EViewType::FeatureType }; bool m_legend_enabled{ true }; + PrintEstimatedTimeStatistics m_time_statistics; #if ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG mutable bool m_time_estimate_enabled{ false }; mutable unsigned int m_time_estimate_frames_count{ 0 }; @@ -391,8 +392,8 @@ public: m_view_type = type; } - bool is_toolpath_move_type_visible(GCodeProcessor::EMoveType type) const; - void set_toolpath_move_type_visible(GCodeProcessor::EMoveType type, bool visible); + bool is_toolpath_move_type_visible(EMoveType type) const; + void set_toolpath_move_type_visible(EMoveType type, bool visible); unsigned int get_toolpath_role_visibility_flags() const { return m_extrusions.role_visibility_flags; } void set_toolpath_role_visibility_flags(unsigned int flags) { m_extrusions.role_visibility_flags = flags; } unsigned int get_options_visibility_flags() const; diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 7d6acad069..f7f6285c65 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -1432,8 +1432,6 @@ void MainFrame::set_mode(EMode mode) select_tab(0); #endif // ENABLE_LAYOUT_NO_RESTART - m_plater->fff_print().print_statistics().clear_time_estimates(); - m_plater->reset(); m_plater->reset_gcode_toolpaths(); @@ -1477,8 +1475,6 @@ void MainFrame::set_mode(EMode mode) update_layout(); #endif // ENABLE_LAYOUT_NO_RESTART - m_plater->fff_print().print_statistics().clear_time_estimates(); - m_plater->reset(); m_plater->reset_last_loaded_gcode(); m_plater->reset_gcode_toolpaths(); From 0840b2328a668f648de117b4743e5769f31990af Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 3 Aug 2020 15:00:19 +0200 Subject: [PATCH 173/255] Tech ENABLE_GCODE_VIEWER_AS_STATE set as default --- src/libslic3r/GCode/GCodeProcessor.cpp | 5 -- src/libslic3r/GCode/GCodeProcessor.hpp | 6 --- src/libslic3r/Technologies.hpp | 1 - src/slic3r/GUI/GCodeViewer.cpp | 15 +----- src/slic3r/GUI/GLCanvas3D.cpp | 29 +++-------- src/slic3r/GUI/GLCanvas3D.hpp | 4 +- src/slic3r/GUI/GUI_App.cpp | 4 +- src/slic3r/GUI/GUI_App.hpp | 4 +- src/slic3r/GUI/GUI_Preview.cpp | 16 +++--- src/slic3r/GUI/MainFrame.cpp | 68 +++++++++++++------------- src/slic3r/GUI/MainFrame.hpp | 16 +++--- src/slic3r/GUI/Plater.cpp | 38 +++++++------- src/slic3r/GUI/Plater.hpp | 29 +++++------ 13 files changed, 91 insertions(+), 144 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 5d9644457d..7612af0e90 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -1147,7 +1147,6 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) else if (delta_pos[X] != 0.0f || delta_pos[Y] != 0.0f || delta_pos[Z] != 0.0f) type = EMoveType::Travel; -#if ENABLE_GCODE_VIEWER_AS_STATE if (type == EMoveType::Extrude && (m_width == 0.0f || m_height == 0.0f)) { if (m_extrusion_role != erCustom) { m_width = 0.5f; @@ -1155,10 +1154,6 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) } type = EMoveType::Travel; } -#else - if (type == EMoveType::Extrude && (m_width == 0.0f || m_height == 0.0f || !is_valid_extrusion_role(m_extrusion_role))) - type = EMoveType::Travel; -#endif // ENABLE_GCODE_VIEWER_AS_STATE return type; }; diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 526300e55a..101c320db8 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -244,10 +244,8 @@ namespace Slic3r { { unsigned int id; std::vector moves; -#if ENABLE_GCODE_VIEWER_AS_STATE Pointfs bed_shape; std::vector extruder_colors; -#endif // ENABLE_GCODE_VIEWER_AS_STATE PrintEstimatedTimeStatistics time_statistics; #if ENABLE_GCODE_VIEWER_STATISTICS @@ -256,19 +254,15 @@ namespace Slic3r { { time = 0; moves = std::vector(); -#if ENABLE_GCODE_VIEWER_AS_STATE bed_shape = Pointfs(); extruder_colors = std::vector(); -#endif // ENABLE_GCODE_VIEWER_AS_STATE } #else void reset() { moves = std::vector(); -#if ENABLE_GCODE_VIEWER_AS_STATE bed_shape = Pointfs(); extruder_colors = std::vector(); -#endif // ENABLE_GCODE_VIEWER_AS_STATE } #endif // ENABLE_GCODE_VIEWER_STATISTICS }; diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 569a73bab1..c14e2df52f 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -58,7 +58,6 @@ #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) #define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_SHADERS_EDITOR (0 && ENABLE_GCODE_VIEWER) -#define ENABLE_GCODE_VIEWER_AS_STATE (1 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR (1 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG (1 && ENABLE_GCODE_VIEWER) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 4faa0486ff..e746635ee2 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -7,9 +7,7 @@ #include "libslic3r/Model.hpp" #include "libslic3r/Utils.hpp" #include "GUI_App.hpp" -#if ENABLE_GCODE_VIEWER_AS_STATE #include "MainFrame.hpp" -#endif // ENABLE_GCODE_VIEWER_AS_STATE #include "Plater.hpp" #include "PresetBundle.hpp" #include "Camera.hpp" @@ -314,13 +312,9 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& reset(); load_toolpaths(gcode_result); -#if ENABLE_GCODE_VIEWER_AS_STATE if (wxGetApp().mainframe->get_mode() != MainFrame::EMode::GCodeViewer) -#endif // ENABLE_GCODE_VIEWER_AS_STATE load_shells(print, initialized); - -#if ENABLE_GCODE_VIEWER_AS_STATE - if (wxGetApp().mainframe->get_mode() == MainFrame::EMode::GCodeViewer) { + else { Pointfs bed_shape; if (!gcode_result.bed_shape.empty()) // bed shape detected in the gcode @@ -337,7 +331,6 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& } wxGetApp().plater()->set_bed_shape(bed_shape, "", "", true); } -#endif // ENABLE_GCODE_VIEWER_AS_STATE m_time_statistics = gcode_result.time_statistics; } @@ -351,12 +344,10 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: if (m_vertices_count == 0) return; -#if ENABLE_GCODE_VIEWER_AS_STATE if (m_view_type == EViewType::Tool && !gcode_result.extruder_colors.empty()) // update tool colors from config stored in the gcode m_tool_colors = decode_colors(gcode_result.extruder_colors); else -#endif // ENABLE_GCODE_VIEWER_AS_STATE // update tool colors m_tool_colors = decode_colors(str_tool_colors); @@ -841,17 +832,13 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) for (size_t i = 0; i < m_vertices_count; ++i) { const GCodeProcessor::MoveVertex& move = gcode_result.moves[i]; -#if ENABLE_GCODE_VIEWER_AS_STATE if (wxGetApp().mainframe->get_mode() == MainFrame::EMode::GCodeViewer) // for the gcode viewer we need all moves to correctly size the printbed m_paths_bounding_box.merge(move.position.cast()); else { -#endif // ENABLE_GCODE_VIEWER_AS_STATE if (move.type == EMoveType::Extrude && move.width != 0.0f && move.height != 0.0f) m_paths_bounding_box.merge(move.position.cast()); -#if ENABLE_GCODE_VIEWER_AS_STATE } -#endif // ENABLE_GCODE_VIEWER_AS_STATE } // add origin diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index dc8b21ce8d..2a744d72d7 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1913,12 +1913,12 @@ void GLCanvas3D::zoom_to_selection() _zoom_to_box(m_selection.get_bounding_box()); } -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER void GLCanvas3D::zoom_to_gcode() { _zoom_to_box(m_gcode_viewer.get_paths_bounding_box(), 1.05); } -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER void GLCanvas3D::select_view(const std::string& direction) { @@ -2696,9 +2696,7 @@ static void load_gcode_retractions(const GCodePreviewData::Retraction& retractio void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result) { m_gcode_viewer.load(gcode_result, *this->fff_print(), m_initialized); -#if ENABLE_GCODE_VIEWER_AS_STATE if (wxGetApp().mainframe->get_mode() != MainFrame::EMode::GCodeViewer) -#endif // ENABLE_GCODE_VIEWER_AS_STATE _show_warning_texture_if_needed(WarningTexture::ToolpathOutside); } @@ -4280,17 +4278,15 @@ void GLCanvas3D::update_ui_from_settings() } #endif // ENABLE_RETINA_GL -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER if (wxGetApp().mainframe != nullptr && wxGetApp().mainframe->get_mode() != MainFrame::EMode::GCodeViewer) wxGetApp().plater()->get_collapse_toolbar().set_enabled(wxGetApp().app_config->get("show_collapse_button") == "1"); #else bool enable_collapse = wxGetApp().app_config->get("show_collapse_button") == "1"; wxGetApp().plater()->get_collapse_toolbar().set_enabled(enable_collapse); -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER } - - GLCanvas3D::WipeTowerInfo GLCanvas3D::get_wipe_tower_info() const { WipeTowerInfo wti; @@ -5385,22 +5381,16 @@ static BoundingBoxf3 print_volume(const DynamicPrintConfig& config) void GLCanvas3D::_render_background() const { #if ENABLE_GCODE_VIEWER -#if ENABLE_GCODE_VIEWER_AS_STATE bool use_error_color = false; if (wxGetApp().mainframe->get_mode() != MainFrame::EMode::GCodeViewer) { use_error_color = m_dynamic_background_enabled; -#else - bool use_error_color = m_dynamic_background_enabled; -#endif // ENABLE_GCODE_VIEWER_AS_STATE if (!m_volumes.empty()) use_error_color &= _is_any_volume_outside(); else { BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3(); use_error_color &= (test_volume.radius() > 0.0) ? !test_volume.contains(m_gcode_viewer.get_paths_bounding_box()) : false; } -#if ENABLE_GCODE_VIEWER_AS_STATE } -#endif // ENABLE_GCODE_VIEWER_AS_STATE #endif // ENABLE_GCODE_VIEWER glsafe(::glPushMatrix()); @@ -7119,20 +7109,13 @@ void GLCanvas3D::_show_warning_texture_if_needed(WarningTexture::Warning warning bool show = false; if (!m_volumes.empty()) show = _is_any_volume_outside(); - else - { -#if ENABLE_GCODE_VIEWER_AS_STATE - if (wxGetApp().mainframe->get_mode() != MainFrame::EMode::GCodeViewer) - { + else { + if (wxGetApp().mainframe->get_mode() != MainFrame::EMode::GCodeViewer) { BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3(); const BoundingBoxf3& paths_volume = m_gcode_viewer.get_paths_bounding_box(); if (test_volume.radius() > 0.0 && paths_volume.radius() > 0.0) show = !test_volume.contains(paths_volume); } -#else - BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3(); - show = (test_volume.radius() > 0.0) ? !test_volume.contains(m_gcode_viewer.get_bounding_box()) : false; -#endif // ENABLE_GCODE_VIEWER_AS_STATE } _set_warning_texture(warning, show); #else diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 0b5a357fdb..15bb3e6f06 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -625,9 +625,9 @@ public: void zoom_to_bed(); void zoom_to_volumes(); void zoom_to_selection(); -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER void zoom_to_gcode(); -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER void select_view(const std::string& direction); void update_volumes_colors_by_extruder(); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 2fb60bf374..433e026f6c 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -754,7 +754,7 @@ void GUI_App::import_model(wxWindow *parent, wxArrayString& input_files) const dialog.GetPaths(input_files); } -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER void GUI_App::load_gcode(wxWindow* parent, wxString& input_file) const { input_file.Clear(); @@ -766,7 +766,7 @@ void GUI_App::load_gcode(wxWindow* parent, wxString& input_file) const if (dialog.ShowModal() == wxID_OK) input_file = dialog.GetPath(); } -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER bool GUI_App::switch_language() { diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index ad874bd1ef..aa94475319 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -156,9 +156,9 @@ public: void keyboard_shortcuts(); void load_project(wxWindow *parent, wxString& input_file) const; void import_model(wxWindow *parent, wxArrayString& input_files) const; -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER void load_gcode(wxWindow* parent, wxString& input_file) const; -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER static bool catch_error(std::function cb, const std::string& err); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 556f5de8cd..98c02322ee 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -13,9 +13,9 @@ #include "PresetBundle.hpp" #include "DoubleSlider.hpp" #include "Plater.hpp" -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER #include "MainFrame.hpp" -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER #include #include @@ -1196,11 +1196,11 @@ void Preview::update_double_slider_from_canvas(wxKeyEvent & event) void Preview::load_print_as_fff(bool keep_z_range) { -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER if (wxGetApp().mainframe == nullptr) // avoid proessing while mainframe is being constructed return; -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER if (m_loaded || m_process->current_printer_technology() != ptFFF) return; @@ -1225,11 +1225,11 @@ void Preview::load_print_as_fff(bool keep_z_range) } } -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER if (wxGetApp().mainframe->get_mode() != MainFrame::EMode::GCodeViewer && !has_layers) #else if (! has_layers) -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER { #if ENABLE_GCODE_VIEWER hide_layers_slider(); @@ -1265,11 +1265,7 @@ void Preview::load_print_as_fff(bool keep_z_range) #if ENABLE_GCODE_VIEWER GCodeViewer::EViewType gcode_view_type = m_canvas->get_gcode_view_preview_type(); -#if ENABLE_GCODE_VIEWER_AS_STATE bool gcode_preview_data_valid = !m_gcode_result->moves.empty(); -#else - bool gcode_preview_data_valid = print->is_step_done(psGCodeExport); -#endif // ENABLE_GCODE_VIEWER_AS_STATE #else bool gcode_preview_data_valid = print->is_step_done(psGCodeExport) && ! m_gcode_preview_data->empty(); #endif // ENABLE_GCODE_VIEWER diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 778ce2134f..f017900f46 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -111,7 +111,7 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S // initialize tabpanel and menubar init_tabpanel(); -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER init_editor_menubar(); init_gcodeviewer_menubar(); @@ -129,7 +129,7 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S #endif // _WIN32 #else init_menubar(); -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER // set default tooltip timer in msec // SetAutoPop supposedly accepts long integers but some bug doesn't allow for larger values @@ -243,9 +243,9 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S update_ui_from_settings(); // FIXME (?) if (m_plater != nullptr) { -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER m_plater->get_collapse_toolbar().set_enabled(wxGetApp().app_config->get("show_collapse_button") == "1"); -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER m_plater->show_action_buttons(true); } } @@ -291,7 +291,7 @@ void MainFrame::update_layout() Layout(); }; -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER ESettingsLayout layout = (m_mode == EMode::GCodeViewer) ? ESettingsLayout::GCodeViewer : (wxGetApp().app_config->get("old_settings_layout_mode") == "1" ? ESettingsLayout::Old : wxGetApp().app_config->get("new_settings_layout_mode") == "1" ? ESettingsLayout::New : @@ -300,7 +300,7 @@ void MainFrame::update_layout() ESettingsLayout layout = wxGetApp().app_config->get("old_settings_layout_mode") == "1" ? ESettingsLayout::Old : wxGetApp().app_config->get("new_settings_layout_mode") == "1" ? ESettingsLayout::New : wxGetApp().app_config->get("dlg_settings_layout_mode") == "1" ? ESettingsLayout::Dlg : ESettingsLayout::Old; -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER if (m_layout == layout) return; @@ -356,14 +356,14 @@ void MainFrame::update_layout() m_plater->Show(); break; } -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER case ESettingsLayout::GCodeViewer: { m_main_sizer->Add(m_plater, 1, wxEXPAND); m_plater->Show(); break; } -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER } //#ifdef __APPLE__ @@ -398,7 +398,7 @@ void MainFrame::shutdown() } #endif // _WIN32 -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER if (m_plater != nullptr) { m_plater->stop_jobs(); @@ -423,7 +423,7 @@ void MainFrame::shutdown() // Cleanup of canvases' volumes needs to be done here or a crash may happen on some Linux Debian flavours // see: https://github.com/prusa3d/PrusaSlicer/issues/3964 if (m_plater) m_plater->reset_canvas_volumes(); -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER // Weird things happen as the Paint messages are floating around the windows being destructed. // Avoid the Paint messages by hiding the main window. @@ -436,11 +436,11 @@ void MainFrame::shutdown() m_settings_dialog.Close(); if (m_plater != nullptr) { -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER // restore sidebar if it was hidden when switching to gcode viewer mode if (m_restore_from_gcode_viewer.collapsed_sidebar) m_plater->collapse_sidebar(false); -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER // Stop the background thread (Windows and Linux). // Disconnect from a 3DConnextion driver (OSX). m_plater->get_mouse3d_controller().shutdown(); @@ -781,7 +781,7 @@ void MainFrame::on_sys_color_changed() msw_rescale_menu(menu_bar->GetMenu(id)); } -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER #ifdef _MSC_VER // \xA0 is a non-breaking space. It is entered here to spoil the automatic accelerators, // as the simple numeric accelerators spoil all numeric data entry. @@ -855,7 +855,7 @@ static void add_common_view_menu_items(wxMenu* view_menu, MainFrame* mainFrame, void MainFrame::init_editor_menubar() #else void MainFrame::init_menubar() -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER { #ifdef __APPLE__ wxMenuBar::SetAutoWindowMenu(false); @@ -1015,7 +1015,7 @@ void MainFrame::init_menubar() append_menu_item(fileMenu, wxID_ANY, _L("&Repair STL file") + dots, _L("Automatically repair an STL file"), [this](wxCommandEvent&) { repair_stl(); }, "wrench", nullptr, [this]() { return true; }, this); -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER fileMenu->AppendSeparator(); append_menu_item(fileMenu, wxID_ANY, _L("&G-code preview"), _L("Switch to G-code preview mode"), [this](wxCommandEvent&) { @@ -1023,13 +1023,13 @@ void MainFrame::init_menubar() set_mode(EMode::GCodeViewer); }, "", nullptr, [this]() { return m_plater != nullptr && m_plater->printer_technology() != ptSLA; }, this); -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER fileMenu->AppendSeparator(); append_menu_item(fileMenu, wxID_EXIT, _L("&Quit"), wxString::Format(_L("Quit %s"), SLIC3R_APP_NAME), [this](wxCommandEvent&) { Close(false); }); } -#if !ENABLE_GCODE_VIEWER_AS_STATE +#if !ENABLE_GCODE_VIEWER #ifdef _MSC_VER // \xA0 is a non-breaking space. It is entered here to spoil the automatic accelerators, // as the simple numeric accelerators spoil all numeric data entry. @@ -1039,7 +1039,7 @@ void MainFrame::init_menubar() wxString sep = " - "; wxString sep_space = ""; #endif -#endif // !ENABLE_GCODE_VIEWER_AS_STATE +#endif // !ENABLE_GCODE_VIEWER // Edit menu wxMenu* editMenu = nullptr; @@ -1123,7 +1123,7 @@ void MainFrame::init_menubar() [this](){return can_change_view(); }, this); } -#if !ENABLE_GCODE_VIEWER_AS_STATE +#if !ENABLE_GCODE_VIEWER #if _WIN32 // This is needed on Windows to fake the CTRL+# of the window menu when using the numpad wxAcceleratorEntry entries[6]; @@ -1136,7 +1136,7 @@ void MainFrame::init_menubar() wxAcceleratorTable accel(6, entries); SetAcceleratorTable(accel); #endif // _WIN32 -#endif // !ENABLE_GCODE_VIEWER_AS_STATE +#endif // !ENABLE_GCODE_VIEWER windowMenu->AppendSeparator(); append_menu_item(windowMenu, wxID_ANY, _L("Print &Host Upload Queue") + "\tCtrl+J", _L("Display the Print Host Upload Queue window"), @@ -1148,7 +1148,7 @@ void MainFrame::init_menubar() wxMenu* viewMenu = nullptr; if (m_plater) { viewMenu = new wxMenu(); -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER add_common_view_menu_items(viewMenu, this, std::bind(&MainFrame::can_change_view, this)); #else // The camera control accelerators are captured by GLCanvas3D::on_char(). @@ -1169,7 +1169,7 @@ void MainFrame::init_menubar() "", nullptr, [this](){return can_change_view(); }, this); append_menu_item(viewMenu, wxID_ANY, _L("Right") + sep + "&6", _L("Right View"), [this](wxCommandEvent&) { select_view("right"); }, "", nullptr, [this](){return can_change_view(); }, this); -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER viewMenu->AppendSeparator(); #if ENABLE_SLOPE_RENDERING wxMenu* options_menu = new wxMenu(); @@ -1191,7 +1191,7 @@ void MainFrame::init_menubar() } // Help menu -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER auto helpMenu = generate_help_menu(); #else auto helpMenu = new wxMenu(); @@ -1228,12 +1228,12 @@ void MainFrame::init_menubar() [this](wxCommandEvent&) { wxGetApp().gcode_thumbnails_debug(); }); #endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG } -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER // menubar // assign menubar to frame after appending items, otherwise special items // will not be handled correctly -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER m_editor_menubar = new wxMenuBar(); m_editor_menubar->Append(fileMenu, _L("&File")); if (editMenu) m_editor_menubar->Append(editMenu, _L("&Edit")); @@ -1253,16 +1253,16 @@ void MainFrame::init_menubar() wxGetApp().add_config_menu(menubar); menubar->Append(helpMenu, _(L("&Help"))); SetMenuBar(menubar); -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER #ifdef __APPLE__ // This fixes a bug on Mac OS where the quit command doesn't emit window close events // wx bug: https://trac.wxwidgets.org/ticket/18328 -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER wxMenu* apple_menu = m_editor_menubar->OSXGetAppleMenu(); #else wxMenu *apple_menu = menubar->OSXGetAppleMenu(); -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER if (apple_menu != nullptr) { apple_menu->Bind(wxEVT_MENU, [this](wxCommandEvent &) { Close(); @@ -1271,14 +1271,14 @@ void MainFrame::init_menubar() #endif if (plater()->printer_technology() == ptSLA) -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER update_editor_menubar(); #else update_menubar(); -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER } -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER void MainFrame::init_gcodeviewer_menubar() { wxMenu* fileMenu = new wxMenu; @@ -1412,13 +1412,13 @@ void MainFrame::set_mode(EMode mode) } } } -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER void MainFrame::update_editor_menubar() #else void MainFrame::update_menubar() -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER { const bool is_fff = plater()->printer_technology() == ptFFF; diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index 8a3e4376b4..8961ad7172 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -68,7 +68,7 @@ class MainFrame : public DPIFrame wxString m_qs_last_input_file = wxEmptyString; wxString m_qs_last_output_file = wxEmptyString; wxString m_last_config = wxEmptyString; -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER wxMenuBar* m_editor_menubar{ nullptr }; wxMenuBar* m_gcodeviewer_menubar{ nullptr }; @@ -79,7 +79,7 @@ class MainFrame : public DPIFrame }; RestoreFromGCodeViewer m_restore_from_gcode_viewer; -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER #if 0 wxMenuItem* m_menu_item_repeat { nullptr }; // doesn't used now @@ -134,14 +134,14 @@ class MainFrame : public DPIFrame Old, New, Dlg, -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER GCodeViewer -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER }; ESettingsLayout m_layout{ ESettingsLayout::Unknown }; -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER public: enum class EMode : unsigned char { @@ -151,7 +151,7 @@ public: private: EMode m_mode{ EMode::Editor }; -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER protected: virtual void on_dpi_changed(const wxRect &suggested_rect); @@ -173,7 +173,7 @@ public: void init_tabpanel(); void create_preset_tabs(); void add_created_tab(Tab* panel); -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER void init_editor_menubar(); void update_editor_menubar(); void init_gcodeviewer_menubar(); @@ -183,7 +183,7 @@ public: #else void init_menubar(); void update_menubar(); -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER void update_ui_from_settings(); bool is_loaded() const { return m_loaded; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 43cf27e30f..b87b3cce36 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -33,13 +33,11 @@ #include "libslic3r/Format/STL.hpp" #include "libslic3r/Format/AMF.hpp" #include "libslic3r/Format/3mf.hpp" -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER #include "libslic3r/GCode/GCodeProcessor.hpp" #else -#if !ENABLE_GCODE_VIEWER #include "libslic3r/GCode/PreviewData.hpp" -#endif // !ENABLE_GCODE_VIEWER -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER #include "libslic3r/GCode/ThumbnailData.hpp" #include "libslic3r/Model.hpp" #include "libslic3r/SLA/Hollowing.hpp" @@ -2767,10 +2765,8 @@ void Plater::priv::reset() #if ENABLE_GCODE_VIEWER reset_gcode_toolpaths(); -#endif // ENABLE_GCODE_VIEWER -#if ENABLE_GCODE_VIEWER_AS_STATE gcode_result.reset(); -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER // Stop and reset the Print content. this->background_process.reset(); @@ -4633,7 +4629,7 @@ void Plater::extract_config_from_project() load_files(input_paths, false, true); } -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER void Plater::load_gcode() { // Ask user for a gcode file name. @@ -4669,7 +4665,7 @@ void Plater::load_gcode(const wxString& filename) p->preview->reload_print(false); p->preview->get_canvas3d()->zoom_to_gcode(); } -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER std::vector Plater::load_files(const std::vector& input_files, bool load_model, bool load_config, bool imperial_units /*= false*/) { return p->load_files(input_files, load_model, load_config, imperial_units); } @@ -5443,7 +5439,7 @@ void Plater::on_config_change(const DynamicPrintConfig &config) void Plater::set_bed_shape() const { -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER set_bed_shape(p->config->option("bed_shape")->values, p->config->option("bed_custom_texture")->value, p->config->option("bed_custom_model")->value); @@ -5451,15 +5447,15 @@ void Plater::set_bed_shape() const p->set_bed_shape(p->config->option("bed_shape")->values, p->config->option("bed_custom_texture")->value, p->config->option("bed_custom_model")->value); -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER } -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER void Plater::set_bed_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom) const { p->set_bed_shape(shape, custom_texture, custom_model, force_as_custom); } -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER void Plater::force_filament_colors_update() { @@ -5634,11 +5630,11 @@ void Plater::set_printer_technology(PrinterTechnology printer_technology) p->label_btn_send = printer_technology == ptFFF ? L("Send G-code") : L("Send to printer"); if (wxGetApp().mainframe != nullptr) -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER wxGetApp().mainframe->update_editor_menubar(); #else wxGetApp().mainframe->update_menubar(); -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER p->update_main_toolbar_tooltips(); @@ -5790,24 +5786,24 @@ bool Plater::init_view_toolbar() return p->init_view_toolbar(); } -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER void Plater::enable_view_toolbar(bool enable) { p->view_toolbar.set_enabled(enable); } -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER bool Plater::init_collapse_toolbar() { return p->init_collapse_toolbar(); } -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER void Plater::enable_collapse_toolbar(bool enable) { p->collapse_toolbar.set_enabled(enable); } -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER const Camera& Plater::get_camera() const { @@ -5936,9 +5932,9 @@ bool Plater::can_undo() const { return p->undo_redo_stack().has_undo_snapshot(); bool Plater::can_redo() const { return p->undo_redo_stack().has_redo_snapshot(); } bool Plater::can_reload_from_disk() const { return p->can_reload_from_disk(); } const UndoRedo::Stack& Plater::undo_redo_stack_main() const { return p->undo_redo_stack_main(); } -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER void Plater::clear_undo_redo_stack_main() { p->undo_redo_stack_main().clear(); } -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER void Plater::enter_gizmos_stack() { p->enter_gizmos_stack(); } void Plater::leave_gizmos_stack() { p->leave_gizmos_stack(); } bool Plater::inside_snapshot_capture() { return p->inside_snapshot_capture(); } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 59d595bbe4..8142a7c359 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -173,10 +173,10 @@ public: void add_model(bool imperial_units = false); void import_sl1_archive(); void extract_config_from_project(); -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER void load_gcode(); void load_gcode(const wxString& filename); -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER std::vector load_files(const std::vector& input_files, bool load_model = true, bool load_config = true, bool imperial_units = false); // To be called when providing a list of files to the GUI slic3r on command line. @@ -256,9 +256,9 @@ public: bool search_string_getter(int idx, const char** label, const char** tooltip); // For the memory statistics. const Slic3r::UndoRedo::Stack& undo_redo_stack_main() const; -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER void clear_undo_redo_stack_main(); -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER // Enter / leave the Gizmos specific Undo / Redo stack. To be used by the SLA support point editing gizmo. void enter_gizmos_stack(); void leave_gizmos_stack(); @@ -322,13 +322,13 @@ public: void sys_color_changed(); bool init_view_toolbar(); -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER void enable_view_toolbar(bool enable); -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER bool init_collapse_toolbar(); -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER void enable_collapse_toolbar(bool enable); -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER const Camera& get_camera() const; Camera& get_camera(); @@ -352,19 +352,16 @@ public: void update_preview_moves_slider(); void reset_gcode_toolpaths(); -#endif // ENABLE_GCODE_VIEWER - -#if ENABLE_GCODE_VIEWER_AS_STATE void reset_last_loaded_gcode() { m_last_loaded_gcode = ""; } -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER const Mouse3DController& get_mouse3d_controller() const; Mouse3DController& get_mouse3d_controller(); void set_bed_shape() const; -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER void set_bed_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false) const; -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER // ROII wrapper for suppressing the Undo / Redo snapshot to be taken. class SuppressSnapshots @@ -415,9 +412,9 @@ private: bool m_tracking_popup_menu = false; wxString m_tracking_popup_menu_error_message; -#if ENABLE_GCODE_VIEWER_AS_STATE +#if ENABLE_GCODE_VIEWER wxString m_last_loaded_gcode; -#endif // ENABLE_GCODE_VIEWER_AS_STATE +#endif // ENABLE_GCODE_VIEWER void suppress_snapshots(); void allow_snapshots(); From 510e787bc7d6c5ceb27340e18457b7a4428fb095 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 4 Aug 2020 10:26:08 +0200 Subject: [PATCH 174/255] Fixed Print.xsp --- xs/xsp/Print.xsp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/xs/xsp/Print.xsp b/xs/xsp/Print.xsp index 0952513ca3..e4957c042f 100644 --- a/xs/xsp/Print.xsp +++ b/xs/xsp/Print.xsp @@ -76,10 +76,10 @@ _constant() %code%{ RETVAL = const_cast(&THIS->skirt()); %}; Ref brim() %code%{ RETVAL = const_cast(&THIS->brim()); %}; - std::string estimated_normal_print_time() - %code%{ RETVAL = THIS->print_statistics().estimated_normal_print_time; %}; - std::string estimated_silent_print_time() - %code%{ RETVAL = THIS->print_statistics().estimated_silent_print_time; %}; +// std::string estimated_normal_print_time() +// %code%{ RETVAL = THIS->print_statistics().estimated_normal_print_time; %}; +// std::string estimated_silent_print_time() +// %code%{ RETVAL = THIS->print_statistics().estimated_silent_print_time; %}; double total_used_filament() %code%{ RETVAL = THIS->print_statistics().total_used_filament; %}; double total_extruded_volume() From 8fc5be7e4f10bc397931269beecf1e5ab1fc8fef Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 5 Aug 2020 15:43:46 +0200 Subject: [PATCH 175/255] Refactoring to allow to quickly build the various options to show the estimated printing time in gcode viewer scene --- src/libslic3r/GCode.cpp | 76 +++++++++++++++------------- src/libslic3r/GCode.hpp | 6 ++- src/libslic3r/GCodeTimeEstimator.cpp | 23 ++------- src/libslic3r/GCodeTimeEstimator.hpp | 10 ++-- src/libslic3r/Print.cpp | 14 +---- src/libslic3r/Print.hpp | 22 ++------ src/libslic3r/Technologies.hpp | 8 ++- src/slic3r/GUI/GCodeViewer.cpp | 42 +++++++++------ src/slic3r/GUI/GCodeViewer.hpp | 10 +++- src/slic3r/GUI/GLCanvas3D.cpp | 11 ++-- src/slic3r/GUI/GLCanvas3D.hpp | 2 + src/slic3r/GUI/GUI_Preview.cpp | 10 ++-- src/slic3r/GUI/GUI_Preview.hpp | 2 + src/slic3r/GUI/KBShortcutsDialog.cpp | 10 ++-- src/slic3r/GUI/Plater.cpp | 53 ++----------------- 15 files changed, 125 insertions(+), 174 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index d7db315a7d..915694d12f 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -779,8 +779,7 @@ void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_ m_processor.process_file(path_tmp); if (result != nullptr) *result = std::move(m_processor.extract_result()); -#endif // ENABLE_GCODE_VIEWER - +#else GCodeTimeEstimator::PostProcessData normal_data = m_normal_time_estimator.get_post_process_data(); GCodeTimeEstimator::PostProcessData silent_data = m_silent_time_estimator.get_post_process_data(); @@ -789,21 +788,19 @@ void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_ BOOST_LOG_TRIVIAL(debug) << "Time estimator post processing" << log_memory_info(); GCodeTimeEstimator::post_process(path_tmp, 60.0f, remaining_times_enabled ? &normal_data : nullptr, (remaining_times_enabled && m_silent_time_estimator_enabled) ? &silent_data : nullptr); - if (remaining_times_enabled) - { + if (remaining_times_enabled) { m_normal_time_estimator.reset(); if (m_silent_time_estimator_enabled) m_silent_time_estimator.reset(); } -#if !ENABLE_GCODE_VIEWER // starts analyzer calculations if (m_enable_analyzer) { BOOST_LOG_TRIVIAL(debug) << "Preparing G-code preview data" << log_memory_info(); m_analyzer.calc_gcode_preview_data(*preview_data, [print]() { print->throw_if_canceled(); }); m_analyzer.reset(); } -#endif // !ENABLE_GCODE_VIEWER +#endif // ENABLE_GCODE_VIEWER if (rename_file(path_tmp, path)) throw std::runtime_error( @@ -820,7 +817,8 @@ void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_ // free functions called by GCode::_do_export() namespace DoExport { - static void init_time_estimators(const PrintConfig &config, GCodeTimeEstimator &normal_time_estimator, GCodeTimeEstimator &silent_time_estimator, bool &silent_time_estimator_enabled) +#if !ENABLE_GCODE_VIEWER + static void init_time_estimators(const PrintConfig &config, GCodeTimeEstimator &normal_time_estimator, GCodeTimeEstimator &silent_time_estimator, bool &silent_time_estimator_enabled) { // resets time estimators normal_time_estimator.reset(); @@ -892,10 +890,12 @@ namespace DoExport { normal_time_estimator.set_filament_unload_times(config.filament_unload_time.values); } } +#endif // !ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER - static void init_gcode_processor(const PrintConfig& config, GCodeProcessor& processor, bool silent_time_estimator_enabled) + static void init_gcode_processor(const PrintConfig& config, GCodeProcessor& processor, bool& silent_time_estimator_enabled) { + silent_time_estimator_enabled = (config.gcode_flavor == gcfMarlin) && config.silent_mode; processor.reset(); processor.apply_config(config); processor.enable_stealth_time_estimator(silent_time_estimator_enabled); @@ -1049,10 +1049,12 @@ namespace DoExport { // Fill in print_statistics and return formatted string containing filament statistics to be inserted into G-code comment section. static std::string update_print_stats_and_format_filament_stats( - const GCodeTimeEstimator &normal_time_estimator, +#if !ENABLE_GCODE_VIEWER + const GCodeTimeEstimator &normal_time_estimator, const GCodeTimeEstimator &silent_time_estimator, const bool silent_time_estimator_enabled, - const bool has_wipe_tower, +#endif // !ENABLE_GCODE_VIEWER + const bool has_wipe_tower, const WipeTowerData &wipe_tower_data, const std::vector &extruders, PrintStatistics &print_statistics) @@ -1060,21 +1062,13 @@ namespace DoExport { std::string filament_stats_string_out; print_statistics.clear(); -#if ENABLE_GCODE_VIEWER -#if ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR - print_statistics.estimated_normal_print_time_str = normal_time_estimator.get_time_dhm/*s*/(); - print_statistics.estimated_silent_print_time_str = silent_time_estimator_enabled ? silent_time_estimator.get_time_dhm/*s*/() : "N/A"; - print_statistics.estimated_normal_custom_gcode_print_times_str = normal_time_estimator.get_custom_gcode_times_dhm(true); - if (silent_time_estimator_enabled) - print_statistics.estimated_silent_custom_gcode_print_times_str = silent_time_estimator.get_custom_gcode_times_dhm(true); -#endif // ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR -#else +#if !ENABLE_GCODE_VIEWER print_statistics.estimated_normal_print_time = normal_time_estimator.get_time_dhm/*s*/(); print_statistics.estimated_silent_print_time = silent_time_estimator_enabled ? silent_time_estimator.get_time_dhm/*s*/() : "N/A"; print_statistics.estimated_normal_custom_gcode_print_times = normal_time_estimator.get_custom_gcode_times_dhm(true); if (silent_time_estimator_enabled) print_statistics.estimated_silent_custom_gcode_print_times = silent_time_estimator.get_custom_gcode_times_dhm(true); -#endif // ENABLE_GCODE_VIEWER +#endif // !ENABLE_GCODE_VIEWER print_statistics.total_toolchanges = std::max(0, wipe_tower_data.number_of_toolchanges); if (! extruders.empty()) { std::pair out_filament_used_mm ("; filament used [mm] = ", 0); @@ -1165,12 +1159,13 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu { PROFILE_FUNC(); - DoExport::init_time_estimators(print.config(), - // modifies the following: - m_normal_time_estimator, m_silent_time_estimator, m_silent_time_estimator_enabled); #if ENABLE_GCODE_VIEWER + // modifies m_silent_time_estimator_enabled DoExport::init_gcode_processor(print.config(), m_processor, m_silent_time_estimator_enabled); #else + DoExport::init_time_estimators(print.config(), + // modifies the following: + m_normal_time_estimator, m_silent_time_estimator, m_silent_time_estimator_enabled); DoExport::init_gcode_analyzer(print.config(), m_analyzer); #endif // ENABLE_GCODE_VIEWER @@ -1274,12 +1269,13 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu print.throw_if_canceled(); // adds tags for time estimators - if (print.config().remaining_times.value) - { +#if !ENABLE_GCODE_VIEWER + if (print.config().remaining_times.value) { _writeln(file, GCodeTimeEstimator::Normal_First_M73_Output_Placeholder_Tag); if (m_silent_time_estimator_enabled) _writeln(file, GCodeTimeEstimator::Silent_First_M73_Output_Placeholder_Tag); } +#endif // !ENABLE_GCODE_VIEWER // Prepare the helper object for replacing placeholders in custom G-code and output filename. m_placeholder_parser = print.placeholder_parser(); @@ -1574,25 +1570,31 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu _write(file, m_writer.postamble()); // adds tags for time estimators +#if !ENABLE_GCODE_VIEWER if (print.config().remaining_times.value) { _writeln(file, GCodeTimeEstimator::Normal_Last_M73_Output_Placeholder_Tag); if (m_silent_time_estimator_enabled) _writeln(file, GCodeTimeEstimator::Silent_Last_M73_Output_Placeholder_Tag); } +#endif // !ENABLE_GCODE_VIEWER print.throw_if_canceled(); // calculates estimated printing time +#if !ENABLE_GCODE_VIEWER m_normal_time_estimator.calculate_time(false); if (m_silent_time_estimator_enabled) m_silent_time_estimator.calculate_time(false); +#endif // !ENABLE_GCODE_VIEWER // Get filament stats. _write(file, DoExport::update_print_stats_and_format_filament_stats( // Const inputs - m_normal_time_estimator, m_silent_time_estimator, m_silent_time_estimator_enabled, - has_wipe_tower, print.wipe_tower_data(), +#if !ENABLE_GCODE_VIEWER + m_normal_time_estimator, m_silent_time_estimator, m_silent_time_estimator_enabled, +#endif // !ENABLE_GCODE_VIEWER + has_wipe_tower, print.wipe_tower_data(), m_writer.extruders(), // Modifies print.m_print_statistics)); @@ -1601,9 +1603,11 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu _write_format(file, "; total filament cost = %.1lf\n", print.m_print_statistics.total_cost); if (print.m_print_statistics.total_toolchanges > 0) _write_format(file, "; total toolchanges = %i\n", print.m_print_statistics.total_toolchanges); +#if !ENABLE_GCODE_VIEWER _write_format(file, "; estimated printing time (normal mode) = %s\n", m_normal_time_estimator.get_time_dhms().c_str()); if (m_silent_time_estimator_enabled) _write_format(file, "; estimated printing time (silent mode) = %s\n", m_silent_time_estimator.get_time_dhms().c_str()); +#endif // !ENABLE_GCODE_VIEWER // Append full config. _write(file, "\n"); @@ -1879,9 +1883,9 @@ namespace ProcessLayer #else // add tag for analyzer gcode += "; " + GCodeAnalyzer::Color_Change_Tag + ",T" + std::to_string(m600_extruder_before_layer) + "\n"; -#endif // ENABLE_GCODE_VIEWER // add tag for time estimator - gcode += "; " + GCodeTimeEstimator::Color_Change_Tag + "\n"; + gcode += "; " + GCodeTimeEstimator::Color_Change_Tag + "\n"; +#endif // ENABLE_GCODE_VIEWER if (!single_extruder_printer && m600_extruder_before_layer >= 0 && first_extruder_id != (unsigned)m600_extruder_before_layer // && !MMU1 @@ -1910,10 +1914,12 @@ namespace ProcessLayer //! FIXME_in_fw show message during print pause if (!pause_print_msg.empty()) gcode += "M117 " + pause_print_msg + "\n"; - // add tag for time estimator +#if !ENABLE_GCODE_VIEWER + // add tag for time estimator gcode += "; " + GCodeTimeEstimator::Pause_Print_Tag + "\n"; gcode += config.pause_print_gcode; - } +#endif // !ENABLE_GCODE_VIEWER + } else { #if ENABLE_GCODE_VIEWER @@ -2422,14 +2428,14 @@ void GCode::process_layer( #endif /* HAS_PRESSURE_EQUALIZER */ _write(file, gcode); - BOOST_LOG_TRIVIAL(trace) << "Exported layer " << layer.id() << " print_z " << print_z << +#if !ENABLE_GCODE_VIEWER + BOOST_LOG_TRIVIAL(trace) << "Exported layer " << layer.id() << " print_z " << print_z << ", time estimator memory: " << format_memsize_MB(m_normal_time_estimator.memory_used() + (m_silent_time_estimator_enabled ? m_silent_time_estimator.memory_used() : 0)) << -#if !ENABLE_GCODE_VIEWER ", analyzer memory: " << format_memsize_MB(m_analyzer.memory_used()) << -#endif // !ENABLE_GCODE_VIEWER log_memory_info(); +#endif // !ENABLE_GCODE_VIEWER } void GCode::apply_print_config(const PrintConfig &print_config) @@ -3078,10 +3084,12 @@ void GCode::_write(FILE* file, const char *what) // writes string to file fwrite(gcode, 1, ::strlen(gcode), file); +#if !ENABLE_GCODE_VIEWER // updates time estimator and gcode lines vector m_normal_time_estimator.add_gcode_block(gcode); if (m_silent_time_estimator_enabled) m_silent_time_estimator.add_gcode_block(gcode); +#endif // !ENABLE_GCODE_VIEWER } } diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 69f98bfa52..6f97d5dbd3 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -17,8 +17,8 @@ #include "GCode/GCodeProcessor.hpp" #else #include "GCode/Analyzer.hpp" -#endif // ENABLE_GCODE_VIEWER #include "GCodeTimeEstimator.hpp" +#endif // ENABLE_GCODE_VIEWER #include "EdgeGrid.hpp" #include "GCode/ThumbnailData.hpp" @@ -179,8 +179,10 @@ public: #endif // !ENABLE_GCODE_VIEWER m_brim_done(false), m_second_layer_things_done(false), +#if !ENABLE_GCODE_VIEWER m_normal_time_estimator(GCodeTimeEstimator::Normal), m_silent_time_estimator(GCodeTimeEstimator::Silent), +#endif // !ENABLE_GCODE_VIEWER m_silent_time_estimator_enabled(false), m_last_obj_copy(nullptr, Point(std::numeric_limits::max(), std::numeric_limits::max())) {} @@ -405,9 +407,11 @@ private: // Index of a last object copy extruded. std::pair m_last_obj_copy; +#if !ENABLE_GCODE_VIEWER // Time estimators GCodeTimeEstimator m_normal_time_estimator; GCodeTimeEstimator m_silent_time_estimator; +#endif // !ENABLE_GCODE_VIEWER bool m_silent_time_estimator_enabled; #if ENABLE_GCODE_VIEWER diff --git a/src/libslic3r/GCodeTimeEstimator.cpp b/src/libslic3r/GCodeTimeEstimator.cpp index 4bfe322ce2..aa9ee2f643 100644 --- a/src/libslic3r/GCodeTimeEstimator.cpp +++ b/src/libslic3r/GCodeTimeEstimator.cpp @@ -9,6 +9,8 @@ #include #include +#if !ENABLE_GCODE_VIEWER + static const float MMMIN_TO_MMSEC = 1.0f / 60.0f; static const float MILLISEC_TO_SEC = 0.001f; static const float INCHES_TO_MM = 25.4f; @@ -722,24 +724,6 @@ namespace Slic3r { return ret; } -#if ENABLE_GCODE_VIEWER -#if ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR - std::vector>> GCodeTimeEstimator::get_custom_gcode_times_dhm(bool include_remaining) const - { - std::vector>> ret; - - float total_time = 0.0f; - for (const auto& [type, time] : m_custom_gcode_times) { - std::string duration = _get_time_dhm(time); - std::string remaining = include_remaining ? _get_time_dhm(m_time - total_time) : ""; - ret.push_back({ type, { duration, remaining } }); - total_time += time; - } - - return ret; - } -#endif // ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR -#else std::vector> GCodeTimeEstimator::get_custom_gcode_times_dhm(bool include_remaining) const { std::vector> ret; @@ -760,7 +744,6 @@ namespace Slic3r { return ret; } -#endif // ENABLE_GCODE_VIEWER // Return an estimate of the memory consumed by the time estimator. size_t GCodeTimeEstimator::memory_used() const @@ -1690,3 +1673,5 @@ namespace Slic3r { } #endif // ENABLE_MOVE_STATS } + +#endif // !ENABLE_GCODE_VIEWER diff --git a/src/libslic3r/GCodeTimeEstimator.hpp b/src/libslic3r/GCodeTimeEstimator.hpp index 3b92f02692..0dd3407cb0 100644 --- a/src/libslic3r/GCodeTimeEstimator.hpp +++ b/src/libslic3r/GCodeTimeEstimator.hpp @@ -6,6 +6,8 @@ #include "GCodeReader.hpp" #include "CustomGCode.hpp" +#if !ENABLE_GCODE_VIEWER + #define ENABLE_MOVE_STATS 0 namespace Slic3r { @@ -370,13 +372,7 @@ namespace Slic3r { // Returns the estimated time, in format DDd HHh MMm, for each custom_gcode // If include_remaining==true the strings will be formatted as: "time for custom_gcode (remaining time at color start)" -#if ENABLE_GCODE_VIEWER -#if ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR - std::vector>> get_custom_gcode_times_dhm(bool include_remaining) const; -#endif // ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR -#else std::vector> get_custom_gcode_times_dhm(bool include_remaining) const; -#endif // ENABLE_GCODE_VIEWER // Return an estimate of the memory consumed by the time estimator. size_t memory_used() const; @@ -487,4 +483,6 @@ namespace Slic3r { } /* namespace Slic3r */ +#endif // !ENABLE_GCODE_VIEWER + #endif /* slic3r_GCodeTimeEstimator_hpp_ */ diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index a48d6f602f..1b1aad2578 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -2190,23 +2190,13 @@ std::string Print::output_filename(const std::string &filename_base) const DynamicConfig PrintStatistics::config() const { DynamicConfig config; -#if ENABLE_GCODE_VIEWER -#if ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR - config.set_key_value("print_time", new ConfigOptionString(this->estimated_normal_print_time_str)); - config.set_key_value("normal_print_time", new ConfigOptionString(this->estimated_normal_print_time_str)); - config.set_key_value("silent_print_time", new ConfigOptionString(this->estimated_silent_print_time_str)); -#else - config.set_key_value("print_time", new ConfigOptionString(short_time(get_time_dhms(this->estimated_normal_print_time)))); - config.set_key_value("normal_print_time", new ConfigOptionString(short_time(get_time_dhms(this->estimated_normal_print_time)))); - config.set_key_value("silent_print_time", new ConfigOptionString(short_time(get_time_dhms(this->estimated_silent_print_time)))); -#endif // ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR -#else +#if !ENABLE_GCODE_VIEWER std::string normal_print_time = short_time(this->estimated_normal_print_time); std::string silent_print_time = short_time(this->estimated_silent_print_time); config.set_key_value("print_time", new ConfigOptionString(normal_print_time)); config.set_key_value("normal_print_time", new ConfigOptionString(normal_print_time)); config.set_key_value("silent_print_time", new ConfigOptionString(silent_print_time)); -#endif // ENABLE_GCODE_VIEWER +#endif // !ENABLE_GCODE_VIEWER config.set_key_value("used_filament", new ConfigOptionFloat(this->total_used_filament / 1000.)); config.set_key_value("extruded_volume", new ConfigOptionFloat(this->total_extruded_volume)); config.set_key_value("total_cost", new ConfigOptionFloat(this->total_cost)); diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 62c00aa88d..73efbf49a1 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -303,19 +303,12 @@ private: struct PrintStatistics { PrintStatistics() { clear(); } -#if ENABLE_GCODE_VIEWER -#if ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR - std::string estimated_normal_print_time_str; - std::string estimated_silent_print_time_str; - std::vector>> estimated_normal_custom_gcode_print_times_str; - std::vector>> estimated_silent_custom_gcode_print_times_str; -#endif // ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR -#else +#if !ENABLE_GCODE_VIEWER std::string estimated_normal_print_time; std::string estimated_silent_print_time; std::vector> estimated_normal_custom_gcode_print_times; std::vector> estimated_silent_custom_gcode_print_times; -#endif // ENABLE_GCODE_VIEWER +#endif // !ENABLE_GCODE_VIEWER double total_used_filament; double total_extruded_volume; double total_cost; @@ -333,19 +326,12 @@ struct PrintStatistics std::string finalize_output_path(const std::string &path_in) const; void clear() { -#if ENABLE_GCODE_VIEWER -#if ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR - estimated_normal_print_time_str.clear(); - estimated_silent_print_time_str.clear(); - estimated_normal_custom_gcode_print_times_str.clear(); - estimated_silent_custom_gcode_print_times_str.clear(); -#endif // ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR -#else +#if !ENABLE_GCODE_VIEWER estimated_normal_print_time.clear(); estimated_silent_print_time.clear(); estimated_normal_custom_gcode_print_times.clear(); estimated_silent_custom_gcode_print_times.clear(); -#endif //ENABLE_GCODE_VIEWER +#endif // !ENABLE_GCODE_VIEWER total_used_filament = 0.; total_extruded_volume = 0.; total_cost = 0.; diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index c14e2df52f..75849b689a 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -58,7 +58,11 @@ #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) #define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_SHADERS_EDITOR (0 && ENABLE_GCODE_VIEWER) -#define ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR (1 && ENABLE_GCODE_VIEWER) -#define ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG (1 && ENABLE_GCODE_VIEWER) + +#define TIME_ESTIMATE_NONE 0 +#define TIME_ESTIMATE_DEFAULT 1 +#define TIME_ESTIMATE_MODAL 2 +#define TIME_ESTIMATE_LEGEND 3 +#define GCODE_VIEWER_TIME_ESTIMATE TIME_ESTIMATE_MODAL #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index e746635ee2..7c5252070d 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -332,7 +332,9 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& wxGetApp().plater()->set_bed_shape(bed_shape, "", "", true); } +#if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE m_time_statistics = gcode_result.time_statistics; +#endif // GCODE_VIEWER_TIME_ESTIMATE } void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors) @@ -406,7 +408,9 @@ void GCodeViewer::reset() m_layers_zs = std::vector(); m_layers_z_range = { 0.0, 0.0 }; m_roles = std::vector(); +#if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE m_time_statistics.reset(); +#endif // GCODE_VIEWER_TIME_ESTIMATE #if ENABLE_GCODE_VIEWER_STATISTICS m_statistics.reset_all(); @@ -419,7 +423,7 @@ void GCodeViewer::render() const m_statistics.reset_opengl(); #endif // ENABLE_GCODE_VIEWER_STATISTICS -#if ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG +#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_MODAL if (m_roles.empty()) { m_time_estimate_frames_count = 0; return; @@ -427,7 +431,7 @@ void GCodeViewer::render() const #else if (m_roles.empty()) return; -#endif // ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG +#endif // GCODE_VIEWER_TIME_ESTIMATE glsafe(::glEnable(GL_DEPTH_TEST)); render_toolpaths(); @@ -435,7 +439,9 @@ void GCodeViewer::render() const m_sequential_view.marker.render(); render_shells(); render_legend(); +#if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE render_time_estimate(); +#endif // GCODE_VIEWER_TIME_ESTIMATE #if ENABLE_GCODE_VIEWER_STATISTICS render_statistics(); #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -474,9 +480,9 @@ unsigned int GCodeViewer::get_options_visibility_flags() const flags = set_flag(flags, static_cast(Preview::OptionType::Shells), m_shells.visible); flags = set_flag(flags, static_cast(Preview::OptionType::ToolMarker), m_sequential_view.marker.is_visible()); flags = set_flag(flags, static_cast(Preview::OptionType::Legend), is_legend_enabled()); -#if !ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG +#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_DEFAULT flags = set_flag(flags, static_cast(Preview::OptionType::TimeEstimate), is_time_estimate_enabled()); -#endif // !ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG +#endif // GCODE_VIEWER_TIME_ESTIMATE return flags; } @@ -496,9 +502,9 @@ void GCodeViewer::set_options_visibility_from_flags(unsigned int flags) m_shells.visible = is_flag_set(static_cast(Preview::OptionType::Shells)); m_sequential_view.marker.set_visible(is_flag_set(static_cast(Preview::OptionType::ToolMarker))); enable_legend(is_flag_set(static_cast(Preview::OptionType::Legend))); -#if !ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG +#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_DEFAULT enable_time_estimate(is_flag_set(static_cast(Preview::OptionType::TimeEstimate))); -#endif // !ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG +#endif // GCODE_VIEWER_TIME_ESTIMATE } void GCodeViewer::set_layers_z_range(const std::array& layers_z_range) @@ -510,6 +516,7 @@ void GCodeViewer::set_layers_z_range(const std::array& layers_z_range wxGetApp().plater()->update_preview_moves_slider(); } +#if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE void GCodeViewer::enable_time_estimate(bool enable) { m_time_estimate_enabled = enable; @@ -517,6 +524,7 @@ void GCodeViewer::enable_time_estimate(bool enable) wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); } +#endif // GCODE_VIEWER_TIME_ESTIMATE void GCodeViewer::export_toolpaths_to_obj(const char* filename) const { @@ -1682,24 +1690,25 @@ void GCodeViewer::render_legend() const ImGui::PopStyleVar(); } +#if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE void GCodeViewer::render_time_estimate() const { if (!m_time_estimate_enabled) { -#if ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG +#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_MODAL m_time_estimate_frames_count = 0; -#endif // ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG +#endif // GCODE_VIEWER_TIME_ESTIMATE return; } ImGuiWrapper& imgui = *wxGetApp().imgui(); -#if ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG +#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_MODAL // esc if (ImGui::GetIO().KeysDown[27]) { m_time_estimate_enabled = false; return; } -#endif // ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG +#endif // GCODE_VIEWER_TIME_ESTIMATE using Times = std::pair; using TimesList = std::vector>; @@ -1833,7 +1842,7 @@ void GCodeViewer::render_time_estimate() const imgui.text(short_time(get_time_dhms(time))); ImGui::SameLine(offsets[1]); char buf[64]; - ::sprintf(buf, "%.2f%%", 100.0f * percentage); + ::sprintf(buf, "%.1f%%", 100.0f * percentage); ImGuiWindow* window = ImGui::GetCurrentWindow(); ImRect frame_bb; frame_bb.Min = { ImGui::GetCursorScreenPos().x, window->DC.CursorPos.y }; @@ -1978,7 +1987,7 @@ void GCodeViewer::render_time_estimate() const }; Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size(); -#if ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG +#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_MODAL std::string title = _u8L("Estimated printing time"); ImGui::OpenPopup(title.c_str()); @@ -1996,14 +2005,14 @@ void GCodeViewer::render_time_estimate() const } #else imgui.set_next_window_pos(static_cast(cnv_size.get_width()), static_cast(cnv_size.get_height()), ImGuiCond_Always, 1.0f, 1.0f); - ImGui::SetNextWindowSizeConstraints({ 0.0f, 0.0f }, { -1.0f, 0.5f * static_cast(cnv_size.get_height() })); + ImGui::SetNextWindowSizeConstraints({ 0.0f, 0.0f }, { -1.0f, 0.5f * static_cast(cnv_size.get_height()) }); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGui::SetNextWindowBgAlpha(0.6f); imgui.begin(std::string("Time_estimate"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove); // title imgui.title(_u8L("Estimated printing time")); -#endif // ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG +#endif // GCODE_VIEWER_TIME_ESTIMATE // mode tabs ImGui::BeginTabBar("mode_tabs"); @@ -2029,7 +2038,7 @@ void GCodeViewer::render_time_estimate() const } ImGui::EndTabBar(); -#if ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG +#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_MODAL // this is ugly, but it is the only way to ensure that the dialog is large // enough to show enterely the title // see: https://github.com/ocornut/imgui/issues/3239 @@ -2044,9 +2053,10 @@ void GCodeViewer::render_time_estimate() const } #else imgui.end(); -#endif // ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG +#endif // GCODE_VIEWER_TIME_ESTIMATE ImGui::PopStyleVar(); } +#endif // GCODE_VIEWER_TIME_ESTIMATE #if ENABLE_GCODE_VIEWER_STATISTICS void GCodeViewer::render_statistics() const diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 0a32a97e67..06cd1326fb 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -341,13 +341,15 @@ private: Shells m_shells; EViewType m_view_type{ EViewType::FeatureType }; bool m_legend_enabled{ true }; +#if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE PrintEstimatedTimeStatistics m_time_statistics; -#if ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG +#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_MODAL mutable bool m_time_estimate_enabled{ false }; mutable unsigned int m_time_estimate_frames_count{ 0 }; #else bool m_time_estimate_enabled{ false }; -#endif // ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG +#endif // GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_MODAL +#endif // GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE #if ENABLE_GCODE_VIEWER_STATISTICS mutable Statistics m_statistics; #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -403,8 +405,10 @@ public: bool is_legend_enabled() const { return m_legend_enabled; } void enable_legend(bool enable) { m_legend_enabled = enable; } +#if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE bool is_time_estimate_enabled() const { return m_time_estimate_enabled; } void enable_time_estimate(bool enable); +#endif // GCODE_VIEWER_TIME_ESTIMATE void export_toolpaths_to_obj(const char* filename) const; @@ -416,7 +420,9 @@ private: void render_toolpaths() const; void render_shells() const; void render_legend() const; +#if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE void render_time_estimate() const; +#endif // GCODE_VIEWER_TIME_ESTIMATE #if ENABLE_GCODE_VIEWER_STATISTICS void render_statistics() const; #endif // ENABLE_GCODE_VIEWER_STATISTICS diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 5a1381a779..35be455591 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3109,17 +3109,18 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) break; } #endif // ENABLE_RENDER_PICKING_PASS -#if ENABLE_GCODE_VIEWER +#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_DEFAULT || GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_MODAL case 'T': - case 't': { + case 't': + { if (!m_main_toolbar.is_enabled()) { m_gcode_viewer.enable_time_estimate(!m_gcode_viewer.is_time_estimate_enabled()); m_dirty = true; wxGetApp().plater()->update_preview_bottom_toolbar(); - } + } break; - } -#endif // ENABLE_GCODE_VIEWER + } +#endif // GCODE_VIEWER_TIME_ESTIMATE case 'Z': #if ENABLE_GCODE_VIEWER case 'z': diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 15bb3e6f06..ee1d32abb8 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -558,7 +558,9 @@ public: void reset_gcode_toolpaths() { m_gcode_viewer.reset(); } const GCodeViewer::SequentialView& get_gcode_sequential_view() const { return m_gcode_viewer.get_sequential_view(); } void update_gcode_sequential_view_current(unsigned int first, unsigned int last) { m_gcode_viewer.update_sequential_view_current(first, last); } +#if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE bool is_time_estimate_enabled() const { return m_gcode_viewer.is_time_estimate_enabled(); } +#endif // GCODE_VIEWER_TIME_ESTIMATE #endif // ENABLE_GCODE_VIEWER void toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 98c02322ee..38657a460a 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -323,12 +323,12 @@ bool Preview::init(wxWindow* parent, Model* model) get_option_type_string(OptionType::CustomGCodes) + "|0|" + get_option_type_string(OptionType::Shells) + "|0|" + get_option_type_string(OptionType::ToolMarker) + "|0|" + -#if ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG - get_option_type_string(OptionType::Legend) + "|1" -#else +#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_DEFAULT get_option_type_string(OptionType::Legend) + "|1|" + get_option_type_string(OptionType::TimeEstimate) + "|1" -#endif // ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG +#else + get_option_type_string(OptionType::Legend) + "|1" +#endif // GCODE_VIEWER_TIME_ESTIMATE ); Slic3r::GUI::create_combochecklist(m_combochecklist_options, GUI::into_u8(_L("Options")), options_items); #else @@ -1459,7 +1459,9 @@ wxString Preview::get_option_type_string(OptionType type) const case OptionType::Shells: { return _L("Shells"); } case OptionType::ToolMarker: { return _L("Tool marker"); } case OptionType::Legend: { return _L("Legend"); } +#if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE case OptionType::TimeEstimate: { return _L("Estimated printing time"); } +#endif // GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE default: { return ""; } } } diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index ff3bf41371..c74dccc5c1 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -150,7 +150,9 @@ public: Shells, ToolMarker, Legend, +#if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE TimeEstimate +#endif // GCODE_VIEWER_TIME_ESTIMATE }; Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process, diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index fc6bc98914..2c65673cd0 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -204,13 +204,11 @@ void KBShortcutsDialog::fill_shortcuts() { "U", L("Upper Layer") }, { "D", L("Lower Layer") }, { "L", L("Show/Hide Legend") }, -#if ENABLE_GCODE_VIEWER -#if ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG - { "T", L("Show Estimated printing time") } -#else +#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_DEFAULT { "T", L("Show/Hide Estimated printing time") } -#endif // ENABLE_GCODE_VIEWER_MODAL_TIME_ESTIMATE_DIALOG -#endif // ENABLE_GCODE_VIEWER +#elif GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_MODAL + { "T", L("Show Estimated printing time") } +#endif // GCODE_VIEWER_TIME_ESTIMATE }; m_full_shortcuts.push_back(std::make_pair(_L("Preview"), preview_shortcuts)); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index e2c141e4be..a03d31bffb 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1324,15 +1324,10 @@ void Sidebar::update_sliced_info_sizer() p->sliced_info->SetTextAndShow(siCost, info_text, new_label); #if ENABLE_GCODE_VIEWER -#if ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR - if (p->plater->get_current_canvas3D()->is_time_estimate_enabled() || (ps.estimated_normal_print_time_str == "N/A" && ps.estimated_silent_print_time_str == "N/A")) + // hide the estimate time + p->sliced_info->SetTextAndShow(siEstimatedTime, "N/A"); #else - if (p->plater->get_current_canvas3D()->is_time_estimate_enabled() || (ps.estimated_normal_print_time <= 0.0f && ps.estimated_silent_print_time <= 0.0f)) -#endif // ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR -#else - if (ps.estimated_normal_print_time == "N/A" && ps.estimated_silent_print_time == "N/A") -#endif // ENABLE_GCODE_VIEWER p->sliced_info->SetTextAndShow(siEstimatedTime, "N/A"); else { new_label = _L("Estimated printing time") + ":"; @@ -1340,15 +1335,7 @@ void Sidebar::update_sliced_info_sizer() wxString str_color = _L("Color"); wxString str_pause = _L("Pause"); -#if ENABLE_GCODE_VIEWER -#if ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR - auto fill_labels = [str_color, str_pause](const std::vector>>& times, -#else - auto fill_labels = [str_color, str_pause](const std::vector>>& times, -#endif // ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR -#else auto fill_labels = [str_color, str_pause](const std::vector>& times, -#endif // ENABLE_GCODE_VIEWER wxString& new_label, wxString& info_text) { int color_change_count = 0; @@ -1366,41 +1353,10 @@ void Sidebar::update_sliced_info_sizer() if (i != (int)times.size() - 1 && times[i].first == CustomGCode::PausePrint) new_label += format_wxstr(" -> %1%", str_pause); -#if ENABLE_GCODE_VIEWER -#if ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR - info_text += format_wxstr("\n%1% (%2%)", times[i].second.first, times[i].second.second); -#else - info_text += format_wxstr("\n%1% (%2%)", short_time(get_time_dhms(times[i].second.first)), short_time(get_time_dhms(times[i].second.second))); -#endif // ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR -#else info_text += format_wxstr("\n%1%", times[i].second); -#endif // ENABLE_GCODE_VIEWER } }; -#if ENABLE_GCODE_VIEWER -#if ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR - if (ps.estimated_normal_print_time_str != "N/A") { - new_label += format_wxstr("\n - %1%", _L("normal mode")); - info_text += format_wxstr("\n%1%", ps.estimated_normal_print_time_str); - fill_labels(ps.estimated_normal_custom_gcode_print_times_str, new_label, info_text); - } - if (ps.estimated_silent_print_time_str != "N/A") { - new_label += format_wxstr("\n - %1%", _L("stealth mode")); - info_text += format_wxstr("\n%1%", ps.estimated_silent_print_time_str); - fill_labels(ps.estimated_silent_custom_gcode_print_times_str, new_label, info_text); -#else - if (ps.estimated_normal_print_time > 0.0f) { - new_label += format_wxstr("\n - %1%", _L("normal mode")); - info_text += format_wxstr("\n%1%", short_time(get_time_dhms(ps.estimated_normal_print_time))); - fill_labels(ps.estimated_normal_custom_gcode_print_times, new_label, info_text); - } - if (ps.estimated_silent_print_time > 0.0f) { - new_label += format_wxstr("\n - %1%", _L("stealth mode")); - info_text += format_wxstr("\n%1%", short_time(get_time_dhms(ps.estimated_silent_print_time))); - fill_labels(ps.estimated_silent_custom_gcode_print_times, new_label, info_text); -#endif // ENABLE_GCODE_VIEWER_USE_OLD_TIME_ESTIMATOR -#else if (ps.estimated_normal_print_time != "N/A") { new_label += format_wxstr("\n - %1%", _L("normal mode")); info_text += format_wxstr("\n%1%", ps.estimated_normal_print_time); @@ -1416,10 +1372,10 @@ void Sidebar::update_sliced_info_sizer() new_label += format_wxstr("\n - %1%", _L("stealth mode")); info_text += format_wxstr("\n%1%", ps.estimated_silent_print_time); fill_labels(ps.estimated_silent_custom_gcode_print_times, new_label, info_text); -#endif // ENABLE_GCODE_VIEWER } p->sliced_info->SetTextAndShow(siEstimatedTime, info_text, new_label); } +#endif // !ENABLE_GCODE_VIEWER // if there is a wipe tower, insert number of toolchanges info into the array: p->sliced_info->SetTextAndShow(siWTNumbetOfToolchanges, is_wipe_tower ? wxString::Format("%.d", ps.total_toolchanges) : "N/A"); @@ -1428,9 +1384,8 @@ void Sidebar::update_sliced_info_sizer() p->sliced_info->SetTextAndShow(siMateril_unit, "N/A"); } } -#if ENABLE_GCODE_VIEWER + Layout(); -#endif // ENABLE_GCODE_VIEWER } void Sidebar::show_sliced_info_sizer(const bool show) From 2aa1c2776c5c6b96b0e60ace24fef8720c73a502 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 6 Aug 2020 10:15:34 +0200 Subject: [PATCH 176/255] GCodeViewer -> Estimated printing times shown in the legend --- src/libslic3r/Technologies.hpp | 2 +- src/slic3r/GUI/GCodeViewer.cpp | 317 ++++++++++++++++++++++++++- src/slic3r/GUI/GCodeViewer.hpp | 3 + src/slic3r/GUI/GUI_Preview.cpp | 4 + src/slic3r/GUI/KBShortcutsDialog.cpp | 4 + 5 files changed, 320 insertions(+), 10 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 75849b689a..609aecf635 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -63,6 +63,6 @@ #define TIME_ESTIMATE_DEFAULT 1 #define TIME_ESTIMATE_MODAL 2 #define TIME_ESTIMATE_LEGEND 3 -#define GCODE_VIEWER_TIME_ESTIMATE TIME_ESTIMATE_MODAL +#define GCODE_VIEWER_TIME_ESTIMATE TIME_ESTIMATE_LEGEND #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 7c5252070d..2b25a11bb5 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -411,6 +411,9 @@ void GCodeViewer::reset() #if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE m_time_statistics.reset(); #endif // GCODE_VIEWER_TIME_ESTIMATE +#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND + m_time_estimate_mode = PrintEstimatedTimeStatistics::ETimeMode::Normal; +#endif // GCODE_VIEWER_TIME_ESTIMATE #if ENABLE_GCODE_VIEWER_STATISTICS m_statistics.reset_all(); @@ -1375,8 +1378,21 @@ void GCodeViewer::render_legend() const Line }; +#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND + const PrintEstimatedTimeStatistics::Mode& time_mode = m_time_statistics.modes[static_cast(m_time_estimate_mode)]; + + float icon_size = ImGui::GetTextLineHeight(); + float percent_bar_size = 2.0f * ImGui::GetTextLineHeight(); + + auto append_item = [this, draw_list, icon_size, percent_bar_size, &imgui](EItemType type, const Color& color, const std::string& label, + bool visible = true, const std::string& time = "", float percent = 0.0f, float max_percent = 0.0f, const std::array& offsets = { 0.0f, 0.0f }, + std::function callback = nullptr) { + if (!visible) + ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.3333f); +#else auto append_item = [this, draw_list, &imgui](EItemType type, const Color& color, const std::string& label, std::function callback = nullptr) { float icon_size = ImGui::GetTextLineHeight(); +#endif // GCODE_VIEWER_TIME_ESTIMATE ImVec2 pos = ImGui::GetCursorScreenPos(); switch (type) { @@ -1438,9 +1454,49 @@ void GCodeViewer::render_legend() const if (callback != nullptr) { if (ImGui::MenuItem(label.c_str())) callback(); +#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND + else { + // show tooltip + if (ImGui::IsItemHovered()) { + if (!visible) + ImGui::PopStyleVar(); + ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BACKGROND); + ImGui::BeginTooltip(); + imgui.text(visible ? _u8L("Click to hide") : _u8L("Click to show")); + ImGui::EndTooltip(); + ImGui::PopStyleColor(); + if (!visible) + ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.3333f); + + // to avoid the tooltip to change size when moving the mouse + wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); + wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); + } + } + + if (!time.empty()) { + ImGui::SameLine(offsets[0]); + imgui.text(time); + ImGui::SameLine(offsets[1]); + pos = ImGui::GetCursorScreenPos(); + float width = percent_bar_size * percent / max_percent; + draw_list->AddRectFilled({ pos.x, pos.y + 2.0f }, { pos.x + width, pos.y + icon_size - 2.0f }, + ImGui::GetColorU32(ImGuiWrapper::COL_ORANGE_LIGHT)); + ImGui::Dummy({ percent_bar_size, icon_size }); + ImGui::SameLine(); + char buf[64]; + ::sprintf(buf, "%.1f%%", 100.0f * percent); + ImGui::TextUnformatted((percent > 0.0f) ? buf : ""); + } +#endif // GCODE_VIEWER_TIME_ESTIMATE } else imgui.text(label); + +#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND + if (!visible) + ImGui::PopStyleVar(); +#endif // GCODE_VIEWER_TIME_ESTIMATE }; auto append_range = [this, draw_list, &imgui, append_item](const Extrusions::Range& range, unsigned int decimals) { @@ -1461,6 +1517,34 @@ void GCodeViewer::render_legend() const } }; +#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND + auto append_headers = [&imgui](const std::array& texts, const std::array& offsets) { + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, texts[0]); + ImGui::SameLine(offsets[0]); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, texts[1]); + ImGui::SameLine(offsets[1]); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, texts[2]); + ImGui::Separator(); + }; + + auto max_width = [](const std::vector& items, const std::string& title, float extra_size = 0.0f) { + float ret = ImGui::CalcTextSize(title.c_str()).x; + for (const std::string& item : items) { + ret = std::max(ret, extra_size + ImGui::CalcTextSize(item.c_str()).x); + } + return ret; + }; + + auto calculate_offsets = [max_width](const std::vector& labels, const std::vector& times, + const std::array& titles, float extra_size = 0.0f) { + const ImGuiStyle& style = ImGui::GetStyle(); + std::array ret = { 0.0f, 0.0f }; + ret[0] = max_width(labels, titles[0], extra_size) + 3.0f * style.ItemSpacing.x; + ret[1] = ret[0] + max_width(times, titles[1]) + style.ItemSpacing.x; + return ret; + }; +#endif // GCODE_VIEWER_TIME_ESTIMATE + auto color_print_ranges = [this](unsigned char extruder_id, const std::vector& custom_gcode_per_print_z) { std::vector>> ret; ret.reserve(custom_gcode_per_print_z.size()); @@ -1508,10 +1592,83 @@ void GCodeViewer::render_legend() const return _u8L("from") + " " + std::string(buf1) + " " + _u8L("to") + " " + std::string(buf2) + " " + _u8L("mm"); }; - // extrusion paths -> title +#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND + auto role_time_and_percent = [this, time_mode](ExtrusionRole role) { + auto it = std::find_if(time_mode.roles_times.begin(), time_mode.roles_times.end(), [role](const std::pair& item) { return role == item.first; }); + return (it != time_mode.roles_times.end()) ? std::make_pair(it->second, it->second / time_mode.time) : std::make_pair(0.0f, 0.0f); + }; + + // data used to properly align items in columns when showing time + std::array offsets = { 0.0f, 0.0f }; + std::vector labels; + std::vector times; + std::vector percents; + float max_percent = 0.0f; + + if (m_view_type == EViewType::FeatureType) { + // calculate offsets to align time/percentage data + for (size_t i = 0; i < m_roles.size(); ++i) { + ExtrusionRole role = m_roles[i]; + if (role < erCount) { + labels.push_back(_u8L(ExtrusionEntity::role_to_string(role))); + auto [time, percent] = role_time_and_percent(role); + times.push_back((time > 0.0f) ? short_time(get_time_dhms(time)) : ""); + percents.push_back(percent); + max_percent = std::max(max_percent, percent); + } + } + + offsets = calculate_offsets(labels, times, { _u8L("Feature type"), _u8L("Time") }, icon_size); + } + + // total estimated printing time section + if (time_mode.time > 0.0f && (m_view_type == EViewType::FeatureType || + (m_view_type == EViewType::ColorPrint && !time_mode.custom_gcode_times.empty()))) { + ImGui::AlignTextToFramePadding(); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Estimated printing time") + ":"); + ImGui::SameLine(); + imgui.text(short_time(get_time_dhms(time_mode.time))); + + auto show_mode_button = [this, &imgui](const std::string& label, PrintEstimatedTimeStatistics::ETimeMode mode) { + if (m_time_statistics.modes[static_cast(mode)].roles_times.size() > 0) { + ImGui::SameLine(0.0f, 10.0f); + if (imgui.button(label)) { + m_time_estimate_mode = mode; + wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); + wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); + } + } + }; + + switch (m_time_estimate_mode) + { + case PrintEstimatedTimeStatistics::ETimeMode::Normal: + { + show_mode_button(_u8L("Show stealth mode"), PrintEstimatedTimeStatistics::ETimeMode::Stealth); + break; + } + case PrintEstimatedTimeStatistics::ETimeMode::Stealth: + { + show_mode_button(_u8L("Show normal mode"), PrintEstimatedTimeStatistics::ETimeMode::Normal); + break; + } + } + ImGui::Spacing(); + } +#endif // GCODE_VIEWER_TIME_ESTIMATE + + // extrusion paths section -> title switch (m_view_type) { +#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND + case EViewType::FeatureType: + { + append_headers({ _u8L("Feature type"), _u8L("Time"), _u8L("Percentage") }, offsets); + break; + } +#else case EViewType::FeatureType: { imgui.title(_u8L("Feature type")); break; } +#endif // GCODE_VIEWER_TIME_ESTIMATE case EViewType::Height: { imgui.title(_u8L("Height (mm)")); break; } case EViewType::Width: { imgui.title(_u8L("Width (mm)")); break; } case EViewType::Feedrate: { imgui.title(_u8L("Speed (mm/s)")); break; } @@ -1522,28 +1679,38 @@ void GCodeViewer::render_legend() const default: { break; } } - // extrusion paths -> items + // extrusion paths section -> items switch (m_view_type) { case EViewType::FeatureType: { - for (ExtrusionRole role : m_roles) { + for (size_t i = 0; i < m_roles.size(); ++i) { + ExtrusionRole role = m_roles[i]; + if (role >= erCount) + continue; bool visible = is_visible(role); +#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND + append_item(EItemType::Hexagon, Extrusion_Role_Colors[static_cast(role)], labels[i], + visible, times[i], percents[i], max_percent, offsets, [this, role, visible]() { +#else if (!visible) ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.3333f); - append_item(EItemType::Hexagon, Extrusion_Role_Colors[static_cast(role)], _u8L(ExtrusionEntity::role_to_string(role)), [this, role]() { - if (role < erCount) { - m_extrusions.role_visibility_flags = is_visible(role) ? m_extrusions.role_visibility_flags & ~(1 << role) : m_extrusions.role_visibility_flags | (1 << role); + append_item(EItemType::Hexagon, Extrusion_Role_Colors[static_cast(role)], _u8L(ExtrusionEntity::role_to_string(role)), + [this, role, visible]() { +#endif // GCODE_VIEWER_TIME_ESTIMATE + m_extrusions.role_visibility_flags = visible ? m_extrusions.role_visibility_flags & ~(1 << role) : m_extrusions.role_visibility_flags | (1 << role); // update buffers' render paths refresh_render_paths(false, false); wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); wxGetApp().plater()->update_preview_bottom_toolbar(); } - }); + ); +#if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_LEGEND if (!visible) ImGui::PopStyleVar(); +#endif // GCODE_VIEWER_TIME_ESTIMATE } break; } @@ -1621,7 +1788,139 @@ void GCodeViewer::render_legend() const default: { break; } } - // travel paths +#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND + // partial estimated printing time section + if (m_view_type == EViewType::ColorPrint) { + using Times = std::pair; + using TimesList = std::vector>; + + // helper structure containig the data needed to render the time items + struct PartialTime + { + enum class EType : unsigned char + { + Print, + ColorChange, + Pause + }; + EType type; + int extruder_id; + Color color1; + Color color2; + Times times; + }; + using PartialTimes = std::vector; + + auto generate_partial_times = [this](const TimesList& times) { + PartialTimes items; + + std::vector custom_gcode_per_print_z = wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes; + int extruders_count = wxGetApp().extruders_edited_cnt(); + std::vector last_color(extruders_count); + for (int i = 0; i < extruders_count; ++i) { + last_color[i] = m_tool_colors[i]; + } + int last_extruder_id = 1; + for (const auto& time_rec : times) { + switch (time_rec.first) + { + case CustomGCode::PausePrint: + { + auto it = std::find_if(custom_gcode_per_print_z.begin(), custom_gcode_per_print_z.end(), [time_rec](const CustomGCode::Item& item) { return item.type == time_rec.first; }); + if (it != custom_gcode_per_print_z.end()) { + items.push_back({ PartialTime::EType::Print, it->extruder, Color(), Color(), time_rec.second }); + items.push_back({ PartialTime::EType::Pause, it->extruder, Color(), Color(), time_rec.second }); + custom_gcode_per_print_z.erase(it); + } + break; + } + case CustomGCode::ColorChange: + { + auto it = std::find_if(custom_gcode_per_print_z.begin(), custom_gcode_per_print_z.end(), [time_rec](const CustomGCode::Item& item) { return item.type == time_rec.first; }); + if (it != custom_gcode_per_print_z.end()) { + items.push_back({ PartialTime::EType::Print, it->extruder, Color(), Color(), time_rec.second }); + items.push_back({ PartialTime::EType::ColorChange, it->extruder, last_color[it->extruder - 1], decode_color(it->color), time_rec.second }); + last_color[it->extruder - 1] = decode_color(it->color); + last_extruder_id = it->extruder; + custom_gcode_per_print_z.erase(it); + } + else + items.push_back({ PartialTime::EType::Print, last_extruder_id, Color(), Color(), time_rec.second }); + + break; + } + default: { break; } + } + } + + return items; + }; + + auto append_color = [this, &imgui](const Color& color1, const Color& color2, std::array& offsets, const Times& times) { + imgui.text(_u8L("Color change")); + ImGui::SameLine(); + + float icon_size = ImGui::GetTextLineHeight(); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + ImVec2 pos = ImGui::GetCursorScreenPos(); + pos.x -= 0.5f * ImGui::GetStyle().ItemSpacing.x; + ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size)); + draw_list->AddNgonFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color1[0], color1[1], color1[2], 1.0f }), 6); + center.x += icon_size; + draw_list->AddNgonFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color2[0], color2[1], color2[2], 1.0f }), 6); + ImGui::SameLine(offsets[0]); + imgui.text(short_time(get_time_dhms(times.second - times.first))); + }; + + PartialTimes partial_times = generate_partial_times(time_mode.custom_gcode_times); + if (!partial_times.empty()) { + labels.clear(); + times.clear(); + + for (const PartialTime& item : partial_times) { + switch (item.type) + { + case PartialTime::EType::Print: { labels.push_back(_u8L("Print")); break; } + case PartialTime::EType::Pause: { labels.push_back(_u8L("Pause")); break; } + case PartialTime::EType::ColorChange: { labels.push_back(_u8L("Color change")); break; } + } + times.push_back(short_time(get_time_dhms(item.times.second))); + } + offsets = calculate_offsets(labels, times, { _u8L("Event"), _u8L("Remaining time") }, 2.0f * icon_size); + + ImGui::Spacing(); + append_headers({ _u8L("Event"), _u8L("Remaining time"), _u8L("Duration") }, offsets); + for (const PartialTime& item : partial_times) { + switch (item.type) + { + case PartialTime::EType::Print: + { + imgui.text(_u8L("Print")); + ImGui::SameLine(offsets[0]); + imgui.text(short_time(get_time_dhms(item.times.second))); + ImGui::SameLine(offsets[1]); + imgui.text(short_time(get_time_dhms(item.times.first))); + break; + } + case PartialTime::EType::Pause: + { + imgui.text(_u8L("Pause")); + ImGui::SameLine(offsets[0]); + imgui.text(short_time(get_time_dhms(item.times.second - item.times.first))); + break; + } + case PartialTime::EType::ColorChange: + { + append_color(item.color1, item.color2, offsets, item.times); + break; + } + } + } + } + } +#endif // GCODE_VIEWER_TIME_ESTIMATE + + // travel paths section if (m_buffers[buffer_id(EMoveType::Travel)].visible) { switch (m_view_type) { @@ -1671,7 +1970,7 @@ void GCodeViewer::render_legend() const #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR }; - // options + // options section if (any_option_available()) { // title ImGui::Spacing(); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 06cd1326fb..038b837b2b 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -350,6 +350,9 @@ private: bool m_time_estimate_enabled{ false }; #endif // GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_MODAL #endif // GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE +#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND + mutable PrintEstimatedTimeStatistics::ETimeMode m_time_estimate_mode{ PrintEstimatedTimeStatistics::ETimeMode::Normal }; +#endif // GCODE_VIEWER_TIME_ESTIMATE #if ENABLE_GCODE_VIEWER_STATISTICS mutable Statistics m_statistics; #endif // ENABLE_GCODE_VIEWER_STATISTICS diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 38657a460a..03e062d65d 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -1458,7 +1458,11 @@ wxString Preview::get_option_type_string(OptionType type) const case OptionType::CustomGCodes: { return _L("Custom GCodes"); } case OptionType::Shells: { return _L("Shells"); } case OptionType::ToolMarker: { return _L("Tool marker"); } +#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND + case OptionType::Legend: { return _L("Legend/Estimated printing time"); } +#else case OptionType::Legend: { return _L("Legend"); } +#endif // GCODE_VIEWER_TIME_ESTIMATE #if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE case OptionType::TimeEstimate: { return _L("Estimated printing time"); } #endif // GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index 2c65673cd0..2d4b65a987 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -203,7 +203,11 @@ void KBShortcutsDialog::fill_shortcuts() { L("Arrow Down"), L("Lower Layer") }, { "U", L("Upper Layer") }, { "D", L("Lower Layer") }, +#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND + { "L", L("Show/Hide Legend/Estimated printing time") }, +#else { "L", L("Show/Hide Legend") }, +#endif // GCODE_VIEWER_TIME_ESTIMATE #if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_DEFAULT { "T", L("Show/Hide Estimated printing time") } #elif GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_MODAL From 0c6f66eca668a2fea9aaa0f4794c08dca2e1a17b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 6 Aug 2020 13:36:21 +0200 Subject: [PATCH 177/255] GCodeViewer -> Tweaks in legend rendering --- src/slic3r/GUI/GCodeViewer.cpp | 46 +++++++++++++++++++-------------- src/slic3r/GUI/ImGuiWrapper.cpp | 21 ++++++++------- src/slic3r/GUI/ImGuiWrapper.hpp | 5 +++- 3 files changed, 43 insertions(+), 29 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 2b25a11bb5..db40e96158 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1460,7 +1460,7 @@ void GCodeViewer::render_legend() const if (ImGui::IsItemHovered()) { if (!visible) ImGui::PopStyleVar(); - ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BACKGROND); + ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BACKGROUND); ImGui::BeginTooltip(); imgui.text(visible ? _u8L("Click to hide") : _u8L("Click to show")); ImGui::EndTooltip(); @@ -1503,7 +1503,7 @@ void GCodeViewer::render_legend() const auto append_range_item = [this, draw_list, &imgui, append_item](int i, float value, unsigned int decimals) { char buf[1024]; ::sprintf(buf, "%.*f", decimals, value); - append_item(EItemType::Hexagon, Range_Colors[i], buf); + append_item(EItemType::Rect, Range_Colors[i], buf); }; float step_size = range.step_size(); @@ -1644,12 +1644,12 @@ void GCodeViewer::render_legend() const { case PrintEstimatedTimeStatistics::ETimeMode::Normal: { - show_mode_button(_u8L("Show stealth mode"), PrintEstimatedTimeStatistics::ETimeMode::Stealth); + show_mode_button(_u8L("Stealth mode"), PrintEstimatedTimeStatistics::ETimeMode::Stealth); break; } case PrintEstimatedTimeStatistics::ETimeMode::Stealth: { - show_mode_button(_u8L("Show normal mode"), PrintEstimatedTimeStatistics::ETimeMode::Normal); + show_mode_button(_u8L("Normal mode"), PrintEstimatedTimeStatistics::ETimeMode::Normal); break; } } @@ -1690,13 +1690,13 @@ void GCodeViewer::render_legend() const continue; bool visible = is_visible(role); #if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND - append_item(EItemType::Hexagon, Extrusion_Role_Colors[static_cast(role)], labels[i], + append_item(EItemType::Rect, Extrusion_Role_Colors[static_cast(role)], labels[i], visible, times[i], percents[i], max_percent, offsets, [this, role, visible]() { #else if (!visible) ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.3333f); - append_item(EItemType::Hexagon, Extrusion_Role_Colors[static_cast(role)], _u8L(ExtrusionEntity::role_to_string(role)), + append_item(EItemType::Rect, Extrusion_Role_Colors[static_cast(role)], _u8L(ExtrusionEntity::role_to_string(role)), [this, role, visible]() { #endif // GCODE_VIEWER_TIME_ESTIMATE m_extrusions.role_visibility_flags = visible ? m_extrusions.role_visibility_flags & ~(1 << role) : m_extrusions.role_visibility_flags | (1 << role); @@ -1723,7 +1723,7 @@ void GCodeViewer::render_legend() const { // shows only extruders actually used for (unsigned char i : m_extruder_ids) { - append_item(EItemType::Hexagon, m_tool_colors[i], _u8L("Extruder") + " " + std::to_string(i + 1)); + append_item(EItemType::Rect, m_tool_colors[i], _u8L("Extruder") + " " + std::to_string(i + 1)); } break; } @@ -1735,20 +1735,20 @@ void GCodeViewer::render_legend() const std::vector>> cp_values = color_print_ranges(0, custom_gcode_per_print_z); const int items_cnt = static_cast(cp_values.size()); if (items_cnt == 0) { // There are no color changes, but there are some pause print or custom Gcode - append_item(EItemType::Hexagon, m_tool_colors.front(), _u8L("Default color")); + append_item(EItemType::Rect, m_tool_colors.front(), _u8L("Default color")); } else { for (int i = items_cnt; i >= 0; --i) { // create label for color change item if (i == 0) { - append_item(EItemType::Hexagon, m_tool_colors[0], upto_label(cp_values.front().second.first)); + append_item(EItemType::Rect, m_tool_colors[0], upto_label(cp_values.front().second.first)); break; } else if (i == items_cnt) { - append_item(EItemType::Hexagon, cp_values[i - 1].first, above_label(cp_values[i - 1].second.second)); + append_item(EItemType::Rect, cp_values[i - 1].first, above_label(cp_values[i - 1].second.second)); continue; } - append_item(EItemType::Hexagon, cp_values[i - 1].first, fromto_label(cp_values[i - 1].second.second, cp_values[i].second.first)); + append_item(EItemType::Rect, cp_values[i - 1].first, fromto_label(cp_values[i - 1].second.second, cp_values[i].second.first)); } } } @@ -1759,7 +1759,7 @@ void GCodeViewer::render_legend() const std::vector>> cp_values = color_print_ranges(i, custom_gcode_per_print_z); const int items_cnt = static_cast(cp_values.size()); if (items_cnt == 0) { // There are no color changes, but there are some pause print or custom Gcode - append_item(EItemType::Hexagon, m_tool_colors[i], _u8L("Extruder") + " " + std::to_string(i + 1) + " " + _u8L("default color")); + append_item(EItemType::Rect, m_tool_colors[i], _u8L("Extruder") + " " + std::to_string(i + 1) + " " + _u8L("default color")); } else { for (int j = items_cnt; j >= 0; --j) { @@ -1767,17 +1767,17 @@ void GCodeViewer::render_legend() const std::string label = _u8L("Extruder") + " " + std::to_string(i + 1); if (j == 0) { label += " " + upto_label(cp_values.front().second.first); - append_item(EItemType::Hexagon, m_tool_colors[i], label); + append_item(EItemType::Rect, m_tool_colors[i], label); break; } else if (j == items_cnt) { label += " " + above_label(cp_values[j - 1].second.second); - append_item(EItemType::Hexagon, cp_values[j - 1].first, label); + append_item(EItemType::Rect, cp_values[j - 1].first, label); continue; } label += " " + fromto_label(cp_values[j - 1].second.second, cp_values[j].second.first); - append_item(EItemType::Hexagon, cp_values[j - 1].first, label); + append_item(EItemType::Rect, cp_values[j - 1].first, label); } } } @@ -1864,10 +1864,18 @@ void GCodeViewer::render_legend() const ImDrawList* draw_list = ImGui::GetWindowDrawList(); ImVec2 pos = ImGui::GetCursorScreenPos(); pos.x -= 0.5f * ImGui::GetStyle().ItemSpacing.x; - ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size)); - draw_list->AddNgonFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color1[0], color1[1], color1[2], 1.0f }), 6); - center.x += icon_size; - draw_list->AddNgonFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color2[0], color2[1], color2[2], 1.0f }), 6); + + draw_list->AddRectFilled({ pos.x + 1.0f, pos.y + 1.0f }, { pos.x + icon_size - 1.0f, pos.y + icon_size - 1.0f }, + ImGui::GetColorU32({ color1[0], color1[1], color1[2], 1.0f })); + pos.x += icon_size; + draw_list->AddRectFilled({ pos.x + 1.0f, pos.y + 1.0f }, { pos.x + icon_size - 1.0f, pos.y + icon_size - 1.0f }, + ImGui::GetColorU32({ color2[0], color2[1], color2[2], 1.0f })); + +// ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size)); +// draw_list->AddNgonFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color1[0], color1[1], color1[2], 1.0f }), 6); +// center.x += icon_size; +// draw_list->AddNgonFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color2[0], color2[1], color2[2], 1.0f }), 6); + ImGui::SameLine(offsets[0]); imgui.text(short_time(get_time_dhms(times.second - times.first))); }; diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 0ecfdaf389..00353e4937 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -50,11 +50,14 @@ static const std::map font_icons = { {ImGui::ErrorMarker , "flag_red" } }; -const ImVec4 ImGuiWrapper::COL_WINDOW_BACKGROND = { 0.133f, 0.133f, 0.133f, 0.8f }; -const ImVec4 ImGuiWrapper::COL_GREY_DARK = { 0.333f, 0.333f, 0.333f, 1.0f }; -const ImVec4 ImGuiWrapper::COL_GREY_LIGHT = { 0.4f, 0.4f, 0.4f, 1.0f }; -const ImVec4 ImGuiWrapper::COL_ORANGE_DARK = { 0.757f, 0.404f, 0.216f, 1.0f }; -const ImVec4 ImGuiWrapper::COL_ORANGE_LIGHT = { 1.0f, 0.49f, 0.216f, 1.0f }; +const ImVec4 ImGuiWrapper::COL_GREY_DARK = { 0.333f, 0.333f, 0.333f, 1.0f }; +const ImVec4 ImGuiWrapper::COL_GREY_LIGHT = { 0.4f, 0.4f, 0.4f, 1.0f }; +const ImVec4 ImGuiWrapper::COL_ORANGE_DARK = { 0.757f, 0.404f, 0.216f, 1.0f }; +const ImVec4 ImGuiWrapper::COL_ORANGE_LIGHT = { 1.0f, 0.49f, 0.216f, 1.0f }; +const ImVec4 ImGuiWrapper::COL_WINDOW_BACKGROUND = { 0.133f, 0.133f, 0.133f, 0.8f }; +const ImVec4 ImGuiWrapper::COL_BUTTON_BACKGROUND = { 0.233f, 0.233f, 0.233f, 1.0f }; +const ImVec4 ImGuiWrapper::COL_BUTTON_HOVERED = { 0.433f, 0.433f, 0.433f, 1.8f }; +const ImVec4 ImGuiWrapper::COL_BUTTON_ACTIVE = ImGuiWrapper::COL_BUTTON_HOVERED; ImGuiWrapper::ImGuiWrapper() : m_glyph_ranges(nullptr) @@ -1031,7 +1034,7 @@ void ImGuiWrapper::init_style() // Window style.WindowRounding = 4.0f; - set_color(ImGuiCol_WindowBg, COL_WINDOW_BACKGROND); + set_color(ImGuiCol_WindowBg, COL_WINDOW_BACKGROUND); set_color(ImGuiCol_TitleBgActive, COL_ORANGE_DARK); // Generics @@ -1043,9 +1046,9 @@ void ImGuiWrapper::init_style() set_color(ImGuiCol_TextSelectedBg, COL_ORANGE_DARK); // Buttons - set_color(ImGuiCol_Button, COL_ORANGE_DARK); - set_color(ImGuiCol_ButtonHovered, COL_ORANGE_LIGHT); - set_color(ImGuiCol_ButtonActive, COL_ORANGE_LIGHT); + set_color(ImGuiCol_Button, COL_BUTTON_BACKGROUND); + set_color(ImGuiCol_ButtonHovered, COL_BUTTON_HOVERED); + set_color(ImGuiCol_ButtonActive, COL_BUTTON_ACTIVE); // Checkbox set_color(ImGuiCol_CheckMark, COL_ORANGE_LIGHT); diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index f1387ec194..5484e46c6f 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -96,11 +96,14 @@ public: bool want_text_input() const; bool want_any_input() const; - static const ImVec4 COL_WINDOW_BACKGROND; static const ImVec4 COL_GREY_DARK; static const ImVec4 COL_GREY_LIGHT; static const ImVec4 COL_ORANGE_DARK; static const ImVec4 COL_ORANGE_LIGHT; + static const ImVec4 COL_WINDOW_BACKGROUND; + static const ImVec4 COL_BUTTON_BACKGROUND; + static const ImVec4 COL_BUTTON_HOVERED; + static const ImVec4 COL_BUTTON_ACTIVE; private: void init_font(bool compress); From bcd998f9f1169f8e41e29f7615a0f4fe5d887014 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 6 Aug 2020 14:25:00 +0200 Subject: [PATCH 178/255] GCodeViewer -> New set of colors for toolpaths --- src/slic3r/GUI/GCodeViewer.cpp | 37 +++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index db40e96158..ad84184015 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -218,23 +218,42 @@ void GCodeViewer::SequentialView::Marker::render() const const std::vector GCodeViewer::Extrusion_Role_Colors {{ { 0.75f, 0.75f, 0.75f }, // erNone - { 1.00f, 1.00f, 0.40f }, // erPerimeter - { 1.00f, 0.65f, 0.00f }, // erExternalPerimeter - { 0.00f, 0.00f, 1.00f }, // erOverhangPerimeter + { 1.00f, 0.90f, 0.43f }, // erPerimeter + { 1.00f, 0.49f, 0.22f }, // erExternalPerimeter + { 0.12f, 0.12f, 1.00f }, // erOverhangPerimeter { 0.69f, 0.19f, 0.16f }, // erInternalInfill - { 0.84f, 0.20f, 0.84f }, // erSolidInfill - { 1.00f, 0.10f, 0.10f }, // erTopSolidInfill - { 1.00f, 0.55f, 0.41f }, // erIroning - { 0.60f, 0.60f, 1.00f }, // erBridgeInfill + { 0.59f, 0.33f, 0.80f }, // erSolidInfill + { 0.94f, 0.33f, 0.33f }, // erTopSolidInfill + { 1.00f, 0.55f, 0.41f }, // erIroning + { 0.30f, 0.50f, 0.73f }, // erBridgeInfill { 1.00f, 1.00f, 1.00f }, // erGapFill - { 0.52f, 0.48f, 0.13f }, // erSkirt + { 0.00f, 0.53f, 0.43f }, // erSkirt { 0.00f, 1.00f, 0.00f }, // erSupportMaterial { 0.00f, 0.50f, 0.00f }, // erSupportMaterialInterface { 0.70f, 0.89f, 0.67f }, // erWipeTower - { 0.16f, 0.80f, 0.58f }, // erCustom + { 0.37f, 0.82f, 0.58f }, // erCustom { 0.00f, 0.00f, 0.00f } // erMixed }}; +//const std::vector GCodeViewer::Extrusion_Role_Colors {{ +// { 0.75f, 0.75f, 0.75f }, // erNone +// { 1.00f, 1.00f, 0.40f }, // erPerimeter +// { 1.00f, 0.65f, 0.00f }, // erExternalPerimeter +// { 0.00f, 0.00f, 1.00f }, // erOverhangPerimeter +// { 0.69f, 0.19f, 0.16f }, // erInternalInfill +// { 0.84f, 0.20f, 0.84f }, // erSolidInfill +// { 1.00f, 0.10f, 0.10f }, // erTopSolidInfill +// { 1.00f, 0.55f, 0.41f }, // erIroning +// { 0.60f, 0.60f, 1.00f }, // erBridgeInfill +// { 1.00f, 1.00f, 1.00f }, // erGapFill +// { 0.52f, 0.48f, 0.13f }, // erSkirt +// { 0.00f, 1.00f, 0.00f }, // erSupportMaterial +// { 0.00f, 0.50f, 0.00f }, // erSupportMaterialInterface +// { 0.70f, 0.89f, 0.67f }, // erWipeTower +// { 0.16f, 0.80f, 0.58f }, // erCustom +// { 0.00f, 0.00f, 0.00f } // erMixed +//}}; + const std::vector GCodeViewer::Options_Colors {{ { 1.00f, 0.00f, 1.00f }, // Retractions { 0.00f, 1.00f, 1.00f }, // Unretractions From 64001c0fe5794dd747cb388b302cb8397e741ecc Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 7 Aug 2020 15:30:08 +0200 Subject: [PATCH 179/255] GCodeProcessor -> Fixed export of estimated time to gcode filename --- src/libslic3r/GCode.cpp | 12 ++++++++++++ src/libslic3r/GCode/GCodeProcessor.hpp | 3 +++ src/libslic3r/Print.cpp | 8 +++----- src/libslic3r/Print.hpp | 2 +- src/libslic3r/Utils.hpp | 19 +++++++++++++++++++ src/slic3r/GUI/3DBed.cpp | 2 ++ 6 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 915694d12f..dec0a7a197 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -715,6 +715,17 @@ std::vector>> GCode::collec } #if ENABLE_GCODE_VIEWER +// free functions called by GCode::do_export() +namespace DoExport { + static void update_print_estimated_times_stats(const GCodeProcessor& processor, PrintStatistics& print_statistics) + { + const GCodeProcessor::Result& result = processor.get_result(); + print_statistics.estimated_normal_print_time = get_time_dhm(result.time_statistics.modes[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Normal)].time); + print_statistics.estimated_silent_print_time = processor.is_stealth_time_estimator_enabled() ? + get_time_dhm(result.time_statistics.modes[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Stealth)].time) : "N/A"; + } +} // namespace DoExport + void GCode::do_export(Print* print, const char* path, GCodeProcessor::Result* result, ThumbnailsGeneratorCallback thumbnail_cb) #else void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_data, ThumbnailsGeneratorCallback thumbnail_cb) @@ -777,6 +788,7 @@ void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_ #if ENABLE_GCODE_VIEWER m_processor.process_file(path_tmp); + DoExport::update_print_estimated_times_stats(m_processor, print->m_print_statistics); if (result != nullptr) *result = std::move(m_processor.extract_result()); #else diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 101c320db8..e9c71038fe 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -317,6 +317,9 @@ namespace Slic3r { void apply_config(const PrintConfig& config); void apply_config(const DynamicPrintConfig& config); void enable_stealth_time_estimator(bool enabled); + bool is_stealth_time_estimator_enabled() const { + return m_time_processor.machines[static_cast(ETimeMode::Stealth)].enabled; + } void enable_producers(bool enabled) { m_producers_enabled = enabled; } void reset(); diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 1b1aad2578..7924f18906 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -2190,13 +2190,11 @@ std::string Print::output_filename(const std::string &filename_base) const DynamicConfig PrintStatistics::config() const { DynamicConfig config; -#if !ENABLE_GCODE_VIEWER std::string normal_print_time = short_time(this->estimated_normal_print_time); std::string silent_print_time = short_time(this->estimated_silent_print_time); - config.set_key_value("print_time", new ConfigOptionString(normal_print_time)); - config.set_key_value("normal_print_time", new ConfigOptionString(normal_print_time)); - config.set_key_value("silent_print_time", new ConfigOptionString(silent_print_time)); -#endif // !ENABLE_GCODE_VIEWER + config.set_key_value("print_time", new ConfigOptionString(normal_print_time)); + config.set_key_value("normal_print_time", new ConfigOptionString(normal_print_time)); + config.set_key_value("silent_print_time", new ConfigOptionString(silent_print_time)); config.set_key_value("used_filament", new ConfigOptionFloat(this->total_used_filament / 1000.)); config.set_key_value("extruded_volume", new ConfigOptionFloat(this->total_extruded_volume)); config.set_key_value("total_cost", new ConfigOptionFloat(this->total_cost)); diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 73efbf49a1..da98bba5f2 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -303,9 +303,9 @@ private: struct PrintStatistics { PrintStatistics() { clear(); } -#if !ENABLE_GCODE_VIEWER std::string estimated_normal_print_time; std::string estimated_silent_print_time; +#if !ENABLE_GCODE_VIEWER std::vector> estimated_normal_custom_gcode_print_times; std::vector> estimated_silent_custom_gcode_print_times; #endif // !ENABLE_GCODE_VIEWER diff --git a/src/libslic3r/Utils.hpp b/src/libslic3r/Utils.hpp index 5cdf75037c..f7ff29b7e0 100644 --- a/src/libslic3r/Utils.hpp +++ b/src/libslic3r/Utils.hpp @@ -337,6 +337,25 @@ inline std::string get_time_dhms(float time_in_secs) return buffer; } +inline std::string get_time_dhm(float time_in_secs) +{ + int days = (int)(time_in_secs / 86400.0f); + time_in_secs -= (float)days * 86400.0f; + int hours = (int)(time_in_secs / 3600.0f); + time_in_secs -= (float)hours * 3600.0f; + int minutes = (int)(time_in_secs / 60.0f); + + char buffer[64]; + if (days > 0) + ::sprintf(buffer, "%dd %dh %dm %ds", days, hours, minutes, (int)time_in_secs); + else if (hours > 0) + ::sprintf(buffer, "%dh %dm %ds", hours, minutes, (int)time_in_secs); + else if (minutes > 0) + ::sprintf(buffer, "%dm %ds", minutes, (int)time_in_secs); + + return buffer; +} + } // namespace Slic3r #if WIN32 diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index b13f774dab..cbb74411e0 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -147,6 +147,8 @@ void Bed3D::Axes::set_stem_length(float length) } #else Bed3D::Axes::Axes() +: origin(Vec3d::Zero()) +, length(25.0 * Vec3d::Ones()) { m_quadric = ::gluNewQuadric(); if (m_quadric != nullptr) From 6ed2cb661de4d5175ebb8ee75b53c33009c9d1a8 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 10 Aug 2020 14:22:05 +0200 Subject: [PATCH 180/255] GCodeProcessor -> Export remaining time (lines M73) to gcode --- src/libslic3r/GCode.cpp | 17 ++- src/libslic3r/GCode/GCodeProcessor.cpp | 160 +++++++++++++++++++++++-- src/libslic3r/GCode/GCodeProcessor.hpp | 10 +- 3 files changed, 173 insertions(+), 14 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index dec0a7a197..c02d24a4ee 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1281,13 +1281,16 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu print.throw_if_canceled(); // adds tags for time estimators -#if !ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER + if (print.config().remaining_times.value) + _writeln(file, GCodeProcessor::First_M73_Output_Placeholder_Tag); +#else if (print.config().remaining_times.value) { _writeln(file, GCodeTimeEstimator::Normal_First_M73_Output_Placeholder_Tag); if (m_silent_time_estimator_enabled) _writeln(file, GCodeTimeEstimator::Silent_First_M73_Output_Placeholder_Tag); } -#endif // !ENABLE_GCODE_VIEWER +#endif // ENABLE_GCODE_VIEWER // Prepare the helper object for replacing placeholders in custom G-code and output filename. m_placeholder_parser = print.placeholder_parser(); @@ -1582,14 +1585,16 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu _write(file, m_writer.postamble()); // adds tags for time estimators -#if !ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER if (print.config().remaining_times.value) - { + _writeln(file, GCodeProcessor::Last_M73_Output_Placeholder_Tag); +#else + if (print.config().remaining_times.value) { _writeln(file, GCodeTimeEstimator::Normal_Last_M73_Output_Placeholder_Tag); if (m_silent_time_estimator_enabled) _writeln(file, GCodeTimeEstimator::Silent_Last_M73_Output_Placeholder_Tag); } -#endif // !ENABLE_GCODE_VIEWER +#endif // ENABLE_GCODE_VIEWER print.throw_if_canceled(); @@ -2087,7 +2092,7 @@ void GCode::process_layer( #if ENABLE_GCODE_VIEWER // export layer z char buf[64]; - sprintf(buf, ";Z%g\n", print_z); + sprintf(buf, ";Z:%g\n", print_z); gcode += buf; // export layer height float height = first_layer ? static_cast(print_z) : static_cast(print_z) - m_last_layer_z; diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 7612af0e90..87bcde9d07 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -4,6 +4,7 @@ #include "GCodeProcessor.hpp" #include +#include #include #include @@ -28,6 +29,9 @@ const std::string GCodeProcessor::Color_Change_Tag = "Color change"; const std::string GCodeProcessor::Pause_Print_Tag = "Pause print"; const std::string GCodeProcessor::Custom_Code_Tag = "Custom gcode"; +const std::string GCodeProcessor::First_M73_Output_Placeholder_Tag = "; _GP_FIRST_M73_OUTPUT_PLACEHOLDER"; +const std::string GCodeProcessor::Last_M73_Output_Placeholder_Tag = "; _GP_LAST_M73_OUTPUT_PLACEHOLDER"; + static bool is_valid_extrusion_role(int value) { return (static_cast(erNone) <= value) && (value <= static_cast(erMixed)); @@ -161,6 +165,7 @@ void GCodeProcessor::TimeMachine::reset() prev.reset(); gcode_time.reset(); blocks = std::vector(); + g1_times_cache = std::vector(); std::fill(moves_time.begin(), moves_time.end(), 0.0f); std::fill(roles_time.begin(), roles_time.end(), 0.0f); } @@ -264,7 +269,6 @@ void GCodeProcessor::TimeMachine::calculate_time(size_t keep_last_n_blocks) recalculate_trapezoids(blocks); size_t n_blocks_process = blocks.size() - keep_last_n_blocks; -// m_g1_times.reserve(m_g1_times.size() + n_blocks_process); for (size_t i = 0; i < n_blocks_process; ++i) { const TimeBlock& block = blocks[i]; float block_time = block.time(); @@ -272,9 +276,7 @@ void GCodeProcessor::TimeMachine::calculate_time(size_t keep_last_n_blocks) gcode_time.cache += block_time; moves_time[static_cast(block.move_type)] += block_time; roles_time[static_cast(block.role)] += block_time; - -// if (block.g1_line_id >= 0) -// m_g1_times.emplace_back(block.g1_line_id, time); + g1_times_cache.push_back(time); } if (keep_last_n_blocks) @@ -286,6 +288,7 @@ void GCodeProcessor::TimeMachine::calculate_time(size_t keep_last_n_blocks) void GCodeProcessor::TimeProcessor::reset() { extruder_unloaded = true; + export_remaining_time_enabled = false; machine_limits = MachineEnvelopeConfig(); filament_load_times = std::vector(); filament_unload_times = std::vector(); @@ -295,6 +298,136 @@ void GCodeProcessor::TimeProcessor::reset() machines[static_cast(ETimeMode::Normal)].enabled = true; } +void GCodeProcessor::TimeProcessor::post_process(const std::string& filename) +{ + boost::nowide::ifstream in(filename); + if (!in.good()) + throw std::runtime_error(std::string("Time estimator post process export failed.\nCannot open file for reading.\n")); + + // temporary file to contain modified gcode + std::string out_path = filename + ".postprocess"; + FILE* out = boost::nowide::fopen(out_path.c_str(), "wb"); + if (out == nullptr) + throw std::runtime_error(std::string("Time estimator post process export failed.\nCannot open file for writing.\n")); + + auto time_in_minutes = [](float time_in_seconds) { + return int(::roundf(time_in_seconds / 60.0f)); + }; + + auto format_line_M73 = [](const std::string& mask, int percent, int time) { + char line_M73[64]; + sprintf(line_M73, mask.c_str(), + std::to_string(percent).c_str(), + std::to_string(time).c_str()); + return std::string(line_M73); + }; + + GCodeReader parser; + std::string gcode_line; + size_t g1_lines_counter = 0; + // keeps track of last exported pair + std::array, static_cast(ETimeMode::Count)> last_exported; + for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + last_exported[i] = { 0, time_in_minutes(machines[i].time) }; + } + + // buffer line to export only when greater than 64K to reduce writing calls + std::string export_line; + + // replace placeholder lines with the proper final value + auto process_placeholders = [&](const std::string& gcode_line) { + std::string ret; + // remove trailing '\n' + std::string line = gcode_line.substr(0, gcode_line.length() - 1); + if (line == First_M73_Output_Placeholder_Tag || line == Last_M73_Output_Placeholder_Tag) { + for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + const TimeMachine& machine = machines[i]; + if (machine.enabled) { + ret += format_line_M73(machine.line_m73_mask.c_str(), + (line == First_M73_Output_Placeholder_Tag) ? 0 : 100, + (line == First_M73_Output_Placeholder_Tag) ? time_in_minutes(machines[i].time) : 0); + } + } + } + return std::make_pair(!ret.empty(), ret.empty() ? gcode_line : ret); + }; + + // add lines M73 to exported gcode + auto process_line_G1 = [&]() { + for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + const TimeMachine& machine = machines[i]; + if (machine.enabled && g1_lines_counter < machine.g1_times_cache.size()) { + float elapsed_time = machine.g1_times_cache[g1_lines_counter]; + std::pair to_export = { int(::roundf(100.0f * elapsed_time / machine.time)), + time_in_minutes(machine.time - elapsed_time) }; + if (last_exported[i] != to_export) { + export_line += format_line_M73(machine.line_m73_mask.c_str(), + to_export.first, to_export.second); + last_exported[i] = to_export; + } + } + } + }; + + // helper function to write to disk + auto write_string = [&](const std::string& str) { + fwrite((const void*)export_line.c_str(), 1, export_line.length(), out); + if (ferror(out)) { + in.close(); + fclose(out); + boost::nowide::remove(out_path.c_str()); + throw std::runtime_error(std::string("Time estimator post process export failed.\nIs the disk full?\n")); + } + export_line.clear(); + }; + + while (std::getline(in, gcode_line)) { + if (!in.good()) { + fclose(out); + throw std::runtime_error(std::string("Time estimator post process export failed.\nError while reading from file.\n")); + } + + gcode_line += "\n"; + auto [processed, result] = process_placeholders(gcode_line); + gcode_line = result; + if (!processed) { + parser.parse_line(gcode_line, + [&](GCodeReader& reader, const GCodeReader::GCodeLine& line) { + if (line.cmd_is("G1")) { + process_line_G1(); + ++g1_lines_counter; + } + }); + } + + export_line += gcode_line; + if (export_line.length() > 65535) + write_string(export_line); + } + + for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + const TimeMachine& machine = machines[i]; + ETimeMode mode = static_cast(i); + if (machine.enabled) { + char line[128]; + sprintf(line, "; estimated printing time (%s mode) = %s\n", + (mode == ETimeMode::Normal) ? "normal" : "silent", + get_time_dhms(machine.time).c_str()); + export_line += line; + } + } + + if (!export_line.empty()) + write_string(export_line); + + fclose(out); + in.close(); + + if (rename_file(out_path, filename)) + throw std::runtime_error(std::string("Failed to rename the output G-code file from ") + out_path + " to " + filename + '\n' + + "Is " + out_path + " locked?" + '\n'); +} + const std::vector> GCodeProcessor::Producers = { { EProducer::PrusaSlicer, "PrusaSlicer" }, { EProducer::Cura, "Cura_SteamEngine" }, @@ -305,6 +438,13 @@ const std::vector> GCodeProces unsigned int GCodeProcessor::s_result_id = 0; +GCodeProcessor::GCodeProcessor() +{ + reset(); + m_time_processor.machines[static_cast(ETimeMode::Normal)].line_m73_mask = "M73 P%s R%s\n"; + m_time_processor.machines[static_cast(ETimeMode::Stealth)].line_m73_mask = "M73 Q%s S%s\n"; +} + void GCodeProcessor::apply_config(const PrintConfig& config) { m_parser.apply_config(config); @@ -346,6 +486,8 @@ void GCodeProcessor::apply_config(const PrintConfig& config) float max_acceleration = get_option_value(m_time_processor.machine_limits.machine_max_acceleration_extruding, i); m_time_processor.machines[i].acceleration = (max_acceleration > 0.0f) ? max_acceleration : DEFAULT_ACCELERATION; } + + m_time_processor.export_remaining_time_enabled = config.remaining_times.value; } void GCodeProcessor::apply_config(const DynamicPrintConfig& config) @@ -572,6 +714,10 @@ void GCodeProcessor::process_file(const std::string& filename) update_estimated_times_stats(); + // post-process to add M73 lines into the gcode + if (m_time_processor.export_remaining_time_enabled) + m_time_processor.post_process(filename); + #if ENABLE_GCODE_VIEWER_STATISTICS m_result.time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -1525,13 +1671,13 @@ void GCodeProcessor::process_M201(const GCodeReader::GCodeLine& line) if (line.has_x()) set_option_value(m_time_processor.machine_limits.machine_max_acceleration_x, i, line.x() * factor); - if (line.has_y() && i < m_time_processor.machine_limits.machine_max_acceleration_y.values.size()) + if (line.has_y()) set_option_value(m_time_processor.machine_limits.machine_max_acceleration_y, i, line.y() * factor); - if (line.has_z() && i < m_time_processor.machine_limits.machine_max_acceleration_z.values.size()) + if (line.has_z()) set_option_value(m_time_processor.machine_limits.machine_max_acceleration_z, i, line.z() * factor); - if (line.has_e() && i < m_time_processor.machine_limits.machine_max_acceleration_e.values.size()) + if (line.has_e()) set_option_value(m_time_processor.machine_limits.machine_max_acceleration_e, i, line.e() * factor); } } diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index e9c71038fe..840b5373bc 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -72,6 +72,8 @@ namespace Slic3r { static const std::string Color_Change_Tag; static const std::string Pause_Print_Tag; static const std::string Custom_Code_Tag; + static const std::string First_M73_Output_Placeholder_Tag; + static const std::string Last_M73_Output_Placeholder_Tag; private: using AxisCoords = std::array; @@ -182,10 +184,12 @@ namespace Slic3r { float acceleration; // mm/s^2 float extrude_factor_override_percentage; float time; // s + std::string line_m73_mask; State curr; State prev; CustomGCodeTime gcode_time; std::vector blocks; + std::vector g1_times_cache; std::array(EMoveType::Count)> moves_time; std::array(ExtrusionRole::erCount)> roles_time; @@ -212,6 +216,7 @@ namespace Slic3r { // This is currently only really used by the MK3 MMU2: // extruder_unloaded = true means no filament is loaded yet, all the filaments are parked in the MK3 MMU2 unit. bool extruder_unloaded; + bool export_remaining_time_enabled; MachineEnvelopeConfig machine_limits; // Additional load / unload times for a filament exchange sequence. std::vector filament_load_times; @@ -219,6 +224,9 @@ namespace Slic3r { std::array(ETimeMode::Count)> machines; void reset(); + + // post process the file with the given filename to add remaining time lines M73 + void post_process(const std::string& filename); }; public: @@ -312,7 +320,7 @@ namespace Slic3r { static unsigned int s_result_id; public: - GCodeProcessor() { reset(); } + GCodeProcessor(); void apply_config(const PrintConfig& config); void apply_config(const DynamicPrintConfig& config); From 5882c121cc2aca8fc85f1106a624d85330b3b968 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 11 Aug 2020 11:12:30 +0200 Subject: [PATCH 181/255] GCodeProcessor -> Fixed time estimate for stealth mode --- src/libslic3r/GCode/GCodeProcessor.cpp | 24 ++++++++++++++++++++++-- src/libslic3r/GCode/GCodeProcessor.hpp | 6 ++++++ src/slic3r/GUI/GCodeViewer.cpp | 14 +++++++++++--- src/slic3r/GUI/Plater.cpp | 2 +- 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 87bcde9d07..e4e52abdbe 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -159,6 +159,7 @@ void GCodeProcessor::TimeMachine::reset() { enabled = false; acceleration = 0.0f; + max_acceleration = 0.0f; extrude_factor_override_percentage = 1.0f; time = 0.0f; curr.reset(); @@ -289,6 +290,7 @@ void GCodeProcessor::TimeProcessor::reset() { extruder_unloaded = true; export_remaining_time_enabled = false; + machine_envelope_processing_enabled = false; machine_limits = MachineEnvelopeConfig(); filament_load_times = std::vector(); filament_unload_times = std::vector(); @@ -484,6 +486,7 @@ void GCodeProcessor::apply_config(const PrintConfig& config) for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { float max_acceleration = get_option_value(m_time_processor.machine_limits.machine_max_acceleration_extruding, i); + m_time_processor.machines[i].max_acceleration = max_acceleration; m_time_processor.machines[i].acceleration = (max_acceleration > 0.0f) ? max_acceleration : DEFAULT_ACCELERATION; } @@ -628,6 +631,7 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config) for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { float max_acceleration = get_option_value(m_time_processor.machine_limits.machine_max_acceleration_extruding, i); + m_time_processor.machines[i].max_acceleration = max_acceleration; m_time_processor.machines[i].acceleration = (max_acceleration > 0.0f) ? max_acceleration : DEFAULT_ACCELERATION; } } @@ -1304,6 +1308,9 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) return type; }; + // enable processing of lines M201/M203/M204/M205 + m_time_processor.machine_envelope_processing_enabled = true; + // updates axes positions from line for (unsigned char a = X; a <= E; ++a) { m_end_position[a] = absolute_position((Axis)a, line); @@ -1664,6 +1671,9 @@ void GCodeProcessor::process_M135(const GCodeReader::GCodeLine& line) void GCodeProcessor::process_M201(const GCodeReader::GCodeLine& line) { + if (!m_time_processor.machine_envelope_processing_enabled) + return; + // see http://reprap.org/wiki/G-code#M201:_Set_max_printing_acceleration float factor = (m_flavor != gcfRepRap && m_units == EUnits::Inches) ? INCHES_TO_MM : 1.0f; @@ -1684,6 +1694,9 @@ void GCodeProcessor::process_M201(const GCodeReader::GCodeLine& line) void GCodeProcessor::process_M203(const GCodeReader::GCodeLine& line) { + if (!m_time_processor.machine_envelope_processing_enabled) + return; + // see http://reprap.org/wiki/G-code#M203:_Set_maximum_feedrate if (m_flavor == gcfRepetier) return; @@ -1709,6 +1722,9 @@ void GCodeProcessor::process_M203(const GCodeReader::GCodeLine& line) void GCodeProcessor::process_M204(const GCodeReader::GCodeLine& line) { + if (!m_time_processor.machine_envelope_processing_enabled) + return; + float value; for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { if (line.has_value('S', value)) { @@ -1736,6 +1752,9 @@ void GCodeProcessor::process_M204(const GCodeReader::GCodeLine& line) void GCodeProcessor::process_M205(const GCodeReader::GCodeLine& line) { + if (!m_time_processor.machine_envelope_processing_enabled) + return; + for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { if (line.has_x()) { float max_jerk = line.x(); @@ -1968,8 +1987,9 @@ void GCodeProcessor::set_acceleration(ETimeMode mode, float value) { size_t id = static_cast(mode); if (id < m_time_processor.machines.size()) { - float max_acceleration = get_option_value(m_time_processor.machine_limits.machine_max_acceleration_extruding, id); - m_time_processor.machines[id].acceleration = (max_acceleration == 0.0f) ? value : std::min(value, max_acceleration); + m_time_processor.machines[id].acceleration = (m_time_processor.machines[id].max_acceleration == 0.0f) ? value : + // Clamp the acceleration with the maximum. + std::min(value, m_time_processor.machines[id].max_acceleration); } } diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 840b5373bc..ba8f921686 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -182,6 +182,8 @@ namespace Slic3r { bool enabled; float acceleration; // mm/s^2 + // hard limit for the acceleration, to which the firmware will clamp. + float max_acceleration; // mm/s^2 float extrude_factor_override_percentage; float time; // s std::string line_m73_mask; @@ -216,7 +218,10 @@ namespace Slic3r { // This is currently only really used by the MK3 MMU2: // extruder_unloaded = true means no filament is loaded yet, all the filaments are parked in the MK3 MMU2 unit. bool extruder_unloaded; + // whether or not to export post-process the gcode to export lines M73 in it bool export_remaining_time_enabled; + // allow to skip the lines M201/M203/M204/M205 generated by GCode::print_machine_envelope() + bool machine_envelope_processing_enabled; MachineEnvelopeConfig machine_limits; // Additional load / unload times for a filament exchange sequence. std::vector filament_load_times; @@ -328,6 +333,7 @@ namespace Slic3r { bool is_stealth_time_estimator_enabled() const { return m_time_processor.machines[static_cast(ETimeMode::Stealth)].enabled; } + void enable_machine_envelope_processing(bool enabled) { m_time_processor.machine_envelope_processing_enabled = enabled; } void enable_producers(bool enabled) { m_producers_enabled = enabled; } void reset(); diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index ad84184015..bbd357e980 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -9,7 +9,7 @@ #include "GUI_App.hpp" #include "MainFrame.hpp" #include "Plater.hpp" -#include "PresetBundle.hpp" +#include "libslic3r/PresetBundle.hpp" #include "Camera.hpp" #include "I18N.hpp" #include "GUI_Utils.hpp" @@ -1498,7 +1498,7 @@ void GCodeViewer::render_legend() const imgui.text(time); ImGui::SameLine(offsets[1]); pos = ImGui::GetCursorScreenPos(); - float width = percent_bar_size * percent / max_percent; + float width = std::max(1.0f, percent_bar_size * percent / max_percent); draw_list->AddRectFilled({ pos.x, pos.y + 2.0f }, { pos.x + width, pos.y + icon_size - 2.0f }, ImGui::GetColorU32(ImGuiWrapper::COL_ORANGE_LIGHT)); ImGui::Dummy({ percent_bar_size, icon_size }); @@ -1649,7 +1649,15 @@ void GCodeViewer::render_legend() const imgui.text(short_time(get_time_dhms(time_mode.time))); auto show_mode_button = [this, &imgui](const std::string& label, PrintEstimatedTimeStatistics::ETimeMode mode) { - if (m_time_statistics.modes[static_cast(mode)].roles_times.size() > 0) { + bool show = false; + for (size_t i = 0; i < m_time_statistics.modes.size(); ++i) { + if (i != static_cast(mode) && + short_time(get_time_dhms(m_time_statistics.modes[static_cast(mode)].time)) != short_time(get_time_dhms(m_time_statistics.modes[i].time))) { + show = true; + break; + } + } + if (show && m_time_statistics.modes[static_cast(mode)].roles_times.size() > 0) { ImGui::SameLine(0.0f, 10.0f); if (imgui.button(label)) { m_time_estimate_mode = mode; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 0b9f884516..dac3f6fae9 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4577,8 +4577,8 @@ void Plater::load_gcode(const wxString& filename) // process gcode GCodeProcessor processor; -// processor.apply_config(config); processor.enable_producers(true); + processor.enable_machine_envelope_processing(true); processor.process_file(filename.ToUTF8().data()); p->gcode_result = std::move(processor.extract_result()); From 5a0e04807965d8443da7793e2c6cacc461718a65 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 11 Aug 2020 14:23:47 +0200 Subject: [PATCH 182/255] ENABLE_GCODE_VIEWER -> Drag and drop .gcode files into gcode viewer --- src/libslic3r/GCode.cpp | 8 ++- src/libslic3r/GCode/GCodeProcessor.cpp | 86 +++++++++++--------------- src/libslic3r/GCode/GCodeProcessor.hpp | 5 +- src/slic3r/GUI/Plater.cpp | 43 +++++++++---- 4 files changed, 76 insertions(+), 66 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index c02d24a4ee..eb5ede0a5b 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1283,7 +1283,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu // adds tags for time estimators #if ENABLE_GCODE_VIEWER if (print.config().remaining_times.value) - _writeln(file, GCodeProcessor::First_M73_Output_Placeholder_Tag); + _writeln(file, GCodeProcessor::First_Line_M73_Placeholder_Tag); #else if (print.config().remaining_times.value) { _writeln(file, GCodeTimeEstimator::Normal_First_M73_Output_Placeholder_Tag); @@ -1587,7 +1587,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu // adds tags for time estimators #if ENABLE_GCODE_VIEWER if (print.config().remaining_times.value) - _writeln(file, GCodeProcessor::Last_M73_Output_Placeholder_Tag); + _writeln(file, GCodeProcessor::Last_Line_M73_Placeholder_Tag); #else if (print.config().remaining_times.value) { _writeln(file, GCodeTimeEstimator::Normal_Last_M73_Output_Placeholder_Tag); @@ -1620,7 +1620,9 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu _write_format(file, "; total filament cost = %.1lf\n", print.m_print_statistics.total_cost); if (print.m_print_statistics.total_toolchanges > 0) _write_format(file, "; total toolchanges = %i\n", print.m_print_statistics.total_toolchanges); -#if !ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER + _writeln(file, GCodeProcessor::Estimated_Printing_Time_Placeholder_Tag); +#else _write_format(file, "; estimated printing time (normal mode) = %s\n", m_normal_time_estimator.get_time_dhms().c_str()); if (m_silent_time_estimator_enabled) _write_format(file, "; estimated printing time (silent mode) = %s\n", m_silent_time_estimator.get_time_dhms().c_str()); diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index e4e52abdbe..530dfb1059 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -29,8 +29,9 @@ const std::string GCodeProcessor::Color_Change_Tag = "Color change"; const std::string GCodeProcessor::Pause_Print_Tag = "Pause print"; const std::string GCodeProcessor::Custom_Code_Tag = "Custom gcode"; -const std::string GCodeProcessor::First_M73_Output_Placeholder_Tag = "; _GP_FIRST_M73_OUTPUT_PLACEHOLDER"; -const std::string GCodeProcessor::Last_M73_Output_Placeholder_Tag = "; _GP_LAST_M73_OUTPUT_PLACEHOLDER"; +const std::string GCodeProcessor::First_Line_M73_Placeholder_Tag = "; _GP_FIRST_LINE_M73_PLACEHOLDER"; +const std::string GCodeProcessor::Last_Line_M73_Placeholder_Tag = "; _GP_LAST_LINE_M73_PLACEHOLDER"; +const std::string GCodeProcessor::Estimated_Printing_Time_Placeholder_Tag = "; _GP_ESTIMATED_PRINTING_TIME_PLACEHOLDER"; static bool is_valid_extrusion_role(int value) { @@ -338,16 +339,29 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename) // replace placeholder lines with the proper final value auto process_placeholders = [&](const std::string& gcode_line) { - std::string ret; // remove trailing '\n' std::string line = gcode_line.substr(0, gcode_line.length() - 1); - if (line == First_M73_Output_Placeholder_Tag || line == Last_M73_Output_Placeholder_Tag) { + + std::string ret; + if (line == First_Line_M73_Placeholder_Tag || line == Last_Line_M73_Placeholder_Tag) { for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { const TimeMachine& machine = machines[i]; if (machine.enabled) { ret += format_line_M73(machine.line_m73_mask.c_str(), - (line == First_M73_Output_Placeholder_Tag) ? 0 : 100, - (line == First_M73_Output_Placeholder_Tag) ? time_in_minutes(machines[i].time) : 0); + (line == First_Line_M73_Placeholder_Tag) ? 0 : 100, + (line == First_Line_M73_Placeholder_Tag) ? time_in_minutes(machines[i].time) : 0); + } + } + } + else if (line == Estimated_Printing_Time_Placeholder_Tag) { + for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + const TimeMachine& machine = machines[i]; + if (machine.enabled) { + char buf[128]; + sprintf(buf, "; estimated printing time (%s mode) = %s\n", + (static_cast(i) == ETimeMode::Normal) ? "normal" : "silent", + get_time_dhms(machine.time).c_str()); + ret += buf; } } } @@ -407,18 +421,6 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename) write_string(export_line); } - for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { - const TimeMachine& machine = machines[i]; - ETimeMode mode = static_cast(i); - if (machine.enabled) { - char line[128]; - sprintf(line, "; estimated printing time (%s mode) = %s\n", - (mode == ETimeMode::Normal) ? "normal" : "silent", - get_time_dhms(machine.time).c_str()); - export_line += line; - } - } - if (!export_line.empty()) write_string(export_line); @@ -870,12 +872,10 @@ void GCodeProcessor::process_tags(const std::string& comment) // width tag pos = comment.find(Width_Tag); if (pos != comment.npos) { - try - { + try { m_width = std::stof(comment.substr(pos + Width_Tag.length())); } - catch (...) - { + catch (...) { BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ")."; } return; @@ -884,12 +884,10 @@ void GCodeProcessor::process_tags(const std::string& comment) // height tag pos = comment.find(Height_Tag); if (pos != comment.npos) { - try - { + try { m_height = std::stof(comment.substr(pos + Height_Tag.length())); } - catch (...) - { + catch (...) { BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ")."; } return; @@ -899,8 +897,7 @@ void GCodeProcessor::process_tags(const std::string& comment) pos = comment.find(Color_Change_Tag); if (pos != comment.npos) { pos = comment.find_last_of(",T"); - try - { + try { unsigned char extruder_id = (pos == comment.npos) ? 0 : static_cast(std::stoi(comment.substr(pos + 1))); m_extruder_colors[extruder_id] = static_cast(m_extruder_offsets.size()) + m_cp_color.counter; // color_change position in list of color for preview @@ -915,8 +912,7 @@ void GCodeProcessor::process_tags(const std::string& comment) process_custom_gcode_time(CustomGCode::ColorChange); } - catch (...) - { + catch (...) { BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Color_Change (" << comment << ")."; } @@ -1115,24 +1111,20 @@ bool GCodeProcessor::process_simplify3d_tags(const std::string& comment) size_t w_start = data.find(w_tag); size_t w_end = data.find_first_of(' ', w_start); if (h_start != data.npos) { - try - { + try { std::string test = data.substr(h_start + 1, (h_end != data.npos) ? h_end - h_start - 1 : h_end); m_height = std::stof(data.substr(h_start + 1, (h_end != data.npos) ? h_end - h_start - 1 : h_end)); } - catch (...) - { + catch (...) { BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ")."; } } if (w_start != data.npos) { - try - { + try { std::string test = data.substr(w_start + 1, (w_end != data.npos) ? w_end - w_start - 1 : w_end); m_width = std::stof(data.substr(w_start + 1, (w_end != data.npos) ? w_end - w_start - 1 : w_end)); } - catch (...) - { + catch (...) { BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ")."; } } @@ -1218,12 +1210,10 @@ bool GCodeProcessor::process_ideamaker_tags(const std::string& comment) tag = "WIDTH:"; pos = comment.find(tag); if (pos != comment.npos) { - try - { + try { m_width = std::stof(comment.substr(pos + tag.length())); } - catch (...) - { + catch (...) { BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ")."; } return true; @@ -1233,12 +1223,10 @@ bool GCodeProcessor::process_ideamaker_tags(const std::string& comment) tag = "HEIGHT:"; pos = comment.find(tag); if (pos != comment.npos) { - try - { + try { m_height = std::stof(comment.substr(pos + tag.length())); } - catch (...) - { + catch (...) { BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ")."; } return true; @@ -1871,8 +1859,7 @@ void GCodeProcessor::process_T(const GCodeReader::GCodeLine& line) void GCodeProcessor::process_T(const std::string& command) { if (command.length() > 1) { - try - { + try { unsigned char id = static_cast(std::stoi(command.substr(1))); if (m_extruder_id != id) { unsigned char extruders_count = static_cast(m_extruder_offsets.size()); @@ -1895,8 +1882,7 @@ void GCodeProcessor::process_T(const std::string& command) store_move_vertex(EMoveType::Tool_change); } } - catch (...) - { + catch (...) { BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid toolchange (" << command << ")."; } } diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index ba8f921686..e35d3a9735 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -72,8 +72,9 @@ namespace Slic3r { static const std::string Color_Change_Tag; static const std::string Pause_Print_Tag; static const std::string Custom_Code_Tag; - static const std::string First_M73_Output_Placeholder_Tag; - static const std::string Last_M73_Output_Placeholder_Tag; + static const std::string First_Line_M73_Placeholder_Tag; + static const std::string Last_Line_M73_Placeholder_Tag; + static const std::string Estimated_Printing_Time_Placeholder_Tag; private: using AxisCoords = std::array; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index dac3f6fae9..79f8b5ad5d 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1349,20 +1349,44 @@ private: Plater *plater; static const std::regex pattern_drop; +#if ENABLE_GCODE_VIEWER + static const std::regex pattern_gcode_drop; +#endif // ENABLE_GCODE_VIEWER }; const std::regex PlaterDropTarget::pattern_drop(".*[.](stl|obj|amf|3mf|prusa)", std::regex::icase); +#if ENABLE_GCODE_VIEWER +const std::regex PlaterDropTarget::pattern_gcode_drop(".*[.](gcode)", std::regex::icase); +#endif // ENABLE_GCODE_VIEWER bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames) { std::vector paths; - for (const auto &filename : filenames) { - fs::path path(into_path(filename)); - if (std::regex_match(path.string(), pattern_drop)) { - paths.push_back(std::move(path)); - } else { +#if ENABLE_GCODE_VIEWER + if (wxGetApp().mainframe->get_mode() == MainFrame::EMode::GCodeViewer) { + for (const auto& filename : filenames) { + fs::path path(into_path(filename)); + if (std::regex_match(path.string(), pattern_gcode_drop)) + paths.push_back(std::move(path)); + } + + if (paths.size() > 1) { + wxMessageDialog((wxWindow*)plater, _L("Only one gcode file at a time can be opened."), wxString(SLIC3R_APP_NAME) + " - " + _L("Open G-code file"), wxCLOSE | wxICON_WARNING | wxCENTRE).ShowModal(); return false; } + else if (paths.size() == 1) { + plater->load_gcode(from_path(paths.front())); + return true; + } + } +#endif // ENABLE_GCODE_VIEWER + + for (const auto &filename : filenames) { + fs::path path(into_path(filename)); + if (std::regex_match(path.string(), pattern_drop)) + paths.push_back(std::move(path)); + else + return false; } wxString snapshot_label; @@ -1390,13 +1414,10 @@ bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &fi // because right now the plater is not cleared, we set the project file (from the latest imported .3mf or .amf file) // only if not set yet // if res is empty no data has been loaded - if (!res.empty() && plater->get_project_filename().empty()) - { - for (std::vector::const_reverse_iterator it = paths.rbegin(); it != paths.rend(); ++it) - { + if (!res.empty() && plater->get_project_filename().empty()) { + for (std::vector::const_reverse_iterator it = paths.rbegin(); it != paths.rend(); ++it) { std::string filename = (*it).filename().string(); - if (boost::algorithm::iends_with(filename, ".3mf") || boost::algorithm::iends_with(filename, ".amf")) - { + if (boost::algorithm::iends_with(filename, ".3mf") || boost::algorithm::iends_with(filename, ".amf")) { plater->set_project_filename(from_path(*it)); break; } From 4ca026d4b6ecfbb11bd8107a427bdbe86cfdc28e Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 11 Aug 2020 15:44:32 +0200 Subject: [PATCH 183/255] ENABLE_GCODE_VIEWER -> More general drag and drop for .gcode files --- src/libslic3r/GCode.cpp | 2 +- src/slic3r/GUI/MainFrame.cpp | 4 +++- src/slic3r/GUI/Plater.cpp | 42 +++++++++++++++++++++++++----------- 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index eb5ede0a5b..795aac898f 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1626,7 +1626,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu _write_format(file, "; estimated printing time (normal mode) = %s\n", m_normal_time_estimator.get_time_dhms().c_str()); if (m_silent_time_estimator_enabled) _write_format(file, "; estimated printing time (silent mode) = %s\n", m_silent_time_estimator.get_time_dhms().c_str()); -#endif // !ENABLE_GCODE_VIEWER +#endif // ENABLE_GCODE_VIEWER // Append full config. _write(file, "\n"); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 794da80b2a..6c3f2a4ea6 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -1006,7 +1006,9 @@ void MainFrame::init_menubar() fileMenu->AppendSeparator(); append_menu_item(fileMenu, wxID_ANY, _L("&G-code preview"), _L("Switch to G-code preview mode"), [this](wxCommandEvent&) { - if (m_plater->model().objects.empty() || wxMessageDialog((wxWindow*)this, _L("Switching to G-code preview mode will remove all objects, continue?"), wxString(SLIC3R_APP_NAME) + " - " + _L("Switch to G-code preview mode"), wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxCENTRE).ShowModal() == wxID_YES) + if (m_plater->model().objects.empty() || + wxMessageDialog((wxWindow*)this, _L("Switching to G-code preview mode will remove all objects, continue?"), + wxString(SLIC3R_APP_NAME) + " - " + _L("Switch to G-code preview mode"), wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxICON_QUESTION | wxCENTRE).ShowModal() == wxID_YES) set_mode(EMode::GCodeViewer); }, "", nullptr, [this]() { return m_plater != nullptr && m_plater->printer_technology() != ptSLA; }, this); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 79f8b5ad5d..67b531eae9 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1362,25 +1362,43 @@ const std::regex PlaterDropTarget::pattern_gcode_drop(".*[.](gcode)", std::regex bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames) { std::vector paths; -#if ENABLE_GCODE_VIEWER - if (wxGetApp().mainframe->get_mode() == MainFrame::EMode::GCodeViewer) { - for (const auto& filename : filenames) { - fs::path path(into_path(filename)); - if (std::regex_match(path.string(), pattern_gcode_drop)) - paths.push_back(std::move(path)); - } - if (paths.size() > 1) { - wxMessageDialog((wxWindow*)plater, _L("Only one gcode file at a time can be opened."), wxString(SLIC3R_APP_NAME) + " - " + _L("Open G-code file"), wxCLOSE | wxICON_WARNING | wxCENTRE).ShowModal(); - return false; - } - else if (paths.size() == 1) { +#if ENABLE_GCODE_VIEWER + // gcode section + for (const auto& filename : filenames) { + fs::path path(into_path(filename)); + if (std::regex_match(path.string(), pattern_gcode_drop)) + paths.push_back(std::move(path)); + } + + if (paths.size() > 1) { + wxMessageDialog((wxWindow*)plater, _L("You can open only one .gcode file at a time."), + wxString(SLIC3R_APP_NAME) + " - " + _L("Open G-code file"), wxCLOSE | wxICON_WARNING | wxCENTRE).ShowModal(); + return false; + } + else if (paths.size() == 1) { + if (wxGetApp().mainframe->get_mode() == MainFrame::EMode::GCodeViewer) { plater->load_gcode(from_path(paths.front())); return true; } + else { + if (wxMessageDialog((wxWindow*)plater, _L("Do you want to switch to G-code preview ?"), + wxString(SLIC3R_APP_NAME) + " - " + _L("Open G-code file"), wxYES_NO | wxCANCEL | wxICON_QUESTION | wxYES_DEFAULT | wxCENTRE).ShowModal() == wxID_YES) { + + if (plater->model().objects.empty() || + wxMessageDialog((wxWindow*)plater, _L("Switching to G-code preview mode will remove all objects, continue?"), + wxString(SLIC3R_APP_NAME) + " - " + _L("Switch to G-code preview mode"), wxYES_NO | wxCANCEL | wxICON_QUESTION | wxYES_DEFAULT | wxCENTRE).ShowModal() == wxID_YES) { + wxGetApp().mainframe->set_mode(MainFrame::EMode::GCodeViewer); + plater->load_gcode(from_path(paths.front())); + return true; + } + } + return false; + } } #endif // ENABLE_GCODE_VIEWER + // model section for (const auto &filename : filenames) { fs::path path(into_path(filename)); if (std::regex_match(path.string(), pattern_drop)) From 493d52850ebdc374c8ae530a664fdc75817402a8 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 12 Aug 2020 15:07:02 +0200 Subject: [PATCH 184/255] ENABLE_GCODE_VIEWER -> Drag and drop for non .gcode files while gcode viewer mode is active --- src/slic3r/GUI/MainFrame.cpp | 2 +- src/slic3r/GUI/Plater.cpp | 21 ++++++++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 6c3f2a4ea6..3f000e3328 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -1008,7 +1008,7 @@ void MainFrame::init_menubar() [this](wxCommandEvent&) { if (m_plater->model().objects.empty() || wxMessageDialog((wxWindow*)this, _L("Switching to G-code preview mode will remove all objects, continue?"), - wxString(SLIC3R_APP_NAME) + " - " + _L("Switch to G-code preview mode"), wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxICON_QUESTION | wxCENTRE).ShowModal() == wxID_YES) + wxString(SLIC3R_APP_NAME) + " - " + _L("Switch to G-code preview mode"), wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION | wxCENTRE).ShowModal() == wxID_YES) set_mode(EMode::GCodeViewer); }, "", nullptr, [this]() { return m_plater != nullptr && m_plater->printer_technology() != ptSLA; }, this); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 67b531eae9..759be43f32 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1364,6 +1364,11 @@ bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &fi std::vector paths; #if ENABLE_GCODE_VIEWER +#ifdef WIN32 + // hides the system icon + this->MSWUpdateDragImageOnLeave(); +#endif // WIN32 + // gcode section for (const auto& filename : filenames) { fs::path path(into_path(filename)); @@ -1373,7 +1378,7 @@ bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &fi if (paths.size() > 1) { wxMessageDialog((wxWindow*)plater, _L("You can open only one .gcode file at a time."), - wxString(SLIC3R_APP_NAME) + " - " + _L("Open G-code file"), wxCLOSE | wxICON_WARNING | wxCENTRE).ShowModal(); + wxString(SLIC3R_APP_NAME) + " - " + _L("Drag and drop G-code file"), wxCLOSE | wxICON_WARNING | wxCENTRE).ShowModal(); return false; } else if (paths.size() == 1) { @@ -1383,11 +1388,11 @@ bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &fi } else { if (wxMessageDialog((wxWindow*)plater, _L("Do you want to switch to G-code preview ?"), - wxString(SLIC3R_APP_NAME) + " - " + _L("Open G-code file"), wxYES_NO | wxCANCEL | wxICON_QUESTION | wxYES_DEFAULT | wxCENTRE).ShowModal() == wxID_YES) { + wxString(SLIC3R_APP_NAME) + " - " + _L("Drag and drop G-code file"), wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT | wxCENTRE).ShowModal() == wxID_YES) { if (plater->model().objects.empty() || wxMessageDialog((wxWindow*)plater, _L("Switching to G-code preview mode will remove all objects, continue?"), - wxString(SLIC3R_APP_NAME) + " - " + _L("Switch to G-code preview mode"), wxYES_NO | wxCANCEL | wxICON_QUESTION | wxYES_DEFAULT | wxCENTRE).ShowModal() == wxID_YES) { + wxString(SLIC3R_APP_NAME) + " - " + _L("Switch to G-code preview mode"), wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT | wxCENTRE).ShowModal() == wxID_YES) { wxGetApp().mainframe->set_mode(MainFrame::EMode::GCodeViewer); plater->load_gcode(from_path(paths.front())); return true; @@ -1407,6 +1412,16 @@ bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &fi return false; } +#if ENABLE_GCODE_VIEWER + if (wxGetApp().mainframe->get_mode() == MainFrame::EMode::GCodeViewer) { + if (wxMessageDialog((wxWindow*)plater, _L("Do you want to exit G-code preview ?"), + wxString(SLIC3R_APP_NAME) + " - " + _L("Drag and drop model file"), wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT | wxCENTRE).ShowModal() == wxID_YES) + wxGetApp().mainframe->set_mode(MainFrame::EMode::Editor); + else + return false; + } +#endif // ENABLE_GCODE_VIEWER + wxString snapshot_label; assert(! paths.empty()); if (paths.size() == 1) { From b80bde11f3929137b2ede00848f99b4c4a1a9d8f Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 13 Aug 2020 12:51:50 +0200 Subject: [PATCH 185/255] GCodeProcessor -> Extract toolpaths height from gcode moves --- src/libslic3r/GCode/GCodeProcessor.cpp | 46 ++++++++++++++++++------ src/libslic3r/GCode/GCodeProcessor.hpp | 1 + src/libslic3r/Utils.hpp | 5 +-- src/slic3r/GUI/GCodeViewer.cpp | 48 +++++++++----------------- src/slic3r/GUI/GCodeViewer.hpp | 10 ++++-- 5 files changed, 64 insertions(+), 46 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 530dfb1059..18878cd5ad 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -23,7 +23,7 @@ static const float DEFAULT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 namespace Slic3r { const std::string GCodeProcessor::Extrusion_Role_Tag = "ExtrType:"; -const std::string GCodeProcessor::Width_Tag = "PrusaSlicer__WIDTH:"; +const std::string GCodeProcessor::Width_Tag = "Width:"; const std::string GCodeProcessor::Height_Tag = "Height:"; const std::string GCodeProcessor::Color_Change_Tag = "Color change"; const std::string GCodeProcessor::Pause_Print_Tag = "Pause print"; @@ -81,6 +81,19 @@ static float acceleration_time_from_distance(float initial_feedrate, float dista return (acceleration != 0.0f) ? (speed_from_distance(initial_feedrate, distance, acceleration) - initial_feedrate) / acceleration : 0.0f; } +float round_to_nearest(float value, unsigned int decimals) +{ + float res = 0.0f; + if (decimals == 0) + res = std::round(value); + else { + char buf[64]; + sprintf(buf, "%.*g", decimals, value); + res = std::stof(buf); + } + return res; +} + void GCodeProcessor::CachedPosition::reset() { std::fill(position.begin(), position.end(), FLT_MAX); @@ -666,6 +679,7 @@ void GCodeProcessor::reset() m_extruder_id = 0; m_extruder_colors = ExtruderColors(); m_filament_diameters = std::vector(); + m_extruded_last_z = 0.0f; m_cp_color.reset(); m_producer = EProducer::Unknown; @@ -1285,14 +1299,6 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) else if (delta_pos[X] != 0.0f || delta_pos[Y] != 0.0f || delta_pos[Z] != 0.0f) type = EMoveType::Travel; - if (type == EMoveType::Extrude && (m_width == 0.0f || m_height == 0.0f)) { - if (m_extrusion_role != erCustom) { - m_width = 0.5f; - m_height = 0.5f; - } - type = EMoveType::Travel; - } - return type; }; @@ -1325,8 +1331,26 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) if (type == EMoveType::Extrude) { if (delta_pos[E] > 0.0f) { float ds = std::sqrt(sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z])); - if (ds > 0.0f && static_cast(m_extruder_id) < m_filament_diameters.size()) - m_mm3_per_mm = round_nearest(delta_pos[E] * static_cast(M_PI) * sqr(static_cast(m_filament_diameters[m_extruder_id])) / (4.0f * ds), 3); + if (ds > 0.0f && static_cast(m_extruder_id) < m_filament_diameters.size()) { + // extruded filament volume / tool displacement + m_mm3_per_mm = round_to_nearest(static_cast(M_PI * sqr(m_filament_diameters[m_extruder_id]) * 0.25) * delta_pos[E] / ds, 4); + } + + if (m_end_position[Z] > m_extruded_last_z + EPSILON) { + m_height = round_to_nearest(m_end_position[Z] - m_extruded_last_z, 4); + m_extruded_last_z = m_end_position[Z]; + } + } + } + + if (type == EMoveType::Extrude && (m_width == 0.0f || m_height == 0.0f)) { + if ((m_width == 0.0f && m_height == 0.0f) || m_extrusion_role == erCustom) + type = EMoveType::Travel; + else { + if (m_width == 0.0f) + m_width = 0.5f; + if (m_height == 0.0f) + m_height = 0.5f; } } diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index e35d3a9735..f103bab967 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -304,6 +304,7 @@ namespace Slic3r { unsigned char m_extruder_id; ExtruderColors m_extruder_colors; std::vector m_filament_diameters; + float m_extruded_last_z; CpColor m_cp_color; enum class EProducer diff --git a/src/libslic3r/Utils.hpp b/src/libslic3r/Utils.hpp index f7ff29b7e0..ef531169d1 100644 --- a/src/libslic3r/Utils.hpp +++ b/src/libslic3r/Utils.hpp @@ -110,19 +110,20 @@ std::string header_slic3r_generated(); // getpid platform wrapper extern unsigned get_current_pid(); +#if !ENABLE_GCODE_VIEWER template Real round_nearest(Real value, unsigned int decimals) { Real res = (Real)0; if (decimals == 0) res = ::round(value); - else - { + else { Real power = ::pow((Real)10, (int)decimals); res = ::round(value * power + (Real)0.5) / power; } return res; } +#endif // !ENABLE_GCODE_VIEWER // Compute the next highest power of 2 of 32-bit v // http://graphics.stanford.edu/~seander/bithacks.html diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index bbd357e980..b7bd81a0fa 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -235,38 +235,19 @@ const std::vector GCodeViewer::Extrusion_Role_Colors {{ { 0.00f, 0.00f, 0.00f } // erMixed }}; -//const std::vector GCodeViewer::Extrusion_Role_Colors {{ -// { 0.75f, 0.75f, 0.75f }, // erNone -// { 1.00f, 1.00f, 0.40f }, // erPerimeter -// { 1.00f, 0.65f, 0.00f }, // erExternalPerimeter -// { 0.00f, 0.00f, 1.00f }, // erOverhangPerimeter -// { 0.69f, 0.19f, 0.16f }, // erInternalInfill -// { 0.84f, 0.20f, 0.84f }, // erSolidInfill -// { 1.00f, 0.10f, 0.10f }, // erTopSolidInfill -// { 1.00f, 0.55f, 0.41f }, // erIroning -// { 0.60f, 0.60f, 1.00f }, // erBridgeInfill -// { 1.00f, 1.00f, 1.00f }, // erGapFill -// { 0.52f, 0.48f, 0.13f }, // erSkirt -// { 0.00f, 1.00f, 0.00f }, // erSupportMaterial -// { 0.00f, 0.50f, 0.00f }, // erSupportMaterialInterface -// { 0.70f, 0.89f, 0.67f }, // erWipeTower -// { 0.16f, 0.80f, 0.58f }, // erCustom -// { 0.00f, 0.00f, 0.00f } // erMixed -//}}; - const std::vector GCodeViewer::Options_Colors {{ - { 1.00f, 0.00f, 1.00f }, // Retractions - { 0.00f, 1.00f, 1.00f }, // Unretractions - { 1.00f, 1.00f, 1.00f }, // ToolChanges - { 1.00f, 0.00f, 0.00f }, // ColorChanges - { 0.00f, 1.00f, 0.00f }, // PausePrints - { 0.00f, 0.00f, 1.00f } // CustomGCodes + { 0.803f, 0.135f, 0.839f }, // Retractions + { 0.287f, 0.679f, 0.810f }, // Unretractions + { 0.758f, 0.744f, 0.389f }, // ToolChanges + { 0.856f, 0.582f, 0.546f }, // ColorChanges + { 0.322f, 0.942f, 0.512f }, // PausePrints + { 0.886f, 0.825f, 0.262f } // CustomGCodes }}; const std::vector GCodeViewer::Travel_Colors {{ - { 0.0f, 0.0f, 0.5f }, // Move - { 0.0f, 0.5f, 0.0f }, // Extrude - { 0.5f, 0.0f, 0.0f } // Retract + { 0.219f, 0.282f, 0.609f }, // Move + { 0.112f, 0.422f, 0.103f }, // Extrude + { 0.505f, 0.064f, 0.028f } // Retract }}; const std::vector GCodeViewer::Range_Colors {{ @@ -279,7 +260,8 @@ const std::vector GCodeViewer::Range_Colors {{ { 0.961f, 0.808f, 0.039f }, { 0.890f, 0.533f, 0.125f }, { 0.820f, 0.408f, 0.188f }, - { 0.761f, 0.322f, 0.235f } // reddish + { 0.761f, 0.322f, 0.235f }, + { 0.581f, 0.149f, 0.087f } // reddish }}; bool GCodeViewer::init() @@ -1525,11 +1507,15 @@ void GCodeViewer::render_legend() const append_item(EItemType::Rect, Range_Colors[i], buf); }; - float step_size = range.step_size(); - if (step_size == 0.0f) + if (range.count == 1) // single item use case append_range_item(0, range.min, decimals); + else if (range.count == 2) { + append_range_item(static_cast(Range_Colors.size()) - 1, range.max, decimals); + append_range_item(0, range.min, decimals); + } else { + float step_size = range.step_size(); for (int i = static_cast(Range_Colors.size()) - 1; i >= 0; --i) { append_range_item(i, range.min + static_cast(i) * step_size, decimals); } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 038b837b2b..74506677a6 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -142,11 +142,17 @@ class GCodeViewer { float min; float max; + unsigned int count; Range() { reset(); } - void update_from(const float value) { min = std::min(min, value); max = std::max(max, value); } - void reset() { min = FLT_MAX; max = -FLT_MAX; } + void update_from(const float value) { + if (value != max && value != min) + ++count; + min = std::min(min, value); + max = std::max(max, value); + } + void reset() { min = FLT_MAX; max = -FLT_MAX; count = 0; } float step_size() const { return (max - min) / (static_cast(Range_Colors.size()) - 1.0f); } Color get_color_at(float value) const; From f2d02faef4f73c9e71c4b06a438920937be7255b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 17 Aug 2020 10:06:41 +0200 Subject: [PATCH 186/255] GCodeProcessor -> Added debug code to check toolpaths data extracted from gcode, as mm3 per mm, height and width --- src/libslic3r/GCode.cpp | 11 ++ src/libslic3r/GCode.hpp | 6 + src/libslic3r/GCode/GCodeProcessor.cpp | 210 ++++++++++++++++--------- src/libslic3r/GCode/GCodeProcessor.hpp | 113 ++++++++++--- src/libslic3r/GCode/WipeTower.cpp | 16 ++ src/libslic3r/Technologies.hpp | 1 + src/slic3r/GUI/GCodeViewer.cpp | 4 +- 7 files changed, 263 insertions(+), 98 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 795aac898f..24c758d502 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1186,6 +1186,9 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu m_last_width = 0.0f; m_last_height = 0.0f; m_last_layer_z = 0.0f; +#if ENABLE_GCODE_VIEWER_DATA_CHECKING + m_last_mm3_per_mm = 0.0; +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING #else m_last_mm3_per_mm = GCodeAnalyzer::Default_mm3_per_mm; m_last_width = GCodeAnalyzer::Default_Width; @@ -3268,6 +3271,14 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, sprintf(buf, ";%s%s\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), ExtrusionEntity::role_to_string(m_last_processor_extrusion_role).c_str()); gcode += buf; } + +#if ENABLE_GCODE_VIEWER_DATA_CHECKING + if (last_was_wipe_tower || (m_last_mm3_per_mm != path.mm3_per_mm)) { + m_last_mm3_per_mm = path.mm3_per_mm; + sprintf(buf, ";%s%f\n", GCodeProcessor::Mm3_Per_Mm_Tag.c_str(), m_last_mm3_per_mm); + gcode += buf; + } +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING #else if (path.role() != m_last_analyzer_extrusion_role) { m_last_analyzer_extrusion_role = path.role(); diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 6f97d5dbd3..76f897c63b 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -172,6 +172,9 @@ public: m_volumetric_speed(0), m_last_pos_defined(false), m_last_extrusion_role(erNone), +#if ENABLE_GCODE_VIEWER_DATA_CHECKING + m_last_mm3_per_mm(0.0), +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING #if !ENABLE_GCODE_VIEWER m_last_mm3_per_mm(GCodeAnalyzer::Default_mm3_per_mm), m_last_width(GCodeAnalyzer::Default_Width), @@ -381,6 +384,9 @@ private: float m_last_width{ 0.0f }; float m_last_height{ 0.0f }; float m_last_layer_z{ 0.0f }; +#if ENABLE_GCODE_VIEWER_DATA_CHECKING + double m_last_mm3_per_mm; +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING #else // Support for G-Code Analyzer double m_last_mm3_per_mm; diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 18878cd5ad..2e6736d1ec 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -33,6 +33,10 @@ const std::string GCodeProcessor::First_Line_M73_Placeholder_Tag = "; _ const std::string GCodeProcessor::Last_Line_M73_Placeholder_Tag = "; _GP_LAST_LINE_M73_PLACEHOLDER"; const std::string GCodeProcessor::Estimated_Printing_Time_Placeholder_Tag = "; _GP_ESTIMATED_PRINTING_TIME_PLACEHOLDER"; +#if ENABLE_GCODE_VIEWER_DATA_CHECKING +const std::string GCodeProcessor::Mm3_Per_Mm_Tag = "Mm3_Per_Mm:"; +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING + static bool is_valid_extrusion_role(int value) { return (static_cast(erNone) <= value) && (value <= static_cast(erMixed)); @@ -308,10 +312,10 @@ void GCodeProcessor::TimeProcessor::reset() machine_limits = MachineEnvelopeConfig(); filament_load_times = std::vector(); filament_unload_times = std::vector(); - for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { machines[i].reset(); } - machines[static_cast(ETimeMode::Normal)].enabled = true; + machines[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Normal)].enabled = true; } void GCodeProcessor::TimeProcessor::post_process(const std::string& filename) @@ -342,8 +346,8 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename) std::string gcode_line; size_t g1_lines_counter = 0; // keeps track of last exported pair - std::array, static_cast(ETimeMode::Count)> last_exported; - for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + std::array, static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count)> last_exported; + for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { last_exported[i] = { 0, time_in_minutes(machines[i].time) }; } @@ -357,7 +361,7 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename) std::string ret; if (line == First_Line_M73_Placeholder_Tag || line == Last_Line_M73_Placeholder_Tag) { - for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { const TimeMachine& machine = machines[i]; if (machine.enabled) { ret += format_line_M73(machine.line_m73_mask.c_str(), @@ -367,12 +371,12 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename) } } else if (line == Estimated_Printing_Time_Placeholder_Tag) { - for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { const TimeMachine& machine = machines[i]; if (machine.enabled) { char buf[128]; sprintf(buf, "; estimated printing time (%s mode) = %s\n", - (static_cast(i) == ETimeMode::Normal) ? "normal" : "silent", + (static_cast(i) == PrintEstimatedTimeStatistics::ETimeMode::Normal) ? "normal" : "silent", get_time_dhms(machine.time).c_str()); ret += buf; } @@ -383,7 +387,7 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename) // add lines M73 to exported gcode auto process_line_G1 = [&]() { - for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { const TimeMachine& machine = machines[i]; if (machine.enabled && g1_lines_counter < machine.g1_times_cache.size()) { float elapsed_time = machine.g1_times_cache[g1_lines_counter]; @@ -458,8 +462,8 @@ unsigned int GCodeProcessor::s_result_id = 0; GCodeProcessor::GCodeProcessor() { reset(); - m_time_processor.machines[static_cast(ETimeMode::Normal)].line_m73_mask = "M73 P%s R%s\n"; - m_time_processor.machines[static_cast(ETimeMode::Stealth)].line_m73_mask = "M73 Q%s S%s\n"; + m_time_processor.machines[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Normal)].line_m73_mask = "M73 P%s R%s\n"; + m_time_processor.machines[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Stealth)].line_m73_mask = "M73 Q%s S%s\n"; } void GCodeProcessor::apply_config(const PrintConfig& config) @@ -478,7 +482,7 @@ void GCodeProcessor::apply_config(const PrintConfig& config) m_extruder_colors.resize(extruders_count); for (size_t i = 0; i < extruders_count; ++i) { - m_extruder_colors[i] = static_cast(i); + m_extruder_colors[i] = static_cast(i); } m_filament_diameters.resize(config.filament_diameter.values.size()); @@ -499,7 +503,7 @@ void GCodeProcessor::apply_config(const PrintConfig& config) m_time_processor.filament_unload_times[i] = static_cast(config.filament_unload_time.values[i]); } - for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { float max_acceleration = get_option_value(m_time_processor.machine_limits.machine_max_acceleration_extruding, i); m_time_processor.machines[i].max_acceleration = max_acceleration; m_time_processor.machines[i].acceleration = (max_acceleration > 0.0f) ? max_acceleration : DEFAULT_ACCELERATION; @@ -561,7 +565,7 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config) m_extruder_colors.resize(m_result.extruder_colors.size()); for (size_t i = 0; i < m_result.extruder_colors.size(); ++i) { - m_extruder_colors[i] = static_cast(i); + m_extruder_colors[i] = static_cast(i); } const ConfigOptionFloats* filament_load_time = config.option("filament_load_time"); @@ -644,7 +648,7 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config) if (machine_min_travel_rate != nullptr) m_time_processor.machine_limits.machine_min_travel_rate.values = machine_min_travel_rate->values; - for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { float max_acceleration = get_option_value(m_time_processor.machine_limits.machine_max_acceleration_extruding, i); m_time_processor.machines[i].max_acceleration = max_acceleration; m_time_processor.machines[i].acceleration = (max_acceleration > 0.0f) ? max_acceleration : DEFAULT_ACCELERATION; @@ -653,15 +657,17 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config) void GCodeProcessor::enable_stealth_time_estimator(bool enabled) { - m_time_processor.machines[static_cast(ETimeMode::Stealth)].enabled = enabled; + m_time_processor.machines[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Stealth)].enabled = enabled; } void GCodeProcessor::reset() { + static const size_t Min_Extruder_Count = 5; + m_units = EUnits::Millimeters; m_global_positioning_type = EPositioningType::Absolute; m_e_local_positioning_type = EPositioningType::Absolute; - m_extruder_offsets = std::vector(1, Vec3f::Zero()); + m_extruder_offsets = std::vector(Min_Extruder_Count, Vec3f::Zero()); m_flavor = gcfRepRap; m_start_position = { 0.0f, 0.0f, 0.0f, 0.0f }; @@ -677,8 +683,12 @@ void GCodeProcessor::reset() m_extrusion_role = erNone; m_extruder_id = 0; - m_extruder_colors = ExtruderColors(); - m_filament_diameters = std::vector(); + m_extruder_colors.resize(Min_Extruder_Count); + for (size_t i = 0; i < Min_Extruder_Count; ++i) { + m_extruder_colors[i] = static_cast(i); + } + + m_filament_diameters = std::vector(Min_Extruder_Count, 1.75f); m_extruded_last_z = 0.0f; m_cp_color.reset(); @@ -689,6 +699,12 @@ void GCodeProcessor::reset() m_result.reset(); m_result.id = ++s_result_id; + +#if ENABLE_GCODE_VIEWER_DATA_CHECKING + m_mm3_per_mm_compare.reset(); + m_height_compare.reset(); + m_width_compare.reset(); +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING } void GCodeProcessor::process_file(const std::string& filename) @@ -724,7 +740,7 @@ void GCodeProcessor::process_file(const std::string& filename) m_parser.parse_file(filename, [this](GCodeReader& reader, const GCodeReader::GCodeLine& line) { process_gcode_line(line); }); // process the remaining time blocks - for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { TimeMachine& machine = m_time_processor.machines[i]; TimeMachine::CustomGCodeTime& gcode_time = machine.gcode_time; machine.calculate_time(); @@ -738,25 +754,31 @@ void GCodeProcessor::process_file(const std::string& filename) if (m_time_processor.export_remaining_time_enabled) m_time_processor.post_process(filename); +#if ENABLE_GCODE_VIEWER_DATA_CHECKING + m_mm3_per_mm_compare.output(); + m_height_compare.output(); + m_width_compare.output(); +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING + #if ENABLE_GCODE_VIEWER_STATISTICS m_result.time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); #endif // ENABLE_GCODE_VIEWER_STATISTICS } -float GCodeProcessor::get_time(ETimeMode mode) const +float GCodeProcessor::get_time(PrintEstimatedTimeStatistics::ETimeMode mode) const { - return (mode < ETimeMode::Count) ? m_time_processor.machines[static_cast(mode)].time : 0.0f; + return (mode < PrintEstimatedTimeStatistics::ETimeMode::Count) ? m_time_processor.machines[static_cast(mode)].time : 0.0f; } -std::string GCodeProcessor::get_time_dhm(ETimeMode mode) const +std::string GCodeProcessor::get_time_dhm(PrintEstimatedTimeStatistics::ETimeMode mode) const { - return (mode < ETimeMode::Count) ? short_time(get_time_dhms(m_time_processor.machines[static_cast(mode)].time)) : std::string("N/A"); + return (mode < PrintEstimatedTimeStatistics::ETimeMode::Count) ? short_time(get_time_dhms(m_time_processor.machines[static_cast(mode)].time)) : std::string("N/A"); } -std::vector>> GCodeProcessor::get_custom_gcode_times(ETimeMode mode, bool include_remaining) const +std::vector>> GCodeProcessor::get_custom_gcode_times(PrintEstimatedTimeStatistics::ETimeMode mode, bool include_remaining) const { std::vector>> ret; - if (mode < ETimeMode::Count) { + if (mode < PrintEstimatedTimeStatistics::ETimeMode::Count) { const TimeMachine& machine = m_time_processor.machines[static_cast(mode)]; float total_time = 0.0f; for (const auto& [type, time] : machine.gcode_time.times) { @@ -768,10 +790,10 @@ std::vector>> GCodeProcesso return ret; } -std::vector> GCodeProcessor::get_moves_time(ETimeMode mode) const +std::vector> GCodeProcessor::get_moves_time(PrintEstimatedTimeStatistics::ETimeMode mode) const { std::vector> ret; - if (mode < ETimeMode::Count) { + if (mode < PrintEstimatedTimeStatistics::ETimeMode::Count) { for (size_t i = 0; i < m_time_processor.machines[static_cast(mode)].moves_time.size(); ++i) { float time = m_time_processor.machines[static_cast(mode)].moves_time[i]; if (time > 0.0f) @@ -781,10 +803,10 @@ std::vector> GCodeProcessor::get_moves_time(ETimeMod return ret; } -std::vector> GCodeProcessor::get_roles_time(ETimeMode mode) const +std::vector> GCodeProcessor::get_roles_time(PrintEstimatedTimeStatistics::ETimeMode mode) const { std::vector> ret; - if (mode < ETimeMode::Count) { + if (mode < PrintEstimatedTimeStatistics::ETimeMode::Count) { for (size_t i = 0; i < m_time_processor.machines[static_cast(mode)].roles_time.size(); ++i) { float time = m_time_processor.machines[static_cast(mode)].roles_time[i]; if (time > 0.0f) @@ -888,6 +910,9 @@ void GCodeProcessor::process_tags(const std::string& comment) if (pos != comment.npos) { try { m_width = std::stof(comment.substr(pos + Width_Tag.length())); +#if ENABLE_GCODE_VIEWER_DATA_CHECKING + m_width_compare.last_tag_value = m_width; +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING } catch (...) { BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ")."; @@ -900,6 +925,9 @@ void GCodeProcessor::process_tags(const std::string& comment) if (pos != comment.npos) { try { m_height = std::stof(comment.substr(pos + Height_Tag.length())); +#if ENABLE_GCODE_VIEWER_DATA_CHECKING + m_height_compare.last_tag_value = m_height; +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING } catch (...) { BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ")."; @@ -947,6 +975,20 @@ void GCodeProcessor::process_tags(const std::string& comment) store_move_vertex(EMoveType::Custom_GCode); return; } + +#if ENABLE_GCODE_VIEWER_DATA_CHECKING + // mm3_per_mm print tag + pos = comment.find(Mm3_Per_Mm_Tag); + if (pos != comment.npos) { + try { + m_mm3_per_mm_compare.last_tag_value = std::stof(comment.substr(pos + Mm3_Per_Mm_Tag.length())); + } + catch (...) { + BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Mm3_Per_Mm (" << comment << ")."; + } + return; + } +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING } bool GCodeProcessor::process_producers_tags(const std::string& comment) @@ -1126,8 +1168,10 @@ bool GCodeProcessor::process_simplify3d_tags(const std::string& comment) size_t w_end = data.find_first_of(' ', w_start); if (h_start != data.npos) { try { - std::string test = data.substr(h_start + 1, (h_end != data.npos) ? h_end - h_start - 1 : h_end); m_height = std::stof(data.substr(h_start + 1, (h_end != data.npos) ? h_end - h_start - 1 : h_end)); +#if ENABLE_GCODE_VIEWER_DATA_CHECKING + m_height_compare.last_tag_value = m_height; +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING } catch (...) { BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ")."; @@ -1135,8 +1179,10 @@ bool GCodeProcessor::process_simplify3d_tags(const std::string& comment) } if (w_start != data.npos) { try { - std::string test = data.substr(w_start + 1, (w_end != data.npos) ? w_end - w_start - 1 : w_end); m_width = std::stof(data.substr(w_start + 1, (w_end != data.npos) ? w_end - w_start - 1 : w_end)); +#if ENABLE_GCODE_VIEWER_DATA_CHECKING + m_width_compare.last_tag_value = m_width; +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING } catch (...) { BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ")."; @@ -1146,7 +1192,7 @@ bool GCodeProcessor::process_simplify3d_tags(const std::string& comment) return true; } - std::cout << comment << "\n"; +// std::cout << comment << "\n"; return false; } @@ -1226,6 +1272,9 @@ bool GCodeProcessor::process_ideamaker_tags(const std::string& comment) if (pos != comment.npos) { try { m_width = std::stof(comment.substr(pos + tag.length())); +#if ENABLE_GCODE_VIEWER_DATA_CHECKING + m_width_compare.last_tag_value = m_width; +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING } catch (...) { BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ")."; @@ -1239,6 +1288,9 @@ bool GCodeProcessor::process_ideamaker_tags(const std::string& comment) if (pos != comment.npos) { try { m_height = std::stof(comment.substr(pos + tag.length())); +#if ENABLE_GCODE_VIEWER_DATA_CHECKING + m_height_compare.last_tag_value = m_height; +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING } catch (...) { BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ")."; @@ -1327,19 +1379,29 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) return; EMoveType type = move_type(delta_pos); + if (type == EMoveType::Extrude && m_end_position[Z] == 0.0f) + type = EMoveType::Travel; if (type == EMoveType::Extrude) { - if (delta_pos[E] > 0.0f) { - float ds = std::sqrt(sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z])); - if (ds > 0.0f && static_cast(m_extruder_id) < m_filament_diameters.size()) { - // extruded filament volume / tool displacement - m_mm3_per_mm = round_to_nearest(static_cast(M_PI * sqr(m_filament_diameters[m_extruder_id]) * 0.25) * delta_pos[E] / ds, 4); - } + float d_xyz = std::sqrt(sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z])); + float filament_diameter = (static_cast(m_extruder_id) < m_filament_diameters.size()) ? m_filament_diameters[m_extruder_id] : m_filament_diameters.back(); + float filament_radius = 0.5f * filament_diameter; + float area_filament_cross_section = static_cast(M_PI) * sqr(filament_radius); + float volume_extruded_filament = area_filament_cross_section * delta_pos[E]; + float area_toolpath_cross_section = volume_extruded_filament / d_xyz; - if (m_end_position[Z] > m_extruded_last_z + EPSILON) { - m_height = round_to_nearest(m_end_position[Z] - m_extruded_last_z, 4); - m_extruded_last_z = m_end_position[Z]; - } + // volume extruded filament / tool displacement = area toolpath cross section + m_mm3_per_mm = round_to_nearest(area_toolpath_cross_section, 3); +#if ENABLE_GCODE_VIEWER_DATA_CHECKING + m_mm3_per_mm_compare.update(area_toolpath_cross_section, m_extrusion_role); +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING + + if (m_end_position[Z] > m_extruded_last_z + EPSILON) { + m_height = round_to_nearest(m_end_position[Z] - m_extruded_last_z, 4); +#if ENABLE_GCODE_VIEWER_DATA_CHECKING + m_height_compare.update(m_height, m_extrusion_role); +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING + m_extruded_last_z = m_end_position[Z]; } } @@ -1368,7 +1430,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) assert(distance != 0.0f); float inv_distance = 1.0f / distance; - for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { TimeMachine& machine = m_time_processor.machines[i]; if (!machine.enabled) continue; @@ -1378,8 +1440,8 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) std::vector& blocks = machine.blocks; curr.feedrate = (delta_pos[E] == 0.0f) ? - minimum_travel_feedrate(static_cast(i), m_feedrate) : - minimum_feedrate(static_cast(i), m_feedrate); + minimum_travel_feedrate(static_cast(i), m_feedrate) : + minimum_feedrate(static_cast(i), m_feedrate); TimeBlock block; block.move_type = type; @@ -1395,7 +1457,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) curr.abs_axis_feedrate[a] = std::abs(curr.axis_feedrate[a]); if (curr.abs_axis_feedrate[a] != 0.0f) { - float axis_max_feedrate = get_axis_max_feedrate(static_cast(i), static_cast(a)); + float axis_max_feedrate = get_axis_max_feedrate(static_cast(i), static_cast(a)); if (axis_max_feedrate != 0.0f) min_feedrate_factor = std::min(min_feedrate_factor, axis_max_feedrate / curr.abs_axis_feedrate[a]); } @@ -1412,11 +1474,11 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) // calculates block acceleration float acceleration = is_extrusion_only_move(delta_pos) ? - get_retract_acceleration(static_cast(i)) : - get_acceleration(static_cast(i)); + get_retract_acceleration(static_cast(i)) : + get_acceleration(static_cast(i)); for (unsigned char a = X; a <= E; ++a) { - float axis_max_acceleration = get_axis_max_acceleration(static_cast(i), static_cast(a)); + float axis_max_acceleration = get_axis_max_acceleration(static_cast(i), static_cast(a)); if (acceleration * std::abs(delta_pos[a]) * inv_distance > axis_max_acceleration) acceleration = axis_max_acceleration; } @@ -1427,7 +1489,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) curr.safe_feedrate = block.feedrate_profile.cruise; for (unsigned char a = X; a <= E; ++a) { - float axis_max_jerk = get_axis_max_jerk(static_cast(i), static_cast(a)); + float axis_max_jerk = get_axis_max_jerk(static_cast(i), static_cast(a)); if (curr.abs_axis_feedrate[a] > axis_max_jerk) curr.safe_feedrate = std::min(curr.safe_feedrate, axis_max_jerk); } @@ -1475,7 +1537,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) // axis reversal std::max(-v_exit, v_entry)); - float axis_max_jerk = get_axis_max_jerk(static_cast(i), static_cast(a)); + float axis_max_jerk = get_axis_max_jerk(static_cast(i), static_cast(a)); if (jerk > axis_max_jerk) { v_factor *= axis_max_jerk / jerk; limited = true; @@ -1689,7 +1751,7 @@ void GCodeProcessor::process_M201(const GCodeReader::GCodeLine& line) // see http://reprap.org/wiki/G-code#M201:_Set_max_printing_acceleration float factor = (m_flavor != gcfRepRap && m_units == EUnits::Inches) ? INCHES_TO_MM : 1.0f; - for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { if (line.has_x()) set_option_value(m_time_processor.machine_limits.machine_max_acceleration_x, i, line.x() * factor); @@ -1717,7 +1779,7 @@ void GCodeProcessor::process_M203(const GCodeReader::GCodeLine& line) // http://smoothieware.org/supported-g-codes float factor = (m_flavor == gcfMarlin || m_flavor == gcfSmoothie) ? 1.0f : MMMIN_TO_MMSEC; - for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { if (line.has_x()) set_option_value(m_time_processor.machine_limits.machine_max_feedrate_x, i, line.x() * factor); @@ -1738,19 +1800,19 @@ void GCodeProcessor::process_M204(const GCodeReader::GCodeLine& line) return; float value; - for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { if (line.has_value('S', value)) { // Legacy acceleration format. This format is used by the legacy Marlin, MK2 or MK3 firmware, // and it is also generated by Slic3r to control acceleration per extrusion type // (there is a separate acceleration settings in Slicer for perimeter, first layer etc). - set_acceleration(static_cast(i), value); + set_acceleration(static_cast(i), value); if (line.has_value('T', value)) set_option_value(m_time_processor.machine_limits.machine_max_acceleration_retracting, i, value); } else { // New acceleration format, compatible with the upstream Marlin. if (line.has_value('P', value)) - set_acceleration(static_cast(i), value); + set_acceleration(static_cast(i), value); if (line.has_value('R', value)) set_option_value(m_time_processor.machine_limits.machine_max_acceleration_retracting, i, value); if (line.has_value('T', value)) { @@ -1767,7 +1829,7 @@ void GCodeProcessor::process_M205(const GCodeReader::GCodeLine& line) if (!m_time_processor.machine_envelope_processing_enabled) return; - for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { if (line.has_x()) { float max_jerk = line.x(); set_option_value(m_time_processor.machine_limits.machine_max_jerk_x, i, max_jerk); @@ -1798,7 +1860,7 @@ void GCodeProcessor::process_M221(const GCodeReader::GCodeLine& line) float value_t; if (line.has_value('S', value_s) && !line.has_value('T', value_t)) { value_s *= 0.01f; - for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { m_time_processor.machines[i].extrude_factor_override_percentage = value_s; } } @@ -1849,7 +1911,7 @@ void GCodeProcessor::process_M402(const GCodeReader::GCodeLine& line) void GCodeProcessor::process_M566(const GCodeReader::GCodeLine& line) { - for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { if (line.has_x()) set_option_value(m_time_processor.machine_limits.machine_max_jerk_x, i, line.x() * MMMIN_TO_MMSEC); @@ -1930,7 +1992,7 @@ void GCodeProcessor::store_move_vertex(EMoveType type) m_result.moves.emplace_back(vertex); } -float GCodeProcessor::minimum_feedrate(ETimeMode mode, float feedrate) const +float GCodeProcessor::minimum_feedrate(PrintEstimatedTimeStatistics::ETimeMode mode, float feedrate) const { if (m_time_processor.machine_limits.machine_min_extruding_rate.empty()) return feedrate; @@ -1938,7 +2000,7 @@ float GCodeProcessor::minimum_feedrate(ETimeMode mode, float feedrate) const return std::max(feedrate, get_option_value(m_time_processor.machine_limits.machine_min_extruding_rate, static_cast(mode))); } -float GCodeProcessor::minimum_travel_feedrate(ETimeMode mode, float feedrate) const +float GCodeProcessor::minimum_travel_feedrate(PrintEstimatedTimeStatistics::ETimeMode mode, float feedrate) const { if (m_time_processor.machine_limits.machine_min_travel_rate.empty()) return feedrate; @@ -1946,7 +2008,7 @@ float GCodeProcessor::minimum_travel_feedrate(ETimeMode mode, float feedrate) co return std::max(feedrate, get_option_value(m_time_processor.machine_limits.machine_min_travel_rate, static_cast(mode))); } -float GCodeProcessor::get_axis_max_feedrate(ETimeMode mode, Axis axis) const +float GCodeProcessor::get_axis_max_feedrate(PrintEstimatedTimeStatistics::ETimeMode mode, Axis axis) const { switch (axis) { @@ -1958,7 +2020,7 @@ float GCodeProcessor::get_axis_max_feedrate(ETimeMode mode, Axis axis) const } } -float GCodeProcessor::get_axis_max_acceleration(ETimeMode mode, Axis axis) const +float GCodeProcessor::get_axis_max_acceleration(PrintEstimatedTimeStatistics::ETimeMode mode, Axis axis) const { switch (axis) { @@ -1970,7 +2032,7 @@ float GCodeProcessor::get_axis_max_acceleration(ETimeMode mode, Axis axis) const } } -float GCodeProcessor::get_axis_max_jerk(ETimeMode mode, Axis axis) const +float GCodeProcessor::get_axis_max_jerk(PrintEstimatedTimeStatistics::ETimeMode mode, Axis axis) const { switch (axis) { @@ -1982,18 +2044,18 @@ float GCodeProcessor::get_axis_max_jerk(ETimeMode mode, Axis axis) const } } -float GCodeProcessor::get_retract_acceleration(ETimeMode mode) const +float GCodeProcessor::get_retract_acceleration(PrintEstimatedTimeStatistics::ETimeMode mode) const { return get_option_value(m_time_processor.machine_limits.machine_max_acceleration_retracting, static_cast(mode)); } -float GCodeProcessor::get_acceleration(ETimeMode mode) const +float GCodeProcessor::get_acceleration(PrintEstimatedTimeStatistics::ETimeMode mode) const { size_t id = static_cast(mode); return (id < m_time_processor.machines.size()) ? m_time_processor.machines[id].acceleration : DEFAULT_ACCELERATION; } -void GCodeProcessor::set_acceleration(ETimeMode mode, float value) +void GCodeProcessor::set_acceleration(PrintEstimatedTimeStatistics::ETimeMode mode, float value) { size_t id = static_cast(mode); if (id < m_time_processor.machines.size()) { @@ -2021,7 +2083,7 @@ float GCodeProcessor::get_filament_unload_time(size_t extruder_id) void GCodeProcessor::process_custom_gcode_time(CustomGCode::Type code) { - for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { TimeMachine& machine = m_time_processor.machines[i]; if (!machine.enabled) continue; @@ -2040,14 +2102,14 @@ void GCodeProcessor::process_custom_gcode_time(CustomGCode::Type code) void GCodeProcessor::simulate_st_synchronize(float additional_time) { - for (size_t i = 0; i < static_cast(ETimeMode::Count); ++i) { + for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { m_time_processor.machines[i].simulate_st_synchronize(additional_time); } } void GCodeProcessor::update_estimated_times_stats() { - auto update_mode = [this](GCodeProcessor::ETimeMode mode) { + auto update_mode = [this](PrintEstimatedTimeStatistics::ETimeMode mode) { PrintEstimatedTimeStatistics::Mode& data = m_result.time_statistics.modes[static_cast(mode)]; data.time = get_time(mode); data.custom_gcode_times = get_custom_gcode_times(mode, true); @@ -2055,11 +2117,11 @@ void GCodeProcessor::update_estimated_times_stats() data.roles_times = get_roles_time(mode); }; - update_mode(GCodeProcessor::ETimeMode::Normal); - if (m_time_processor.machines[static_cast(GCodeProcessor::ETimeMode::Stealth)].enabled) - update_mode(GCodeProcessor::ETimeMode::Stealth); + update_mode(PrintEstimatedTimeStatistics::ETimeMode::Normal); + if (m_time_processor.machines[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Stealth)].enabled) + update_mode(PrintEstimatedTimeStatistics::ETimeMode::Stealth); else - m_result.time_statistics.modes[static_cast(GCodeProcessor::ETimeMode::Stealth)].reset(); + m_result.time_statistics.modes[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Stealth)].reset(); } } /* namespace Slic3r */ diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index f103bab967..166e1b8cca 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -76,6 +76,10 @@ namespace Slic3r { static const std::string Last_Line_M73_Placeholder_Tag; static const std::string Estimated_Printing_Time_Placeholder_Tag; +#if ENABLE_GCODE_VIEWER_DATA_CHECKING + static const std::string Mm3_Per_Mm_Tag; +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING + private: using AxisCoords = std::array; using ExtruderColors = std::vector; @@ -152,13 +156,6 @@ namespace Slic3r { float time() const; }; - enum class ETimeMode : unsigned char - { - Normal, - Stealth, - Count - }; - private: struct TimeMachine { @@ -227,7 +224,7 @@ namespace Slic3r { // Additional load / unload times for a filament exchange sequence. std::vector filament_load_times; std::vector filament_unload_times; - std::array(ETimeMode::Count)> machines; + std::array(PrintEstimatedTimeStatistics::ETimeMode::Count)> machines; void reset(); @@ -281,6 +278,72 @@ namespace Slic3r { #endif // ENABLE_GCODE_VIEWER_STATISTICS }; +#if ENABLE_GCODE_VIEWER_DATA_CHECKING + struct DataChecker + { + struct Error + { + float value; + float tag_value; + ExtrusionRole role; + }; + + std::string type; + float threshold{ 0.01f }; + float last_tag_value{ 0.0f }; + unsigned int count{ 0 }; + std::vector errors; + + DataChecker(const std::string& type, float threshold) + : type(type), threshold(threshold) + {} + + void update(float value, ExtrusionRole role) { + ++count; + if (last_tag_value != 0.0f) { + if (std::abs(value - last_tag_value) / last_tag_value > threshold) + errors.push_back({ value, last_tag_value, role }); + } + } + + void reset() { last_tag_value = 0.0f; errors.clear(); count = 0; } + + std::pair get_min() const { + float delta_min = FLT_MAX; + float perc_min = 0.0f; + for (const Error& e : errors) { + if (delta_min > e.value - e.tag_value) { + delta_min = e.value - e.tag_value; + perc_min = 100.0f * delta_min / e.tag_value; + } + } + return { delta_min, perc_min }; + } + + std::pair get_max() const { + float delta_max = -FLT_MAX; + float perc_max = 0.0f; + for (const Error& e : errors) { + if (delta_max < e.value - e.tag_value) { + delta_max = e.value - e.tag_value; + perc_max = 100.0f * delta_max / e.tag_value; + } + } + return { delta_max, perc_max }; + } + + void output() const { + if (!errors.empty()) { + std::cout << type << ":\n"; + std::cout << "Errors: " << errors.size() << " (" << 100.0f * float(errors.size()) / float(count) << "%)\n"; + auto [min, perc_min] = get_min(); + auto [max, perc_max] = get_max(); + std::cout << "min: " << min << "(" << perc_min << "%) - max: " << max << "(" << perc_max << "%)\n"; + } + } + }; +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING + private: GCodeReader m_parser; @@ -326,6 +389,12 @@ namespace Slic3r { Result m_result; static unsigned int s_result_id; +#if ENABLE_GCODE_VIEWER_DATA_CHECKING + DataChecker m_mm3_per_mm_compare{ "mm3_per_mm", 0.01f }; + DataChecker m_height_compare{ "height", 0.01f }; + DataChecker m_width_compare{ "width", 0.01f }; +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING + public: GCodeProcessor(); @@ -333,7 +402,7 @@ namespace Slic3r { void apply_config(const DynamicPrintConfig& config); void enable_stealth_time_estimator(bool enabled); bool is_stealth_time_estimator_enabled() const { - return m_time_processor.machines[static_cast(ETimeMode::Stealth)].enabled; + return m_time_processor.machines[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Stealth)].enabled; } void enable_machine_envelope_processing(bool enabled) { m_time_processor.machine_envelope_processing_enabled = enabled; } void enable_producers(bool enabled) { m_producers_enabled = enabled; } @@ -345,12 +414,12 @@ namespace Slic3r { // Process the gcode contained in the file with the given filename void process_file(const std::string& filename); - float get_time(ETimeMode mode) const; - std::string get_time_dhm(ETimeMode mode) const; - std::vector>> get_custom_gcode_times(ETimeMode mode, bool include_remaining) const; + float get_time(PrintEstimatedTimeStatistics::ETimeMode mode) const; + std::string get_time_dhm(PrintEstimatedTimeStatistics::ETimeMode mode) const; + std::vector>> get_custom_gcode_times(PrintEstimatedTimeStatistics::ETimeMode mode, bool include_remaining) const; - std::vector> get_moves_time(ETimeMode mode) const; - std::vector> get_roles_time(ETimeMode mode) const; + std::vector> get_moves_time(PrintEstimatedTimeStatistics::ETimeMode mode) const; + std::vector> get_roles_time(PrintEstimatedTimeStatistics::ETimeMode mode) const; private: void process_gcode_line(const GCodeReader::GCodeLine& line); @@ -454,14 +523,14 @@ namespace Slic3r { void store_move_vertex(EMoveType type); - float minimum_feedrate(ETimeMode mode, float feedrate) const; - float minimum_travel_feedrate(ETimeMode mode, float feedrate) const; - float get_axis_max_feedrate(ETimeMode mode, Axis axis) const; - float get_axis_max_acceleration(ETimeMode mode, Axis axis) const; - float get_axis_max_jerk(ETimeMode mode, Axis axis) const; - float get_retract_acceleration(ETimeMode mode) const; - float get_acceleration(ETimeMode mode) const; - void set_acceleration(ETimeMode mode, float value); + float minimum_feedrate(PrintEstimatedTimeStatistics::ETimeMode mode, float feedrate) const; + float minimum_travel_feedrate(PrintEstimatedTimeStatistics::ETimeMode mode, float feedrate) const; + float get_axis_max_feedrate(PrintEstimatedTimeStatistics::ETimeMode mode, Axis axis) const; + float get_axis_max_acceleration(PrintEstimatedTimeStatistics::ETimeMode mode, Axis axis) const; + float get_axis_max_jerk(PrintEstimatedTimeStatistics::ETimeMode mode, Axis axis) const; + float get_retract_acceleration(PrintEstimatedTimeStatistics::ETimeMode mode) const; + float get_acceleration(PrintEstimatedTimeStatistics::ETimeMode mode) const; + void set_acceleration(PrintEstimatedTimeStatistics::ETimeMode mode, float value); float get_filament_load_time(size_t extruder_id); float get_filament_unload_time(size_t extruder_id); diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index c20009a487..e6e60b6186 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -84,6 +84,17 @@ public: return *this; } +#if ENABLE_GCODE_VIEWER_DATA_CHECKING + WipeTowerWriter& change_analyzer_mm3_per_mm(float len, float e) { + static const float area = float(M_PI) * 1.75f * 1.75f / 4.f; + float mm3_per_mm = (len == 0.f ? 0.f : area * e / len); + // adds tag for processor: + char buf[64]; + sprintf(buf, ";%s%f\n", GCodeProcessor::Mm3_Per_Mm_Tag.c_str(), mm3_per_mm); + m_gcode += buf; + return *this; + } +#else #if !ENABLE_GCODE_VIEWER WipeTowerWriter& change_analyzer_mm3_per_mm(float len, float e) { static const float area = float(M_PI) * 1.75f * 1.75f / 4.f; @@ -95,6 +106,7 @@ public: return *this; } #endif // !ENABLE_GCODE_VIEWER +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING WipeTowerWriter& set_initial_position(const Vec2f &pos, float width = 0.f, float depth = 0.f, float internal_angle = 0.f) { m_wipe_tower_width = width; @@ -167,9 +179,13 @@ public: Vec2f rot(this->rotate(Vec2f(x,y))); // this is where we want to go if (! m_preview_suppressed && e > 0.f && len > 0.f) { +#if ENABLE_GCODE_VIEWER_DATA_CHECKING + change_analyzer_mm3_per_mm(len, e); +#else #if !ENABLE_GCODE_VIEWER change_analyzer_mm3_per_mm(len, e); #endif // !ENABLE_GCODE_VIEWER +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING // Width of a squished extrusion, corrected for the roundings of the squished extrusions. // This is left zero if it is a travel move. float width = e * m_filpar[0].filament_area / (len * m_layer_height); diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 609aecf635..e10cabc6cf 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -58,6 +58,7 @@ #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) #define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_SHADERS_EDITOR (0 && ENABLE_GCODE_VIEWER) +#define ENABLE_GCODE_VIEWER_DATA_CHECKING (0 && ENABLE_GCODE_VIEWER) #define TIME_ESTIMATE_NONE 0 #define TIME_ESTIMATE_DEFAULT 1 diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index b7bd81a0fa..17651fef37 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -975,8 +975,8 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) for (const TBuffer& buffer : m_buffers) { m_statistics.paths_size += SLIC3R_STDVEC_MEMSIZE(buffer.paths, Path); } - m_statistics.travel_segments_count = indices[buffer_id(GCodeProcessor::EMoveType::Travel)].size() / 2; - m_statistics.extrude_segments_count = indices[buffer_id(GCodeProcessor::EMoveType::Extrude)].size() / 2; + m_statistics.travel_segments_count = indices[buffer_id(EMoveType::Travel)].size() / 2; + m_statistics.extrude_segments_count = indices[buffer_id(EMoveType::Extrude)].size() / 2; #endif // ENABLE_GCODE_VIEWER_STATISTICS // layers zs / roles / extruder ids / cp color ids -> extract from result From 5b579aee9a4c97ccb0c0cd469750ecac3dcbb176 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 17 Aug 2020 10:54:41 +0200 Subject: [PATCH 187/255] GCodeProcessor -> Extract toolpaths width from gcode moves --- src/libslic3r/GCode/GCodeProcessor.cpp | 27 ++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 2e6736d1ec..a0661191cb 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -755,6 +755,7 @@ void GCodeProcessor::process_file(const std::string& filename) m_time_processor.post_process(filename); #if ENABLE_GCODE_VIEWER_DATA_CHECKING + std::cout << "\n"; m_mm3_per_mm_compare.output(); m_height_compare.output(); m_width_compare.output(); @@ -1403,18 +1404,24 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING m_extruded_last_z = m_end_position[Z]; } + + if (m_extrusion_role == erExternalPerimeter) + // cross section: rectangle + m_width = round_to_nearest(delta_pos[E] * static_cast(M_PI * sqr(1.05 * filament_radius)) / (d_xyz * m_height), 3); + else if (m_extrusion_role == erBridgeInfill || m_extrusion_role == erNone) + // cross section: circle + m_width = round_to_nearest(static_cast(m_filament_diameters[m_extruder_id]) * std::sqrt(delta_pos[E] / d_xyz), 3); + else + // cross section: rectangle + 2 semicircles + m_width = round_to_nearest(delta_pos[E] * static_cast(M_PI * sqr(filament_radius)) / (d_xyz * m_height) + static_cast(1.0 - 0.25 * M_PI) * m_height, 3); + +#if ENABLE_GCODE_VIEWER_DATA_CHECKING + m_width_compare.update(m_width, m_extrusion_role); +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING } - if (type == EMoveType::Extrude && (m_width == 0.0f || m_height == 0.0f)) { - if ((m_width == 0.0f && m_height == 0.0f) || m_extrusion_role == erCustom) - type = EMoveType::Travel; - else { - if (m_width == 0.0f) - m_width = 0.5f; - if (m_height == 0.0f) - m_height = 0.5f; - } - } + if (type == EMoveType::Extrude && (m_extrusion_role == erCustom || m_width == 0.0f || m_height == 0.0f)) + type = EMoveType::Travel; // time estimate section auto move_length = [](const AxisCoords& delta_pos) { From b1561534050a23acb323f355b6153e04a7a7e2fa Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 17 Aug 2020 13:07:13 +0200 Subject: [PATCH 188/255] GCodeViewer -> Use rounded values for toolpaths height, width and volumetric rate to reduce the number of generated paths --- src/libslic3r/GCode/GCodeProcessor.cpp | 50 ++++++++++---------------- src/slic3r/GUI/GCodeViewer.cpp | 30 ++++++++++++---- 2 files changed, 43 insertions(+), 37 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index a0661191cb..ab9a1039cd 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -85,19 +85,6 @@ static float acceleration_time_from_distance(float initial_feedrate, float dista return (acceleration != 0.0f) ? (speed_from_distance(initial_feedrate, distance, acceleration) - initial_feedrate) / acceleration : 0.0f; } -float round_to_nearest(float value, unsigned int decimals) -{ - float res = 0.0f; - if (decimals == 0) - res = std::round(value); - else { - char buf[64]; - sprintf(buf, "%.*g", decimals, value); - res = std::stof(buf); - } - return res; -} - void GCodeProcessor::CachedPosition::reset() { std::fill(position.begin(), position.end(), FLT_MAX); @@ -1392,13 +1379,13 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) float area_toolpath_cross_section = volume_extruded_filament / d_xyz; // volume extruded filament / tool displacement = area toolpath cross section - m_mm3_per_mm = round_to_nearest(area_toolpath_cross_section, 3); + m_mm3_per_mm = area_toolpath_cross_section; #if ENABLE_GCODE_VIEWER_DATA_CHECKING m_mm3_per_mm_compare.update(area_toolpath_cross_section, m_extrusion_role); #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING if (m_end_position[Z] > m_extruded_last_z + EPSILON) { - m_height = round_to_nearest(m_end_position[Z] - m_extruded_last_z, 4); + m_height = m_end_position[Z] - m_extruded_last_z; #if ENABLE_GCODE_VIEWER_DATA_CHECKING m_height_compare.update(m_height, m_extrusion_role); #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING @@ -1407,13 +1394,13 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) if (m_extrusion_role == erExternalPerimeter) // cross section: rectangle - m_width = round_to_nearest(delta_pos[E] * static_cast(M_PI * sqr(1.05 * filament_radius)) / (d_xyz * m_height), 3); + m_width = delta_pos[E] * static_cast(M_PI * sqr(1.05 * filament_radius)) / (d_xyz * m_height); else if (m_extrusion_role == erBridgeInfill || m_extrusion_role == erNone) // cross section: circle - m_width = round_to_nearest(static_cast(m_filament_diameters[m_extruder_id]) * std::sqrt(delta_pos[E] / d_xyz), 3); + m_width = static_cast(m_filament_diameters[m_extruder_id]) * std::sqrt(delta_pos[E] / d_xyz); else // cross section: rectangle + 2 semicircles - m_width = round_to_nearest(delta_pos[E] * static_cast(M_PI * sqr(filament_radius)) / (d_xyz * m_height) + static_cast(1.0 - 0.25 * M_PI) * m_height, 3); + m_width = delta_pos[E] * static_cast(M_PI * sqr(filament_radius)) / (d_xyz * m_height) + static_cast(1.0 - 0.25 * M_PI) * m_height; #if ENABLE_GCODE_VIEWER_DATA_CHECKING m_width_compare.update(m_width, m_extrusion_role); @@ -1983,19 +1970,20 @@ void GCodeProcessor::process_T(const std::string& command) void GCodeProcessor::store_move_vertex(EMoveType type) { - MoveVertex vertex; - vertex.type = type; - vertex.extrusion_role = m_extrusion_role; - vertex.position = Vec3f(m_end_position[X], m_end_position[Y], m_end_position[Z]) + m_extruder_offsets[m_extruder_id]; - vertex.delta_extruder = m_end_position[E] - m_start_position[E]; - vertex.feedrate = m_feedrate; - vertex.width = m_width; - vertex.height = m_height; - vertex.mm3_per_mm = m_mm3_per_mm; - vertex.fan_speed = m_fan_speed; - vertex.extruder_id = m_extruder_id; - vertex.cp_color_id = m_cp_color.current; - vertex.time = static_cast(m_result.moves.size()); + MoveVertex vertex = { + type, + m_extrusion_role, + m_extruder_id, + m_cp_color.current, + Vec3f(m_end_position[X], m_end_position[Y], m_end_position[Z]) + m_extruder_offsets[m_extruder_id], + m_end_position[E] - m_start_position[E], + m_feedrate, + m_width, + m_height, + m_mm3_per_mm, + m_fan_speed, + static_cast(m_result.moves.size()) + }; m_result.moves.emplace_back(vertex); } diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 17651fef37..4cb3ae1c52 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -38,7 +38,7 @@ static EMoveType buffer_type(unsigned char id) { return static_cast(static_cast(EMoveType::Retract) + id); } -std::array decode_color(const std::string& color) { +static std::array decode_color(const std::string& color) { static const float INV_255 = 1.0f / 255.0f; std::array ret = { 0.0f, 0.0f, 0.0f }; @@ -56,7 +56,7 @@ std::array decode_color(const std::string& color) { return ret; } -std::vector> decode_colors(const std::vector& colors) { +static std::vector> decode_colors(const std::vector& colors) { std::vector> output(colors.size(), { 0.0f, 0.0f, 0.0f }); for (size_t i = 0; i < colors.size(); ++i) { output[i] = decode_color(colors[i]); @@ -64,6 +64,19 @@ std::vector> decode_colors(const std::vector& return output; } +static float round_to_nearest(float value, unsigned int decimals) +{ + float res = 0.0f; + if (decimals == 0) + res = std::round(value); + else { + char buf[64]; + sprintf(buf, "%.*g", decimals, value); + res = std::stof(buf); + } + return res; +} + void GCodeViewer::VBuffer::reset() { // release gpu memory @@ -98,9 +111,11 @@ bool GCodeViewer::Path::matches(const GCodeProcessor::MoveVertex& move) const case EMoveType::Unretract: case EMoveType::Extrude: { - return type == move.type && role == move.extrusion_role && height == move.height && width == move.width && - feedrate == move.feedrate && fan_speed == move.fan_speed && volumetric_rate == move.volumetric_rate() && - extruder_id == move.extruder_id && cp_color_id == move.cp_color_id; + // use rounding to reduce the number of generated paths + return type == move.type && role == move.extrusion_role && height == round_to_nearest(move.height, 2) && + width == round_to_nearest(move.width, 2) && feedrate == move.feedrate && fan_speed == move.fan_speed && + volumetric_rate == round_to_nearest(move.volumetric_rate(), 2) && extruder_id == move.extruder_id && + cp_color_id == move.cp_color_id; } case EMoveType::Travel: { @@ -124,7 +139,10 @@ void GCodeViewer::TBuffer::reset() void GCodeViewer::TBuffer::add_path(const GCodeProcessor::MoveVertex& move, unsigned int i_id, unsigned int s_id) { Path::Endpoint endpoint = { i_id, s_id, move.position }; - paths.push_back({ move.type, move.extrusion_role, endpoint, endpoint, move.delta_extruder, move.height, move.width, move.feedrate, move.fan_speed, move.volumetric_rate(), move.extruder_id, move.cp_color_id }); + // use rounding to reduce the number of generated paths + paths.push_back({ move.type, move.extrusion_role, endpoint, endpoint, move.delta_extruder, + round_to_nearest(move.height, 2), round_to_nearest(move.width, 2), move.feedrate, move.fan_speed, + round_to_nearest(move.volumetric_rate(), 2), move.extruder_id, move.cp_color_id }); } GCodeViewer::Color GCodeViewer::Extrusions::Range::get_color_at(float value) const From 73603e49371f12e73a0a93b54ca88f11b1bdbbd5 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 17 Aug 2020 14:37:26 +0200 Subject: [PATCH 189/255] GCodeProcessor -> Do not export width tags to gcode --- src/libslic3r/GCode.cpp | 43 +++++++-- src/libslic3r/GCode.hpp | 10 ++- src/libslic3r/GCode/GCodeProcessor.cpp | 115 +++++++++++++++++++------ src/libslic3r/GCode/GCodeProcessor.hpp | 7 +- src/libslic3r/GCode/WipeTower.cpp | 89 ++++++++++++++++--- 5 files changed, 216 insertions(+), 48 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 24c758d502..63f215b76d 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1183,11 +1183,16 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu // resets analyzer's tracking data #if ENABLE_GCODE_VIEWER - m_last_width = 0.0f; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// m_last_width = 0.0f; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_last_height = 0.0f; m_last_layer_z = 0.0f; #if ENABLE_GCODE_VIEWER_DATA_CHECKING m_last_mm3_per_mm = 0.0; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + m_last_width = 0.0f; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING #else m_last_mm3_per_mm = GCodeAnalyzer::Default_mm3_per_mm; @@ -3255,8 +3260,12 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, if (m_enable_analyzer) { #endif // !ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER - // PrusaMultiMaterial::Writer may generate GCodeProcessor::Height_Tag and GCodeProcessor::Width_Tag lines without updating m_last_height and m_last_width - // so, if the last role was erWipeTower we force export of GCodeProcessor::Height_Tag and GCodeProcessor::Width_Tag lines +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // PrusaMultiMaterial::Writer may generate GCodeProcessor::Height_Tag lines without updating m_last_height + // so, if the last role was erWipeTower we force export of GCodeProcessor::Height_Tag lines +// // PrusaMultiMaterial::Writer may generate GCodeProcessor::Height_Tag and GCodeProcessor::Width_Tag lines without updating m_last_height and m_last_width +// // so, if the last role was erWipeTower we force export of GCodeProcessor::Height_Tag and GCodeProcessor::Width_Tag lines +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool last_was_wipe_tower = (m_last_processor_extrusion_role == erWipeTower); #else // PrusaMultiMaterial::Writer may generate GCodeAnalyzer::Height_Tag and GCodeAnalyzer::Width_Tag lines without updating m_last_height and m_last_width @@ -3278,6 +3287,14 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, sprintf(buf, ";%s%f\n", GCodeProcessor::Mm3_Per_Mm_Tag.c_str(), m_last_mm3_per_mm); gcode += buf; } + +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + if (last_was_wipe_tower || m_last_width != path.width) { + m_last_width = path.width; + sprintf(buf, ";%s%g\n", GCodeProcessor::Width_Tag.c_str(), m_last_width); + gcode += buf; + } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING #else if (path.role() != m_last_analyzer_extrusion_role) { @@ -3291,17 +3308,27 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, sprintf(buf, ";%s%f\n", GCodeAnalyzer::Mm3_Per_Mm_Tag.c_str(), m_last_mm3_per_mm); gcode += buf; } -#endif // ENABLE_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (last_was_wipe_tower || m_last_width != path.width) { m_last_width = path.width; -#if ENABLE_GCODE_VIEWER - sprintf(buf, ";%s%g\n", GCodeProcessor::Width_Tag.c_str(), m_last_width); -#else sprintf(buf, ";%s%f\n", GCodeAnalyzer::Width_Tag.c_str(), m_last_width); -#endif // ENABLE_GCODE_VIEWER gcode += buf; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_GCODE_VIEWER + +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// if (last_was_wipe_tower || m_last_width != path.width) { +// m_last_width = path.width; +//#if ENABLE_GCODE_VIEWER +// sprintf(buf, ";%s%g\n", GCodeProcessor::Width_Tag.c_str(), m_last_width); +//#else +// sprintf(buf, ";%s%f\n", GCodeAnalyzer::Width_Tag.c_str(), m_last_width); +//#endif // ENABLE_GCODE_VIEWER +// gcode += buf; +// } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 76f897c63b..3c8cf64b74 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -174,6 +174,9 @@ public: m_last_extrusion_role(erNone), #if ENABLE_GCODE_VIEWER_DATA_CHECKING m_last_mm3_per_mm(0.0), +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + m_last_width(0.0f), +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING #if !ENABLE_GCODE_VIEWER m_last_mm3_per_mm(GCodeAnalyzer::Default_mm3_per_mm), @@ -381,11 +384,16 @@ private: ExtrusionRole m_last_extrusion_role; #if ENABLE_GCODE_VIEWER // Support for G-Code Processor - float m_last_width{ 0.0f }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// float m_last_width{ 0.0f }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ float m_last_height{ 0.0f }; float m_last_layer_z{ 0.0f }; #if ENABLE_GCODE_VIEWER_DATA_CHECKING double m_last_mm3_per_mm; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + float m_last_width{ 0.0f }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING #else // Support for G-Code Analyzer diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index ab9a1039cd..39b9539c0c 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -23,7 +23,9 @@ static const float DEFAULT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 namespace Slic3r { const std::string GCodeProcessor::Extrusion_Role_Tag = "ExtrType:"; -const std::string GCodeProcessor::Width_Tag = "Width:"; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//const std::string GCodeProcessor::Width_Tag = "Width:"; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const std::string GCodeProcessor::Height_Tag = "Height:"; const std::string GCodeProcessor::Color_Change_Tag = "Color change"; const std::string GCodeProcessor::Pause_Print_Tag = "Pause print"; @@ -34,6 +36,9 @@ const std::string GCodeProcessor::Last_Line_M73_Placeholder_Tag = "; _ const std::string GCodeProcessor::Estimated_Printing_Time_Placeholder_Tag = "; _GP_ESTIMATED_PRINTING_TIME_PLACEHOLDER"; #if ENABLE_GCODE_VIEWER_DATA_CHECKING +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +const std::string GCodeProcessor::Width_Tag = "Width:"; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const std::string GCodeProcessor::Mm3_Per_Mm_Tag = "Mm3_Per_Mm:"; #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING @@ -893,35 +898,67 @@ void GCodeProcessor::process_tags(const std::string& comment) return; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_GCODE_VIEWER_DATA_CHECKING // width tag pos = comment.find(Width_Tag); if (pos != comment.npos) { try { - m_width = std::stof(comment.substr(pos + Width_Tag.length())); -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - m_width_compare.last_tag_value = m_width; -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING + m_width_compare.last_tag_value = std::stof(comment.substr(pos + Width_Tag.length())); } catch (...) { BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ")."; } return; } +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING +// // width tag +// pos = comment.find(Width_Tag); +// if (pos != comment.npos) { +// try { +// m_width = std::stof(comment.substr(pos + Width_Tag.length())); +//#if ENABLE_GCODE_VIEWER_DATA_CHECKING +// m_width_compare.last_tag_value = m_width; +//#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING +// } +// catch (...) { +// BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ")."; +// } +// return; +// } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_GCODE_VIEWER_DATA_CHECKING // height tag pos = comment.find(Height_Tag); if (pos != comment.npos) { try { - m_height = std::stof(comment.substr(pos + Height_Tag.length())); -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - m_height_compare.last_tag_value = m_height; -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING + m_height_compare.last_tag_value = std::stof(comment.substr(pos + Height_Tag.length())); } catch (...) { BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ")."; } return; } +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING + +// // height tag +// pos = comment.find(Height_Tag); +// if (pos != comment.npos) { +// try { +// m_height = std::stof(comment.substr(pos + Height_Tag.length())); +//#if ENABLE_GCODE_VIEWER_DATA_CHECKING +// m_height_compare.last_tag_value = m_height; +//#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING +// } +// catch (...) { +// BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ")."; +// } +// return; +// } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // color change tag pos = comment.find(Color_Change_Tag); @@ -1144,6 +1181,9 @@ bool GCodeProcessor::process_simplify3d_tags(const std::string& comment) // geometry // ; tool +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_GCODE_VIEWER_DATA_CHECKING +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::string tag = " tool"; pos = comment.find(tag); if (pos == 0) { @@ -1156,10 +1196,14 @@ bool GCodeProcessor::process_simplify3d_tags(const std::string& comment) size_t w_end = data.find_first_of(' ', w_start); if (h_start != data.npos) { try { - m_height = std::stof(data.substr(h_start + 1, (h_end != data.npos) ? h_end - h_start - 1 : h_end)); -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - m_height_compare.last_tag_value = m_height; -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + m_height_compare.last_tag_value = std::stof(data.substr(h_start + 1, (h_end != data.npos) ? h_end - h_start - 1 : h_end)); + +// m_height = std::stof(data.substr(h_start + 1, (h_end != data.npos) ? h_end - h_start - 1 : h_end)); +//#if ENABLE_GCODE_VIEWER_DATA_CHECKING +// m_height_compare.last_tag_value = m_height; +//#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } catch (...) { BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ")."; @@ -1167,10 +1211,14 @@ bool GCodeProcessor::process_simplify3d_tags(const std::string& comment) } if (w_start != data.npos) { try { - m_width = std::stof(data.substr(w_start + 1, (w_end != data.npos) ? w_end - w_start - 1 : w_end)); -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - m_width_compare.last_tag_value = m_width; -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + m_width_compare.last_tag_value = std::stof(data.substr(w_start + 1, (w_end != data.npos) ? w_end - w_start - 1 : w_end)); + +// m_width = std::stof(data.substr(w_start + 1, (w_end != data.npos) ? w_end - w_start - 1 : w_end)); +//#if ENABLE_GCODE_VIEWER_DATA_CHECKING +// m_width_compare.last_tag_value = m_width; +//#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } catch (...) { BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ")."; @@ -1179,6 +1227,9 @@ bool GCodeProcessor::process_simplify3d_tags(const std::string& comment) return true; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // std::cout << comment << "\n"; return false; @@ -1254,15 +1305,22 @@ bool GCodeProcessor::process_ideamaker_tags(const std::string& comment) // geometry +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_GCODE_VIEWER_DATA_CHECKING +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // width tag = "WIDTH:"; pos = comment.find(tag); if (pos != comment.npos) { try { - m_width = std::stof(comment.substr(pos + tag.length())); -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - m_width_compare.last_tag_value = m_width; -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + m_width_compare.last_tag_value = std::stof(comment.substr(pos + tag.length())); + +// m_width = std::stof(comment.substr(pos + tag.length())); +//#if ENABLE_GCODE_VIEWER_DATA_CHECKING +// m_width_compare.last_tag_value = m_width; +//#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } catch (...) { BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ")."; @@ -1275,16 +1333,23 @@ bool GCodeProcessor::process_ideamaker_tags(const std::string& comment) pos = comment.find(tag); if (pos != comment.npos) { try { - m_height = std::stof(comment.substr(pos + tag.length())); -#if ENABLE_GCODE_VIEWER_DATA_CHECKING - m_height_compare.last_tag_value = m_height; -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + m_height_compare.last_tag_value = std::stof(comment.substr(pos + tag.length())); + +// m_height = std::stof(comment.substr(pos + tag.length())); +//#if ENABLE_GCODE_VIEWER_DATA_CHECKING +// m_height_compare.last_tag_value = m_height; +//#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } catch (...) { BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ")."; } return true; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ return false; } diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 166e1b8cca..52ae76f7ee 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -67,7 +67,9 @@ namespace Slic3r { { public: static const std::string Extrusion_Role_Tag; - static const std::string Width_Tag; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// static const std::string Width_Tag; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ static const std::string Height_Tag; static const std::string Color_Change_Tag; static const std::string Pause_Print_Tag; @@ -77,6 +79,9 @@ namespace Slic3r { static const std::string Estimated_Printing_Time_Placeholder_Tag; #if ENABLE_GCODE_VIEWER_DATA_CHECKING +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + static const std::string Width_Tag; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ static const std::string Mm3_Per_Mm_Tag; #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index e6e60b6186..3eaf31e1cd 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -51,7 +51,13 @@ public: m_extrusion_flow(0.f), m_preview_suppressed(false), m_elapsed_time(0.f), +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_GCODE_VIEWER_DATA_CHECKING +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_default_analyzer_line_width(line_width), +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_GCODE_VIEWER_DATA_CHECKING +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_gcode_flavor(flavor), m_filpar(filament_parameters) { @@ -69,20 +75,48 @@ public: sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), erWipeTower); #endif // ENABLE_GCODE_VIEWER m_gcode += buf; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_GCODE_VIEWER_DATA_CHECKING +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ change_analyzer_line_width(line_width); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } - WipeTowerWriter& change_analyzer_line_width(float line_width) { - // adds tag for analyzer: - char buf[64]; -#if ENABLE_GCODE_VIEWER - sprintf(buf, ";%s%f\n", GCodeProcessor::Width_Tag.c_str(), line_width); -#else - sprintf(buf, ";%s%f\n", GCodeAnalyzer::Width_Tag.c_str(), line_width); -#endif // ENABLE_GCODE_VIEWER - m_gcode += buf; - return *this; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_GCODE_VIEWER_DATA_CHECKING + WipeTowerWriter& change_analyzer_line_width(float line_width) { + // adds tag for analyzer: + char buf[64]; + sprintf(buf, ";%s%f\n", GCodeProcessor::Width_Tag.c_str(), line_width); + m_gcode += buf; + return *this; } +#else +#if !ENABLE_GCODE_VIEWER + WipeTowerWriter& change_analyzer_line_width(float line_width) { + // adds tag for analyzer: + char buf[64]; + sprintf(buf, ";%s%f\n", GCodeAnalyzer::Width_Tag.c_str(), line_width); + m_gcode += buf; + return *this; +} +#endif // !ENABLE_GCODE_VIEWER +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING + +// WipeTowerWriter& change_analyzer_line_width(float line_width) { +// // adds tag for analyzer: +// char buf[64]; +//#if ENABLE_GCODE_VIEWER +// sprintf(buf, ";%s%f\n", GCodeProcessor::Width_Tag.c_str(), line_width); +//#else +// sprintf(buf, ";%s%f\n", GCodeAnalyzer::Width_Tag.c_str(), line_width); +//#endif // ENABLE_GCODE_VIEWER +// m_gcode += buf; +// return *this; +// } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_DATA_CHECKING WipeTowerWriter& change_analyzer_mm3_per_mm(float len, float e) { @@ -141,8 +175,17 @@ public: // Suppress / resume G-code preview in Slic3r. Slic3r will have difficulty to differentiate the various // filament loading and cooling moves from normal extrusion moves. Therefore the writer // is asked to suppres output of some lines, which look like extrusions. - WipeTowerWriter& suppress_preview() { change_analyzer_line_width(0.f); m_preview_suppressed = true; return *this; } - WipeTowerWriter& resume_preview() { change_analyzer_line_width(m_default_analyzer_line_width); m_preview_suppressed = false; return *this; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_GCODE_VIEWER_DATA_CHECKING + WipeTowerWriter& suppress_preview() { change_analyzer_line_width(0.f); m_preview_suppressed = true; return *this; } + WipeTowerWriter& resume_preview() { change_analyzer_line_width(m_default_analyzer_line_width); m_preview_suppressed = false; return *this; } +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + WipeTowerWriter& suppress_preview() { m_preview_suppressed = true; return *this; } + WipeTowerWriter& resume_preview() { m_preview_suppressed = false; return *this; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ WipeTowerWriter& feedrate(float f) { @@ -447,7 +490,13 @@ private: float m_wipe_tower_depth = 0.f; unsigned m_last_fan_speed = 0; int current_temp = -1; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_GCODE_VIEWER_DATA_CHECKING +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const float m_default_analyzer_line_width; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_GCODE_VIEWER_DATA_CHECKING +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ float m_used_filament_length = 0.f; GCodeFlavor m_gcode_flavor; const std::vector& m_filpar; @@ -888,8 +937,16 @@ void WipeTower::toolchange_Unload( const float line_width = m_perimeter_width * m_filpar[m_current_tool].ramming_line_width_multiplicator; // desired ramming line thickness const float y_step = line_width * m_filpar[m_current_tool].ramming_step_multiplicator * m_extra_spacing; // spacing between lines in mm +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_GCODE_VIEWER_DATA_CHECKING writer.append("; CP TOOLCHANGE UNLOAD\n") - .change_analyzer_line_width(line_width); + .change_analyzer_line_width(line_width); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + writer.append("; CP TOOLCHANGE UNLOAD\n"); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ unsigned i = 0; // iterates through ramming_speed m_left_to_right = true; // current direction of ramming @@ -966,7 +1023,13 @@ void WipeTower::toolchange_Unload( } } Vec2f end_of_ramming(writer.x(),writer.y()); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_GCODE_VIEWER_DATA_CHECKING +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ writer.change_analyzer_line_width(m_perimeter_width); // so the next lines are not affected by ramming_line_width_multiplier +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Retraction: float old_x = writer.x(); From c81d87b470f5550938202a222d79c01f1aba500b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 17 Aug 2020 15:59:36 +0200 Subject: [PATCH 190/255] Code cleanup --- src/libslic3r/GCode.cpp | 50 +++----------- src/libslic3r/GCode.hpp | 7 -- src/libslic3r/GCode/GCodeProcessor.cpp | 96 +++----------------------- src/libslic3r/GCode/GCodeProcessor.hpp | 5 -- src/libslic3r/GCode/WipeTower.cpp | 67 ++++-------------- src/slic3r/GUI/GCodeViewer.cpp | 6 +- 6 files changed, 34 insertions(+), 197 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 63f215b76d..3de70d0611 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1183,16 +1183,11 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu // resets analyzer's tracking data #if ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// m_last_width = 0.0f; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_last_height = 0.0f; m_last_layer_z = 0.0f; #if ENABLE_GCODE_VIEWER_DATA_CHECKING m_last_mm3_per_mm = 0.0; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_last_width = 0.0f; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING #else m_last_mm3_per_mm = GCodeAnalyzer::Default_mm3_per_mm; @@ -3256,18 +3251,12 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } // adds processor tags and updates processor tracking data -#if !ENABLE_GCODE_VIEWER - if (m_enable_analyzer) { -#endif // !ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - // PrusaMultiMaterial::Writer may generate GCodeProcessor::Height_Tag lines without updating m_last_height - // so, if the last role was erWipeTower we force export of GCodeProcessor::Height_Tag lines -// // PrusaMultiMaterial::Writer may generate GCodeProcessor::Height_Tag and GCodeProcessor::Width_Tag lines without updating m_last_height and m_last_width -// // so, if the last role was erWipeTower we force export of GCodeProcessor::Height_Tag and GCodeProcessor::Width_Tag lines -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - bool last_was_wipe_tower = (m_last_processor_extrusion_role == erWipeTower); + // PrusaMultiMaterial::Writer may generate GCodeProcessor::Height_Tag lines without updating m_last_height + // so, if the last role was erWipeTower we force export of GCodeProcessor::Height_Tag lines + bool last_was_wipe_tower = (m_last_processor_extrusion_role == erWipeTower); #else + if (m_enable_analyzer) { // PrusaMultiMaterial::Writer may generate GCodeAnalyzer::Height_Tag and GCodeAnalyzer::Width_Tag lines without updating m_last_height and m_last_width // so, if the last role was erWipeTower we force export of GCodeAnalyzer::Height_Tag and GCodeAnalyzer::Width_Tag lines bool last_was_wipe_tower = (m_last_analyzer_extrusion_role == erWipeTower); @@ -3288,14 +3277,18 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, gcode += buf; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (last_was_wipe_tower || m_last_width != path.width) { m_last_width = path.width; sprintf(buf, ";%s%g\n", GCodeProcessor::Width_Tag.c_str(), m_last_width); gcode += buf; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING + + if (last_was_wipe_tower || std::abs(m_last_height - path.height) > EPSILON) { + m_last_height = path.height; + sprintf(buf, ";%s%g\n", GCodeProcessor::Height_Tag.c_str(), m_last_height); + gcode += buf; + } #else if (path.role() != m_last_analyzer_extrusion_role) { m_last_analyzer_extrusion_role = path.role(); @@ -3309,35 +3302,12 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, gcode += buf; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (last_was_wipe_tower || m_last_width != path.width) { m_last_width = path.width; sprintf(buf, ";%s%f\n", GCodeAnalyzer::Width_Tag.c_str(), m_last_width); gcode += buf; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#endif // ENABLE_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// if (last_was_wipe_tower || m_last_width != path.width) { -// m_last_width = path.width; -//#if ENABLE_GCODE_VIEWER -// sprintf(buf, ";%s%g\n", GCodeProcessor::Width_Tag.c_str(), m_last_width); -//#else -// sprintf(buf, ";%s%f\n", GCodeAnalyzer::Width_Tag.c_str(), m_last_width); -//#endif // ENABLE_GCODE_VIEWER -// gcode += buf; -// } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - - -#if ENABLE_GCODE_VIEWER - if (last_was_wipe_tower || std::abs(m_last_height - path.height) > EPSILON) { - m_last_height = path.height; - sprintf(buf, ";%s%g\n", GCodeProcessor::Height_Tag.c_str(), m_last_height); - gcode += buf; - } -#else if (last_was_wipe_tower || m_last_height != path.height) { m_last_height = path.height; sprintf(buf, ";%s%f\n", GCodeAnalyzer::Height_Tag.c_str(), m_last_height); diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 3c8cf64b74..8bae2ef43d 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -174,9 +174,7 @@ public: m_last_extrusion_role(erNone), #if ENABLE_GCODE_VIEWER_DATA_CHECKING m_last_mm3_per_mm(0.0), -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_last_width(0.0f), -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING #if !ENABLE_GCODE_VIEWER m_last_mm3_per_mm(GCodeAnalyzer::Default_mm3_per_mm), @@ -384,16 +382,11 @@ private: ExtrusionRole m_last_extrusion_role; #if ENABLE_GCODE_VIEWER // Support for G-Code Processor -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// float m_last_width{ 0.0f }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ float m_last_height{ 0.0f }; float m_last_layer_z{ 0.0f }; #if ENABLE_GCODE_VIEWER_DATA_CHECKING double m_last_mm3_per_mm; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ float m_last_width{ 0.0f }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING #else // Support for G-Code Analyzer diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 39b9539c0c..6684255918 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -22,24 +22,19 @@ static const float DEFAULT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 namespace Slic3r { -const std::string GCodeProcessor::Extrusion_Role_Tag = "ExtrType:"; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -//const std::string GCodeProcessor::Width_Tag = "Width:"; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -const std::string GCodeProcessor::Height_Tag = "Height:"; -const std::string GCodeProcessor::Color_Change_Tag = "Color change"; -const std::string GCodeProcessor::Pause_Print_Tag = "Pause print"; -const std::string GCodeProcessor::Custom_Code_Tag = "Custom gcode"; +const std::string GCodeProcessor::Extrusion_Role_Tag = "TYPE:"; +const std::string GCodeProcessor::Height_Tag = "HEIGHT:"; +const std::string GCodeProcessor::Color_Change_Tag = "COLOR CHANGE"; +const std::string GCodeProcessor::Pause_Print_Tag = "PAUSE PRINT"; +const std::string GCodeProcessor::Custom_Code_Tag = "CUSTOM GCODE"; const std::string GCodeProcessor::First_Line_M73_Placeholder_Tag = "; _GP_FIRST_LINE_M73_PLACEHOLDER"; const std::string GCodeProcessor::Last_Line_M73_Placeholder_Tag = "; _GP_LAST_LINE_M73_PLACEHOLDER"; const std::string GCodeProcessor::Estimated_Printing_Time_Placeholder_Tag = "; _GP_ESTIMATED_PRINTING_TIME_PLACEHOLDER"; #if ENABLE_GCODE_VIEWER_DATA_CHECKING -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -const std::string GCodeProcessor::Width_Tag = "Width:"; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -const std::string GCodeProcessor::Mm3_Per_Mm_Tag = "Mm3_Per_Mm:"; +const std::string GCodeProcessor::Width_Tag = "WIDTH:"; +const std::string GCodeProcessor::Mm3_Per_Mm_Tag = "MM3_PER_MM:"; #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING static bool is_valid_extrusion_role(int value) @@ -898,7 +893,6 @@ void GCodeProcessor::process_tags(const std::string& comment) return; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_DATA_CHECKING // width tag pos = comment.find(Width_Tag); @@ -911,26 +905,7 @@ void GCodeProcessor::process_tags(const std::string& comment) } return; } -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING -// // width tag -// pos = comment.find(Width_Tag); -// if (pos != comment.npos) { -// try { -// m_width = std::stof(comment.substr(pos + Width_Tag.length())); -//#if ENABLE_GCODE_VIEWER_DATA_CHECKING -// m_width_compare.last_tag_value = m_width; -//#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING -// } -// catch (...) { -// BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ")."; -// } -// return; -// } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if ENABLE_GCODE_VIEWER_DATA_CHECKING // height tag pos = comment.find(Height_Tag); if (pos != comment.npos) { @@ -944,22 +919,6 @@ void GCodeProcessor::process_tags(const std::string& comment) } #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING -// // height tag -// pos = comment.find(Height_Tag); -// if (pos != comment.npos) { -// try { -// m_height = std::stof(comment.substr(pos + Height_Tag.length())); -//#if ENABLE_GCODE_VIEWER_DATA_CHECKING -// m_height_compare.last_tag_value = m_height; -//#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING -// } -// catch (...) { -// BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ")."; -// } -// return; -// } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - // color change tag pos = comment.find(Color_Change_Tag); if (pos != comment.npos) { @@ -1178,12 +1137,10 @@ bool GCodeProcessor::process_simplify3d_tags(const std::string& comment) return true; } +#if ENABLE_GCODE_VIEWER_DATA_CHECKING // geometry // ; tool -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if ENABLE_GCODE_VIEWER_DATA_CHECKING -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::string tag = " tool"; pos = comment.find(tag); if (pos == 0) { @@ -1196,14 +1153,7 @@ bool GCodeProcessor::process_simplify3d_tags(const std::string& comment) size_t w_end = data.find_first_of(' ', w_start); if (h_start != data.npos) { try { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_height_compare.last_tag_value = std::stof(data.substr(h_start + 1, (h_end != data.npos) ? h_end - h_start - 1 : h_end)); - -// m_height = std::stof(data.substr(h_start + 1, (h_end != data.npos) ? h_end - h_start - 1 : h_end)); -//#if ENABLE_GCODE_VIEWER_DATA_CHECKING -// m_height_compare.last_tag_value = m_height; -//#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } catch (...) { BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ")."; @@ -1211,14 +1161,7 @@ bool GCodeProcessor::process_simplify3d_tags(const std::string& comment) } if (w_start != data.npos) { try { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_width_compare.last_tag_value = std::stof(data.substr(w_start + 1, (w_end != data.npos) ? w_end - w_start - 1 : w_end)); - -// m_width = std::stof(data.substr(w_start + 1, (w_end != data.npos) ? w_end - w_start - 1 : w_end)); -//#if ENABLE_GCODE_VIEWER_DATA_CHECKING -// m_width_compare.last_tag_value = m_width; -//#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } catch (...) { BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ")."; @@ -1227,11 +1170,8 @@ bool GCodeProcessor::process_simplify3d_tags(const std::string& comment) return true; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// std::cout << comment << "\n"; return false; } @@ -1303,24 +1243,15 @@ bool GCodeProcessor::process_ideamaker_tags(const std::string& comment) return true; } +#if ENABLE_GCODE_VIEWER_DATA_CHECKING // geometry -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if ENABLE_GCODE_VIEWER_DATA_CHECKING -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // width tag = "WIDTH:"; pos = comment.find(tag); if (pos != comment.npos) { try { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_width_compare.last_tag_value = std::stof(comment.substr(pos + tag.length())); - -// m_width = std::stof(comment.substr(pos + tag.length())); -//#if ENABLE_GCODE_VIEWER_DATA_CHECKING -// m_width_compare.last_tag_value = m_width; -//#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } catch (...) { BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ")."; @@ -1333,23 +1264,14 @@ bool GCodeProcessor::process_ideamaker_tags(const std::string& comment) pos = comment.find(tag); if (pos != comment.npos) { try { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_height_compare.last_tag_value = std::stof(comment.substr(pos + tag.length())); - -// m_height = std::stof(comment.substr(pos + tag.length())); -//#if ENABLE_GCODE_VIEWER_DATA_CHECKING -// m_height_compare.last_tag_value = m_height; -//#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } catch (...) { BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ")."; } return true; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ return false; } diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 52ae76f7ee..b19610801c 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -67,9 +67,6 @@ namespace Slic3r { { public: static const std::string Extrusion_Role_Tag; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// static const std::string Width_Tag; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ static const std::string Height_Tag; static const std::string Color_Change_Tag; static const std::string Pause_Print_Tag; @@ -79,9 +76,7 @@ namespace Slic3r { static const std::string Estimated_Printing_Time_Placeholder_Tag; #if ENABLE_GCODE_VIEWER_DATA_CHECKING -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ static const std::string Width_Tag; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ static const std::string Mm3_Per_Mm_Tag; #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index 3eaf31e1cd..1e8323230b 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -51,13 +51,9 @@ public: m_extrusion_flow(0.f), m_preview_suppressed(false), m_elapsed_time(0.f), -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_GCODE_VIEWER_DATA_CHECKING -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_default_analyzer_line_width(line_width), -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_GCODE_VIEWER_DATA_CHECKING -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_gcode_flavor(flavor), m_filpar(filament_parameters) { @@ -65,26 +61,20 @@ public: char buf[64]; #if ENABLE_GCODE_VIEWER sprintf(buf, ";%s%f\n", GCodeProcessor::Height_Tag.c_str(), m_layer_height); // don't rely on GCodeAnalyzer knowing the layer height - it knows nothing at priming + m_gcode += buf; + sprintf(buf, ";%s%s\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), ExtrusionEntity::role_to_string(erWipeTower).c_str()); + m_gcode += buf; #else sprintf(buf, ";%s%f\n", GCodeAnalyzer::Height_Tag.c_str(), m_layer_height); // don't rely on GCodeAnalyzer knowing the layer height - it knows nothing at priming -#endif // ENABLE_GCODE_VIEWER m_gcode += buf; -#if ENABLE_GCODE_VIEWER - sprintf(buf, ";%s%s\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), ExtrusionEntity::role_to_string(erWipeTower).c_str()); -#else sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), erWipeTower); -#endif // ENABLE_GCODE_VIEWER m_gcode += buf; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER_DATA_CHECKING -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ change_analyzer_line_width(line_width); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_DATA_CHECKING WipeTowerWriter& change_analyzer_line_width(float line_width) { // adds tag for analyzer: @@ -93,32 +83,7 @@ public: m_gcode += buf; return *this; } -#else -#if !ENABLE_GCODE_VIEWER - WipeTowerWriter& change_analyzer_line_width(float line_width) { - // adds tag for analyzer: - char buf[64]; - sprintf(buf, ";%s%f\n", GCodeAnalyzer::Width_Tag.c_str(), line_width); - m_gcode += buf; - return *this; -} -#endif // !ENABLE_GCODE_VIEWER -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING -// WipeTowerWriter& change_analyzer_line_width(float line_width) { -// // adds tag for analyzer: -// char buf[64]; -//#if ENABLE_GCODE_VIEWER -// sprintf(buf, ";%s%f\n", GCodeProcessor::Width_Tag.c_str(), line_width); -//#else -// sprintf(buf, ";%s%f\n", GCodeAnalyzer::Width_Tag.c_str(), line_width); -//#endif // ENABLE_GCODE_VIEWER -// m_gcode += buf; -// return *this; -// } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -#if ENABLE_GCODE_VIEWER_DATA_CHECKING WipeTowerWriter& change_analyzer_mm3_per_mm(float len, float e) { static const float area = float(M_PI) * 1.75f * 1.75f / 4.f; float mm3_per_mm = (len == 0.f ? 0.f : area * e / len); @@ -130,6 +95,14 @@ public: } #else #if !ENABLE_GCODE_VIEWER + WipeTowerWriter& change_analyzer_line_width(float line_width) { + // adds tag for analyzer: + char buf[64]; + sprintf(buf, ";%s%f\n", GCodeAnalyzer::Width_Tag.c_str(), line_width); + m_gcode += buf; + return *this; + } + WipeTowerWriter& change_analyzer_mm3_per_mm(float len, float e) { static const float area = float(M_PI) * 1.75f * 1.75f / 4.f; float mm3_per_mm = (len == 0.f ? 0.f : area * e / len); @@ -175,17 +148,13 @@ public: // Suppress / resume G-code preview in Slic3r. Slic3r will have difficulty to differentiate the various // filament loading and cooling moves from normal extrusion moves. Therefore the writer // is asked to suppres output of some lines, which look like extrusions. -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_DATA_CHECKING WipeTowerWriter& suppress_preview() { change_analyzer_line_width(0.f); m_preview_suppressed = true; return *this; } WipeTowerWriter& resume_preview() { change_analyzer_line_width(m_default_analyzer_line_width); m_preview_suppressed = false; return *this; } #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ WipeTowerWriter& suppress_preview() { m_preview_suppressed = true; return *this; } WipeTowerWriter& resume_preview() { m_preview_suppressed = false; return *this; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ WipeTowerWriter& feedrate(float f) { @@ -490,13 +459,9 @@ private: float m_wipe_tower_depth = 0.f; unsigned m_last_fan_speed = 0; int current_temp = -1; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if !ENABLE_GCODE_VIEWER_DATA_CHECKING -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const float m_default_analyzer_line_width; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // !ENABLE_GCODE_VIEWER_DATA_CHECKING -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ float m_used_filament_length = 0.f; GCodeFlavor m_gcode_flavor; const std::vector& m_filpar; @@ -937,16 +902,12 @@ void WipeTower::toolchange_Unload( const float line_width = m_perimeter_width * m_filpar[m_current_tool].ramming_line_width_multiplicator; // desired ramming line thickness const float y_step = line_width * m_filpar[m_current_tool].ramming_step_multiplicator * m_extra_spacing; // spacing between lines in mm -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_DATA_CHECKING writer.append("; CP TOOLCHANGE UNLOAD\n") .change_analyzer_line_width(line_width); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ writer.append("; CP TOOLCHANGE UNLOAD\n"); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ unsigned i = 0; // iterates through ramming_speed m_left_to_right = true; // current direction of ramming @@ -1023,13 +984,9 @@ void WipeTower::toolchange_Unload( } } Vec2f end_of_ramming(writer.x(),writer.y()); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_GCODE_VIEWER_DATA_CHECKING -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ writer.change_analyzer_line_width(m_perimeter_width); // so the next lines are not affected by ramming_line_width_multiplier -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Retraction: float old_x = writer.x(); diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 4cb3ae1c52..1a4485402b 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -385,10 +385,10 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: { case EMoveType::Extrude: { - m_extrusions.ranges.height.update_from(curr.height); - m_extrusions.ranges.width.update_from(curr.width); + m_extrusions.ranges.height.update_from(round_to_nearest(curr.height, 2)); + m_extrusions.ranges.width.update_from(round_to_nearest(curr.width, 2)); m_extrusions.ranges.fan_speed.update_from(curr.fan_speed); - m_extrusions.ranges.volumetric_rate.update_from(curr.volumetric_rate()); + m_extrusions.ranges.volumetric_rate.update_from(round_to_nearest(curr.volumetric_rate(), 2)); [[fallthrough]]; } case EMoveType::Travel: From ca27d7296f5b892417508bdbedbbb789f4db8bbc Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 18 Aug 2020 08:27:07 +0200 Subject: [PATCH 191/255] Fixed build when ENABLE_GCODE_VIEWER is disabled --- src/libslic3r/GCode/WipeTower.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index 1e8323230b..0752b6dfcb 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -51,9 +51,9 @@ public: m_extrusion_flow(0.f), m_preview_suppressed(false), m_elapsed_time(0.f), -#if !ENABLE_GCODE_VIEWER_DATA_CHECKING +#if !ENABLE_GCODE_VIEWER || ENABLE_GCODE_VIEWER_DATA_CHECKING m_default_analyzer_line_width(line_width), -#endif // !ENABLE_GCODE_VIEWER_DATA_CHECKING +#endif // !ENABLE_GCODE_VIEWER || ENABLE_GCODE_VIEWER_DATA_CHECKING m_gcode_flavor(flavor), m_filpar(filament_parameters) { @@ -148,13 +148,13 @@ public: // Suppress / resume G-code preview in Slic3r. Slic3r will have difficulty to differentiate the various // filament loading and cooling moves from normal extrusion moves. Therefore the writer // is asked to suppres output of some lines, which look like extrusions. -#if ENABLE_GCODE_VIEWER_DATA_CHECKING +#if !ENABLE_GCODE_VIEWER || ENABLE_GCODE_VIEWER_DATA_CHECKING WipeTowerWriter& suppress_preview() { change_analyzer_line_width(0.f); m_preview_suppressed = true; return *this; } WipeTowerWriter& resume_preview() { change_analyzer_line_width(m_default_analyzer_line_width); m_preview_suppressed = false; return *this; } #else WipeTowerWriter& suppress_preview() { m_preview_suppressed = true; return *this; } WipeTowerWriter& resume_preview() { m_preview_suppressed = false; return *this; } -#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING +#endif // !ENABLE_GCODE_VIEWER || ENABLE_GCODE_VIEWER_DATA_CHECKING WipeTowerWriter& feedrate(float f) { @@ -459,9 +459,9 @@ private: float m_wipe_tower_depth = 0.f; unsigned m_last_fan_speed = 0; int current_temp = -1; -#if !ENABLE_GCODE_VIEWER_DATA_CHECKING +#if !ENABLE_GCODE_VIEWER || ENABLE_GCODE_VIEWER_DATA_CHECKING const float m_default_analyzer_line_width; -#endif // !ENABLE_GCODE_VIEWER_DATA_CHECKING +#endif // !ENABLE_GCODE_VIEWER || ENABLE_GCODE_VIEWER_DATA_CHECKING float m_used_filament_length = 0.f; GCodeFlavor m_gcode_flavor; const std::vector& m_filpar; From 7fd2209b48a6dfeb6c4b884200c617279e6de79a Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 5 Aug 2020 13:30:05 +0200 Subject: [PATCH 192/255] Gizmos can be shown depending on current mode --- src/slic3r/GUI/GUI_App.cpp | 2 ++ src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp | 3 ++- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 12 ++++++++---- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 82c2861bc2..8f33a6e996 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -41,6 +41,7 @@ #include "3DScene.hpp" #include "MainFrame.hpp" #include "Plater.hpp" +#include "GLCanvas3D.hpp" #include "../Utils/PresetUpdater.hpp" #include "../Utils/PrintHost.hpp" @@ -1012,6 +1013,7 @@ void GUI_App::update_mode() tab->update_mode(); plater()->update_object_menu(); + plater()->canvas3D()->update_gizmos_on_off_state(); } void GUI_App::add_config_menu(wxMenuBar *menu) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index 309c7cf423..58b46f0b6a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -631,7 +631,8 @@ bool GLGizmoFdmSupports::on_is_activable() const bool GLGizmoFdmSupports::on_is_selectable() const { - return (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptFFF ); + return (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptFFF + && wxGetApp().get_mode() != comSimple ); } std::string GLGizmoFdmSupports::on_get_name() const diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index c33ba2850e..78998b92d9 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -144,8 +144,11 @@ void GLGizmosManager::refresh_on_off_state() if (m_serializing || m_current == Undefined || m_gizmos.empty()) return; - if (m_current != Undefined && ! m_gizmos[m_current]->is_activable()) + if (m_current != Undefined + && (! m_gizmos[m_current]->is_activable() || ! m_gizmos[m_current]->is_selectable())) { activate_gizmo(Undefined); + update_data(); + } } void GLGizmosManager::reset_all_states() @@ -204,9 +207,10 @@ void GLGizmosManager::update_data() enable_grabber(Scale, i, enable_scale_xyz); } - m_common_gizmos_data->update(get_current() - ? get_current()->get_requirements() - : CommonGizmosDataID(0)); + if (m_common_gizmos_data) + m_common_gizmos_data->update(get_current() + ? get_current()->get_requirements() + : CommonGizmosDataID(0)); if (selection.is_single_full_instance()) { From 97bc092cce53b893aa796779f2735b87a266e888 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 5 Aug 2020 14:03:22 +0200 Subject: [PATCH 193/255] Renamed FacetSupportType to EnforcerBlockerType So it's not misleading if we use it for seam painting --- src/libslic3r/Model.cpp | 2 +- src/libslic3r/Model.hpp | 4 ++-- src/libslic3r/Print.hpp | 6 ++--- src/libslic3r/PrintObject.cpp | 2 +- src/libslic3r/TriangleSelector.cpp | 24 ++++++++++---------- src/libslic3r/TriangleSelector.hpp | 20 ++++++++-------- src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp | 20 ++++++++-------- src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp | 2 +- 8 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 3beb74f235..196e9c213b 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -1831,7 +1831,7 @@ arrangement::ArrangePolygon ModelInstance::get_arrange_polygon() const } -indexed_triangle_set FacetsAnnotation::get_facets(const ModelVolume& mv, FacetSupportType type) const +indexed_triangle_set FacetsAnnotation::get_facets(const ModelVolume& mv, EnforcerBlockerType type) const { TriangleSelector selector(mv.mesh()); selector.deserialize(m_data); diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 92dc84d17a..608ce670f6 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -394,7 +394,7 @@ enum class ModelVolumeType : int { SUPPORT_BLOCKER, }; -enum class FacetSupportType : int8_t { +enum class EnforcerBlockerType : int8_t { // Maximum is 3. The value is serialized in TriangleSelector into 2 bits! NONE = 0, ENFORCER = 1, @@ -407,7 +407,7 @@ public: const std::map>& get_data() const { return m_data; } bool set(const TriangleSelector& selector); - indexed_triangle_set get_facets(const ModelVolume& mv, FacetSupportType type) const; + indexed_triangle_set get_facets(const ModelVolume& mv, EnforcerBlockerType type) const; void clear(); std::string get_triangle_as_string(int i) const; void set_triangle_from_string(int triangle_id, const std::string& str); diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 05929dd2ef..08acb7a105 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -187,9 +187,9 @@ public: std::vector slice_support_enforcers() const { return this->slice_support_volumes(ModelVolumeType::SUPPORT_ENFORCER); } // Helpers to project custom supports on slices - void project_and_append_custom_supports(FacetSupportType type, std::vector& expolys) const; - void project_and_append_custom_enforcers(std::vector& enforcers) const { project_and_append_custom_supports(FacetSupportType::ENFORCER, enforcers); } - void project_and_append_custom_blockers(std::vector& blockers) const { project_and_append_custom_supports(FacetSupportType::BLOCKER, blockers); } + void project_and_append_custom_supports(EnforcerBlockerType type, std::vector& expolys) const; + void project_and_append_custom_enforcers(std::vector& enforcers) const { project_and_append_custom_supports(EnforcerBlockerType::ENFORCER, enforcers); } + void project_and_append_custom_blockers(std::vector& blockers) const { project_and_append_custom_supports(EnforcerBlockerType::BLOCKER, blockers); } private: // to be called from Print only. diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index c90a05ef31..ddeee1e778 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -2670,7 +2670,7 @@ void PrintObject::_generate_support_material() void PrintObject::project_and_append_custom_supports( - FacetSupportType type, std::vector& expolys) const + EnforcerBlockerType type, std::vector& expolys) const { for (const ModelVolume* mv : this->model_object()->volumes) { const indexed_triangle_set custom_facets = mv->m_supported_facets.get_facets(*mv, type); diff --git a/src/libslic3r/TriangleSelector.cpp b/src/libslic3r/TriangleSelector.cpp index 9555c42a69..9f04374fdc 100644 --- a/src/libslic3r/TriangleSelector.cpp +++ b/src/libslic3r/TriangleSelector.cpp @@ -35,7 +35,7 @@ void TriangleSelector::Triangle::set_division(int sides_to_split, int special_si void TriangleSelector::select_patch(const Vec3f& hit, int facet_start, const Vec3f& source, const Vec3f& dir, - float radius, FacetSupportType new_state) + float radius, EnforcerBlockerType new_state) { assert(facet_start < m_orig_size_indices); assert(is_approx(dir.norm(), 1.f)); @@ -77,7 +77,7 @@ void TriangleSelector::select_patch(const Vec3f& hit, int facet_start, // the triangle recursively, selecting just subtriangles truly inside the circle. // This is done by an actual recursive call. Returns false if the triangle is // outside the cursor. -bool TriangleSelector::select_triangle(int facet_idx, FacetSupportType type, bool recursive_call) +bool TriangleSelector::select_triangle(int facet_idx, EnforcerBlockerType type, bool recursive_call) { assert(facet_idx < int(m_triangles.size())); @@ -140,7 +140,7 @@ bool TriangleSelector::select_triangle(int facet_idx, FacetSupportType type, boo -void TriangleSelector::set_facet(int facet_idx, FacetSupportType state) +void TriangleSelector::set_facet(int facet_idx, EnforcerBlockerType state) { assert(facet_idx < m_orig_size_indices); undivide_triangle(facet_idx); @@ -157,7 +157,7 @@ void TriangleSelector::split_triangle(int facet_idx) Triangle* tr = &m_triangles[facet_idx]; - FacetSupportType old_type = tr->get_state(); + EnforcerBlockerType old_type = tr->get_state(); if (tr->was_split_before() != 0) { // This triangle is not split at the moment, but was at one point @@ -323,7 +323,7 @@ void TriangleSelector::remove_useless_children(int facet_idx) // Return if a child is not leaf or two children differ in type. - FacetSupportType first_child_type = FacetSupportType::NONE; + EnforcerBlockerType first_child_type = EnforcerBlockerType::NONE; for (int child_idx=0; child_idx<=tr.number_of_split_sides(); ++child_idx) { if (m_triangles[tr.children[child_idx]].is_split()) return; @@ -456,7 +456,7 @@ void TriangleSelector::push_triangle(int a, int b, int c) } -void TriangleSelector::perform_split(int facet_idx, FacetSupportType old_state) +void TriangleSelector::perform_split(int facet_idx, EnforcerBlockerType old_state) { Triangle* tr = &m_triangles[facet_idx]; @@ -520,7 +520,7 @@ void TriangleSelector::perform_split(int facet_idx, FacetSupportType old_state) -indexed_triangle_set TriangleSelector::get_facets(FacetSupportType state) const +indexed_triangle_set TriangleSelector::get_facets(EnforcerBlockerType state) const { indexed_triangle_set out; for (const Triangle& tr : m_triangles) { @@ -542,7 +542,7 @@ std::map> TriangleSelector::serialize() const { // Each original triangle of the mesh is assigned a number encoding its state // or how it is split. Each triangle is encoded by 4 bits (xxyy): - // leaf triangle: xx = FacetSupportType, yy = 0 + // leaf triangle: xx = EnforcerBlockerType, yy = 0 // non-leaf: xx = special side, yy = number of split sides // These are bitwise appended and formed into one 64-bit integer. @@ -553,7 +553,7 @@ std::map> TriangleSelector::serialize() const for (int i=0; i data; // complete encoding of this mesh triangle @@ -627,7 +627,7 @@ void TriangleSelector::deserialize(const std::map> data) int num_of_split_sides = (next_code & 0b11); int num_of_children = num_of_split_sides != 0 ? num_of_split_sides + 1 : 0; bool is_split = num_of_children != 0; - FacetSupportType state = FacetSupportType(next_code >> 2); + EnforcerBlockerType state = EnforcerBlockerType(next_code >> 2); int special_side = (next_code >> 2); // Take care of the first iteration separately, so handling of the others is simpler. @@ -641,7 +641,7 @@ void TriangleSelector::deserialize(const std::map> data) // then go to the next. parents.push_back({triangle_id, 0, num_of_children}); m_triangles[triangle_id].set_division(num_of_children-1, special_side); - perform_split(triangle_id, FacetSupportType::NONE); + perform_split(triangle_id, EnforcerBlockerType::NONE); continue; } } @@ -655,7 +655,7 @@ void TriangleSelector::deserialize(const std::map> data) const ProcessingInfo& last = parents.back(); int this_idx = m_triangles[last.facet_id].children[last.processed_children]; m_triangles[this_idx].set_division(num_of_children-1, special_side); - perform_split(this_idx, FacetSupportType::NONE); + perform_split(this_idx, EnforcerBlockerType::NONE); parents.push_back({this_idx, 0, num_of_children}); } else { // this triangle belongs to last split one diff --git a/src/libslic3r/TriangleSelector.hpp b/src/libslic3r/TriangleSelector.hpp index fb90cff769..be1b20ed40 100644 --- a/src/libslic3r/TriangleSelector.hpp +++ b/src/libslic3r/TriangleSelector.hpp @@ -9,7 +9,7 @@ namespace Slic3r { -enum class FacetSupportType : int8_t; +enum class EnforcerBlockerType : int8_t; @@ -29,13 +29,13 @@ public: const Vec3f& source, // camera position (mesh coords) const Vec3f& dir, // direction of the ray (mesh coords) float radius, // radius of the cursor - FacetSupportType new_state); // enforcer or blocker? + EnforcerBlockerType new_state); // enforcer or blocker? // Get facets currently in the given state. - indexed_triangle_set get_facets(FacetSupportType state) const; + indexed_triangle_set get_facets(EnforcerBlockerType state) const; // Set facet of the mesh to a given state. Only works for original triangles. - void set_facet(int facet_idx, FacetSupportType state); + void set_facet(int facet_idx, EnforcerBlockerType state); // Clear everything and make the tree empty. void reset(); @@ -59,7 +59,7 @@ protected: // It increments/decrements reference counter on vertices. Triangle(int a, int b, int c) : verts_idxs{a, b, c}, - state{FacetSupportType(0)}, + state{EnforcerBlockerType(0)}, number_of_splits{0}, special_side_idx{0}, old_number_of_splits{0} @@ -77,8 +77,8 @@ protected: void set_division(int sides_to_split, int special_side_idx = -1); // Get/set current state. - void set_state(FacetSupportType type) { assert(! is_split()); state = type; } - FacetSupportType get_state() const { assert(! is_split()); return state; } + void set_state(EnforcerBlockerType type) { assert(! is_split()); state = type; } + EnforcerBlockerType get_state() const { assert(! is_split()); return state; } // Get info on how it's split. bool is_split() const { return number_of_split_sides() != 0; } @@ -90,7 +90,7 @@ protected: private: int number_of_splits; int special_side_idx; - FacetSupportType state; + EnforcerBlockerType state; // How many children were spawned during last split? // Is not reset on remerging the triangle. @@ -133,7 +133,7 @@ protected: float m_old_cursor_radius; // Private functions: - bool select_triangle(int facet_idx, FacetSupportType type, + bool select_triangle(int facet_idx, EnforcerBlockerType type, bool recursive_call = false); bool is_point_inside_cursor(const Vec3f& point) const; int vertices_inside(int facet_idx) const; @@ -144,7 +144,7 @@ protected: bool is_pointer_in_triangle(int facet_idx) const; bool is_edge_inside_cursor(int facet_idx) const; void push_triangle(int a, int b, int c); - void perform_split(int facet_idx, FacetSupportType old_state); + void perform_split(int facet_idx, EnforcerBlockerType old_state); }; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index 58b46f0b6a..f3b6db4f26 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -296,16 +296,16 @@ bool GLGizmoFdmSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous if (m_triangle_selectors.empty()) return false; - FacetSupportType new_state = FacetSupportType::NONE; + EnforcerBlockerType new_state = EnforcerBlockerType::NONE; if (! shift_down) { if (action == SLAGizmoEventType::Dragging) new_state = m_button_down == Button::Left - ? FacetSupportType::ENFORCER - : FacetSupportType::BLOCKER; + ? EnforcerBlockerType::ENFORCER + : EnforcerBlockerType::BLOCKER; else new_state = action == SLAGizmoEventType::LeftDown - ? FacetSupportType::ENFORCER - : FacetSupportType::BLOCKER; + ? EnforcerBlockerType::ENFORCER + : EnforcerBlockerType::BLOCKER; } const Camera& camera = wxGetApp().plater()->get_camera(); @@ -465,8 +465,8 @@ void GLGizmoFdmSupports::select_facets_by_angle(float threshold_deg, bool block) if (facet.normal.dot(down) > dot_limit) m_triangle_selectors[mesh_id]->set_facet(idx, block - ? FacetSupportType::BLOCKER - : FacetSupportType::ENFORCER); + ? EnforcerBlockerType::BLOCKER + : EnforcerBlockerType::ENFORCER); } } @@ -719,13 +719,13 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui) m_iva_blockers.release_geometry(); for (const Triangle& tr : m_triangles) { - if (! tr.valid || tr.is_split() || tr.get_state() == FacetSupportType::NONE) + if (! tr.valid || tr.is_split() || tr.get_state() == EnforcerBlockerType::NONE) continue; - GLIndexedVertexArray& va = tr.get_state() == FacetSupportType::ENFORCER + GLIndexedVertexArray& va = tr.get_state() == EnforcerBlockerType::ENFORCER ? m_iva_enforcers : m_iva_blockers; - int& cnt = tr.get_state() == FacetSupportType::ENFORCER + int& cnt = tr.get_state() == EnforcerBlockerType::ENFORCER ? enf_cnt : blc_cnt; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp index ce24ea8d28..e1dee373f2 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp @@ -15,7 +15,7 @@ namespace Slic3r { -enum class FacetSupportType : int8_t; +enum class EnforcerBlockerType : int8_t; namespace GUI { From 6db1e5ab8fb6bacf0a1e47e7796beb8cc902dfda Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 12 Aug 2020 12:58:23 +0200 Subject: [PATCH 194/255] Slight code cleanup --- src/libslic3r/ExtrusionEntity.hpp | 4 ++-- src/libslic3r/GCode.cpp | 16 ++++------------ 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/libslic3r/ExtrusionEntity.hpp b/src/libslic3r/ExtrusionEntity.hpp index 879f564b6c..4749b52622 100644 --- a/src/libslic3r/ExtrusionEntity.hpp +++ b/src/libslic3r/ExtrusionEntity.hpp @@ -121,8 +121,8 @@ public: // Height of the extrusion, used for visualization purposes. float height; - ExtrusionPath(ExtrusionRole role) : mm3_per_mm(-1), width(-1), height(-1), m_role(role) {}; - ExtrusionPath(ExtrusionRole role, double mm3_per_mm, float width, float height) : mm3_per_mm(mm3_per_mm), width(width), height(height), m_role(role) {}; + ExtrusionPath(ExtrusionRole role) : mm3_per_mm(-1), width(-1), height(-1), m_role(role) {} + ExtrusionPath(ExtrusionRole role, double mm3_per_mm, float width, float height) : mm3_per_mm(mm3_per_mm), width(width), height(height), m_role(role) {} ExtrusionPath(const ExtrusionPath& rhs) : polyline(rhs.polyline), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), m_role(rhs.m_role) {} ExtrusionPath(ExtrusionPath&& rhs) : polyline(std::move(rhs.polyline)), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), m_role(rhs.m_role) {} ExtrusionPath(const Polyline &polyline, const ExtrusionPath &rhs) : polyline(polyline), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), m_role(rhs.m_role) {} diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 7d80677184..62eb4b920c 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2463,7 +2463,7 @@ plot(p2.subs(r,0.2).subs(z,1.), (x, -1, 3), adaptive=False, nb_of_points=400) } } -static Points::iterator project_point_to_polygon_and_insert(Polygon &polygon, const Point &pt, double eps) +static Points::const_iterator project_point_to_polygon_and_insert(Polygon &polygon, const Point &pt, double eps) { assert(polygon.points.size() >= 2); if (polygon.points.size() <= 1) @@ -2651,7 +2651,7 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou // Insert a projection of last_pos into the polygon. size_t last_pos_proj_idx; { - Points::iterator it = project_point_to_polygon_and_insert(polygon, last_pos, 0.1 * nozzle_r); + auto it = project_point_to_polygon_and_insert(polygon, last_pos, 0.1 * nozzle_r); last_pos_proj_idx = it - polygon.points.begin(); } @@ -2671,11 +2671,9 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou if (was_clockwise) ccwAngle = - ccwAngle; float penalty = 0; -// if (ccwAngle <- float(PI/3.)) if (ccwAngle <- float(0.6 * PI)) // Sharp reflex vertex. We love that, it hides the seam perfectly. penalty = 0.f; -// else if (ccwAngle > float(PI/3.)) else if (ccwAngle > float(0.6 * PI)) // Seams on sharp convex vertices are more visible than on reflex vertices. penalty = penaltyConvexVertex; @@ -2688,7 +2686,6 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou penalty = penaltyConvexVertex + (penaltyFlatSurface - penaltyConvexVertex) * bspline_kernel(ccwAngle * float(PI * 2. / 3.)); } // Give a negative penalty for points close to the last point or the prefered seam location. - //float dist_to_last_pos_proj = last_pos_proj.distance_to(polygon.points[i]); float dist_to_last_pos_proj = (i < last_pos_proj_idx) ? std::min(lengths[last_pos_proj_idx] - lengths[i], lengths.back() - lengths[last_pos_proj_idx] + lengths[i]) : std::min(lengths[i] - lengths[last_pos_proj_idx], lengths.back() - lengths[i] + lengths[last_pos_proj_idx]); @@ -2708,14 +2705,10 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou // Signed distance is positive outside the object, negative inside the object. // The point is considered at an overhang, if it is more than nozzle radius // outside of the lower layer contour. - #ifdef NDEBUG // to suppress unused variable warning in release mode - (*lower_layer_edge_grid)->signed_distance(p, search_r, dist); - #else - bool found = (*lower_layer_edge_grid)->signed_distance(p, search_r, dist); - #endif + [[maybe_unused]] bool found = (*lower_layer_edge_grid)->signed_distance(p, search_r, dist); // If the approximate Signed Distance Field was initialized over lower_layer_edge_grid, // then the signed distnace shall always be known. - assert(found); + assert(found); penalties[i] += extrudate_overlap_penalty(float(nozzle_r), penaltyOverhangHalf, float(dist)); } } @@ -2723,7 +2716,6 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou // Find a point with a minimum penalty. size_t idx_min = std::min_element(penalties.begin(), penalties.end()) - penalties.begin(); - // if (seam_position == spAligned) // For all (aligned, nearest, rear) seams: { // Very likely the weight of idx_min is very close to the weight of last_pos_proj_idx. From bd4e4535f902e1a935a5241b8df187709f7baced Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 18 Aug 2020 12:37:07 +0200 Subject: [PATCH 195/255] GCodeProcessor -> Calculate per layer time estimate --- src/libslic3r/GCode.cpp | 2 + src/libslic3r/GCode/GCodeProcessor.cpp | 55 ++++++++++++++++++++++++-- src/libslic3r/GCode/GCodeProcessor.hpp | 7 ++++ src/slic3r/GUI/GCodeViewer.cpp | 2 +- 4 files changed, 61 insertions(+), 5 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 3de70d0611..9e1600cb43 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2095,6 +2095,8 @@ void GCode::process_layer( std::string gcode; #if ENABLE_GCODE_VIEWER + // add tag for processor + gcode += "; " + GCodeProcessor::Layer_Change_Tag + "\n"; // export layer z char buf[64]; sprintf(buf, ";Z:%g\n", print_z); diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 6684255918..5124e1a99d 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -24,9 +24,10 @@ namespace Slic3r { const std::string GCodeProcessor::Extrusion_Role_Tag = "TYPE:"; const std::string GCodeProcessor::Height_Tag = "HEIGHT:"; -const std::string GCodeProcessor::Color_Change_Tag = "COLOR CHANGE"; -const std::string GCodeProcessor::Pause_Print_Tag = "PAUSE PRINT"; -const std::string GCodeProcessor::Custom_Code_Tag = "CUSTOM GCODE"; +const std::string GCodeProcessor::Layer_Change_Tag = "LAYER_CHANGE"; +const std::string GCodeProcessor::Color_Change_Tag = "COLOR_CHANGE"; +const std::string GCodeProcessor::Pause_Print_Tag = "PAUSE_PRINT"; +const std::string GCodeProcessor::Custom_Code_Tag = "CUSTOM_GCODE"; const std::string GCodeProcessor::First_Line_M73_Placeholder_Tag = "; _GP_FIRST_LINE_M73_PLACEHOLDER"; const std::string GCodeProcessor::Last_Line_M73_Placeholder_Tag = "; _GP_LAST_LINE_M73_PLACEHOLDER"; @@ -174,6 +175,7 @@ void GCodeProcessor::TimeMachine::reset() g1_times_cache = std::vector(); std::fill(moves_time.begin(), moves_time.end(), 0.0f); std::fill(roles_time.begin(), roles_time.end(), 0.0f); + layers_time = std::vector(); } void GCodeProcessor::TimeMachine::simulate_st_synchronize(float additional_time) @@ -282,6 +284,16 @@ void GCodeProcessor::TimeMachine::calculate_time(size_t keep_last_n_blocks) gcode_time.cache += block_time; moves_time[static_cast(block.move_type)] += block_time; roles_time[static_cast(block.role)] += block_time; + if (block.layer_id > 0) { + if (block.layer_id >= layers_time.size()) { + size_t curr_size = layers_time.size(); + layers_time.resize(block.layer_id); + for (size_t i = curr_size; i < layers_time.size(); ++i) { + layers_time[i] = 0.0f; + } + } + layers_time[block.layer_id - 1] += block_time; + } g1_times_cache.push_back(time); } @@ -347,6 +359,7 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename) std::string line = gcode_line.substr(0, gcode_line.length() - 1); std::string ret; + if (line == First_Line_M73_Placeholder_Tag || line == Last_Line_M73_Placeholder_Tag) { for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { const TimeMachine& machine = machines[i]; @@ -369,9 +382,20 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename) } } } + return std::make_pair(!ret.empty(), ret.empty() ? gcode_line : ret); }; + // check for temporary lines + auto is_temporary_decoration = [](const std::string& gcode_line) { + // remove trailing '\n' + std::string line = gcode_line.substr(0, gcode_line.length() - 1); + if (line == "; " + Layer_Change_Tag) + return true; + else + return false; + }; + // add lines M73 to exported gcode auto process_line_G1 = [&]() { for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { @@ -408,9 +432,15 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename) } gcode_line += "\n"; + // replace placeholder lines auto [processed, result] = process_placeholders(gcode_line); gcode_line = result; if (!processed) { + // remove temporary lines + if (is_temporary_decoration(gcode_line)) + continue; + + // add lines M73 where needed parser.parse_line(gcode_line, [&](GCodeReader& reader, const GCodeReader::GCodeLine& line) { if (line.cmd_is("G1")) { @@ -677,6 +707,7 @@ void GCodeProcessor::reset() m_filament_diameters = std::vector(Min_Extruder_Count, 1.75f); m_extruded_last_z = 0.0f; + m_layer_id = 0; m_cp_color.reset(); m_producer = EProducer::Unknown; @@ -726,7 +757,7 @@ void GCodeProcessor::process_file(const std::string& filename) m_result.moves.emplace_back(MoveVertex()); m_parser.parse_file(filename, [this](GCodeReader& reader, const GCodeReader::GCodeLine& line) { process_gcode_line(line); }); - // process the remaining time blocks + // process the time blocks for (size_t i = 0; i < static_cast(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { TimeMachine& machine = m_time_processor.machines[i]; TimeMachine::CustomGCodeTime& gcode_time = machine.gcode_time; @@ -804,6 +835,13 @@ std::vector> GCodeProcessor::get_roles_time(Prin return ret; } +std::vector GCodeProcessor::get_layers_time(PrintEstimatedTimeStatistics::ETimeMode mode) const +{ + return (mode < PrintEstimatedTimeStatistics::ETimeMode::Count) ? + m_time_processor.machines[static_cast(mode)].layers_time : + std::vector(); +} + void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line) { /* std::cout << line.raw() << std::endl; */ @@ -973,6 +1011,13 @@ void GCodeProcessor::process_tags(const std::string& comment) return; } #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING + + // layer change tag + pos = comment.find(Layer_Change_Tag); + if (pos != comment.npos) { + ++m_layer_id; + return; + } } bool GCodeProcessor::process_producers_tags(const std::string& comment) @@ -1428,6 +1473,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) block.move_type = type; block.role = m_extrusion_role; block.distance = distance; + block.layer_id = m_layer_id; // calculates block cruise feedrate float min_feedrate_factor = 1.0f; @@ -2097,6 +2143,7 @@ void GCodeProcessor::update_estimated_times_stats() data.custom_gcode_times = get_custom_gcode_times(mode, true); data.moves_times = get_moves_time(mode); data.roles_times = get_roles_time(mode); + data.layers_times = get_layers_time(mode); }; update_mode(PrintEstimatedTimeStatistics::ETimeMode::Normal); diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index b19610801c..90552e6582 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -43,12 +43,14 @@ namespace Slic3r { std::vector>> custom_gcode_times; std::vector> moves_times; std::vector> roles_times; + std::vector layers_times; void reset() { time = 0.0f; custom_gcode_times.clear(); moves_times.clear(); roles_times.clear(); + layers_times.clear(); } }; @@ -68,6 +70,7 @@ namespace Slic3r { public: static const std::string Extrusion_Role_Tag; static const std::string Height_Tag; + static const std::string Layer_Change_Tag; static const std::string Color_Change_Tag; static const std::string Pause_Print_Tag; static const std::string Custom_Code_Tag; @@ -142,6 +145,7 @@ namespace Slic3r { EMoveType move_type{ EMoveType::Noop }; ExtrusionRole role{ erNone }; + unsigned int layer_id{ 0 }; float distance{ 0.0f }; // mm float acceleration{ 0.0f }; // mm/s^2 float max_entry_speed{ 0.0f }; // mm/s @@ -192,6 +196,7 @@ namespace Slic3r { std::vector g1_times_cache; std::array(EMoveType::Count)> moves_time; std::array(ExtrusionRole::erCount)> roles_time; + std::vector layers_time; void reset(); @@ -368,6 +373,7 @@ namespace Slic3r { ExtruderColors m_extruder_colors; std::vector m_filament_diameters; float m_extruded_last_z; + unsigned int m_layer_id; CpColor m_cp_color; enum class EProducer @@ -420,6 +426,7 @@ namespace Slic3r { std::vector> get_moves_time(PrintEstimatedTimeStatistics::ETimeMode mode) const; std::vector> get_roles_time(PrintEstimatedTimeStatistics::ETimeMode mode) const; + std::vector get_layers_time(PrintEstimatedTimeStatistics::ETimeMode mode) const; private: void process_gcode_line(const GCodeReader::GCodeLine& line); diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 1a4485402b..ed1d5bc5c9 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -2352,7 +2352,7 @@ void GCodeViewer::render_time_estimate() const imgui.title(_u8L("Estimated printing time")); #endif // GCODE_VIEWER_TIME_ESTIMATE - // mode tabs + // mode tabs ImGui::BeginTabBar("mode_tabs"); const PrintEstimatedTimeStatistics::Mode& normal_mode = m_time_statistics.modes[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Normal)]; if (normal_mode.time > 0.0f) { From 7b5f84b7dfdb9de22bfb87d3d69ab29e021a5a23 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 18 Aug 2020 12:39:46 +0200 Subject: [PATCH 196/255] Extended hover capability in DoubleSlider::Control --- src/slic3r/GUI/DoubleSlider.cpp | 26 ++++++++++++++++++-------- src/slic3r/GUI/DoubleSlider.hpp | 6 ++++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index a7cb7d54d1..8a9ac34ea1 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -600,10 +600,8 @@ void Control::draw_tick_text(wxDC& dc, const wxPoint& pos, int tick, bool right_ const wxString label = get_label(tick); dc.GetMultiLineTextExtent(label, &text_width, &text_height); wxPoint text_pos; - if (right_side) - { - if (is_horizontal()) - { + if (right_side) { + if (is_horizontal()) { int width; int height; get_size(&width, &height); @@ -614,17 +612,21 @@ void Control::draw_tick_text(wxDC& dc, const wxPoint& pos, int tick, bool right_ } else text_pos = wxPoint(pos.x + m_thumb_size.x + 1, pos.y - 0.5 * text_height - 1); + + // update text rectangle + m_rect_lower_thumb_text = wxRect(text_pos, wxSize(text_width, text_height)); } - else - { - if (is_horizontal()) - { + else { + if (is_horizontal()) { int x = pos.x - text_width - 1; int xx = (x > 0) ? x : pos.x + 1; text_pos = wxPoint(xx, pos.y - m_thumb_size.x / 2 - text_height - 1); } else text_pos = wxPoint(pos.x - text_width - 1 - m_thumb_size.x, pos.y - 0.5 * text_height + 1); + + // update text rectangle + m_rect_higher_thumb_text = wxRect(text_pos, wxSize(text_width, text_height)); } dc.DrawText(label, text_pos); @@ -1206,6 +1208,14 @@ void Control::OnMotion(wxMouseEvent& event) else if (m_mode == SingleExtruder && is_point_in_rect(pos, get_colored_band_rect()) && get_edited_tick_for_position(pos) >= 0 ) m_focus = fiColorBand; + else if (is_point_in_rect(pos, m_rect_lower_thumb)) + m_focus = fiLowerThumb; + else if (is_point_in_rect(pos, m_rect_higher_thumb)) + m_focus = fiHigherThumb; + else if (is_point_in_rect(pos, m_rect_lower_thumb_text)) + m_focus = fiLowerThumbText; + else if (is_point_in_rect(pos, m_rect_higher_thumb_text)) + m_focus = fiHigherThumbText; else { m_focus = fiTick; tick = get_tick_near_point(pos); diff --git a/src/slic3r/GUI/DoubleSlider.hpp b/src/slic3r/GUI/DoubleSlider.hpp index fc8ebced87..fb87ac4a97 100644 --- a/src/slic3r/GUI/DoubleSlider.hpp +++ b/src/slic3r/GUI/DoubleSlider.hpp @@ -44,6 +44,10 @@ enum FocusedItem { fiCogIcon, fiColorBand, fiActionIcon, + fiLowerThumb, + fiHigherThumb, + fiLowerThumbText, + fiHigherThumbText, fiTick }; @@ -360,6 +364,8 @@ private: wxRect m_rect_lower_thumb; wxRect m_rect_higher_thumb; + mutable wxRect m_rect_lower_thumb_text; + mutable wxRect m_rect_higher_thumb_text; wxRect m_rect_tick_action; wxRect m_rect_one_layer_icon; wxRect m_rect_revert_icon; From d91fc7b8ab0f5a3ce284483d2fa339fa04f643c3 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 19 Aug 2020 11:25:12 +0200 Subject: [PATCH 197/255] ENABLE_GCODE_VIEWER -> Removed options_120_solid shader --- resources/shaders/options_120_solid.fs | 89 -------------------------- resources/shaders/options_120_solid.vs | 14 ---- src/slic3r/GUI/GCodeViewer.cpp | 6 +- src/slic3r/GUI/GCodeViewer.hpp | 4 +- src/slic3r/GUI/GLShadersManager.cpp | 4 +- 5 files changed, 5 insertions(+), 112 deletions(-) delete mode 100644 resources/shaders/options_120_solid.fs delete mode 100644 resources/shaders/options_120_solid.vs diff --git a/resources/shaders/options_120_solid.fs b/resources/shaders/options_120_solid.fs deleted file mode 100644 index 4480d7b147..0000000000 --- a/resources/shaders/options_120_solid.fs +++ /dev/null @@ -1,89 +0,0 @@ -// version 120 is needed for gl_PointCoord -#version 120 - -#define INTENSITY_CORRECTION 0.6 - -// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) -const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); -#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) -#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) -#define LIGHT_TOP_SHININESS 20.0 - -// normalized values for (1./1.43, 0.2/1.43, 1./1.43) -const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074); -#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) - -#define INTENSITY_AMBIENT 0.3 - -uniform vec3 uniform_color; - -uniform ivec4 viewport; -uniform float point_size; -uniform mat4 inv_proj_matrix; - -varying vec3 eye_center; -// x = tainted, y = specular; -vec2 intensity; - -float radius = 0.5 * point_size; - -vec3 eye_position_from_fragment() -{ - // Convert screen coordinates to normalized device coordinates (NDC) - vec4 ndc = vec4((gl_FragCoord.x / viewport.z - 0.5) * 2.0, - (gl_FragCoord.y / viewport.w - 0.5) * 2.0, - (gl_FragCoord.z - 0.5) * 2.0, - gl_FragCoord.w); - // Convert NDC throuch inverse clip coordinates to view coordinates - vec4 clip = inv_proj_matrix * ndc; - return clip.xyz; -} - -vec3 eye_position_on_sphere(vec3 eye_fragment_position) -{ - vec3 eye_dir = normalize(eye_fragment_position); - float a = dot(eye_dir, eye_dir); - float b = 2.0 * dot(-eye_center, eye_dir); - float c = dot(eye_center, eye_center) - radius * radius; - float discriminant = b * b - 4 * a * c; - float t = -(b + sqrt(discriminant)) / (2.0 * a); - return t * eye_dir; -} - -vec4 on_sphere_color(vec3 eye_on_sphere_position) -{ - vec3 eye_normal = normalize(eye_on_sphere_position - eye_center); - - // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. - // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. - float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0); - - intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; - intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_on_sphere_position), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS); - - // Perform the same lighting calculation for the 2nd light source (no specular applied). - NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0); - intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; - - return vec4(intensity.y + uniform_color.rgb * intensity.x, 1.0); -} - -float fragment_depth(vec3 eye_pos) -{ - vec4 clip_pos = gl_ProjectionMatrix * vec4(eye_pos, 1.0); - float ndc_depth = clip_pos.z / clip_pos.w; - return ((gl_DepthRange.far - gl_DepthRange.near) * ndc_depth + gl_DepthRange.near + gl_DepthRange.far) / 2.0; -} - -void main() -{ - vec2 pos = (gl_PointCoord - 0.5) * 2.0; - float radius = length(pos); - if (radius > 1.0) - discard; - - vec3 eye_on_sphere_position = eye_position_on_sphere(eye_position_from_fragment()); - -// gl_FragDepth = fragment_depth(eye_on_sphere_position); - gl_FragColor = on_sphere_color(eye_on_sphere_position); -} diff --git a/resources/shaders/options_120_solid.vs b/resources/shaders/options_120_solid.vs deleted file mode 100644 index 745ec8ddd1..0000000000 --- a/resources/shaders/options_120_solid.vs +++ /dev/null @@ -1,14 +0,0 @@ -#version 120 - -uniform float zoom; -uniform float point_size; -uniform float near_plane_height; - -varying vec3 eye_center; - -void main() -{ - eye_center = (gl_ModelViewMatrix * gl_Vertex).xyz; - gl_Position = ftransform(); - gl_PointSize = (gl_Position.w == 1.0) ? zoom * near_plane_height * point_size : near_plane_height * point_size / gl_Position.w; -} diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index ed1d5bc5c9..40c31d257d 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -2479,8 +2479,8 @@ void GCodeViewer::render_statistics() const void GCodeViewer::render_shaders_editor() const { auto set_shader = [this](const std::string& shader) { - unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); - unsigned char end_id = buffer_id(GCodeProcessor::EMoveType::Custom_GCode); + unsigned char begin_id = buffer_id(EMoveType::Retract); + unsigned char end_id = buffer_id(EMoveType::Custom_GCode); for (unsigned char i = begin_id; i <= end_id; ++i) { m_buffers[i].shader = shader; } @@ -2497,7 +2497,6 @@ void GCodeViewer::render_shaders_editor() const if (ImGui::TreeNode("GLSL version")) { ImGui::RadioButton("1.10 (low end PCs)", &m_shaders_editor.points.shader_version, 0); ImGui::RadioButton("1.20 flat (billboards) [default]", &m_shaders_editor.points.shader_version, 1); - ImGui::RadioButton("1.20 solid (spheres)", &m_shaders_editor.points.shader_version, 2); ImGui::TreePop(); } @@ -2505,7 +2504,6 @@ void GCodeViewer::render_shaders_editor() const { case 0: { set_shader("options_110"); break; } case 1: { set_shader("options_120_flat"); break; } - case 2: { set_shader("options_120_solid"); break; } } if (ImGui::TreeNode("Options")) { diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 74506677a6..0be17f790a 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -33,7 +33,7 @@ class GCodeViewer CustomGCodes }; - // vbo buffer containing vertices data for a specific toolpath type + // vbo buffer containing vertices data used to rendder a specific toolpath type struct VBuffer { enum class EFormat : unsigned char @@ -65,7 +65,7 @@ class GCodeViewer void reset(); }; - // ibo buffer containing indices data for a specific toolpath type + // ibo buffer containing indices data (triangles) used to render a specific toolpath type struct IBuffer { // ibo id diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index e62a81d39b..5f726d4ef1 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -35,10 +35,8 @@ std::pair GLShadersManager::init() valid &= append_shader("printbed", { "printbed.vs", "printbed.fs" }); // used to render options in gcode preview valid &= append_shader("options_110", { "options_110.vs", "options_110.fs" }); - if (GUI::wxGetApp().is_glsl_version_greater_or_equal_to(1, 20)) { + if (GUI::wxGetApp().is_glsl_version_greater_or_equal_to(1, 20)) valid &= append_shader("options_120_flat", { "options_120_flat.vs", "options_120_flat.fs" }); - valid &= append_shader("options_120_solid", { "options_120_solid.vs", "options_120_solid.fs" }); - } // used to render extrusion and travel paths in gcode preview valid &= append_shader("toolpaths", { "toolpaths.vs", "toolpaths.fs" }); // used to render objects in 3d editor From 41579db708fa45544db685121a809fc8d81b9f7b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 19 Aug 2020 11:55:18 +0200 Subject: [PATCH 198/255] GCodeViewer -> Use only white texts in legend --- src/slic3r/GUI/GCodeViewer.cpp | 24 ++++++++++++------------ src/slic3r/GUI/ImGuiWrapper.cpp | 2 -- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 40c31d257d..22d8615ca0 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1542,11 +1542,11 @@ void GCodeViewer::render_legend() const #if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND auto append_headers = [&imgui](const std::array& texts, const std::array& offsets) { - imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, texts[0]); + imgui.text(texts[0]); ImGui::SameLine(offsets[0]); - imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, texts[1]); + imgui.text(texts[1]); ImGui::SameLine(offsets[1]); - imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, texts[2]); + imgui.text(texts[2]); ImGui::Separator(); }; @@ -1648,7 +1648,7 @@ void GCodeViewer::render_legend() const if (time_mode.time > 0.0f && (m_view_type == EViewType::FeatureType || (m_view_type == EViewType::ColorPrint && !time_mode.custom_gcode_times.empty()))) { ImGui::AlignTextToFramePadding(); - imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Estimated printing time") + ":"); + imgui.text(_u8L("Estimated printing time") + ":"); ImGui::SameLine(); imgui.text(short_time(get_time_dhms(time_mode.time))); @@ -1703,7 +1703,7 @@ void GCodeViewer::render_legend() const case EViewType::Height: { imgui.title(_u8L("Height (mm)")); break; } case EViewType::Width: { imgui.title(_u8L("Width (mm)")); break; } case EViewType::Feedrate: { imgui.title(_u8L("Speed (mm/s)")); break; } - case EViewType::FanSpeed: { imgui.title(_u8L("Fan Speed (%%)")); break; } + case EViewType::FanSpeed: { imgui.title(_u8L("Fan Speed (%)")); break; } case EViewType::VolumetricRate: { imgui.title(_u8L("Volumetric flow rate (mm³/s)")); break; } case EViewType::Tool: { imgui.title(_u8L("Tool")); break; } case EViewType::ColorPrint: { imgui.title(_u8L("Color Print")); break; } @@ -2071,11 +2071,11 @@ void GCodeViewer::render_time_estimate() const using PartialTimes = std::vector; auto append_headers = [&imgui](const Headers& headers, const ColumnOffsets& offsets) { - imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, headers[0]); + imgui.text(headers[0]); ImGui::SameLine(offsets[0]); - imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, headers[1]); + imgui.text(headers[1]); ImGui::SameLine(offsets[1]); - imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, headers[2]); + imgui.text(headers[2]); ImGui::Separator(); }; @@ -2135,7 +2135,7 @@ void GCodeViewer::render_time_estimate() const { case PartialTime::EType::Print: { - imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Print")); + imgui.text(_u8L("Print")); ImGui::SameLine(offsets[0]); imgui.text(short_time(get_time_dhms(item.times.second))); ImGui::SameLine(offsets[1]); @@ -2144,7 +2144,7 @@ void GCodeViewer::render_time_estimate() const } case PartialTime::EType::Pause: { - imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Pause")); + imgui.text(_u8L("Pause")); ImGui::SameLine(offsets[0]); imgui.text(short_time(get_time_dhms(item.times.second - item.times.first))); break; @@ -2175,7 +2175,7 @@ void GCodeViewer::render_time_estimate() const }; auto append_time_item = [&imgui] (const std::string& label, float time, float percentage, const ImVec4& color, const ColumnOffsets& offsets) { - imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, label); + imgui.text(label); ImGui::SameLine(offsets[0]); imgui.text(short_time(get_time_dhms(time))); ImGui::SameLine(offsets[1]); @@ -2254,7 +2254,7 @@ void GCodeViewer::render_time_estimate() const return ret; }; - imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Time") + ":"); + imgui.text(_u8L("Time") + ":"); ImGui::SameLine(); imgui.text(short_time(get_time_dhms(total_time))); append_partial_times(items, partial_times_headers); diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index b79f119d45..7c27545026 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -803,9 +803,7 @@ void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, co void ImGuiWrapper::title(const std::string& str) { - ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT); text(str); - ImGui::PopStyleColor(); ImGui::Separator(); } From eca4f0a4cd31279fa27f84490dfb15f72c5d10e3 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 19 Aug 2020 12:59:50 +0200 Subject: [PATCH 199/255] GCodeViewer -> Changed layout of sliders in preview --- src/slic3r/GUI/GUI_Preview.cpp | 51 +++++++++++++++++++--------------- src/slic3r/GUI/GUI_Preview.hpp | 1 + 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 2c5a6fe88b..d62b4dd506 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -186,6 +186,7 @@ Preview::Preview( : m_canvas_widget(nullptr) , m_canvas(nullptr) #if ENABLE_GCODE_VIEWER + , m_left_sizer(nullptr) , m_layers_slider_sizer(nullptr) , m_bottom_toolbar_panel(nullptr) #else @@ -237,6 +238,8 @@ bool Preview::init(wxWindow* parent, Model* model) if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 /* disable wxTAB_TRAVERSAL */)) return false; + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + m_canvas_widget = OpenGLManager::create_wxglcanvas(*this); if (m_canvas_widget == nullptr) return false; @@ -255,9 +258,7 @@ bool Preview::init(wxWindow* parent, Model* model) m_layers_slider_sizer = create_layers_slider_sizer(); m_bottom_toolbar_panel = new wxPanel(this); - m_label_view_type = new wxStaticText(m_bottom_toolbar_panel, wxID_ANY, _L("View")); - m_choice_view_type = new wxChoice(m_bottom_toolbar_panel, wxID_ANY); #else m_double_slider_sizer = new wxBoxSizer(wxHORIZONTAL); @@ -340,15 +341,13 @@ bool Preview::init(wxWindow* parent, Model* model) m_checkbox_legend->SetValue(true); #endif // ENABLE_GCODE_VIEWER - wxBoxSizer* top_sizer = new wxBoxSizer(wxHORIZONTAL); - top_sizer->Add(m_canvas_widget, 1, wxALL | wxEXPAND, 0); #if ENABLE_GCODE_VIEWER - top_sizer->Add(m_layers_slider_sizer, 0, wxEXPAND, 0); -#else - top_sizer->Add(m_double_slider_sizer, 0, wxEXPAND, 0); -#endif // ENABLE_GCODE_VIEWER + m_left_sizer = new wxBoxSizer(wxVERTICAL); + m_left_sizer->Add(m_canvas_widget, 1, wxALL | wxEXPAND, 0); + + wxBoxSizer* right_sizer = new wxBoxSizer(wxVERTICAL); + right_sizer->Add(m_layers_slider_sizer, 1, wxEXPAND, 0); -#if ENABLE_GCODE_VIEWER m_moves_slider = new DoubleSlider::Control(m_bottom_toolbar_panel, wxID_ANY, 0, 0, 0, 100, wxDefaultPosition, wxSize(-1, 3 * GetTextExtent("m").y), wxSL_HORIZONTAL); m_moves_slider->SetDrawMode(DoubleSlider::dmSequentialGCodeView); @@ -366,7 +365,18 @@ bool Preview::init(wxWindow* parent, Model* model) bottom_toolbar_sizer->AddSpacer(5); bottom_toolbar_sizer->Add(m_moves_slider, 1, wxALL | wxEXPAND, 0); m_bottom_toolbar_panel->SetSizer(bottom_toolbar_sizer); + + m_left_sizer->Add(m_bottom_toolbar_panel, 0, wxALL | wxEXPAND, 0); + m_left_sizer->Hide(m_bottom_toolbar_panel); + + wxBoxSizer* main_sizer = new wxBoxSizer(wxHORIZONTAL); + main_sizer->Add(m_left_sizer, 1, wxALL | wxEXPAND, 0); + main_sizer->Add(right_sizer, 0, wxALL | wxEXPAND, 0); #else + wxBoxSizer* top_sizer = new wxBoxSizer(wxHORIZONTAL); + top_sizer->Add(m_canvas_widget, 1, wxALL | wxEXPAND, 0); + top_sizer->Add(m_double_slider_sizer, 0, wxEXPAND, 0); + wxBoxSizer* bottom_sizer = new wxBoxSizer(wxHORIZONTAL); bottom_sizer->Add(m_label_view_type, 0, wxALIGN_CENTER_VERTICAL, 5); bottom_sizer->Add(m_choice_view_type, 0, wxEXPAND | wxALL, 5); @@ -383,16 +393,12 @@ bool Preview::init(wxWindow* parent, Model* model) bottom_sizer->Add(m_checkbox_shells, 0, wxEXPAND | wxALL, 5); bottom_sizer->AddSpacer(20); bottom_sizer->Add(m_checkbox_legend, 0, wxEXPAND | wxALL, 5); -#endif // ENABLE_GCODE_VIEWER wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); main_sizer->Add(top_sizer, 1, wxALL | wxEXPAND, 0); -#if ENABLE_GCODE_VIEWER - main_sizer->Add(m_bottom_toolbar_panel, 0, wxALL | wxEXPAND, 0); - main_sizer->Hide(m_bottom_toolbar_panel); -#else main_sizer->Add(bottom_sizer, 0, wxALL | wxEXPAND, 0); #endif // ENABLE_GCODE_VIEWER + SetSizer(main_sizer); SetMinSize(GetSize()); GetSizer()->SetSizeHints(this); @@ -1233,8 +1239,8 @@ void Preview::load_print_as_fff(bool keep_z_range) { #if ENABLE_GCODE_VIEWER hide_layers_slider(); - GetSizer()->Hide(m_bottom_toolbar_panel); - GetSizer()->Layout(); + m_left_sizer->Hide(m_bottom_toolbar_panel); + m_left_sizer->Layout(); Refresh(); #else reset_sliders(true); @@ -1309,8 +1315,8 @@ void Preview::load_print_as_fff(bool keep_z_range) #if ENABLE_GCODE_VIEWER m_canvas->load_gcode_preview(*m_gcode_result); m_canvas->refresh_gcode_preview(*m_gcode_result, colors); - GetSizer()->Show(m_bottom_toolbar_panel); - GetSizer()->Layout(); + m_left_sizer->Show(m_bottom_toolbar_panel); + m_left_sizer->Layout(); Refresh(); zs = m_canvas->get_gcode_layers_zs(); #else @@ -1321,8 +1327,8 @@ void Preview::load_print_as_fff(bool keep_z_range) // Load the initial preview based on slices, not the final G-code. m_canvas->load_preview(colors, color_print_values); #if ENABLE_GCODE_VIEWER - GetSizer()->Hide(m_bottom_toolbar_panel); - GetSizer()->Layout(); + m_left_sizer->Hide(m_bottom_toolbar_panel); + m_left_sizer->Layout(); Refresh(); zs = m_canvas->get_volumes_print_zs(true); #endif // ENABLE_GCODE_VIEWER @@ -1384,8 +1390,9 @@ void Preview::load_print_as_sla() { m_canvas->load_sla_preview(); #if ENABLE_GCODE_VIEWER - GetSizer()->Hide(m_bottom_toolbar_panel); - GetSizer()->Layout(); + m_left_sizer->Hide(m_bottom_toolbar_panel); + m_left_sizer->Hide(m_bottom_toolbar_panel); + m_left_sizer->Layout(); Refresh(); #else show_hide_ui_elements("none"); diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index c74dccc5c1..ddb7af86fb 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -84,6 +84,7 @@ class Preview : public wxPanel wxGLCanvas* m_canvas_widget; GLCanvas3D* m_canvas; #if ENABLE_GCODE_VIEWER + wxBoxSizer* m_left_sizer; wxBoxSizer* m_layers_slider_sizer; wxPanel* m_bottom_toolbar_panel; #else From db77f806819bcb1c395fff338a15b25d67d862a5 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 19 Aug 2020 13:14:47 +0200 Subject: [PATCH 200/255] Follow-up of eca4f0a4cd31279fa27f84490dfb15f72c5d10e3. Fixed preview background on all platforms --- src/slic3r/GUI/GUI_Preview.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index d62b4dd506..57b1158f65 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -238,7 +238,14 @@ bool Preview::init(wxWindow* parent, Model* model) if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 /* disable wxTAB_TRAVERSAL */)) return false; +#if ENABLE_GCODE_VIEWER + // to match the background of the sliders +#ifdef _WIN32 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); +#else + SetBackgroundColour(GetParent()->GetBackgroundColour()); +#endif // _WIN32 +#endif // ENABLE_GCODE_VIEWER m_canvas_widget = OpenGLManager::create_wxglcanvas(*this); if (m_canvas_widget == nullptr) From 992d7065b2c456f8aa964969c9e003de7450e60a Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 19 Aug 2020 15:19:07 +0200 Subject: [PATCH 201/255] GCodeViewer -> Modified shape of printbed for the unknown size case --- src/slic3r/GUI/3DBed.cpp | 109 +++++++++++---------------------- src/slic3r/GUI/GCodeViewer.cpp | 19 ++++-- 2 files changed, 52 insertions(+), 76 deletions(-) diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 11fa745f49..aa9bf38035 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -45,10 +45,8 @@ bool GeometryBuffer::set_from_triangles(const Polygons& triangles, float z, bool float max_y = min_y; unsigned int v_count = 0; - for (const Polygon& t : triangles) - { - for (unsigned int i = 0; i < 3; ++i) - { + for (const Polygon& t : triangles) { + for (unsigned int i = 0; i < 3; ++i) { Vertex& v = m_vertices[v_count]; const Point& p = t.points[i]; @@ -59,8 +57,7 @@ bool GeometryBuffer::set_from_triangles(const Polygons& triangles, float z, bool v.position[1] = y; v.position[2] = z; - if (generate_tex_coords) - { + if (generate_tex_coords) { v.tex_coords[0] = x; v.tex_coords[1] = y; @@ -74,17 +71,14 @@ bool GeometryBuffer::set_from_triangles(const Polygons& triangles, float z, bool } } - if (generate_tex_coords) - { + if (generate_tex_coords) { float size_x = max_x - min_x; float size_y = max_y - min_y; - if ((size_x != 0.0f) && (size_y != 0.0f)) - { + if ((size_x != 0.0f) && (size_y != 0.0f)) { float inv_size_x = 1.0f / size_x; float inv_size_y = -1.0f / size_y; - for (Vertex& v : m_vertices) - { + for (Vertex& v : m_vertices) { v.tex_coords[0] = (v.tex_coords[0] - min_x) * inv_size_x; v.tex_coords[1] = (v.tex_coords[1] - min_y) * inv_size_y; } @@ -105,8 +99,7 @@ bool GeometryBuffer::set_from_lines(const Lines& lines, float z) m_vertices = std::vector(v_size, Vertex()); unsigned int v_count = 0; - for (const Line& l : lines) - { + for (const Line& l : lines) { Vertex& v1 = m_vertices[v_count]; v1.position[0] = unscale(l.a(0)); v1.position[1] = unscale(l.a(1)); @@ -360,8 +353,7 @@ void Bed3D::render(GLCanvas3D& canvas, bool bottom, float scale_factor, void Bed3D::calc_bounding_boxes() const { m_bounding_box = BoundingBoxf3(); - for (const Vec2d& p : m_shape) - { + for (const Vec2d& p : m_shape) { m_bounding_box.merge(Vec3d(p(0), p(1), 0.0)); } @@ -374,8 +366,7 @@ void Bed3D::calc_bounding_boxes() const // extend to contain model, if any BoundingBoxf3 model_bb = m_model.get_bounding_box(); - if (model_bb.defined) - { + if (model_bb.defined) { model_bb.translate(m_model_offset); m_extended_bounding_box.merge(model_bb); } @@ -390,7 +381,7 @@ void Bed3D::calc_bounding_boxes() const void Bed3D::calc_triangles(const ExPolygon& poly) { Polygons triangles; - poly.triangulate(&triangles); + poly.triangulate_p2t(&triangles); if (!m_triangles.set_from_triangles(triangles, GROUND_Z, true)) printf("Unable to create bed triangles\n"); @@ -399,15 +390,13 @@ void Bed3D::calc_triangles(const ExPolygon& poly) void Bed3D::calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox) { Polylines axes_lines; - for (coord_t x = bed_bbox.min(0); x <= bed_bbox.max(0); x += scale_(10.0)) - { + for (coord_t x = bed_bbox.min(0); x <= bed_bbox.max(0); x += scale_(10.0)) { Polyline line; line.append(Point(x, bed_bbox.min(1))); line.append(Point(x, bed_bbox.max(1))); axes_lines.push_back(line); } - for (coord_t y = bed_bbox.min(1); y <= bed_bbox.max(1); y += scale_(10.0)) - { + for (coord_t y = bed_bbox.min(1); y <= bed_bbox.max(1); y += scale_(10.0)) { Polyline line; line.append(Point(bed_bbox.min(0), y)); line.append(Point(bed_bbox.max(0), y)); @@ -482,26 +471,21 @@ void Bed3D::render_system(GLCanvas3D& canvas, bool bottom, bool show_texture) co void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const { - if (m_texture_filename.empty()) - { + if (m_texture_filename.empty()) { m_texture.reset(); render_default(bottom); return; } - if ((m_texture.get_id() == 0) || (m_texture.get_source() != m_texture_filename)) - { + if ((m_texture.get_id() == 0) || (m_texture.get_source() != m_texture_filename)) { m_texture.reset(); - if (boost::algorithm::iends_with(m_texture_filename, ".svg")) - { + if (boost::algorithm::iends_with(m_texture_filename, ".svg")) { // use higher resolution images if graphic card and opengl version allow GLint max_tex_size = OpenGLManager::get_gl_info().get_max_tex_size(); - if ((m_temp_texture.get_id() == 0) || (m_temp_texture.get_source() != m_texture_filename)) - { + if ((m_temp_texture.get_id() == 0) || (m_temp_texture.get_source() != m_texture_filename)) { // generate a temporary lower resolution texture to show while no main texture levels have been compressed - if (!m_temp_texture.load_from_svg_file(m_texture_filename, false, false, false, max_tex_size / 8)) - { + if (!m_temp_texture.load_from_svg_file(m_texture_filename, false, false, false, max_tex_size / 8)) { render_default(bottom); return; } @@ -509,19 +493,15 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const } // starts generating the main texture, compression will run asynchronously - if (!m_texture.load_from_svg_file(m_texture_filename, true, true, true, max_tex_size)) - { + if (!m_texture.load_from_svg_file(m_texture_filename, true, true, true, max_tex_size)) { render_default(bottom); return; } - } - else if (boost::algorithm::iends_with(m_texture_filename, ".png")) - { + } + else if (boost::algorithm::iends_with(m_texture_filename, ".png")) { // generate a temporary lower resolution texture to show while no main texture levels have been compressed - if ((m_temp_texture.get_id() == 0) || (m_temp_texture.get_source() != m_texture_filename)) - { - if (!m_temp_texture.load_from_file(m_texture_filename, false, GLTexture::None, false)) - { + if ((m_temp_texture.get_id() == 0) || (m_temp_texture.get_source() != m_texture_filename)) { + if (!m_temp_texture.load_from_file(m_texture_filename, false, GLTexture::None, false)) { render_default(bottom); return; } @@ -529,20 +509,17 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const } // starts generating the main texture, compression will run asynchronously - if (!m_texture.load_from_file(m_texture_filename, true, GLTexture::MultiThreaded, true)) - { + if (!m_texture.load_from_file(m_texture_filename, true, GLTexture::MultiThreaded, true)) { render_default(bottom); return; } } - else - { + else { render_default(bottom); return; } } - else if (m_texture.unsent_compressed_data_available()) - { + else if (m_texture.unsent_compressed_data_available()) { // sends to gpu the already available compressed levels of the main texture m_texture.send_compressed_data_to_gpu(); @@ -554,17 +531,14 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const } - if (m_triangles.get_vertices_count() > 0) - { + if (m_triangles.get_vertices_count() > 0) { GLShaderProgram* shader = wxGetApp().get_shader("printbed"); - if (shader != nullptr) - { + if (shader != nullptr) { shader->start_using(); shader->set_uniform("transparent_background", bottom); shader->set_uniform("svg_source", boost::algorithm::iends_with(m_texture.get_source(), ".svg")); - if (m_vbo_id == 0) - { + if (m_vbo_id == 0) { glsafe(::glGenBuffers(1, &m_vbo_id)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id)); glsafe(::glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)m_triangles.get_vertices_data_size(), (const GLvoid*)m_triangles.get_vertices_data(), GL_STATIC_DRAW)); @@ -593,13 +567,11 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const glsafe(::glBindTexture(GL_TEXTURE_2D, tex_id)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id)); - if (position_id != -1) - { + if (position_id != -1) { glsafe(::glEnableVertexAttribArray(position_id)); glsafe(::glVertexAttribPointer(position_id, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*)(intptr_t)m_triangles.get_position_offset())); } - if (tex_coords_id != -1) - { + if (tex_coords_id != -1) { glsafe(::glEnableVertexAttribArray(tex_coords_id)); glsafe(::glVertexAttribPointer(tex_coords_id, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*)(intptr_t)m_triangles.get_tex_coords_offset())); } @@ -631,8 +603,7 @@ void Bed3D::render_model() const if (m_model_filename.empty()) return; - if ((m_model.get_filename() != m_model_filename) && m_model.init_from_file(m_model_filename)) - { + if ((m_model.get_filename() != m_model_filename) && m_model.init_from_file(m_model_filename)) { // move the model so that its origin (0.0, 0.0, 0.0) goes into the bed shape center and a bit down to avoid z-fighting with the texture quad Vec3d shift = m_bounding_box.center(); shift(2) = -0.03; @@ -646,11 +617,9 @@ void Bed3D::render_model() const calc_bounding_boxes(); } - if (!m_model.get_filename().empty()) - { + if (!m_model.get_filename().empty()) { GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); - if (shader != nullptr) - { + if (shader != nullptr) { shader->start_using(); #if ENABLE_GCODE_VIEWER shader->set_uniform("uniform_color", m_model_color); @@ -668,8 +637,7 @@ void Bed3D::render_model() const void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture) const { - if (m_texture_filename.empty() && m_model_filename.empty()) - { + if (m_texture_filename.empty() && m_model_filename.empty()) { render_default(bottom); return; } @@ -686,8 +654,7 @@ void Bed3D::render_default(bool bottom) const m_texture.reset(); unsigned int triangles_vcount = m_triangles.get_vertices_count(); - if (triangles_vcount > 0) - { + if (triangles_vcount > 0) { bool has_model = !m_model.get_filename().empty(); glsafe(::glEnable(GL_DEPTH_TEST)); @@ -696,8 +663,7 @@ void Bed3D::render_default(bool bottom) const glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - if (!has_model && !bottom) - { + if (!has_model && !bottom) { // draw background glsafe(::glDepthMask(GL_FALSE)); #if ENABLE_GCODE_VIEWER @@ -728,8 +694,7 @@ void Bed3D::render_default(bool bottom) const void Bed3D::reset() { - if (m_vbo_id > 0) - { + if (m_vbo_id > 0) { glsafe(::glDeleteBuffers(1, &m_vbo_id)); m_vbo_id = 0; } diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 22d8615ca0..db126552f6 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -343,10 +343,21 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& const double margin = 10.0; Vec2d min(m_paths_bounding_box.min(0) - margin, m_paths_bounding_box.min(1) - margin); Vec2d max(m_paths_bounding_box.max(0) + margin, m_paths_bounding_box.max(1) + margin); - bed_shape = { { min(0), min(1) }, - { max(0), min(1) }, - { max(0), max(1) }, - { min(0), max(1) } }; + + Vec2d size = max - min; + bed_shape = { + { min(0), min(1) }, + { max(0), min(1) }, + { max(0), min(1) + 0.442265 * size[1]}, + { max(0) - 10.0, min(1) + 0.4711325 * size[1]}, + { max(0) + 10.0, min(1) + 0.5288675 * size[1]}, + { max(0), min(1) + 0.557735 * size[1]}, + { max(0), max(1) }, + { min(0) + 0.557735 * size[0], max(1)}, + { min(0) + 0.5288675 * size[0], max(1) - 10.0}, + { min(0) + 0.4711325 * size[0], max(1) + 10.0}, + { min(0) + 0.442265 * size[0], max(1)}, + { min(0), max(1) } }; } wxGetApp().plater()->set_bed_shape(bed_shape, "", "", true); } From 739cd2a4a20f50dace8cd053b671f3451fb9160a Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 19 Aug 2020 17:15:01 +0200 Subject: [PATCH 202/255] Fixed several indentation-related warnings --- src/libslic3r/PrintBase.hpp | 12 ++++++------ src/slic3r/GUI/Plater.cpp | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/libslic3r/PrintBase.hpp b/src/libslic3r/PrintBase.hpp index 5e94e011a7..647c24c1ce 100644 --- a/src/libslic3r/PrintBase.hpp +++ b/src/libslic3r/PrintBase.hpp @@ -507,9 +507,9 @@ protected: bool set_started(PrintStepEnum step) { return m_state.set_started(step, this->state_mutex(), [this](){ this->throw_if_canceled(); }); } PrintStateBase::TimeStamp set_done(PrintStepEnum step) { std::pair status = m_state.set_done(step, this->state_mutex(), [this](){ this->throw_if_canceled(); }); - if (status.second) - this->status_update_warnings(this->id(), static_cast(step), PrintStateBase::WarningLevel::NON_CRITICAL, std::string()); - return status.first; + if (status.second) + this->status_update_warnings(this->id(), static_cast(step), PrintStateBase::WarningLevel::NON_CRITICAL, std::string()); + return status.first; } bool invalidate_step(PrintStepEnum step) { return m_state.invalidate(step, this->cancel_callback()); } @@ -556,9 +556,9 @@ protected: { return m_state.set_started(step, PrintObjectBase::state_mutex(m_print), [this](){ this->throw_if_canceled(); }); } PrintStateBase::TimeStamp set_done(PrintObjectStepEnum step) { std::pair status = m_state.set_done(step, PrintObjectBase::state_mutex(m_print), [this](){ this->throw_if_canceled(); }); - if (status.second) - this->status_update_warnings(m_print, static_cast(step), PrintStateBase::WarningLevel::NON_CRITICAL, std::string()); - return status.first; + if (status.second) + this->status_update_warnings(m_print, static_cast(step), PrintStateBase::WarningLevel::NON_CRITICAL, std::string()); + return status.first; } bool invalidate_step(PrintObjectStepEnum step) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 2c330b60e6..027611750a 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2841,7 +2841,7 @@ void Plater::priv::export_gcode(fs::path output_path, bool output_path_on_remova if ((state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) != 0) return; - show_warning_dialog = true; + show_warning_dialog = true; if (! output_path.empty()) { background_process.schedule_export(output_path.string(), output_path_on_removable_media); } else { @@ -4697,8 +4697,8 @@ void Plater::export_gcode(bool prefer_removable) if (p->model.objects.empty()) return; - if (p->process_completed_with_error)//here - return; + if (p->process_completed_with_error)//here + return; // If possible, remove accents from accented latin characters. // This function is useful for generating file names to be processed by legacy firmwares. From c29171790930a1a9f9b0374b6a5ab8ccec1e88a9 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 18 Aug 2020 15:17:26 +0200 Subject: [PATCH 203/255] Forbid translation of objects when SLA/Hollow/FDM gizmos are active --- src/slic3r/GUI/GLCanvas3D.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 9bed5fde7c..94f6f6ef32 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3658,6 +3658,13 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) { m_mouse.dragging = true; + // Translation of objects is forbidden when SLA supports/hollowing/fdm + // supports gizmo is active. + if (m_gizmos.get_current_type() == GLGizmosManager::SlaSupports + || m_gizmos.get_current_type() == GLGizmosManager::FdmSupports + || m_gizmos.get_current_type() == GLGizmosManager::Hollow) + return; + Vec3d cur_pos = m_mouse.drag.start_position_3D; // we do not want to translate objects if the user just clicked on an object while pressing shift to remove it from the selection and then drag if (m_selection.contains_volume(get_first_hover_volume_idx())) From 320964a68c0004a59972ba9ec841b0572ef783e4 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 18 Aug 2020 15:18:00 +0200 Subject: [PATCH 204/255] TriangleSelector paints continuously when dragging fast Previously there would be distinct circles with gaps in between --- src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp | 195 +++++++++++-------- src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp | 1 + 2 files changed, 110 insertions(+), 86 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index 309c7cf423..e5a648d11e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -314,106 +314,128 @@ bool GLGizmoFdmSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous const ModelInstance* mi = mo->instances[selection.get_instance_idx()]; const Transform3d& instance_trafo = mi->get_transformation().get_matrix(); - std::vector>> hit_positions_and_facet_ids; - bool clipped_mesh_was_hit = false; + // List of mouse positions that will be used as seeds for painting. + std::vector mouse_positions{mouse_position}; - Vec3f normal = Vec3f::Zero(); - Vec3f hit = Vec3f::Zero(); - size_t facet = 0; - Vec3f closest_hit = Vec3f::Zero(); - double closest_hit_squared_distance = std::numeric_limits::max(); - size_t closest_facet = 0; - int closest_hit_mesh_id = -1; + // In case current mouse position is far from the last one, + // add several positions from between into the list, so there + // are no gaps in the painted region. + { + if (m_last_mouse_position == Vec2d::Zero()) + m_last_mouse_position = mouse_position; + // resolution describes minimal distance limit using circle radius + // as a unit (e.g., 2 would mean the patches will be touching). + double resolution = 0.7; + double diameter_px = resolution * m_cursor_radius * camera.get_zoom(); + int patches_in_between = int(((mouse_position - m_last_mouse_position).norm() - diameter_px) / diameter_px); + if (patches_in_between > 0) { + Vec2d diff = (mouse_position - m_last_mouse_position)/(patches_in_between+1); + for (int i=1; i<=patches_in_between; ++i) + mouse_positions.emplace_back(m_last_mouse_position + i*diff); + } + } + m_last_mouse_position = Vec2d::Zero(); // only actual hits should be saved - // Transformations of individual meshes - std::vector trafo_matrices; + // Now "click" into all the prepared points and spill paint around them. + for (const Vec2d& mp : mouse_positions) { + std::vector>> hit_positions_and_facet_ids; + bool clipped_mesh_was_hit = false; - int mesh_id = -1; - // Cast a ray on all meshes, pick the closest hit and save it for the respective mesh - for (const ModelVolume* mv : mo->volumes) { - if (! mv->is_model_part()) - continue; + Vec3f normal = Vec3f::Zero(); + Vec3f hit = Vec3f::Zero(); + size_t facet = 0; + Vec3f closest_hit = Vec3f::Zero(); + double closest_hit_squared_distance = std::numeric_limits::max(); + size_t closest_facet = 0; + int closest_hit_mesh_id = -1; - ++mesh_id; + // Transformations of individual meshes + std::vector trafo_matrices; - trafo_matrices.push_back(instance_trafo * mv->get_matrix()); - hit_positions_and_facet_ids.push_back(std::vector>()); - - if (m_c->raycaster()->raycasters()[mesh_id]->unproject_on_mesh( - mouse_position, - trafo_matrices[mesh_id], - camera, - hit, - normal, - m_clipping_plane.get(), - &facet)) - { - // In case this hit is clipped, skip it. - if (is_mesh_point_clipped(hit.cast())) { - clipped_mesh_was_hit = true; + int mesh_id = -1; + // Cast a ray on all meshes, pick the closest hit and save it for the respective mesh + for (const ModelVolume* mv : mo->volumes) { + if (! mv->is_model_part()) continue; - } - // Is this hit the closest to the camera so far? - double hit_squared_distance = (camera.get_position()-trafo_matrices[mesh_id]*hit.cast()).squaredNorm(); - if (hit_squared_distance < closest_hit_squared_distance) { - closest_hit_squared_distance = hit_squared_distance; - closest_facet = facet; - closest_hit_mesh_id = mesh_id; - closest_hit = hit; + ++mesh_id; + + trafo_matrices.push_back(instance_trafo * mv->get_matrix()); + hit_positions_and_facet_ids.push_back(std::vector>()); + + if (m_c->raycaster()->raycasters()[mesh_id]->unproject_on_mesh( + mp, + trafo_matrices[mesh_id], + camera, + hit, + normal, + m_clipping_plane.get(), + &facet)) + { + // In case this hit is clipped, skip it. + if (is_mesh_point_clipped(hit.cast())) { + clipped_mesh_was_hit = true; + continue; + } + + // Is this hit the closest to the camera so far? + double hit_squared_distance = (camera.get_position()-trafo_matrices[mesh_id]*hit.cast()).squaredNorm(); + if (hit_squared_distance < closest_hit_squared_distance) { + closest_hit_squared_distance = hit_squared_distance; + closest_facet = facet; + closest_hit_mesh_id = mesh_id; + closest_hit = hit; + } } } - } - bool dragging_while_painting = (action == SLAGizmoEventType::Dragging && m_button_down != Button::None); + bool dragging_while_painting = (action == SLAGizmoEventType::Dragging && m_button_down != Button::None); - // The mouse button click detection is enabled when there is a valid hit - // or when the user clicks the clipping plane. Missing the object entirely - // shall not capture the mouse. - if (closest_hit_mesh_id != -1 || clipped_mesh_was_hit) { - if (m_button_down == Button::None) - m_button_down = ((action == SLAGizmoEventType::LeftDown) ? Button::Left : Button::Right); - } - - if (closest_hit_mesh_id == -1) { - // In case we have no valid hit, we can return. The event will - // be stopped in following two cases: - // 1. clicking the clipping plane - // 2. dragging while painting (to prevent scene rotations and moving the object) - return clipped_mesh_was_hit - || dragging_while_painting; - } - - // Find respective mesh id. - // FIXME We need a separate TriangleSelector for each volume mesh. - mesh_id = -1; - //const TriangleMesh* mesh = nullptr; - for (const ModelVolume* mv : mo->volumes) { - if (! mv->is_model_part()) - continue; - ++mesh_id; - if (mesh_id == closest_hit_mesh_id) { - //mesh = &mv->mesh(); - break; + // The mouse button click detection is enabled when there is a valid hit + // or when the user clicks the clipping plane. Missing the object entirely + // shall not capture the mouse. + if (closest_hit_mesh_id != -1 || clipped_mesh_was_hit) { + if (m_button_down == Button::None) + m_button_down = ((action == SLAGizmoEventType::LeftDown) ? Button::Left : Button::Right); } + + if (closest_hit_mesh_id == -1) { + // In case we have no valid hit, we can return. The event will + // be stopped in following two cases: + // 1. clicking the clipping plane + // 2. dragging while painting (to prevent scene rotations and moving the object) + return clipped_mesh_was_hit + || dragging_while_painting; + } + + // Find respective mesh id. + mesh_id = -1; + for (const ModelVolume* mv : mo->volumes) { + if (! mv->is_model_part()) + continue; + ++mesh_id; + if (mesh_id == closest_hit_mesh_id) + break; + } + + const Transform3d& trafo_matrix = trafo_matrices[mesh_id]; + + // Calculate how far can a point be from the line (in mesh coords). + // FIXME: The scaling of the mesh can be non-uniform. + const Vec3d sf = Geometry::Transformation(trafo_matrix).get_scaling_factor(); + const float avg_scaling = (sf(0) + sf(1) + sf(2))/3.; + const float limit = m_cursor_radius/avg_scaling; + + // Calculate direction from camera to the hit (in mesh coords): + Vec3f camera_pos = (trafo_matrix.inverse() * camera.get_position()).cast(); + Vec3f dir = (closest_hit - camera_pos).normalized(); + + assert(mesh_id < int(m_triangle_selectors.size())); + m_triangle_selectors[mesh_id]->select_patch(closest_hit, closest_facet, camera_pos, + dir, limit, new_state); + m_last_mouse_position = mouse_position; } - const Transform3d& trafo_matrix = trafo_matrices[mesh_id]; - - // Calculate how far can a point be from the line (in mesh coords). - // FIXME: The scaling of the mesh can be non-uniform. - const Vec3d sf = Geometry::Transformation(trafo_matrix).get_scaling_factor(); - const float avg_scaling = (sf(0) + sf(1) + sf(2))/3.; - const float limit = m_cursor_radius/avg_scaling; - - // Calculate direction from camera to the hit (in mesh coords): - Vec3f camera_pos = (trafo_matrix.inverse() * camera.get_position()).cast(); - Vec3f dir = (closest_hit - camera_pos).normalized(); - - assert(mesh_id < int(m_triangle_selectors.size())); - m_triangle_selectors[mesh_id]->select_patch(closest_hit, closest_facet, camera_pos, - dir, limit, new_state); - return true; } @@ -430,6 +452,7 @@ bool GLGizmoFdmSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous update_model_object(); m_button_down = Button::None; + m_last_mouse_position = Vec2d::Zero(); return true; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp index ce24ea8d28..350f7c8908 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp @@ -92,6 +92,7 @@ private: bool m_setting_angle = false; bool m_internal_stack_active = false; bool m_schedule_update = false; + Vec2d m_last_mouse_position = Vec2d::Zero(); // This map holds all translated description texts, so they can be easily referenced during layout calculations // etc. When language changes, GUI is recreated and this class constructed again, so the change takes effect. From 7a093b08fd12537a347cbafeabe8307c3a295d55 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 21 Aug 2020 10:59:07 +0200 Subject: [PATCH 205/255] GCodeViewer -> Show printbed model and texture for system printers detected when loading gcode files produced by PrusaSlicer --- src/libslic3r/GCode/GCodeProcessor.cpp | 4 ++++ src/libslic3r/GCode/GCodeProcessor.hpp | 1 + src/libslic3r/Preset.cpp | 20 ++++++++++++++++++++ src/libslic3r/Preset.hpp | 4 ++++ src/slic3r/GUI/3DBed.cpp | 7 +++++++ src/slic3r/GUI/GCodeViewer.cpp | 17 +++++++++++++++-- 6 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 5124e1a99d..54addbd979 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -541,6 +541,10 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config) if (bed_shape != nullptr) m_result.bed_shape = bed_shape->values; + const ConfigOptionString* printer_settings_id = config.option("printer_settings_id"); + if (printer_settings_id != nullptr) + m_result.printer_settings_id = printer_settings_id->value; + const ConfigOptionFloats* filament_diameters = config.option("filament_diameter"); if (filament_diameters != nullptr) { for (double diam : filament_diameters->values) { diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 90552e6582..22aeed7620 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -261,6 +261,7 @@ namespace Slic3r { unsigned int id; std::vector moves; Pointfs bed_shape; + std::string printer_settings_id; std::vector extruder_colors; PrintEstimatedTimeStatistics time_statistics; diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 7176ca81a4..a5160d2db3 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -1812,6 +1812,26 @@ namespace PresetUtils { } return out; } + +#if ENABLE_GCODE_VIEWER + std::string system_printer_bed_model(const Preset& preset) + { + std::string out; + const VendorProfile::PrinterModel* pm = PresetUtils::system_printer_model(preset); + if (pm != nullptr && !pm->bed_model.empty()) + out = Slic3r::resources_dir() + "/profiles/" + preset.vendor->id + "/" + pm->bed_model; + return out; + } + + std::string system_printer_bed_texture(const Preset& preset) + { + std::string out; + const VendorProfile::PrinterModel* pm = PresetUtils::system_printer_model(preset); + if (pm != nullptr && !pm->bed_texture.empty()) + out = Slic3r::resources_dir() + "/profiles/" + preset.vendor->id + "/" + pm->bed_texture; + return out; + } +#endif // ENABLE_GCODE_VIEWER } // namespace PresetUtils } // namespace Slic3r diff --git a/src/libslic3r/Preset.hpp b/src/libslic3r/Preset.hpp index e34fca4dd7..30edfc859a 100644 --- a/src/libslic3r/Preset.hpp +++ b/src/libslic3r/Preset.hpp @@ -527,6 +527,10 @@ public: namespace PresetUtils { // PrinterModel of a system profile, from which this preset is derived, or null if it is not derived from a system profile. const VendorProfile::PrinterModel* system_printer_model(const Preset &preset); +#if ENABLE_GCODE_VIEWER + std::string system_printer_bed_model(const Preset& preset); + std::string system_printer_bed_texture(const Preset& preset); +#endif // ENABLE_GCODE_VIEWER } // namespace PresetUtils diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index aa9bf38035..8a29d08bd8 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -414,6 +414,7 @@ void Bed3D::calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox) printf("Unable to create bed grid lines\n"); } +#if !ENABLE_GCODE_VIEWER static std::string system_print_bed_model(const Preset &preset) { std::string out; @@ -431,6 +432,7 @@ static std::string system_print_bed_texture(const Preset &preset) out = Slic3r::resources_dir() + "/profiles/" + preset.vendor->id + "/" + pm->bed_texture; return out; } +#endif // !ENABLE_GCODE_VIEWER std::tuple Bed3D::detect_type(const Pointfs& shape) const { @@ -440,8 +442,13 @@ std::tuple Bed3D::detect_type(const Poin while (curr != nullptr) { if (curr->config.has("bed_shape")) { if (shape == dynamic_cast(curr->config.option("bed_shape"))->values) { +#if ENABLE_GCODE_VIEWER + std::string model_filename = PresetUtils::system_printer_bed_model(*curr); + std::string texture_filename = PresetUtils::system_printer_bed_texture(*curr); +#else std::string model_filename = system_print_bed_model(*curr); std::string texture_filename = system_print_bed_texture(*curr); +#endif // ENABLE_GCODE_VIEWER if (!model_filename.empty() && !texture_filename.empty()) return { System, model_filename, texture_filename }; } diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index db126552f6..80a5e15ed5 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -335,9 +335,21 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& load_shells(print, initialized); else { Pointfs bed_shape; - if (!gcode_result.bed_shape.empty()) + std::string texture; + std::string model; + + if (!gcode_result.bed_shape.empty()) { // bed shape detected in the gcode bed_shape = gcode_result.bed_shape; + auto bundle = wxGetApp().preset_bundle; + if (bundle != nullptr && !gcode_result.printer_settings_id.empty()) { + const Preset* preset = bundle->printers.find_preset(gcode_result.printer_settings_id); + if (preset != nullptr) { + model = PresetUtils::system_printer_bed_model(*preset); + texture = PresetUtils::system_printer_bed_texture(*preset); + } + } + } else { // adjust printbed size in dependence of toolpaths bbox const double margin = 10.0; @@ -359,7 +371,8 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& { min(0) + 0.442265 * size[0], max(1)}, { min(0), max(1) } }; } - wxGetApp().plater()->set_bed_shape(bed_shape, "", "", true); + + wxGetApp().plater()->set_bed_shape(bed_shape, texture, model, gcode_result.bed_shape.empty()); } #if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE From 99a15af03d75c976264364d2ec25cb99948dc3c9 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 21 Aug 2020 11:36:08 +0200 Subject: [PATCH 206/255] GCodeViewer -> Allow to switch to gcode viewer state when an sla printer is selected --- src/slic3r/GUI/MainFrame.cpp | 16 ++++++++++++++-- src/slic3r/GUI/MainFrame.hpp | 1 + src/slic3r/GUI/Plater.cpp | 15 +++++++++++++++ src/slic3r/GUI/Plater.hpp | 4 ++++ 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 3f000e3328..ce8772eedc 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -434,6 +434,10 @@ void MainFrame::shutdown() // restore sidebar if it was hidden when switching to gcode viewer mode if (m_restore_from_gcode_viewer.collapsed_sidebar) m_plater->collapse_sidebar(false); + + // restore sla printer if it was deselected when switching to gcode viewer mode + if (m_restore_from_gcode_viewer.sla_technology) + m_plater->set_printer_technology(ptSLA); #endif // ENABLE_GCODE_VIEWER // Stop the background thread (Windows and Linux). // Disconnect from a 3DConnextion driver (OSX). @@ -1010,8 +1014,7 @@ void MainFrame::init_menubar() wxMessageDialog((wxWindow*)this, _L("Switching to G-code preview mode will remove all objects, continue?"), wxString(SLIC3R_APP_NAME) + " - " + _L("Switch to G-code preview mode"), wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION | wxCENTRE).ShowModal() == wxID_YES) set_mode(EMode::GCodeViewer); - }, "", nullptr, - [this]() { return m_plater != nullptr && m_plater->printer_technology() != ptSLA; }, this); + }, "", nullptr); #endif // ENABLE_GCODE_VIEWER fileMenu->AppendSeparator(); append_menu_item(fileMenu, wxID_EXIT, _L("&Quit"), wxString::Format(_L("Quit %s"), SLIC3R_APP_NAME), @@ -1329,6 +1332,12 @@ void MainFrame::set_mode(EMode mode) m_plater->clear_undo_redo_stack_main(); m_plater->take_snapshot(_L("New Project")); + // restore sla printer if it was deselected when switching to gcode viewer mode + if (m_restore_from_gcode_viewer.sla_technology) { + m_plater->set_printer_technology(ptSLA); + m_restore_from_gcode_viewer.sla_technology = false; + } + // switch view m_plater->select_view_3D("3D"); m_plater->select_view("iso"); @@ -1371,6 +1380,9 @@ void MainFrame::set_mode(EMode mode) m_plater->clear_undo_redo_stack_main(); m_plater->take_snapshot(_L("New Project")); + // switch to FFF printer mode + m_restore_from_gcode_viewer.sla_technology = m_plater->set_printer_technology(ptFFF); + // switch view m_plater->select_view_3D("Preview"); m_plater->select_view("iso"); diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index 8961ad7172..53d8488768 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -76,6 +76,7 @@ class MainFrame : public DPIFrame { bool collapsed_sidebar{ false }; bool collapse_toolbar_enabled{ false }; + bool sla_technology{ false }; }; RestoreFromGCodeViewer m_restore_from_gcode_viewer; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 97372b2474..1fe32fd2dc 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -5596,12 +5596,23 @@ PrinterTechnology Plater::printer_technology() const const DynamicPrintConfig * Plater::config() const { return p->config; } +#if ENABLE_GCODE_VIEWER +bool Plater::set_printer_technology(PrinterTechnology printer_technology) +#else void Plater::set_printer_technology(PrinterTechnology printer_technology) +#endif // ENABLE_GCODE_VIEWER { p->printer_technology = printer_technology; +#if ENABLE_GCODE_VIEWER + bool ret = p->background_process.select_technology(printer_technology); + if (ret) { + // Update the active presets. + } +#else if (p->background_process.select_technology(printer_technology)) { // Update the active presets. } +#endif // ENABLE_GCODE_VIEWER //FIXME for SLA synchronize //p->background_process.apply(Model)! @@ -5618,6 +5629,10 @@ void Plater::set_printer_technology(PrinterTechnology printer_technology) p->update_main_toolbar_tooltips(); p->sidebar->get_searcher().set_printer_technology(printer_technology); + +#if ENABLE_GCODE_VIEWER + return ret; +#endif // ENABLE_GCODE_VIEWER } void Plater::changed_object(int obj_idx) diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 9c1270bcec..cc80186202 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -263,7 +263,11 @@ public: PrinterTechnology printer_technology() const; const DynamicPrintConfig * config() const; +#if ENABLE_GCODE_VIEWER + bool set_printer_technology(PrinterTechnology printer_technology); +#else void set_printer_technology(PrinterTechnology printer_technology); +#endif // ENABLE_GCODE_VIEWER void copy_selection_to_clipboard(); void paste_from_clipboard(); From 5ff6f3045edf5e488312344c064c822afe868fcc Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 21 Aug 2020 11:50:05 +0200 Subject: [PATCH 207/255] ENABLE_GCODE_VIEWER -> KBShortcutsDialog shows only related tabs when gcode viewer state is active --- src/slic3r/GUI/KBShortcutsDialog.cpp | 197 +++++++++++++-------------- src/slic3r/GUI/KBShortcutsDialog.hpp | 4 - 2 files changed, 98 insertions(+), 103 deletions(-) diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index 2d4b65a987..1a551216e7 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -7,6 +7,9 @@ #include #include "GUI_App.hpp" #include "wxExtensions.hpp" +#if ENABLE_GCODE_VIEWER +#include "MainFrame.hpp" +#endif // ENABLE_GCODE_VIEWER #define NOTEBOOK_TOP 1 #define NOTEBOOK_LEFT 2 @@ -31,11 +34,7 @@ namespace GUI { KBShortcutsDialog::KBShortcutsDialog() : DPIDialog(NULL, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _L("Keyboard Shortcuts"), -#if ENABLE_SCROLLABLE wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) -#else - wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE) -#endif // ENABLE_SCROLLABLE { SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); @@ -66,13 +65,9 @@ main_sizer->Add(book, 1, wxEXPAND | wxALL, 10); fill_shortcuts(); for (size_t i = 0; i < m_full_shortcuts.size(); ++i) { -#if ENABLE_SCROLLABLE wxPanel* page = create_page(book, m_full_shortcuts[i], font, bold_font); m_pages.push_back(page); book->AddPage(page, m_full_shortcuts[i].first, i == 0); -#else - book->AddPage(create_page(book, m_full_shortcuts[i], font, bold_font), m_full_shortcuts[i].first, i == 0); -#endif // ENABLE_SCROLLABLE } wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxOK); @@ -99,104 +94,112 @@ void KBShortcutsDialog::fill_shortcuts() const std::string& ctrl = GUI::shortkey_ctrl_prefix(); const std::string& alt = GUI::shortkey_alt_prefix(); - Shortcuts commands_shortcuts = { - // File - { ctrl + "N", L("New project, clear plater") }, - { ctrl + "O", L("Open project STL/OBJ/AMF/3MF with config, clear plater") }, - { ctrl + "S", L("Save project (3mf)") }, - { ctrl + alt + "S", L("Save project as (3mf)") }, - { ctrl + "R", L("(Re)slice") }, - // File>Import - { ctrl + "I", L("Import STL/OBJ/AMF/3MF without config, keep plater") }, - { ctrl + "L", L("Import Config from ini/amf/3mf/gcode") }, - { ctrl + alt + "L", L("Load Config from ini/amf/3mf/gcode and merge") }, - // File>Export - { ctrl + "G", L("Export G-code") }, - { ctrl + "Shift+" + "G", L("Send G-code") }, - { ctrl + "E", L("Export config") }, - { ctrl + "U", L("Export to SD card / Flash drive") }, - { ctrl + "T", L("Eject SD card / Flash drive") }, - // Edit - { ctrl + "A", L("Select all objects") }, - { "Esc", L("Deselect all") }, - { "Del", L("Delete selected") }, - { ctrl + "Del", L("Delete all") }, - { ctrl + "Z", L("Undo") }, - { ctrl + "Y", L("Redo") }, - { ctrl + "C", L("Copy to clipboard") }, - { ctrl + "V", L("Paste from clipboard") }, - { "F5", L("Reload plater from disk") }, - { ctrl + "F", L("Search") }, - // Window - { ctrl + "1", L("Select Plater Tab") }, - { ctrl + "2", L("Select Print Settings Tab") }, - { ctrl + "3", L("Select Filament Settings Tab") }, - { ctrl + "4", L("Select Printer Settings Tab") }, - { ctrl + "5", L("Switch to 3D") }, - { ctrl + "6", L("Switch to Preview") }, - { ctrl + "J", L("Print host upload queue") }, - // View - { "0-6", L("Camera view") }, - { "E", L("Show/Hide object/instance labels") }, +#if ENABLE_GCODE_VIEWER + bool is_gcode_viewer = wxGetApp().mainframe->get_mode() == MainFrame::EMode::GCodeViewer; + + if (!is_gcode_viewer) { +#endif // ENABLE_GCODE_VIEWER + Shortcuts commands_shortcuts = { + // File + { ctrl + "N", L("New project, clear plater") }, + { ctrl + "O", L("Open project STL/OBJ/AMF/3MF with config, clear plater") }, + { ctrl + "S", L("Save project (3mf)") }, + { ctrl + alt + "S", L("Save project as (3mf)") }, + { ctrl + "R", L("(Re)slice") }, + // File>Import + { ctrl + "I", L("Import STL/OBJ/AMF/3MF without config, keep plater") }, + { ctrl + "L", L("Import Config from ini/amf/3mf/gcode") }, + { ctrl + alt + "L", L("Load Config from ini/amf/3mf/gcode and merge") }, + // File>Export + { ctrl + "G", L("Export G-code") }, + { ctrl + "Shift+" + "G", L("Send G-code") }, + { ctrl + "E", L("Export config") }, + { ctrl + "U", L("Export to SD card / Flash drive") }, + { ctrl + "T", L("Eject SD card / Flash drive") }, + // Edit + { ctrl + "A", L("Select all objects") }, + { "Esc", L("Deselect all") }, + { "Del", L("Delete selected") }, + { ctrl + "Del", L("Delete all") }, + { ctrl + "Z", L("Undo") }, + { ctrl + "Y", L("Redo") }, + { ctrl + "C", L("Copy to clipboard") }, + { ctrl + "V", L("Paste from clipboard") }, + { "F5", L("Reload plater from disk") }, + { ctrl + "F", L("Search") }, + // Window + { ctrl + "1", L("Select Plater Tab") }, + { ctrl + "2", L("Select Print Settings Tab") }, + { ctrl + "3", L("Select Filament Settings Tab") }, + { ctrl + "4", L("Select Printer Settings Tab") }, + { ctrl + "5", L("Switch to 3D") }, + { ctrl + "6", L("Switch to Preview") }, + { ctrl + "J", L("Print host upload queue") }, + // View + { "0-6", L("Camera view") }, + { "E", L("Show/Hide object/instance labels") }, #if ENABLE_SLOPE_RENDERING - { "D", L("Turn On/Off facets' slope rendering") }, + { "D", L("Turn On/Off facets' slope rendering") }, #endif // ENABLE_SLOPE_RENDERING - // Configuration - { ctrl + "P", L("Preferences") }, - // Help - { "?", L("Show keyboard shortcuts list") } - }; + // Configuration + { ctrl + "P", L("Preferences") }, + // Help + { "?", L("Show keyboard shortcuts list") } + }; - m_full_shortcuts.push_back(std::make_pair(_L("Commands"), commands_shortcuts)); + m_full_shortcuts.push_back(std::make_pair(_L("Commands"), commands_shortcuts)); - Shortcuts plater_shortcuts = { - { "A", L("Arrange") }, - { "Shift+A", L("Arrange selection") }, - { "+", L("Add Instance of the selected object") }, - { "-", L("Remove Instance of the selected object") }, - { ctrl, L("Press to select multiple objects\nor move multiple objects with mouse") }, - { "Shift+", L("Press to activate selection rectangle") }, - { alt, L("Press to activate deselection rectangle") }, - { L("Arrow Up"), L("Move selection 10 mm in positive Y direction") }, - { L("Arrow Down"), L("Move selection 10 mm in negative Y direction") }, - { L("Arrow Left"), L("Move selection 10 mm in negative X direction") }, - { L("Arrow Right"), L("Move selection 10 mm in positive X direction") }, - { std::string("Shift+") + L("Any arrow"), L("Movement step set to 1 mm") }, - { ctrl + L("Any arrow"), L("Movement in camera space") }, - { L("Page Up"), L("Rotate selection 45 degrees CCW") }, - { L("Page Down"), L("Rotate selection 45 degrees CW") }, - { "M", L("Gizmo move") }, - { "S", L("Gizmo scale") }, - { "R", L("Gizmo rotate") }, - { "C", L("Gizmo cut") }, - { "F", L("Gizmo Place face on bed") }, - { "H", L("Gizmo SLA hollow") }, - { "L", L("Gizmo SLA support points") }, - { "Esc", L("Unselect gizmo or clear selection") }, - { "K", L("Change camera type (perspective, orthographic)") }, - { "B", L("Zoom to Bed") }, - { "Z", L("Zoom to selected object\nor all objects in scene, if none selected") }, - { "I", L("Zoom in") }, - { "O", L("Zoom out") }, + Shortcuts plater_shortcuts = { + { "A", L("Arrange") }, + { "Shift+A", L("Arrange selection") }, + { "+", L("Add Instance of the selected object") }, + { "-", L("Remove Instance of the selected object") }, + { ctrl, L("Press to select multiple objects\nor move multiple objects with mouse") }, + { "Shift+", L("Press to activate selection rectangle") }, + { alt, L("Press to activate deselection rectangle") }, + { L("Arrow Up"), L("Move selection 10 mm in positive Y direction") }, + { L("Arrow Down"), L("Move selection 10 mm in negative Y direction") }, + { L("Arrow Left"), L("Move selection 10 mm in negative X direction") }, + { L("Arrow Right"), L("Move selection 10 mm in positive X direction") }, + { std::string("Shift+") + L("Any arrow"), L("Movement step set to 1 mm") }, + { ctrl + L("Any arrow"), L("Movement in camera space") }, + { L("Page Up"), L("Rotate selection 45 degrees CCW") }, + { L("Page Down"), L("Rotate selection 45 degrees CW") }, + { "M", L("Gizmo move") }, + { "S", L("Gizmo scale") }, + { "R", L("Gizmo rotate") }, + { "C", L("Gizmo cut") }, + { "F", L("Gizmo Place face on bed") }, + { "H", L("Gizmo SLA hollow") }, + { "L", L("Gizmo SLA support points") }, + { "Esc", L("Unselect gizmo or clear selection") }, + { "K", L("Change camera type (perspective, orthographic)") }, + { "B", L("Zoom to Bed") }, + { "Z", L("Zoom to selected object\nor all objects in scene, if none selected") }, + { "I", L("Zoom in") }, + { "O", L("Zoom out") }, #ifdef __linux__ - { ctrl + "M", L("Show/Hide 3Dconnexion devices settings dialog") }, + { ctrl + "M", L("Show/Hide 3Dconnexion devices settings dialog") }, #endif // __linux__ #if ENABLE_RENDER_PICKING_PASS - // Don't localize debugging texts. - { "P", "Toggle picking pass texture rendering on/off" }, + // Don't localize debugging texts. + { "P", "Toggle picking pass texture rendering on/off" }, #endif // ENABLE_RENDER_PICKING_PASS - }; + }; - m_full_shortcuts.push_back(std::make_pair(_L("Plater"), plater_shortcuts)); + m_full_shortcuts.push_back(std::make_pair(_L("Plater"), plater_shortcuts)); - Shortcuts gizmos_shortcuts = { - { "Shift+", L("Press to snap by 5% in Gizmo scale\nor to snap by 1mm in Gizmo move") }, - { "F", L("Scale selection to fit print volume\nin Gizmo scale") }, - { ctrl, L("Press to activate one direction scaling in Gizmo scale") }, - { alt, L("Press to scale (in Gizmo scale) or rotate (in Gizmo rotate)\nselected objects around their own center") }, - }; + Shortcuts gizmos_shortcuts = { + { "Shift+", L("Press to snap by 5% in Gizmo scale\nor to snap by 1mm in Gizmo move") }, + { "F", L("Scale selection to fit print volume\nin Gizmo scale") }, + { ctrl, L("Press to activate one direction scaling in Gizmo scale") }, + { alt, L("Press to scale (in Gizmo scale) or rotate (in Gizmo rotate)\nselected objects around their own center") }, + }; - m_full_shortcuts.push_back(std::make_pair(_L("Gizmos"), gizmos_shortcuts)); + m_full_shortcuts.push_back(std::make_pair(_L("Gizmos"), gizmos_shortcuts)); +#if ENABLE_GCODE_VIEWER + } +#endif // ENABLE_GCODE_VIEWER Shortcuts preview_shortcuts = { { L("Arrow Up"), L("Upper Layer") }, @@ -277,13 +280,9 @@ wxPanel* KBShortcutsDialog::create_page(wxWindow* parent, const std::pairSetScrollbars(20, 20, 50, 50); page->SetInitialSize(wxSize(850, 450)); -#else - wxPanel* page = new wxPanel(parent); -#endif // ENABLE_SCROLLABLE #if (BOOK_TYPE == LISTBOOK_TOP) || (BOOK_TYPE == LISTBOOK_LEFT) wxStaticBoxSizer* sizer = new wxStaticBoxSizer(wxVERTICAL, page, " " + shortcuts.first + " "); diff --git a/src/slic3r/GUI/KBShortcutsDialog.hpp b/src/slic3r/GUI/KBShortcutsDialog.hpp index 70820ae774..a8ec4e4267 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.hpp +++ b/src/slic3r/GUI/KBShortcutsDialog.hpp @@ -8,8 +8,6 @@ #include "GUI_Utils.hpp" #include "wxExtensions.hpp" -#define ENABLE_SCROLLABLE 1 - namespace Slic3r { namespace GUI { @@ -22,9 +20,7 @@ class KBShortcutsDialog : public DPIDialog ShortcutsVec m_full_shortcuts; ScalableBitmap m_logo_bmp; wxStaticBitmap* m_header_bitmap; -#if ENABLE_SCROLLABLE std::vector m_pages; -#endif // ENABLE_SCROLLABLE public: KBShortcutsDialog(); From a95509ce36a125086b64ad56f2debc7cd3e82837 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 19 Aug 2020 15:24:55 +0200 Subject: [PATCH 208/255] Changed internal coordinates of drain holes Drain holes reference position was saved slightly above the mesh to avoid problem when the hole is placed on flat or nearly flat surface The depth of the hole was internally bigger than what the user has set to compensato for it However, this leads to problem with scaling and makes reprojection of the holes on the mesh complicated This commit changes the reference point to the point on the mesh and the extra elevation is handled when rendering and drilling the hole. The change is reflected in 3MF drain holes versioning so that old 3MFs are loaded correctly. Reprojection on the mesh after reload from disk/fix through netfabb has been enabled. --- src/libslic3r/Format/3mf.cpp | 12 ++++++++++- src/libslic3r/Format/3mf.hpp | 11 ++++++++-- src/libslic3r/SLA/Hollowing.hpp | 2 ++ src/libslic3r/SLA/ReprojectPointsOnMesh.hpp | 14 ++++--------- src/libslic3r/SLAPrint.cpp | 6 ++++++ src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp | 21 +++++++------------- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 8 ++++---- src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp | 2 -- 8 files changed, 43 insertions(+), 33 deletions(-) diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index 59dc85a0ae..c25b7b96a5 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -1103,7 +1103,7 @@ namespace Slic3r { sla::DrainHoles sla_drain_holes; - if (version == 1) { + if (version == 1 || version == 2) { for (unsigned int i=0; i; +constexpr float HoleStickOutLength = 1.f; + std::unique_ptr generate_interior(const TriangleMesh &mesh, const HollowingConfig & = {}, const JobController &ctl = {}); diff --git a/src/libslic3r/SLA/ReprojectPointsOnMesh.hpp b/src/libslic3r/SLA/ReprojectPointsOnMesh.hpp index 4737a6c212..20804193e2 100644 --- a/src/libslic3r/SLA/ReprojectPointsOnMesh.hpp +++ b/src/libslic3r/SLA/ReprojectPointsOnMesh.hpp @@ -28,15 +28,9 @@ void reproject_support_points(const IndexedMesh &mesh, std::vector &p inline void reproject_points_and_holes(ModelObject *object) { bool has_sppoints = !object->sla_support_points.empty(); + bool has_holes = !object->sla_drain_holes.empty(); - // Disabling reprojection of holes as they have a significant offset away - // from the model body which tolerates minor geometrical changes. - // - // TODO: uncomment and ensure the right offset of the hole points if - // reprojection would still be necessary. - // bool has_holes = !object->sla_drain_holes.empty(); - - if (!object || (/*!has_holes &&*/ !has_sppoints)) return; + if (!object || (!has_holes && !has_sppoints)) return; TriangleMesh rmsh = object->raw_mesh(); rmsh.require_shared_vertices(); @@ -45,8 +39,8 @@ inline void reproject_points_and_holes(ModelObject *object) if (has_sppoints) reproject_support_points(emesh, object->sla_support_points); -// if (has_holes) -// reproject_support_points(emesh, object->sla_drain_holes); + if (has_holes) + reproject_support_points(emesh, object->sla_drain_holes); } }} diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 4395bea461..07ec380160 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -1181,6 +1181,12 @@ sla::DrainHoles SLAPrintObject::transformed_drainhole_points() const hl.normal = Vec3f(hl.normal(0)/(sc(0)*sc(0)), hl.normal(1)/(sc(1)*sc(1)), hl.normal(2)/(sc(2)*sc(2))); + + // Now shift the hole a bit above the object and make it deeper to + // compensate for it. This is to avoid problems when the hole is placed + // on (nearly) flat surface. + hl.pos -= hl.normal.normalized() * sla::HoleStickOutLength; + hl.height += sla::HoleStickOutLength; } return pts; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index 273384da2e..04ada52536 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -130,7 +130,7 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons const sla::DrainHole& drain_hole = drain_holes[i]; const bool& point_selected = m_selected[i]; - if (is_mesh_point_clipped((drain_hole.pos+HoleStickOutLength*drain_hole.normal).cast())) + if (is_mesh_point_clipped(drain_hole.pos.cast())) continue; // First decide about the color of the point. @@ -174,10 +174,10 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis()(0), aa.axis()(1), aa.axis()(2))); glsafe(::glPushMatrix()); glsafe(::glTranslated(0., 0., -drain_hole.height)); - ::gluCylinder(m_quadric, drain_hole.radius, drain_hole.radius, drain_hole.height, 24, 1); - glsafe(::glTranslated(0., 0., drain_hole.height)); + ::gluCylinder(m_quadric, drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength, 24, 1); + glsafe(::glTranslated(0., 0., drain_hole.height + sla::HoleStickOutLength)); ::gluDisk(m_quadric, 0.0, drain_hole.radius, 24, 1); - glsafe(::glTranslated(0., 0., -drain_hole.height)); + glsafe(::glTranslated(0., 0., -drain_hole.height - sla::HoleStickOutLength)); glsafe(::glRotatef(180.f, 1.f, 0.f, 0.f)); ::gluDisk(m_quadric, 0.0, drain_hole.radius, 24, 1); glsafe(::glPopMatrix()); @@ -307,13 +307,8 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos if (unproject_on_mesh(mouse_position, pos_and_normal)) { // we got an intersection Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Add drainage hole"))); - Vec3d scaling = mo->instances[active_inst]->get_scaling_factor(); - Vec3f normal_transformed(pos_and_normal.second(0)/scaling(0), - pos_and_normal.second(1)/scaling(1), - pos_and_normal.second(2)/scaling(2)); - - mo->sla_drain_holes.emplace_back(pos_and_normal.first + HoleStickOutLength * pos_and_normal.second/* normal_transformed.normalized()*/, - -pos_and_normal.second, m_new_hole_radius, m_new_hole_height); + mo->sla_drain_holes.emplace_back(pos_and_normal.first, + -pos_and_normal.second, m_new_hole_radius, m_new_hole_height); m_selected.push_back(false); assert(m_selected.size() == mo->sla_drain_holes.size()); m_parent.set_as_dirty(); @@ -447,7 +442,7 @@ void GLGizmoHollow::on_update(const UpdateData& data) std::pair pos_and_normal; if (! unproject_on_mesh(data.mouse_pos.cast(), pos_and_normal)) return; - drain_holes[m_hover_id].pos = pos_and_normal.first + HoleStickOutLength * pos_and_normal.second; + drain_holes[m_hover_id].pos = pos_and_normal.first; drain_holes[m_hover_id].normal = -pos_and_normal.second; } } @@ -661,9 +656,7 @@ RENDER_AGAIN: m_imgui->text(m_desc["hole_depth"]); ImGui::SameLine(diameter_slider_left); - m_new_hole_height -= HoleStickOutLength; ImGui::SliderFloat(" ", &m_new_hole_height, 0.f, 10.f, "%.1f mm"); - m_new_hole_height += HoleStickOutLength; clicked |= ImGui::IsItemClicked(); edited |= ImGui::IsItemEdited(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 2856bb35de..bc29da6d2b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -222,7 +222,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) render_color[3] = 0.7f; glsafe(::glColor4fv(render_color)); for (const sla::DrainHole& drain_hole : m_c->selection_info()->model_object()->sla_drain_holes) { - if (is_mesh_point_clipped((drain_hole.pos+HoleStickOutLength*drain_hole.normal).cast())) + if (is_mesh_point_clipped(drain_hole.pos.cast())) continue; // Inverse matrix of the instance scaling is applied so that the mark does not scale with the object. @@ -241,10 +241,10 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis()(0), aa.axis()(1), aa.axis()(2))); glsafe(::glPushMatrix()); glsafe(::glTranslated(0., 0., -drain_hole.height)); - ::gluCylinder(m_quadric, drain_hole.radius, drain_hole.radius, drain_hole.height, 24, 1); - glsafe(::glTranslated(0., 0., drain_hole.height)); + ::gluCylinder(m_quadric, drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength, 24, 1); + glsafe(::glTranslated(0., 0., drain_hole.height + sla::HoleStickOutLength)); ::gluDisk(m_quadric, 0.0, drain_hole.radius, 24, 1); - glsafe(::glTranslated(0., 0., -drain_hole.height)); + glsafe(::glTranslated(0., 0., -drain_hole.height - sla::HoleStickOutLength)); glsafe(::glRotatef(180.f, 1.f, 0.f, 0.f)); ::gluDisk(m_quadric, 0.0, drain_hole.radius, 24, 1); glsafe(::glPopMatrix()); diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp index 31c473bac7..aedf782e89 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp @@ -15,8 +15,6 @@ namespace GUI { class GLCanvas3D; -static constexpr float HoleStickOutLength = 1.f; - enum class SLAGizmoEventType : unsigned char { LeftDown = 1, LeftUp, From c51a45ee0f8c08cbee0d874d81da3ba5d42d9cea Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Mon, 24 Aug 2020 08:04:16 +0200 Subject: [PATCH 209/255] Drainholes are saved elevated for 3MF compatibility This is a follow-up of previous commit --- src/libslic3r/Format/3mf.cpp | 30 ++++++++++++++++++++---------- src/libslic3r/Format/3mf.hpp | 9 +-------- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index c25b7b96a5..52a3335ee4 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -1103,7 +1103,7 @@ namespace Slic3r { sla::DrainHoles sla_drain_holes; - if (version == 1 || version == 2) { + if (version == 1) { for (unsigned int i=0; isla_drain_holes; + sla::DrainHoles drain_holes = object->sla_drain_holes; + + // The holes were placed 1mm above the mesh in the first implementation. + // This was a bad idea and the reference point was changed in 2.3 so + // to be on the mesh exactly. The elevated position is still saved + // in 3MFs for compatibility reasons. + for (sla::DrainHole& hole : drain_holes) { + hole.pos -= hole.normal.normalized(); + hole.height += 1.f; + } + + if (!drain_holes.empty()) { out += string_printf(fmt, count); diff --git a/src/libslic3r/Format/3mf.hpp b/src/libslic3r/Format/3mf.hpp index 02e2bd1d3c..ccfd9356d8 100644 --- a/src/libslic3r/Format/3mf.hpp +++ b/src/libslic3r/Format/3mf.hpp @@ -20,15 +20,8 @@ namespace Slic3r { support_points_format_version = 1 }; - - /* The same for holes. - - * version 0: undefined - * version 1: holes saved a bit above the mesh and deeper - * version 2: holes are saved on the mesh exactly - */ enum { - drain_holes_format_version = 2 + drain_holes_format_version = 1 }; class Model; From ac8a6fccbe6e649bb55452d1e5859a2029257678 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 25 Aug 2020 08:12:28 +0200 Subject: [PATCH 210/255] Renamed shaders --- .../{options_120_flat.fs => options_120.fs} | 0 .../{options_120_flat.vs => options_120.vs} | 0 .../{toolpaths.fs => toolpaths_lines.fs} | 0 .../{toolpaths.vs => toolpaths_lines.vs} | 0 src/slic3r/GUI/GCodeViewer.cpp | 25 +++++++++---------- src/slic3r/GUI/GCodeViewer.hpp | 2 +- src/slic3r/GUI/GLShadersManager.cpp | 4 +-- 7 files changed, 15 insertions(+), 16 deletions(-) rename resources/shaders/{options_120_flat.fs => options_120.fs} (100%) rename resources/shaders/{options_120_flat.vs => options_120.vs} (100%) rename resources/shaders/{toolpaths.fs => toolpaths_lines.fs} (100%) rename resources/shaders/{toolpaths.vs => toolpaths_lines.vs} (100%) diff --git a/resources/shaders/options_120_flat.fs b/resources/shaders/options_120.fs similarity index 100% rename from resources/shaders/options_120_flat.fs rename to resources/shaders/options_120.fs diff --git a/resources/shaders/options_120_flat.vs b/resources/shaders/options_120.vs similarity index 100% rename from resources/shaders/options_120_flat.vs rename to resources/shaders/options_120.vs diff --git a/resources/shaders/toolpaths.fs b/resources/shaders/toolpaths_lines.fs similarity index 100% rename from resources/shaders/toolpaths.fs rename to resources/shaders/toolpaths_lines.fs diff --git a/resources/shaders/toolpaths.vs b/resources/shaders/toolpaths_lines.vs similarity index 100% rename from resources/shaders/toolpaths.vs rename to resources/shaders/toolpaths_lines.vs diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 80a5e15ed5..bcb4a0a268 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -606,8 +606,7 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const fprintf(fp, "# Generated by %s based on Slic3r\n", SLIC3R_BUILD_ID); unsigned int colors_count = 1; - for (const Color& color : colors) - { + for (const Color& color : colors) { fprintf(fp, "\nnewmtl material_%d\n", colors_count++); fprintf(fp, "Ka 1 1 1\n"); fprintf(fp, "Kd %f %f %f\n", color[0], color[1], color[2]); @@ -858,14 +857,14 @@ void GCodeViewer::init_shaders() for (unsigned char i = begin_id; i < end_id; ++i) { switch (buffer_type(i)) { - case EMoveType::Tool_change: { m_buffers[i].shader = is_glsl_120 ? "options_120_flat" : "options_110"; break; } - case EMoveType::Color_change: { m_buffers[i].shader = is_glsl_120 ? "options_120_flat" : "options_110"; break; } - case EMoveType::Pause_Print: { m_buffers[i].shader = is_glsl_120 ? "options_120_flat" : "options_110"; break; } - case EMoveType::Custom_GCode: { m_buffers[i].shader = is_glsl_120 ? "options_120_flat" : "options_110"; break; } - case EMoveType::Retract: { m_buffers[i].shader = is_glsl_120 ? "options_120_flat" : "options_110"; break; } - case EMoveType::Unretract: { m_buffers[i].shader = is_glsl_120 ? "options_120_flat" : "options_110"; break; } - case EMoveType::Extrude: { m_buffers[i].shader = "toolpaths"; break; } - case EMoveType::Travel: { m_buffers[i].shader = "toolpaths"; break; } + case EMoveType::Tool_change: { m_buffers[i].shader = is_glsl_120 ? "options_120" : "options_110"; break; } + case EMoveType::Color_change: { m_buffers[i].shader = is_glsl_120 ? "options_120" : "options_110"; break; } + case EMoveType::Pause_Print: { m_buffers[i].shader = is_glsl_120 ? "options_120" : "options_110"; break; } + case EMoveType::Custom_GCode: { m_buffers[i].shader = is_glsl_120 ? "options_120" : "options_110"; break; } + case EMoveType::Retract: { m_buffers[i].shader = is_glsl_120 ? "options_120" : "options_110"; break; } + case EMoveType::Unretract: { m_buffers[i].shader = is_glsl_120 ? "options_120" : "options_110"; break; } + case EMoveType::Extrude: { m_buffers[i].shader = "toolpaths_lines"; break; } + case EMoveType::Travel: { m_buffers[i].shader = "toolpaths_lines"; break; } default: { break; } } } @@ -1463,8 +1462,8 @@ void GCodeViewer::render_legend() const else draw_list->AddCircleFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); #else - ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size)); - if (m_buffers[buffer_id(EMoveType::Retract)].shader == "options_120_flat") { + ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size)); + if (m_buffers[buffer_id(EMoveType::Retract)].shader == "options_120") { draw_list->AddCircleFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); float radius = 0.5f * icon_size; @@ -2527,7 +2526,7 @@ void GCodeViewer::render_shaders_editor() const switch (m_shaders_editor.points.shader_version) { case 0: { set_shader("options_110"); break; } - case 1: { set_shader("options_120_flat"); break; } + case 1: { set_shader("options_120"); break; } } if (ImGui::TreeNode("Options")) { diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 0be17f790a..e6c3e26eaa 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -65,7 +65,7 @@ class GCodeViewer void reset(); }; - // ibo buffer containing indices data (triangles) used to render a specific toolpath type + // ibo buffer containing indices data (lines/triangles) used to render a specific toolpath type struct IBuffer { // ibo id diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index 5f726d4ef1..6baf46f6b4 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -36,9 +36,9 @@ std::pair GLShadersManager::init() // used to render options in gcode preview valid &= append_shader("options_110", { "options_110.vs", "options_110.fs" }); if (GUI::wxGetApp().is_glsl_version_greater_or_equal_to(1, 20)) - valid &= append_shader("options_120_flat", { "options_120_flat.vs", "options_120_flat.fs" }); + valid &= append_shader("options_120", { "options_120.vs", "options_120.fs" }); // used to render extrusion and travel paths in gcode preview - valid &= append_shader("toolpaths", { "toolpaths.vs", "toolpaths.fs" }); + valid &= append_shader("toolpaths_lines", { "toolpaths_lines.vs", "toolpaths_lines.fs" }); // used to render objects in 3d editor valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" }); // used to render variable layers heights in 3d editor From 2783653369fd080b2b585d02525a905eee524432 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 26 Aug 2020 13:01:54 +0200 Subject: [PATCH 211/255] Added icon for gcode viewer mode --- .../icons/PrusaSlicerGCodeViewer_128px.png | Bin 0 -> 15949 bytes src/slic3r/GUI/MainFrame.cpp | 48 +++++++++++------- 2 files changed, 29 insertions(+), 19 deletions(-) create mode 100644 resources/icons/PrusaSlicerGCodeViewer_128px.png diff --git a/resources/icons/PrusaSlicerGCodeViewer_128px.png b/resources/icons/PrusaSlicerGCodeViewer_128px.png new file mode 100644 index 0000000000000000000000000000000000000000..0bf85abbd6ea0585d127686a8200b4a647a030b8 GIT binary patch literal 15949 zcmeHuby$?$_V&;%jWk1d4c#$Fmy{sQ%n;HrbR(cB0s=~Ri6|l6DI!Rhgi_K1LnuRk zgYSFZ^PclN@ty1Xe&1h*>l&En+4s8F-fORY@3o&9V)b>^i12Cg0RRAzhPsLY>TmeX z3l|&pyGP!35Oseg(8v^SVCx6;@N&0za)ANi0Uj_Q%-_i#0PvriN;mUjle(pH9q>d7 zT`6+jvoT|c=nQ#8^4!2lqpVr6@=Y{TAACaOt14emEa#Wt#DeFSVAS2%%@%PiO%#txkSWOduD; zPz~~0>RD|*qvnb^ZlnakXI1sXRE zu!UUb^1!|0Ywuo`@yP7ScC$Upi!YG7f?7@Tp3A_LgJ%9Co(nel)SW4RWQ6GO4rqfVe$lm)Rj0 zU>UIA-k!zSIWFrh2B&X#RT*55@j^<5MUVJuhQ-hEc?HJ9){GZkm%nX?fs5bD?6wY8 zwCsj1&BdzeNuQ<|>d9PE*5SO~zne_lACizEt1r@f++1;?{H&+Am5`Z(^P><(bsqZ4 zdy??cE}d30|Xa zk?4-*-gUund=daUHS?2{LMO!SDb2PtVC^N^WqY1uj#P9`pK0?+oQ$XMcisBbX5Tr4+H~kW+PgEVhW~9Pz&8(3^FfsR4U~LQN(<|Dhjm|aP1XQv9LfS zXcc`TTZv3k>w9MlsX_a|VO`GudXmAuT$^S~p!~C$eVsSmc7u6F>i3si*-e~DTP|F5 z6PtbNVcRw(L+&HgzRo`|yh;{I;O}g7OeOEf?HM(_1U7HmbP8!1l>|=H233=6@e&ZP z2~MR4P3P}w<25lp*+?0SCjElv^q2@Nw}@$9O`)S~G$W4}p7H(ht!Hu%r;}Eht=>3` znRtlKFyMvV7oaz2dp?j%VVN|bUM^}zSTYE*zW+oA?iZeUuEo=&u*^sz`Yy!$jw|1N z)+aMQ&q#Y=G8^e5RfbMyvbUVM`G>f*>)lx1ADRkJwkG0#3M(ysm6~gtuLbk>^I|(> zWe!Pw*u~!a_IQjyY@FG0m93t_l2dlY~k66NCwr9*xOOk9e5VrfM z>6@VsPDcWsx$PlF(a$O)Sjf6SIP`gGaPa>7YgnJ8eH23gwP zbcp&SLhwR%TWCWYsQ3+Nz=Ub$pY zN6lXNFKBNrh&)c%%cu0quc`Px=2G_oKF&a+6sRR#^2$--fY{qE(xQMRZ+m4dxkh{6 zXDy=YIHScg@Y559{0oL}mC%fio7ckMYg)d*r-|E!XcnPQ zfu^)45b2z!8tU8yju8rT5?{Ag!p}XM7M-+B1T)8b$-dA$Z4O^a{usLJU(sD!ToKu< z`*Jo$R9UAyj=9KfaM*tC(_=dknwPpVY-gd(ZEqGKK@}HICv%n0|-o$lTBr%$Ynlhf9Nv7`ecrvbrtJt zZFw1cz1)2V!p!_Z(g8vWI>Rqqa$?J!|3%LaYN>Ch42teTs`Pl_#bKzx z1R3AXZAZ5egeN;e^>Pi)laR4dbFpC>^XHG;jrt=^S98oH#F>L`n-$$j-i~xu6unfm z^94q$3HX9~!9!rZAB4Zul10%z7XqY?+N!qH>^@l_KwR2 z{JpPQNOP>xk$g#wx9XHN4;!L2a|g0Vl2%{VcGKT=?W`NAsLg zRET7x_hv}kt-`)=O{;R$IZD+BHJ5(ARy|!S8ExjO&7*2;QmLQZ)S$nAjenxX0{)a= zG^izq{*vo(A*E^>F*|oHAW7_nC*veeU1pj7(=!oAojXnyx|x=D7TN6z7JqLfv@C)L z=hP{onNL1B$TX_riC^^nye#sDrazl%m$O?%g^hj2X)OJjX5&IF2u7Q*gR#P z;D>s~YJLXHu)I4B3ZSE1w8vI>{^$q2BKKEVXuuMX0INOYGetXZl4<(=VvI>TBh%M zx?t?-vlChFFthW8MefiMXQq{y7eNQ&dj%vJ7k3T@O)lcFI?6-#T2?+JRj&Anke0q_ z#9r4if0Bt2+iLxGx1nCuX{BHH6?;8TLi>2=V^@=u-m_0Xi=FN4=rWS8f`2@mCzevl zk8LE(@zFlrByW}v@zc|-x|m~0V1NEHBPE0bVDfdbh)AD{wRwJ#%Yi6^kZ8tGFtfK@IqDU```us zCKuC%CKvD+qv4D^K$yVN{`E(5hek&udkuWFs)1Lp+dT@XIlrDVpXibf6yx%BT#0v= zjgeGnn$O2lMZHPxyLzoF$_8cbCfaYXQ6u=Fc7`dxZKQJl#aFqAmUI{Ak}9PXq>z*M z>m5c(mq$1O5Vj|P*~x=!_%qwfOOBZk>F0?*+CB)yaGEOeYFXcN^@~h2=Q;ppeVB~1 zpd)-n zn~@9t)!T}0`=@o+Me(DH?5fqmIduCRi#TPwZzVKN!m}}8)_8QaFKuY|9Q#&SRO_*p zogAt1-nwLZy%Z)=VhHt^^ENf>&dav|{|x|d0t z@GFbn)_mDzt5I(YsVMO~hr&aAaIK|kDT_x(7)n??6_27P%r#1Xis7P)&KUe+CF2g< zNnid+vwc8B6_#I(fEgmb@-x;i|kB^SAI}5u<-zyUGDU%?Dv=H?h zns@7mqyrNxUfkJoQ*O=FJ$xV2jg_yyX)ey5LW9qf{VG#4wjqTuO>3T#{=88o%*y4O z$}j32aynmrnyu1%*I{vyidwB)`kf}SNPJ5<0+R_krR{>k7yB$ox-_-+k8Uz4j75qJHAd-A{0P}YD@q)na_`=-atbcau;o{@{XP-Xau$x=I`t1U>7esaHm*+p*sA=fv|6y|z zMh7QXk6#uy=szQ&kUwx9K3*=rFi?mf%mwC(>WDXrS@>`89**vCcW*~`k3Y=*W>9}L z|Bo)A9RFjJzeMg=uYN^XTE!jWbK_n^eH{S{;a^YTV5f*V$0Apyx>4N!=*DvHt;m5WZU zwhk~s4>yNj4Sx+O*xkk5OUE4wlVcJ2yCw}VSpT;tL~<{mWq+3eX>E6i?TuXg)^X^s#^1C= z+15euH>}{l0{;&tLq~T%xBokyze4|DQSyTOxqCV5dFk0bfI;B@n&%&Z|6npeskk@X zD?sDl4C?Q2vcD}qb(F2USHPeA8^Sz)yZS9WE>6Eh6$tz#Z_>7qn<&b$Kz=0v^w%7s z;{02q(?3{x!Xly~API4Memfy?2*0QuDp#b0VWRwE5Md!(I|-S-jot;eNJW zFeL|+EXc7a-RxdK{l91t5DW(1WE_x7#}?w`b|X;Se{1jO2)kJj|1>Lqo9*9sl7BKh zZ(Cp3-wh7pXzS(xLv544YvjKgG)%%?R8&eB#4jZ!Da9{p4+Zf{qBM(N7$htqA_qXZ0u>jtli(K>MJcT)2sPc3QWBE<;=)1@C`3%eUc&zG zLi%@uRzq!Ezmx&U^}8DWlbHnx@uT)^khqaBNLmaeEh5hH`|xB1Z>oX6WU%bbeyO7) z{pTE)z1dHtHEwj#(8t5W#R=y1x4HipE%+z6KiU7168C>={%6>4)?jy!0MriS2-ov- z`a{xjsau>7fLLJj%1d#GXzRoe;vQQZB$@=aK<&9483>pzOXe+2$-cKtsK7ye%#55e3}#jYRf;SW(^ z!T{>Q5w@L{n#!+7NPtstOBm`Mo`<@bHvm9De)B>DWMomJZsNc-bnf7M!==R+W$Sg$ zz5)Ok(lk_*jQrEpGQ|xH?7yyk zdgSevlmsJ5Y?hdKAKUmGNWlAI|Hy5mg+4!}Ks5p20z@nNG=cjGZ5_QP+{C8-G;l6B z0mA5X#RR}dpv}l)*$`4=yP;!r@-NYPU^HTU8!{BVuIErtZ^4ev5sh>KtfT1x2E$L+ z&7e^^JQ$B*m;#)5?eqXZ#HqIpVnKtqryAhO|^)fsNPU>aVIO(>^WSxwc`myMZ#CKS@~)#k#V6G2!->WGsO zH~N-l6rpMM*b_q2j;4!l*;(4BW0Yxu6{#8m*xb^05Vh2&Q%i4TcEAiH zlSGGO+>Ri{i248!np<$eyymMS_a9e5q*D(C700_+@Ou%Z&&u?!0ayygOOm&aF+PMZ zrp;VQ8uY(Hv!R)2C-o=t|A^_QfN6Lwq}Y#kJ5CHqu>Y(ROvf4CKzMT}m%cr!eS7drf%}Gn>-j{BcjEV*YT&iADwNs|A%) zZ^q0EH7~q-5!W~ulo{%@5$2e`|%GocMxRG+Wkyo5Tno zFplXb6NdtvB`aDT)>%(l|FDW2$a>(`Z922jIKSjoMFy{;v?@(Qr%OJdJzT1&Jyj`1t$6Q zyAXh6=w_vFx3~&>{bYe!va+NrOMXnp22<0!t-GDiG51iuk_3>n=eu?)h;{3I$W-J` zxu-(eho_2-s0@APx9r_|HHe9E?=E;o|I~abUQu5$U-5yVV9_20IWC1}%fm4MC1xH4 zdW2x|k|^tVP2$i|BL7kKx=xaK^STI(ucjJAJ*OH+lC7S4hNN%ibNq8dpe2oxCG2aRPkvGw@iO#mX(ECUV3X* zD=$6t>P(Mzv5Kto!20>F?(^WZ?TA%W|D^M6VG%|BzKbxx1x_-{)}ClxL@lC8XW?;La&6c8XWQw{M`p6AEQpE!=2R6$tzmns@!^m)?;8WB6SxtTN83m+-{z{xQ90Z%yBN`yfnD z30Z_>yIMHzwDw|*_Yva*@b~~%gh+>&<+aYY1MfhX4RK&gi85BlNPrBxaC9lB|en@NXZVsXnvjCtWug*+k`xYZxlC8Ix>-+z7hYCbnITg{&Dt*!FLsb??q{X3W}>57tQJYly^R(btH ztdko9qbDZ>?S{-As~7Rm(3xƱP!zMbgU>w5y&M#U}^&`k0&MOnp8QNi7luuiF86J*75K=b~qbn^}Nm*vwj-)YlpB~Dx+Hlof;lj z4LE4mY)ys&QsmGss+j`~?uz(z^#h_uTDa-Y_^)Oj0iT15-fZezf*Y~Zskly9-siL- zSuu(lIyCKuIG|vYmhyotX}I$jnN93u-U&~v3AAt_?M1hvS{2%3EVQdpokKaMyU5KM z%$epyr`s+x31wmGPxBs*lU@ieIt0V1#l)4pR(+upZ!{wm)50$}JMV4o6)c|@OHZIF z;(y7#HiUB~#F-!^xZoj*S3MZ7GMQMnN106Z!8K_meL%igb;^Sd`ToZ8M4xAD(m7K! z%COZ4ztKxf&ar1DCvn^RCyN{T&SyJ1S4`QnOzn5_H^7HXyJ|!~S$34v?|$L9ZqJWH zZ$X=trn`I3TH`iJj%db<5C+R9w-fBpXh*Rg-)3bGGEz*WD?-eY9zMFl7DIA_V4qv= zQ?^r(gdb*jinpl-eqdVWvx@d06H(L^8f@Hg+q?Bzz6z^q44m$s0T9Y4xmAqY=S4A+ z1-s?`iA@(m5Pxs(|DSeImVf z+NNZGpptnWlf0#5RgGu+1jqgE<`qt>_al-rbkld@V%E5d3zSzeaz%buq`K#tDt3L* zOas0Z&zD>Glj~X^{Zx45rX9zzaqkIGLM8u%1eLA0o^;Embvs8`Tq7d(*Tx{3#Xhrl z*v~(yFkc{`gc68PCuV2?#EaJ;QmVid^UfBpc;yqN$!tMV4F{GQ6T|M*z72_07yoC+ z6@IlN2`0!jlO;-W0#no!V>B->ecY^F6bj)aUbfy-DuL}{hbVhf3=FQo+w(EnH^su< zQ6fp3{R;O&0ac?AzRax>b0pW%7ah zLcgy@M^Pc@-KRAQHf5ZQ)2AhEyodueY_1&X7+T3f?uq+^r&zBF)bt&DtxiB&sVqdu zJ-_Wyu`DrdmZNWM=*-UJF;Xfjr?0yuzuwDT3c194EK|32G8o+6wro5u6IP&+12x9& zSa|2IuvO5HF5PuxPFv_^bO*79mX@L5rfX~ko~XCo)?B(p1NmMc}+YY_=d3d8Lo=Sbvg zf(A!&mV8J?Obm8LX6DxS?`+8*dx;|Tr+J@=QCI7zNX~qFOuBZ3_JHqE*e=Llf`q2@ ztT2qZbA~XtZCPx*WpPY?Q3E6@s_o||aelJD(Hl$7Mury&RMh-uMlHpYja42UCBNoW-6(yBp!Jhq6eQt$ZI%4<9tL5; z!**A;wc*HM;VnXzyxwS7qK*-)hVu_-=pjzq+S(-Jj~JF0iTu!`NKg?B3<{D8Mhbz! zU{CXiC|k^l@r&iyen1|@fHz*BY8O*w`@&*eJg>Fip(LFZ>*e8y2TJPL#|du{d0rqr zf9`$JLQROlz&>SY6ML0wW>=R|Jfqw|x`;#n#*rt64e2Nux{dhrx1NSeP5RV0#&0Sn z1u5F;OnxZmb|~WngQb_|Tl@r3`DXgkc>FL3VnvFH7ON6j<1jM*<;zfizj~HQr?5#_ zyh;O!T0@Q;uD+Yq{%TpDxsipQNH7CAO?%=uDUT&Z?xkb{UGvA9TW?t*5J;A^&y%B# z5koGD6+%q9h}m(KC{h7Wqa`Z+b^_%W?M4iQ){0Bwi>~XY&Go$qA3s0urOpVlj}WtI z48vAUZoa{l^2+v=WIcIXI9ybhHxY23J>%+`0KjN_?@9fG=k1AH3P41L&*D{upJ-dA zy0GXQ!?w1d6R*Q>9}RM@t1jA8k|H9|hO?x4rpoVmT1r$b&SAf^r6Sqo7mbb<|=;x5p#ydYdll0r8FDxwdG$!EB69@$0qUjpAkFux|;zsZ^OV3$%sEusD z@H}VknVFaXqjE>nOjv2Q{@G5mMUxl1t^^Rw!bQprKvmP@&FHV}=9u}hkZ1!#8R7f8 zc*bo)a|!{6-{drM)T+@xLX)npLItc^sbv7)9ewn}chlTvRlcbt+9MTD&9a`kCw~25 zn8lv)E!|>-nAh(GMJP2Gl~`_HTR#?SrE*c=dqOeD`qc~CqYZJR)_@=%-~_2X+H#7U zWcf+6EfQX9J&eef^hBSp=UqA4U&BVNkdTlNLSo_%q&Vt8Qeskf^L`gzwoKOhM=Tu2 zyXHGq!Vfbtmg#62bAT6Hpx_rCSQr=>3+*8?_2_r`03Q|XVSF@(w%y9t}#E?IP?+WmeI&d zK#^a&%vu8@*Z1ceD(wgtd-?#YtE=CwT^YB$HLHGM!UGYw`#=95>MGs zXl5ldzzMdZnoog~+Zwy$CzXz)I*1)5j1oCCFS0gW(HJ%(pn+4?+Rk%tle~o$id1RY z$KQWI?>45h)|@*?&*^D@UnbCM7STAI>^}%ci~TCdL_ouzMd5pXKMUqe`tE>PBi}2g z@?dYYkBk99bc^W4_URg-b={{O4en|_-gq-KV(OI5p>a3u4!L*jctKODD!#?-d0Vzo z*2lPqFu7pE6nIN>^J`tCEeEhT4g-L-^ipL}CYiHjn*O=^D&KCW)i~Pg3eiBh-SEmc z?g|zi_vI@nb-x=u9m#z{fIB!uI!tu7sa5KxnYY-8CRm~e;FZbjjd36ua@MbqXfumI zu33K|?vMher>4d}e>P<)V3EFqdYr-Fmi4+ad?mbJ@ltR4ENRxg+swV$Z>Z74bo@(4m;y>C*&|Emq6DK9aU(VY zCTC_Q#>dIT02WJu>X>Upv~~=}q`G9KA(S7PDH`Jk^cRk-&0sbuC8yOu8}NJ@X?+Vsk~+g==kU#VnXAkPh}` zh$VcR{$k3T172eoBGUNMppgH_{h)V*kvyC-1a>*YMCWAY*WrxG&iTyddbK9 zTwUdqsxQKOGgBqfLvV)yBV4A}m)Iknw_h~T;v6!$iF?{X$4rf+a+qLbK*;42$gH7R zi*1}5W&?4#sGfexRmgq+^tKvaxc>A87)H#X_cgD8sg18Y{+ndBr-hoK8nRNBMS}4v3?evy@hV`wKd?4c|-hcje}bH_3d!Mu@n4+RKne&3xs*z zOnCkS`Ko*kLhHuZ^64n1=GVsMCS$X+8mJUYSr5YuNm%k3ppD?<%f)wpzfaL_@ML=0L|R(fwAS%%iWVz)O@6qjd~J=sKh8LLeTJ+@!gx^Ak^Lm$9@Oeud7Bb#A7at(s zEP!ZN(j_TIfOD zp$9AP?@|RTiZnTdhn$RGoudIBW(h3$IWjgC*djlFroO54Q#&r$QS~doaBv;z#+nFcfFUTk;gRr=4|dmaD!r%pWR9*N)kpZ$QDf;2DOc zy0-JavAgA1iYWvN&(*6!&V8-IE`6kBWSm@F;_f3En>)NK1KQm0j^vbR(4b$Th0KoT z=ARHK9J_=(~xVGBJpgnibR?w+m!qzKT)hJ;ZmV zNi`UsoK$ge;C%b`EuU#sc!K=dV^kSRhN%=w!jr(TV)vsP1pho;=d)vC6}ZJ-?=su{ z#;m3w{%4P&5ZYo(-?5$yBxuwxQ>1AP{rIv*i-(dJms!1Zg3q!!WqsYAivND^a?c~F zfI~J^b+brQ5XYlK7$WPatB^agDtW8?UgdhaLyj#`P1j^dh)rP*}4;7 zzYaJ1?0l|uBG1mwuC1+2{0LoX#RO@Og<)Oz!QWm-e3U-Gol8cSjtC?E4vksIOEGAy z&=N>p-JUAHIS`I0TxUJKE$DT62#bk{(VVG`*;}@)75*gI9j${p2{d_cjH6tP7i*by zgv#m3pR&!myo5_L{NP(O>h2)AphfC+Zg5y~Y68OB!~N+Hw>y20cUeX32woVV&TvSi zB?x$cEOJhP8PKnEF6@yn z4?W&-K0 zYh}iVhL+Y23XMY1XUq7Zs%-z9M+W%Z?D4CKx}_+&MeVCOsI=SO*{OD=Lk*0LtXMUL zN1B=WB%w1*q|(p7_bkq`OTu?lrT7j6k2cnZt|{eR3Qbf6OXkqZdFaPnJprK?EioQi z_ddyoNXv%-khn;#r@;=1q z70CJCXO%C)q1+DWFXUoG-}whKzWmmN-imYKzIV&VBo6tiHiPTouoXs(dFKeBXNo`H z2+kQjLCo^GLZ{#uo!pZbS4wu+0X}pgyr<@!OodO?r-b46zi4o2uLS;*DZXZGNZj~&?bs@~@xh?Yel(Zr-mFdf<8|wuk zILL`xvA?S}q}}PJF|rMmh}*07XF@*1JKG~!7Jd0Rze$<;tvg1ji$%A%jX-lf0*s?< zGyY9}b!Sne>5|{h^b@n4OG6UJEmMH3vqeurSf?T`)?xzV%vq3Vp&!wgUeb~JpFEol z$(xbm!J^TvP@mR*rbMY0RGN0JV^jIeyuww&gJL z$XgX5=ZJsuQe)@hLEuEelk+|H=ABn#rV&IOs-^_BnU$pxYzHJ-1GqId!ARV|m_tzy z^tOck=Gbk5se*$#%fs?X!L+;S8SH?^~S)U>|uO=L>8ehyab*U)Pc=PfJ_oh^6BiTpTQ zS%3qrD0DY#a=ena!IXEqvK$J2RnWITTodP!+-C_T)XE#bYrBL%?U zG}vhjXoFzNM6Iv7({>SO>~p7azAX3S^|?~mrRclUzK{XG`BYcqj;>0DvQ6aw0c}dE AMF0Q* literal 0 HcmV?d00001 diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index ce8772eedc..7e12be4fcd 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -84,16 +84,19 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S #endif // Font is already set in DPIFrame constructor */ - // Load the icon either from the exe, or from the ico file. -#if _WIN32 - { - TCHAR szExeFileName[MAX_PATH]; - GetModuleFileName(nullptr, szExeFileName, MAX_PATH); - SetIcon(wxIcon(szExeFileName, wxBITMAP_TYPE_ICO)); - } -#else + SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG)); -#endif // _WIN32 +// // Load the icon either from the exe, or from the ico file. +//#if _WIN32 +// { +// +// TCHAR szExeFileName[MAX_PATH]; +// GetModuleFileName(nullptr, szExeFileName, MAX_PATH); +// SetIcon(wxIcon(szExeFileName, wxBITMAP_TYPE_ICO)); +// } +//#else +// SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG)); +//#endif // _WIN32 // initialize status bar m_statusbar = std::make_shared(this); @@ -1364,6 +1367,8 @@ void MainFrame::set_mode(EMode mode) m_plater->Thaw(); + SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG)); + break; } case EMode::GCodeViewer: @@ -1409,6 +1414,8 @@ void MainFrame::set_mode(EMode mode) m_plater->Thaw(); + SetIcon(wxIcon(Slic3r::var("PrusaSlicerGCodeViewer_128px.png"), wxBITMAP_TYPE_PNG)); + break; } } @@ -1912,16 +1919,19 @@ SettingsDialog::SettingsDialog(MainFrame* mainframe) this->SetFont(wxGetApp().normal_font()); this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); - // Load the icon either from the exe, or from the ico file. -#if _WIN32 - { - TCHAR szExeFileName[MAX_PATH]; - GetModuleFileName(nullptr, szExeFileName, MAX_PATH); - SetIcon(wxIcon(szExeFileName, wxBITMAP_TYPE_ICO)); - } -#else - SetIcon(wxIcon(var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG)); -#endif // _WIN32 + + SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG)); +// // Load the icon either from the exe, or from the ico file. +//#if _WIN32 +// { +// +// TCHAR szExeFileName[MAX_PATH]; +// GetModuleFileName(nullptr, szExeFileName, MAX_PATH); +// SetIcon(wxIcon(szExeFileName, wxBITMAP_TYPE_ICO)); +// } +//#else +// SetIcon(wxIcon(var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG)); +//#endif // _WIN32 this->Bind(wxEVT_SHOW, [this](wxShowEvent& evt) { From 56431d26e5b01d9f206ad52a7eff4de443ec8038 Mon Sep 17 00:00:00 2001 From: Slic3rPE Date: Wed, 26 Aug 2020 14:56:26 +0200 Subject: [PATCH 212/255] Starting a new Slicer instance from the menu --- src/slic3r/GUI/MainFrame.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index bbc1da534e..122d9c6108 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -8,9 +8,12 @@ #include #include //#include +#include +#include #include #include +#include #include "libslic3r/Print.hpp" #include "libslic3r/Polygon.hpp" @@ -979,6 +982,18 @@ void MainFrame::init_menubar() append_menu_item(windowMenu, wxID_ANY, _(L("Print &Host Upload Queue")) + "\tCtrl+J", _(L("Display the Print Host Upload Queue window")), [this](wxCommandEvent&) { m_printhost_queue_dlg->Show(); }, "upload_queue", nullptr, [this]() {return true; }, this); + + windowMenu->AppendSeparator(); + append_menu_item(windowMenu, wxID_ANY, _(L("Open new instance")) + "\tCtrl+I", _(L("Open a new PrusaSlicer instance")), + [this](wxCommandEvent&) { + wxString path = wxStandardPaths::Get().GetExecutablePath(); +#ifdef __APPLE__ + boost::process::spawn((const char*)path.c_str()); +#else + wxExecute(wxStandardPaths::Get().GetExecutablePath(), wxEXEC_ASYNC | wxEXEC_HIDE_CONSOLE | wxEXEC_MAKE_GROUP_LEADER); +#endif + }, "upload_queue", nullptr, + [this]() {return true; }, this); } // View menu From ba9c3a74ed6f46725fd092a43ae3895c38a19bc7 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 26 Aug 2020 15:29:33 +0200 Subject: [PATCH 213/255] GCodeViewer -> 1st iteration of rendering of extrude toolpaths as solid --- resources/shaders/options_110.fs | 4 +- resources/shaders/options_120.fs | 10 +- resources/shaders/toolpaths_lines.fs | 4 +- src/libslic3r/Technologies.hpp | 1 + src/slic3r/GUI/GCodeViewer.cpp | 330 ++++++++++++++++++++------- src/slic3r/GUI/GCodeViewer.hpp | 64 +++++- src/slic3r/GUI/GLShadersManager.cpp | 2 +- 7 files changed, 303 insertions(+), 112 deletions(-) diff --git a/resources/shaders/options_110.fs b/resources/shaders/options_110.fs index 474e355e09..ab656998df 100644 --- a/resources/shaders/options_110.fs +++ b/resources/shaders/options_110.fs @@ -1,8 +1,8 @@ #version 110 -uniform vec3 uniform_color; +uniform vec4 uniform_color; void main() { - gl_FragColor = vec4(uniform_color, 1.0); + gl_FragColor = uniform_color; } diff --git a/resources/shaders/options_120.fs b/resources/shaders/options_120.fs index 5bcc718761..d897a8ca73 100644 --- a/resources/shaders/options_120.fs +++ b/resources/shaders/options_120.fs @@ -1,19 +1,15 @@ // version 120 is needed for gl_PointCoord #version 120 -uniform vec3 uniform_color; +uniform vec4 uniform_color; uniform float percent_outline_radius; uniform float percent_center_radius; -vec4 hardcoded_color(float radius, vec3 color) -{ - return ((radius < 0.15) || (radius > 0.85)) ? vec4(0.5 * color, 1.0) : vec4(color, 1.0); -} -vec4 customizable_color(float radius, vec3 color) +vec4 customizable_color(float radius, vec4 color) { return ((radius < percent_center_radius) || (radius > 1.0 - percent_outline_radius)) ? - vec4(0.5 * color, 1.0) : vec4(color, 1.0); + vec4(0.5 * color.rgb, color.a) : color; } void main() diff --git a/resources/shaders/toolpaths_lines.fs b/resources/shaders/toolpaths_lines.fs index 13f60c0a82..7202a2e3e4 100644 --- a/resources/shaders/toolpaths_lines.fs +++ b/resources/shaders/toolpaths_lines.fs @@ -6,7 +6,7 @@ const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0); // x = ambient, y = top diffuse, z = front diffuse, w = global uniform vec4 light_intensity; -uniform vec3 uniform_color; +uniform vec4 uniform_color; varying vec3 eye_position; varying vec3 eye_normal; @@ -27,5 +27,5 @@ void main() NdotL = abs(dot(normal, LIGHT_FRONT_DIR)); intensity += NdotL * light_intensity.z; - gl_FragColor = vec4(uniform_color * light_intensity.w * intensity, 1.0); + gl_FragColor = vec4(uniform_color.rgb * light_intensity.w * intensity, uniform_color.a); } diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index e10cabc6cf..00c899201a 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -59,6 +59,7 @@ #define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_SHADERS_EDITOR (0 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_DATA_CHECKING (0 && ENABLE_GCODE_VIEWER) +#define ENABLE_GCODE_RENDER_EXTRUSION_AS_TRIANGLES (1 && ENABLE_GCODE_VIEWER) #define TIME_ESTIMATE_NONE 0 #define TIME_ESTIMATE_DEFAULT 1 diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index bcb4a0a268..70b571fe00 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -286,6 +286,7 @@ bool GCodeViewer::init() { for (size_t i = 0; i < m_buffers.size(); ++i) { + TBuffer& buffer = m_buffers[i]; switch (buffer_type(i)) { default: { break; } @@ -296,13 +297,25 @@ bool GCodeViewer::init() case EMoveType::Retract: case EMoveType::Unretract: { - m_buffers[i].vertices.format = VBuffer::EFormat::Position; + buffer.primitive_type = TBuffer::EPrimitiveType::Point; + buffer.vertices.format = VBuffer::EFormat::Position; break; } case EMoveType::Extrude: + { +#if ENABLE_GCODE_RENDER_EXTRUSION_AS_TRIANGLES + buffer.primitive_type = TBuffer::EPrimitiveType::Triangle; + buffer.vertices.format = VBuffer::EFormat::PositionNormal3; +#else + buffer.primitive_type = TBuffer::EPrimitiveType::Line; + buffer.vertices.format = VBuffer::EFormat::PositionNormal1; +#endif // ENABLE_GCODE_RENDER_EXTRUSION_AS_TRIANGLES + break; + } case EMoveType::Travel: { - m_buffers[i].vertices.format = VBuffer::EFormat::PositionNormal; + buffer.primitive_type = TBuffer::EPrimitiveType::Line; + buffer.vertices.format = VBuffer::EFormat::PositionNormal1; break; } } @@ -863,7 +876,11 @@ void GCodeViewer::init_shaders() case EMoveType::Custom_GCode: { m_buffers[i].shader = is_glsl_120 ? "options_120" : "options_110"; break; } case EMoveType::Retract: { m_buffers[i].shader = is_glsl_120 ? "options_120" : "options_110"; break; } case EMoveType::Unretract: { m_buffers[i].shader = is_glsl_120 ? "options_120" : "options_110"; break; } +#if ENABLE_GCODE_RENDER_EXTRUSION_AS_TRIANGLES + case EMoveType::Extrude: { m_buffers[i].shader = "gouraud_light"; break; } +#else case EMoveType::Extrude: { m_buffers[i].shader = "toolpaths_lines"; break; } +#endif // ENABLE_GCODE_RENDER_EXTRUSION_AS_TRIANGLES case EMoveType::Travel: { m_buffers[i].shader = "toolpaths_lines"; break; } default: { break; } } @@ -901,6 +918,127 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) m_max_bounding_box = m_paths_bounding_box; m_max_bounding_box.merge(m_paths_bounding_box.max + m_sequential_view.marker.get_bounding_box().size()[2] * Vec3d::UnitZ()); + // format data into the buffers to be rendered as points + auto add_as_point = [](const GCodeProcessor::MoveVertex& curr, TBuffer& buffer, + std::vector& buffer_vertices, std::vector& buffer_indices, size_t move_id) { + for (int j = 0; j < 3; ++j) { + buffer_vertices.push_back(curr.position[j]); + } + buffer.add_path(curr, static_cast(buffer_indices.size()), static_cast(move_id)); + buffer_indices.push_back(static_cast(buffer_indices.size())); + }; + + // format data into the buffers to be rendered as lines + auto add_as_line = [](const GCodeProcessor::MoveVertex& prev, const GCodeProcessor::MoveVertex& curr, TBuffer& buffer, + std::vector& buffer_vertices, std::vector& buffer_indices, size_t move_id) { + // x component of the normal to the current segment (the normal is parallel to the XY plane) + float normal_x = (curr.position - prev.position).normalized()[1]; + + if (prev.type != curr.type || !buffer.paths.back().matches(curr)) { + // add starting vertex position + for (int j = 0; j < 3; ++j) { + buffer_vertices.push_back(prev.position[j]); + } + // add starting vertex normal x component + buffer_vertices.push_back(normal_x); + // add starting index + buffer_indices.push_back(static_cast(buffer_indices.size())); + buffer.add_path(curr, static_cast(buffer_indices.size() - 1), static_cast(move_id - 1)); + buffer.paths.back().first.position = prev.position; + } + + Path& last_path = buffer.paths.back(); + if (last_path.first.i_id != last_path.last.i_id) { + // add previous vertex position + for (int j = 0; j < 3; ++j) { + buffer_vertices.push_back(prev.position[j]); + } + // add previous vertex normal x component + buffer_vertices.push_back(normal_x); + // add previous index + buffer_indices.push_back(static_cast(buffer_indices.size())); + } + + // add current vertex position + for (int j = 0; j < 3; ++j) { + buffer_vertices.push_back(curr.position[j]); + } + // add current vertex normal x component + buffer_vertices.push_back(normal_x); + // add current index + buffer_indices.push_back(static_cast(buffer_indices.size())); + last_path.last = { static_cast(buffer_indices.size() - 1), static_cast(move_id), curr.position }; + }; + + // format data into the buffers to be rendered as solid + auto add_as_solid = [](const GCodeProcessor::MoveVertex& prev, const GCodeProcessor::MoveVertex& curr, TBuffer& buffer, + std::vector& buffer_vertices, std::vector& buffer_indices, size_t move_id) { + auto store_vertex = [](std::vector& buffer_vertices, const Vec3f& position, const Vec3f& normal) { + // append position + for (int j = 0; j < 3; ++j) { + buffer_vertices.push_back(position[j]); + } + // append normal + for (int j = 0; j < 3; ++j) { + buffer_vertices.push_back(normal[j]); + } + }; + auto store_triangle = [](std::vector& buffer_indices, unsigned int i1, unsigned int i2, unsigned int i3) { + buffer_indices.push_back(i1); + buffer_indices.push_back(i2); + buffer_indices.push_back(i3); + }; + + Vec3f dir = (curr.position - prev.position).normalized(); + Vec3f right = (std::abs(std::abs(dir.dot(Vec3f::UnitZ())) - 1.0f) < EPSILON) ? -Vec3f::UnitY() : Vec3f(dir[1], -dir[0], 0.0f).normalized(); + Vec3f up = right.cross(dir); + float prev_half_width = 0.5f * prev.width; + float prev_half_height = 0.5f * prev.height; + float curr_half_width = 0.5f * curr.width; + float curr_half_height = 0.5f * curr.height; + Vec3f prev_pos = Vec3f(prev.position[0], prev.position[1], prev.position[2]) - prev_half_height * up; + Vec3f curr_pos = Vec3f(curr.position[0], curr.position[1], curr.position[2]) - curr_half_height * up; + + if (prev.type != curr.type || !buffer.paths.back().matches(curr)) { + buffer.add_path(curr, static_cast(buffer_indices.size()), static_cast(move_id - 1)); + buffer.paths.back().first.position = prev.position; + } + + unsigned int starting_vertices_size = static_cast(buffer_vertices.size() / buffer.vertices.vertex_size_floats()); + + // vertices 1st endpoint + store_vertex(buffer_vertices, prev_pos + prev_half_height * up, up); // top + store_vertex(buffer_vertices, prev_pos + prev_half_width * right, right); // right + store_vertex(buffer_vertices, prev_pos - prev_half_height * up, -up); // bottom + store_vertex(buffer_vertices, prev_pos - prev_half_width * right, -right); // left + + // vertices 2nd endpoint + store_vertex(buffer_vertices, curr_pos + curr_half_height * up, up); // top + store_vertex(buffer_vertices, curr_pos + curr_half_width * right, right); // right + store_vertex(buffer_vertices, curr_pos - curr_half_height * up, -up); // bottom + store_vertex(buffer_vertices, curr_pos - curr_half_width * right, -right); // left + + // triangles starting cap + store_triangle(buffer_indices, starting_vertices_size + 0, starting_vertices_size + 2, starting_vertices_size + 1); + store_triangle(buffer_indices, starting_vertices_size + 0, starting_vertices_size + 3, starting_vertices_size + 2); + + // triangles sides + store_triangle(buffer_indices, starting_vertices_size + 0, starting_vertices_size + 1, starting_vertices_size + 4); + store_triangle(buffer_indices, starting_vertices_size + 1, starting_vertices_size + 5, starting_vertices_size + 4); + store_triangle(buffer_indices, starting_vertices_size + 1, starting_vertices_size + 2, starting_vertices_size + 5); + store_triangle(buffer_indices, starting_vertices_size + 2, starting_vertices_size + 6, starting_vertices_size + 5); + store_triangle(buffer_indices, starting_vertices_size + 2, starting_vertices_size + 3, starting_vertices_size + 6); + store_triangle(buffer_indices, starting_vertices_size + 3, starting_vertices_size + 7, starting_vertices_size + 6); + store_triangle(buffer_indices, starting_vertices_size + 3, starting_vertices_size + 0, starting_vertices_size + 7); + store_triangle(buffer_indices, starting_vertices_size + 0, starting_vertices_size + 4, starting_vertices_size + 7); + + // triangles ending cap + store_triangle(buffer_indices, starting_vertices_size + 4, starting_vertices_size + 6, starting_vertices_size + 7); + store_triangle(buffer_indices, starting_vertices_size + 4, starting_vertices_size + 5, starting_vertices_size + 6); + + buffer.paths.back().last = { static_cast(buffer_indices.size() - 1), static_cast(move_id), curr.position }; + }; + // toolpaths data -> extract from result std::vector> vertices(m_buffers.size()); std::vector> indices(m_buffers.size()); @@ -926,55 +1064,21 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) case EMoveType::Retract: case EMoveType::Unretract: { - for (int j = 0; j < 3; ++j) { - buffer_vertices.push_back(curr.position[j]); - } - buffer.add_path(curr, static_cast(buffer_indices.size()), static_cast(i)); - buffer_indices.push_back(static_cast(buffer_indices.size())); + add_as_point(curr, buffer, buffer_vertices, buffer_indices, i); break; } +#if ENABLE_GCODE_RENDER_EXTRUSION_AS_TRIANGLES case EMoveType::Extrude: + { + add_as_solid(prev, curr, buffer, buffer_vertices, buffer_indices, i); + break; + } +#else + case EMoveType::Extrude: +#endif // ENABLE_GCODE_RENDER_EXTRUSION_AS_TRIANGLES case EMoveType::Travel: { - // x component of the normal to the current segment (the normal is parallel to the XY plane) - float normal_x = (curr.position - prev.position).normalized()[1]; - - if (prev.type != curr.type || !buffer.paths.back().matches(curr)) { - // add starting vertex position - for (int j = 0; j < 3; ++j) { - buffer_vertices.push_back(prev.position[j]); - } - // add starting vertex normal x component - buffer_vertices.push_back(normal_x); - // add starting index - buffer_indices.push_back(buffer_indices.size()); - buffer.add_path(curr, static_cast(buffer_indices.size() - 1), static_cast(i - 1)); - Path& last_path = buffer.paths.back(); - last_path.first.position = prev.position; - } - - Path& last_path = buffer.paths.back(); - if (last_path.first.i_id != last_path.last.i_id) - { - // add previous vertex position - for (int j = 0; j < 3; ++j) { - buffer_vertices.push_back(prev.position[j]); - } - // add previous vertex normal x component - buffer_vertices.push_back(normal_x); - // add previous index - buffer_indices.push_back(buffer_indices.size()); - } - - // add current vertex position - for (int j = 0; j < 3; ++j) { - buffer_vertices.push_back(curr.position[j]); - } - // add current vertex normal x component - buffer_vertices.push_back(normal_x); - // add current index - buffer_indices.push_back(buffer_indices.size()); - last_path.last = { static_cast(buffer_indices.size() - 1), static_cast(i), curr.position }; + add_as_line(prev, curr, buffer, buffer_vertices, buffer_indices, i); break; } default: { break; } @@ -989,7 +1093,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) const std::vector& buffer_vertices = vertices[i]; buffer.vertices.count = buffer_vertices.size() / buffer.vertices.vertex_size_floats(); #if ENABLE_GCODE_VIEWER_STATISTICS - m_statistics.vertices_gpu_size = buffer_vertices.size() * sizeof(float); + m_statistics.vertices_gpu_size += buffer_vertices.size() * sizeof(float); #endif // ENABLE_GCODE_VIEWER_STATISTICS glsafe(::glGenBuffers(1, &buffer.vertices.id)); @@ -1199,15 +1303,24 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool // searches the path containing the current position for (const Path& path : buffer.paths) { if (path.first.s_id <= m_sequential_view.current.last && m_sequential_view.current.last <= path.last.s_id) { - size_t offset = m_sequential_view.current.last - path.first.s_id; - if (offset > 0 && (path.type == EMoveType::Travel || path.type == EMoveType::Extrude)) - offset = 1 + 2 * (offset - 1); - + unsigned int offset = m_sequential_view.current.last - path.first.s_id; + if (offset > 0) { + if (buffer.primitive_type == TBuffer::EPrimitiveType::Line) + offset = 2 * offset - 1; + else if (buffer.primitive_type == TBuffer::EPrimitiveType::Triangle) + offset = 36 * (offset - 1) + 30; + } offset += path.first.i_id; + // gets the index from the index buffer on gpu + unsigned int index = 0; + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.indices.id)); + glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast(offset * sizeof(unsigned int)), static_cast(sizeof(unsigned int)), static_cast(&index))); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + // gets the position from the vertices buffer on gpu glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.vertices.id)); - glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, static_cast(offset * buffer.vertices.vertex_size_bytes()), static_cast(3 * sizeof(float)), static_cast(m_sequential_view.current_position.data()))); + glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, static_cast(index * buffer.vertices.vertex_size_bytes()), static_cast(3 * sizeof(float)), static_cast(m_sequential_view.current_position.data()))); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); found = true; break; @@ -1238,15 +1351,23 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool it->path_id = id; } - unsigned int size = std::min(m_sequential_view.current.last, path.last.s_id) - std::max(m_sequential_view.current.first, path.first.s_id) + 1; - if (path.type == EMoveType::Extrude || path.type == EMoveType::Travel) - size = 2 * (size - 1); + unsigned int size_in_vertices = std::min(m_sequential_view.current.last, path.last.s_id) - std::max(m_sequential_view.current.first, path.first.s_id) + 1; + unsigned int size_in_indices = 0; + switch (buffer->primitive_type) + { + case TBuffer::EPrimitiveType::Point: { size_in_indices = size_in_vertices; break; } + case TBuffer::EPrimitiveType::Line: { size_in_indices = 2 * (size_in_vertices - 1); break; } + case TBuffer::EPrimitiveType::Triangle: { size_in_indices = 36 * (size_in_vertices - 1); break; } + } + it->sizes.push_back(size_in_indices); - it->sizes.push_back(size); unsigned int delta_1st = 0; - if ((path.first.s_id < m_sequential_view.current.first) && (m_sequential_view.current.first <= path.last.s_id)) + if (path.first.s_id < m_sequential_view.current.first && m_sequential_view.current.first <= path.last.s_id) delta_1st = m_sequential_view.current.first - path.first.s_id; + if (buffer->primitive_type == TBuffer::EPrimitiveType::Triangle) + delta_1st *= 36; + it->offsets.push_back(static_cast((path.first.i_id + delta_1st) * sizeof(unsigned int))); } @@ -1266,8 +1387,15 @@ void GCodeViewer::render_toolpaths() const { #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR float point_size = m_shaders_editor.points.point_size; + std::array light_intensity = { + m_shaders_editor.lines.lights.ambient, + m_shaders_editor.lines.lights.top_diffuse, + m_shaders_editor.lines.lights.front_diffuse, + m_shaders_editor.lines.lights.global + }; #else float point_size = 0.8f; + std::array light_intensity = { 0.25f, 0.7f, 0.75f, 0.75f }; #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR const Camera& camera = wxGetApp().plater()->get_camera(); double zoom = camera.get_zoom(); @@ -1275,10 +1403,13 @@ void GCodeViewer::render_toolpaths() const float near_plane_height = camera.get_type() == Camera::Perspective ? static_cast(viewport[3]) / (2.0f * static_cast(2.0 * std::tan(0.5 * Geometry::deg2rad(camera.get_fov())))) : static_cast(viewport[3]) * 0.0005; - Transform3d inv_proj = camera.get_projection_matrix().inverse(); + auto set_uniform_color = [](const std::array& color, GLShaderProgram& shader) { + std::array color4 = { color[0], color[1], color[2], 1.0f }; + shader.set_uniform("uniform_color", color4); + }; - auto render_as_points = [this, zoom, inv_proj, viewport, point_size, near_plane_height](const TBuffer& buffer, EOptionsColors color_id, GLShaderProgram& shader) { - shader.set_uniform("uniform_color", Options_Colors[static_cast(color_id)]); + auto render_as_points = [this, zoom, point_size, near_plane_height, set_uniform_color](const TBuffer& buffer, EOptionsColors color_id, GLShaderProgram& shader) { + set_uniform_color(Options_Colors[static_cast(color_id)], shader); shader.set_uniform("zoom", zoom); #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR shader.set_uniform("percent_outline_radius", 0.01f * static_cast(m_shaders_editor.points.percent_outline)); @@ -1287,8 +1418,6 @@ void GCodeViewer::render_toolpaths() const shader.set_uniform("percent_outline_radius", 0.0f); shader.set_uniform("percent_center_radius", 0.33f); #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR - shader.set_uniform("viewport", viewport); - shader.set_uniform("inv_proj_matrix", inv_proj); shader.set_uniform("point_size", point_size); shader.set_uniform("near_plane_height", near_plane_height); @@ -1306,12 +1435,23 @@ void GCodeViewer::render_toolpaths() const glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); }; - auto render_as_lines = [this](const TBuffer& buffer, GLShaderProgram& shader) { + auto render_as_lines = [this, light_intensity, set_uniform_color](const TBuffer& buffer, GLShaderProgram& shader) { + shader.set_uniform("light_intensity", light_intensity); for (const RenderPath& path : buffer.render_paths) { - shader.set_uniform("uniform_color", path.color); + set_uniform_color(path.color, shader); glsafe(::glMultiDrawElements(GL_LINES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.gl_multi_line_strip_calls_count; + ++m_statistics.gl_multi_lines_calls_count; +#endif // ENABLE_GCODE_VIEWER_STATISTICS + } + }; + + auto render_as_triangles = [this, set_uniform_color](const TBuffer& buffer, GLShaderProgram& shader) { + for (const RenderPath& path : buffer.render_paths) { + set_uniform_color(path.color, shader); + glsafe(::glMultiDrawElements(GL_TRIANGLES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); +#if ENABLE_GCODE_VIEWER_STATISTICS + ++m_statistics.gl_multi_triangles_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } }; @@ -1338,40 +1478,50 @@ void GCodeViewer::render_toolpaths() const shader->start_using(); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.vertices.id)); - glsafe(::glVertexPointer(buffer.vertices.vertex_size_floats(), GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)0)); + glsafe(::glVertexPointer(buffer.vertices.position_size_floats(), GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_size())); glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + bool has_normals = buffer.vertices.normal_size_floats() > 0; + if (has_normals) { + glsafe(::glNormalPointer(GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_size())); + glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); + } glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.indices.id)); - switch (buffer_type(i)) + switch (buffer.primitive_type) { - default: { break; } - case EMoveType::Tool_change: { render_as_points(buffer, EOptionsColors::ToolChanges, *shader); break; } - case EMoveType::Color_change: { render_as_points(buffer, EOptionsColors::ColorChanges, *shader); break; } - case EMoveType::Pause_Print: { render_as_points(buffer, EOptionsColors::PausePrints, *shader); break; } - case EMoveType::Custom_GCode: { render_as_points(buffer, EOptionsColors::CustomGCodes, *shader); break; } - case EMoveType::Retract: { render_as_points(buffer, EOptionsColors::Retractions, *shader); break; } - case EMoveType::Unretract: { render_as_points(buffer, EOptionsColors::Unretractions, *shader); break; } - case EMoveType::Extrude: - case EMoveType::Travel: + case TBuffer::EPrimitiveType::Point: + { + EOptionsColors color; + switch (buffer_type(i)) + { + case EMoveType::Tool_change: { color = EOptionsColors::ToolChanges; break; } + case EMoveType::Color_change: { color = EOptionsColors::ColorChanges; break; } + case EMoveType::Pause_Print: { color = EOptionsColors::PausePrints; break; } + case EMoveType::Custom_GCode: { color = EOptionsColors::CustomGCodes; break; } + case EMoveType::Retract: { color = EOptionsColors::Retractions; break; } + case EMoveType::Unretract: { color = EOptionsColors::Unretractions; break; } + } + render_as_points(buffer, color, *shader); + break; + } + case TBuffer::EPrimitiveType::Line: { -#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR - std::array light_intensity = { - m_shaders_editor.lines.lights.ambient, - m_shaders_editor.lines.lights.top_diffuse, - m_shaders_editor.lines.lights.front_diffuse, - m_shaders_editor.lines.lights.global }; -#else - std::array light_intensity = { 0.25f, 0.7f, 0.75f, 0.75f }; -#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR - shader->set_uniform("light_intensity", light_intensity); render_as_lines(buffer, *shader); break; } + case TBuffer::EPrimitiveType::Triangle: + { + render_as_triangles(buffer, *shader); + break; + } } glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + if (has_normals) + glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); @@ -2454,9 +2604,13 @@ void GCodeViewer::render_statistics() const ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.gl_multi_points_calls_count)); - imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, std::string("Multi GL_LINE_STRIP calls:")); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, std::string("Multi GL_LINES calls:")); ImGui::SameLine(offset); - imgui.text(std::to_string(m_statistics.gl_multi_line_strip_calls_count)); + imgui.text(std::to_string(m_statistics.gl_multi_lines_calls_count)); + + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, std::string("Multi GL_TRIANGLES calls:")); + ImGui::SameLine(offset); + imgui.text(std::to_string(m_statistics.gl_multi_triangles_calls_count)); ImGui::Separator(); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index e6c3e26eaa..919b9de6e1 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -38,8 +38,12 @@ class GCodeViewer { enum class EFormat : unsigned char { + // vertex format: 3 floats -> position.x|position.y|position.z Position, - PositionNormal + // vertex format: 4 floats -> position.x|position.y|position.z|normal.x + PositionNormal1, + // vertex format: 6 floats -> position.x|position.y|position.z|normal.x|normal.y|normal.z + PositionNormal3 }; EFormat format{ EFormat::Position }; @@ -49,18 +53,45 @@ class GCodeViewer size_t count{ 0 }; size_t data_size_bytes() const { return count * vertex_size_bytes(); } - size_t vertex_size_floats() const + + size_t vertex_size_floats() const { return position_size_floats() + normal_size_floats(); } + size_t vertex_size_bytes() const { return vertex_size_floats() * sizeof(float); } + + size_t position_offset_floats() const { return 0; } + size_t position_offset_size() const { return position_offset_floats() * sizeof(float); } + size_t position_size_floats() const { switch (format) { - // vertex format: 3 floats -> position.x|position.y|position.z - case EFormat::Position: { return 3; } - // vertex format: 4 floats -> position.x|position.y|position.z|normal.x - case EFormat::PositionNormal: { return 4; } - default: { return 0; } + case EFormat::Position: + case EFormat::PositionNormal3: { return 3; } + case EFormat::PositionNormal1: { return 4; } + default: { return 0; } } } - size_t vertex_size_bytes() const { return vertex_size_floats() * sizeof(float); } + size_t position_size_bytes() const { return position_size_floats() * sizeof(float); } + + size_t normal_offset_floats() const + { + switch (format) + { + case EFormat::Position: + case EFormat::PositionNormal1: { return 0; } + case EFormat::PositionNormal3: { return 3; } + default: { return 0; } + } + } + size_t normal_offset_size() const { return normal_offset_floats() * sizeof(float); } + size_t normal_size_floats() const { + switch (format) + { + default: + case EFormat::Position: + case EFormat::PositionNormal1: { return 0; } + case EFormat::PositionNormal3: { return 3; } + } + } + size_t normal_size_bytes() const { return normal_size_floats() * sizeof(float); } void reset(); }; @@ -116,6 +147,14 @@ class GCodeViewer // buffer containing data for rendering a specific toolpath type struct TBuffer { + enum class EPrimitiveType : unsigned char + { + Point, + Line, + Triangle + }; + + EPrimitiveType primitive_type; VBuffer vertices; IBuffer indices; @@ -185,8 +224,7 @@ class GCodeViewer void reset_role_visibility_flags() { role_visibility_flags = 0; - for (unsigned int i = 0; i < erCount; ++i) - { + for (unsigned int i = 0; i < erCount; ++i) { role_visibility_flags |= 1 << i; } } @@ -204,7 +242,8 @@ class GCodeViewer long long refresh_paths_time{ 0 }; // opengl calls long long gl_multi_points_calls_count{ 0 }; - long long gl_multi_line_strip_calls_count{ 0 }; + long long gl_multi_lines_calls_count{ 0 }; + long long gl_multi_triangles_calls_count{ 0 }; // memory long long results_size{ 0 }; long long vertices_gpu_size{ 0 }; @@ -231,7 +270,8 @@ class GCodeViewer void reset_opengl() { gl_multi_points_calls_count = 0; - gl_multi_line_strip_calls_count = 0; + gl_multi_lines_calls_count = 0; + gl_multi_triangles_calls_count = 0; } void reset_sizes() { diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index 6baf46f6b4..1041faa3dc 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -37,7 +37,7 @@ std::pair GLShadersManager::init() valid &= append_shader("options_110", { "options_110.vs", "options_110.fs" }); if (GUI::wxGetApp().is_glsl_version_greater_or_equal_to(1, 20)) valid &= append_shader("options_120", { "options_120.vs", "options_120.fs" }); - // used to render extrusion and travel paths in gcode preview + // used to render extrusion and travel paths as lines in gcode preview valid &= append_shader("toolpaths_lines", { "toolpaths_lines.vs", "toolpaths_lines.fs" }); // used to render objects in 3d editor valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" }); From e0e75f4a0e9a3942edd5f635ba309adb2f8208ef Mon Sep 17 00:00:00 2001 From: Slic3rPE Date: Wed, 26 Aug 2020 15:50:05 +0200 Subject: [PATCH 214/255] Starting a new Slicer instance from the menu - fix of Windows build --- src/slic3r/GUI/MainFrame.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 122d9c6108..8f2aeef8ab 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -13,7 +13,6 @@ #include #include -#include #include "libslic3r/Print.hpp" #include "libslic3r/Polygon.hpp" @@ -41,6 +40,12 @@ #include #endif // _WIN32 +// For starting another PrusaSlicer instance on OSX. +// Fails to compile on Windows on the build server. +#ifdef __APPLE__ + #include +#endif + namespace Slic3r { namespace GUI { From 41f474a884bdad01b973cd6bb734cea3a31384fc Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 26 Aug 2020 21:51:50 +0200 Subject: [PATCH 215/255] Fixed performance issues when adding / removing Presets into PresetCollection. This improves application startup time by 25-33%. --- src/libslic3r/PrintConfig.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index c4566c983e..b133a2e4eb 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -239,9 +239,13 @@ class DynamicPrintConfig : public DynamicConfig public: DynamicPrintConfig() {} DynamicPrintConfig(const DynamicPrintConfig &rhs) : DynamicConfig(rhs) {} + DynamicPrintConfig(DynamicPrintConfig &&rhs) noexcept : DynamicConfig(std::move(rhs)) {} explicit DynamicPrintConfig(const StaticPrintConfig &rhs); explicit DynamicPrintConfig(const ConfigBase &rhs) : DynamicConfig(rhs) {} + DynamicPrintConfig& operator=(const DynamicPrintConfig &rhs) { DynamicConfig::operator=(rhs); return *this; } + DynamicPrintConfig& operator=(DynamicPrintConfig &&rhs) noexcept { DynamicConfig::operator=(std::move(rhs)); return *this; } + static DynamicPrintConfig full_print_config(); static DynamicPrintConfig* new_from_defaults_keys(const std::vector &keys); From af30a3ab7ef303852575c1aaa54210bc48388dd4 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 27 Aug 2020 09:13:30 +0200 Subject: [PATCH 216/255] Code cleanup --- resources/shaders/options_120.fs | 5 +- resources/shaders/toolpaths_lines.fs | 5 +- resources/shaders/toolpaths_lines.vs | 2 - src/libslic3r/Technologies.hpp | 1 - src/slic3r/GUI/GCodeViewer.cpp | 102 +-------------------------- src/slic3r/GUI/GCodeViewer.hpp | 35 --------- 6 files changed, 4 insertions(+), 146 deletions(-) diff --git a/resources/shaders/options_120.fs b/resources/shaders/options_120.fs index d897a8ca73..e9b61304f2 100644 --- a/resources/shaders/options_120.fs +++ b/resources/shaders/options_120.fs @@ -5,8 +5,7 @@ uniform vec4 uniform_color; uniform float percent_outline_radius; uniform float percent_center_radius; - -vec4 customizable_color(float radius, vec4 color) +vec4 calc_color(float radius, vec4 color) { return ((radius < percent_center_radius) || (radius > 1.0 - percent_outline_radius)) ? vec4(0.5 * color.rgb, color.a) : color; @@ -19,5 +18,5 @@ void main() if (radius > 1.0) discard; - gl_FragColor = customizable_color(radius, uniform_color); + gl_FragColor = calc_color(radius, uniform_color); } diff --git a/resources/shaders/toolpaths_lines.fs b/resources/shaders/toolpaths_lines.fs index 7202a2e3e4..31151cdc17 100644 --- a/resources/shaders/toolpaths_lines.fs +++ b/resources/shaders/toolpaths_lines.fs @@ -8,11 +8,8 @@ const vec3 LIGHT_FRONT_DIR = vec3(0.0, 0.0, 1.0); uniform vec4 light_intensity; uniform vec4 uniform_color; -varying vec3 eye_position; varying vec3 eye_normal; -float intensity; - void main() { vec3 normal = normalize(eye_normal); @@ -21,7 +18,7 @@ void main() // Since these two are normalized the cosine is the dot product. Take the abs value to light the lines no matter in which direction the normal points. float NdotL = abs(dot(normal, LIGHT_TOP_DIR)); - intensity = light_intensity.x + NdotL * light_intensity.y; + float intensity = light_intensity.x + NdotL * light_intensity.y; // Perform the same lighting calculation for the 2nd light source. NdotL = abs(dot(normal, LIGHT_FRONT_DIR)); diff --git a/resources/shaders/toolpaths_lines.vs b/resources/shaders/toolpaths_lines.vs index 34d141bfe1..85d5c641f3 100644 --- a/resources/shaders/toolpaths_lines.vs +++ b/resources/shaders/toolpaths_lines.vs @@ -1,6 +1,5 @@ #version 110 -varying vec3 eye_position; varying vec3 eye_normal; vec3 world_normal() @@ -16,6 +15,5 @@ void main() { vec4 world_position = vec4(gl_Vertex.xyz, 1.0); gl_Position = gl_ModelViewProjectionMatrix * world_position; - eye_position = (gl_ModelViewMatrix * world_position).xyz; eye_normal = gl_NormalMatrix * world_normal(); } diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 00c899201a..de5933c7cf 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -57,7 +57,6 @@ // Enable G-Code viewer #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) #define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) -#define ENABLE_GCODE_VIEWER_SHADERS_EDITOR (0 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_DATA_CHECKING (0 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_RENDER_EXTRUSION_AS_TRIANGLES (1 && ENABLE_GCODE_VIEWER) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 70b571fe00..5e15889c86 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -504,9 +504,6 @@ void GCodeViewer::render() const #if ENABLE_GCODE_VIEWER_STATISTICS render_statistics(); #endif // ENABLE_GCODE_VIEWER_STATISTICS -#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR - render_shaders_editor(); -#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR } bool GCodeViewer::is_toolpath_move_type_visible(EMoveType type) const @@ -1385,18 +1382,8 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool void GCodeViewer::render_toolpaths() const { -#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR - float point_size = m_shaders_editor.points.point_size; - std::array light_intensity = { - m_shaders_editor.lines.lights.ambient, - m_shaders_editor.lines.lights.top_diffuse, - m_shaders_editor.lines.lights.front_diffuse, - m_shaders_editor.lines.lights.global - }; -#else float point_size = 0.8f; - std::array light_intensity = { 0.25f, 0.7f, 0.75f, 0.75f }; -#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR + std::array light_intensity = { 0.25f, 0.70f, 0.75f, 0.75f }; const Camera& camera = wxGetApp().plater()->get_camera(); double zoom = camera.get_zoom(); const std::array& viewport = camera.get_viewport(); @@ -1411,13 +1398,8 @@ void GCodeViewer::render_toolpaths() const auto render_as_points = [this, zoom, point_size, near_plane_height, set_uniform_color](const TBuffer& buffer, EOptionsColors color_id, GLShaderProgram& shader) { set_uniform_color(Options_Colors[static_cast(color_id)], shader); shader.set_uniform("zoom", zoom); -#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR - shader.set_uniform("percent_outline_radius", 0.01f * static_cast(m_shaders_editor.points.percent_outline)); - shader.set_uniform("percent_center_radius", 0.01f * static_cast(m_shaders_editor.points.percent_center)); -#else shader.set_uniform("percent_outline_radius", 0.0f); shader.set_uniform("percent_center_radius", 0.33f); -#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR shader.set_uniform("point_size", point_size); shader.set_uniform("near_plane_height", near_plane_height); @@ -1597,21 +1579,6 @@ void GCodeViewer::render_legend() const } case EItemType::Circle: { -#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR - ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size)); - if (m_shaders_editor.points.shader_version == 1) { - draw_list->AddCircleFilled(center, 0.5f * icon_size, - ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); - float radius = 0.5f * icon_size * (1.0f - 0.01f * static_cast(m_shaders_editor.points.percent_outline)); - draw_list->AddCircleFilled(center, radius, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); - if (m_shaders_editor.points.percent_center > 0) { - radius = 0.5f * icon_size * 0.01f * static_cast(m_shaders_editor.points.percent_center); - draw_list->AddCircleFilled(center, radius, ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); - } - } - else - draw_list->AddCircleFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); -#else ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size)); if (m_buffers[buffer_id(EMoveType::Retract)].shader == "options_120") { draw_list->AddCircleFilled(center, 0.5f * icon_size, @@ -1623,7 +1590,6 @@ void GCodeViewer::render_legend() const } else draw_list->AddCircleFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); -#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR break; } @@ -2175,11 +2141,7 @@ void GCodeViewer::render_legend() const auto add_option = [this, append_item](EMoveType move_type, EOptionsColors color, const std::string& text) { const TBuffer& buffer = m_buffers[buffer_id(move_type)]; if (buffer.visible && buffer.indices.count > 0) -#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR - append_item((m_shaders_editor.points.shader_version == 0) ? EItemType::Rect : EItemType::Circle, Options_Colors[static_cast(color)], text); -#else append_item((buffer.shader == "options_110") ? EItemType::Rect : EItemType::Circle, Options_Colors[static_cast(color)], text); -#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR }; // options section @@ -2652,68 +2614,6 @@ void GCodeViewer::render_statistics() const } #endif // ENABLE_GCODE_VIEWER_STATISTICS -#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR -void GCodeViewer::render_shaders_editor() const -{ - auto set_shader = [this](const std::string& shader) { - unsigned char begin_id = buffer_id(EMoveType::Retract); - unsigned char end_id = buffer_id(EMoveType::Custom_GCode); - for (unsigned char i = begin_id; i <= end_id; ++i) { - m_buffers[i].shader = shader; - } - }; - - ImGuiWrapper& imgui = *wxGetApp().imgui(); - - Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size(); - imgui.set_next_window_pos(static_cast(cnv_size.get_width()), 0.5f * static_cast(cnv_size.get_height()), ImGuiCond_Once, 1.0f, 0.5f); - - imgui.begin(std::string("Shaders editor (DEV only)"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize); - - if (ImGui::CollapsingHeader("Points", ImGuiTreeNodeFlags_DefaultOpen)) { - if (ImGui::TreeNode("GLSL version")) { - ImGui::RadioButton("1.10 (low end PCs)", &m_shaders_editor.points.shader_version, 0); - ImGui::RadioButton("1.20 flat (billboards) [default]", &m_shaders_editor.points.shader_version, 1); - ImGui::TreePop(); - } - - switch (m_shaders_editor.points.shader_version) - { - case 0: { set_shader("options_110"); break; } - case 1: { set_shader("options_120"); break; } - } - - if (ImGui::TreeNode("Options")) { - ImGui::SliderFloat("point size", &m_shaders_editor.points.point_size, 0.5f, 3.0f, "%.2f"); - if (m_shaders_editor.points.shader_version == 1) { - ImGui::SliderInt("% outline", &m_shaders_editor.points.percent_outline, 0, 50); - ImGui::SliderInt("% center", &m_shaders_editor.points.percent_center, 0, 50); - } - ImGui::TreePop(); - } - } - - if (ImGui::CollapsingHeader("Lines", ImGuiTreeNodeFlags_DefaultOpen)) { - if (ImGui::TreeNode("Lights")) { - ImGui::SliderFloat("ambient", &m_shaders_editor.lines.lights.ambient, 0.0f, 1.0f, "%.2f"); - ImGui::SliderFloat("top diffuse", &m_shaders_editor.lines.lights.top_diffuse, 0.0f, 1.0f, "%.2f"); - ImGui::SliderFloat("front diffuse", &m_shaders_editor.lines.lights.front_diffuse, 0.0f, 1.0f, "%.2f"); - ImGui::SliderFloat("global", &m_shaders_editor.lines.lights.global, 0.0f, 1.0f, "%.2f"); - ImGui::TreePop(); - } - } - - ImGui::SetWindowSize(ImVec2(std::max(ImGui::GetWindowWidth(), 600.0f), -1.0f), ImGuiCond_Always); - if (ImGui::GetWindowPos().x + ImGui::GetWindowWidth() > static_cast(cnv_size.get_width())) { - ImGui::SetWindowPos(ImVec2(static_cast(cnv_size.get_width()) - ImGui::GetWindowWidth(), ImGui::GetWindowPos().y), ImGuiCond_Always); - wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); - wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); - } - - imgui.end(); -} -#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR - bool GCodeViewer::is_travel_in_z_range(size_t id) const { const TBuffer& buffer = m_buffers[buffer_id(EMoveType::Travel)]; diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 919b9de6e1..55c8ea1993 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -289,35 +289,6 @@ class GCodeViewer }; #endif // ENABLE_GCODE_VIEWER_STATISTICS -#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR - struct ShadersEditor - { - struct Points - { - int shader_version{ 1 }; - float point_size{ 0.8f }; - int percent_outline{ 0 }; - int percent_center{ 33 }; - }; - - struct Lines - { - struct Lights - { - float ambient{ 0.25f }; - float top_diffuse{ 0.7f }; - float front_diffuse{ 0.75f }; - float global{ 0.75f }; - }; - - Lights lights; - }; - - Points points; - Lines lines; - }; -#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR - public: struct SequentialView { @@ -402,9 +373,6 @@ private: #if ENABLE_GCODE_VIEWER_STATISTICS mutable Statistics m_statistics; #endif // ENABLE_GCODE_VIEWER_STATISTICS -#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR - mutable ShadersEditor m_shaders_editor; -#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR std::array m_detected_point_sizes = { 0.0f, 0.0f }; public: @@ -475,9 +443,6 @@ private: #if ENABLE_GCODE_VIEWER_STATISTICS void render_statistics() const; #endif // ENABLE_GCODE_VIEWER_STATISTICS -#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR - void render_shaders_editor() const; -#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR bool is_visible(ExtrusionRole role) const { return role < erCount && (m_extrusions.role_visibility_flags & (1 << role)) != 0; } From 689c8691ee45947d1b7d1f626d8bd65b622f3cbd Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 27 Aug 2020 10:15:07 +0200 Subject: [PATCH 217/255] Another code cleanup --- src/libslic3r/Technologies.hpp | 1 - src/slic3r/GUI/GCodeViewer.cpp | 13 ------------- 2 files changed, 14 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index de5933c7cf..af08d16401 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -58,7 +58,6 @@ #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) #define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_DATA_CHECKING (0 && ENABLE_GCODE_VIEWER) -#define ENABLE_GCODE_RENDER_EXTRUSION_AS_TRIANGLES (1 && ENABLE_GCODE_VIEWER) #define TIME_ESTIMATE_NONE 0 #define TIME_ESTIMATE_DEFAULT 1 diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 5e15889c86..64916182ad 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -303,13 +303,8 @@ bool GCodeViewer::init() } case EMoveType::Extrude: { -#if ENABLE_GCODE_RENDER_EXTRUSION_AS_TRIANGLES buffer.primitive_type = TBuffer::EPrimitiveType::Triangle; buffer.vertices.format = VBuffer::EFormat::PositionNormal3; -#else - buffer.primitive_type = TBuffer::EPrimitiveType::Line; - buffer.vertices.format = VBuffer::EFormat::PositionNormal1; -#endif // ENABLE_GCODE_RENDER_EXTRUSION_AS_TRIANGLES break; } case EMoveType::Travel: @@ -873,11 +868,7 @@ void GCodeViewer::init_shaders() case EMoveType::Custom_GCode: { m_buffers[i].shader = is_glsl_120 ? "options_120" : "options_110"; break; } case EMoveType::Retract: { m_buffers[i].shader = is_glsl_120 ? "options_120" : "options_110"; break; } case EMoveType::Unretract: { m_buffers[i].shader = is_glsl_120 ? "options_120" : "options_110"; break; } -#if ENABLE_GCODE_RENDER_EXTRUSION_AS_TRIANGLES case EMoveType::Extrude: { m_buffers[i].shader = "gouraud_light"; break; } -#else - case EMoveType::Extrude: { m_buffers[i].shader = "toolpaths_lines"; break; } -#endif // ENABLE_GCODE_RENDER_EXTRUSION_AS_TRIANGLES case EMoveType::Travel: { m_buffers[i].shader = "toolpaths_lines"; break; } default: { break; } } @@ -1064,15 +1055,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) add_as_point(curr, buffer, buffer_vertices, buffer_indices, i); break; } -#if ENABLE_GCODE_RENDER_EXTRUSION_AS_TRIANGLES case EMoveType::Extrude: { add_as_solid(prev, curr, buffer, buffer_vertices, buffer_indices, i); break; } -#else - case EMoveType::Extrude: -#endif // ENABLE_GCODE_RENDER_EXTRUSION_AS_TRIANGLES case EMoveType::Travel: { add_as_line(prev, curr, buffer, buffer_vertices, buffer_indices, i); From 17170b81b51dfd7a99d1f3ef7f7d9038bf3502c0 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 27 Aug 2020 12:14:49 +0200 Subject: [PATCH 218/255] Clean-up of Shiny profiler integration, so that the intrusiver profiling can be controlled per module. --- src/clipper/clipper.cpp | 58 ++++++++++++++++++++-------------- src/libslic3r/ClipperUtils.cpp | 25 ++++++++++----- src/slic3r/CMakeLists.txt | 1 + src/slic3r/Utils/Profile.hpp | 19 +++++++++++ 4 files changed, 71 insertions(+), 32 deletions(-) create mode 100644 src/slic3r/Utils/Profile.hpp diff --git a/src/clipper/clipper.cpp b/src/clipper/clipper.cpp index b85cf9025e..be4cb4a6a8 100644 --- a/src/clipper/clipper.cpp +++ b/src/clipper/clipper.cpp @@ -48,9 +48,19 @@ #include #include #include -#include #include +// Profiling support using the Shiny intrusive profiler +//#define CLIPPERLIB_PROFILE +#if defined(SLIC3R_PROFILE) && defined(CLIPPERLIB_PROFILE) + #include + #define CLIPPERLIB_PROFILE_FUNC() PROFILE_FUNC() + #define CLIPPERLIB_PROFILE_BLOCK(name) PROFILE_BLOCK(name) +#else + #define CLIPPERLIB_PROFILE_FUNC() + #define CLIPPERLIB_PROFILE_BLOCK(name) +#endif + #ifdef use_xyz namespace ClipperLib_Z { #else /* use_xyz */ @@ -263,7 +273,7 @@ int PointInPolygon (const IntPoint &pt, OutPt *op) // This is potentially very expensive! O(n^2)! bool Poly2ContainsPoly1(OutPt *OutPt1, OutPt *OutPt2) { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); OutPt* op = OutPt1; do { @@ -714,7 +724,7 @@ TEdge* ClipperBase::ProcessBound(TEdge* E, bool NextIsForward) bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed) { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); // Remove duplicate end point from a closed input path. // Remove duplicate points from the end of the input path. int highI = (int)pg.size() -1; @@ -738,7 +748,7 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed) bool ClipperBase::AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed) { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); std::vector num_edges(ppg.size(), 0); int num_edges_total = 0; for (size_t i = 0; i < ppg.size(); ++ i) { @@ -780,7 +790,7 @@ bool ClipperBase::AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed) bool ClipperBase::AddPathInternal(const Path &pg, int highI, PolyType PolyTyp, bool Closed, TEdge* edges) { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); #ifdef use_lines if (!Closed && PolyTyp == ptClip) throw clipperException("AddPath: Open paths must be subject."); @@ -954,7 +964,7 @@ bool ClipperBase::AddPathInternal(const Path &pg, int highI, PolyType PolyTyp, b void ClipperBase::Clear() { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); m_MinimaList.clear(); m_edges.clear(); m_UseFullRange = false; @@ -966,7 +976,7 @@ void ClipperBase::Clear() // Sort the LML entries, initialize the left / right bound edges of each Local Minima. void ClipperBase::Reset() { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); if (m_MinimaList.empty()) return; //ie nothing to process std::sort(m_MinimaList.begin(), m_MinimaList.end(), [](const LocalMinimum& lm1, const LocalMinimum& lm2){ return lm1.Y < lm2.Y; }); @@ -995,7 +1005,7 @@ void ClipperBase::Reset() // Returns (0,0,0,0) for an empty rectangle. IntRect ClipperBase::GetBounds() { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); IntRect result; auto lm = m_MinimaList.begin(); if (lm == m_MinimaList.end()) @@ -1056,7 +1066,7 @@ Clipper::Clipper(int initOptions) : void Clipper::Reset() { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); ClipperBase::Reset(); m_Scanbeam = std::priority_queue(); m_Maxima.clear(); @@ -1071,7 +1081,7 @@ void Clipper::Reset() bool Clipper::Execute(ClipType clipType, Paths &solution, PolyFillType subjFillType, PolyFillType clipFillType) { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); if (m_HasOpenPaths) throw clipperException("Error: PolyTree struct is needed for open path clipping."); solution.resize(0); @@ -1089,7 +1099,7 @@ bool Clipper::Execute(ClipType clipType, Paths &solution, bool Clipper::Execute(ClipType clipType, PolyTree& polytree, PolyFillType subjFillType, PolyFillType clipFillType) { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); m_SubjFillType = subjFillType; m_ClipFillType = clipFillType; m_ClipType = clipType; @@ -1103,10 +1113,10 @@ bool Clipper::Execute(ClipType clipType, PolyTree& polytree, bool Clipper::ExecuteInternal() { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); bool succeeded = true; try { - PROFILE_BLOCK(Clipper_ExecuteInternal_Process); + CLIPPERLIB_PROFILE_BLOCK(Clipper_ExecuteInternal_Process); Reset(); if (m_MinimaList.empty()) return true; cInt botY = m_Scanbeam.top(); @@ -1131,13 +1141,13 @@ bool Clipper::ExecuteInternal() if (succeeded) { - PROFILE_BLOCK(Clipper_ExecuteInternal_Fix); + CLIPPERLIB_PROFILE_BLOCK(Clipper_ExecuteInternal_Fix); //fix orientations ... //FIXME Vojtech: Does it not invalidate the loop hierarchy maintained as OutRec::FirstLeft pointers? //FIXME Vojtech: The area is calculated with floats, it may not be numerically stable! { - PROFILE_BLOCK(Clipper_ExecuteInternal_Fix_orientations); + CLIPPERLIB_PROFILE_BLOCK(Clipper_ExecuteInternal_Fix_orientations); for (OutRec *outRec : m_PolyOuts) if (outRec->Pts && !outRec->IsOpen && (outRec->IsHole ^ m_ReverseOutput) == (Area(*outRec) > 0)) ReversePolyPtLinks(outRec->Pts); @@ -1147,7 +1157,7 @@ bool Clipper::ExecuteInternal() //unfortunately FixupOutPolygon() must be done after JoinCommonEdges() { - PROFILE_BLOCK(Clipper_ExecuteInternal_Fix_fixup); + CLIPPERLIB_PROFILE_BLOCK(Clipper_ExecuteInternal_Fix_fixup); for (OutRec *outRec : m_PolyOuts) if (outRec->Pts) { if (outRec->IsOpen) @@ -1401,7 +1411,7 @@ bool Clipper::IsContributing(const TEdge& edge) const // Called from Clipper::InsertLocalMinimaIntoAEL() and Clipper::IntersectEdges(). OutPt* Clipper::AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt) { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); OutPt* result; TEdge *e, *prevE; if (IsHorizontal(*e2) || ( e1->Dx > e2->Dx )) @@ -1493,7 +1503,7 @@ void Clipper::CopyAELToSEL() // Called from Clipper::ExecuteInternal() void Clipper::InsertLocalMinimaIntoAEL(const cInt botY) { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); while (!m_MinimaList.empty() && m_MinimaList.back().Y == botY) { TEdge* lb = m_MinimaList.back().LeftBound; @@ -2043,7 +2053,7 @@ OutPt* Clipper::GetLastOutPt(TEdge *e) void Clipper::ProcessHorizontals() { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); TEdge* horzEdge = m_SortedEdges; while(horzEdge) { @@ -2414,7 +2424,7 @@ void Clipper::UpdateEdgeIntoAEL(TEdge *&e) bool Clipper::ProcessIntersections(const cInt topY) { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); if( !m_ActiveEdges ) return true; try { BuildIntersectList(topY); @@ -2569,7 +2579,7 @@ void Clipper::DoMaxima(TEdge *e) void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY) { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); TEdge* e = m_ActiveEdges; while( e ) { @@ -3177,7 +3187,7 @@ bool Clipper::JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2) // This is potentially very expensive! O(n^3)! void Clipper::FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec) const { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); //tests if NewOutRec contains the polygon before reassigning FirstLeft for (OutRec *outRec : m_PolyOuts) { @@ -3201,7 +3211,7 @@ void Clipper::FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec) const void Clipper::JoinCommonEdges() { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); for (Join &join : m_Joins) { OutRec *outRec1 = GetOutRec(join.OutPt1->Idx); @@ -3771,7 +3781,7 @@ void ClipperOffset::DoRound(int j, int k) // http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Classes/Clipper/Properties/StrictlySimple.htm void Clipper::DoSimplePolygons() { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); size_t i = 0; while (i < m_PolyOuts.size()) { diff --git a/src/libslic3r/ClipperUtils.cpp b/src/libslic3r/ClipperUtils.cpp index d40d79b3d8..16d985e9c9 100644 --- a/src/libslic3r/ClipperUtils.cpp +++ b/src/libslic3r/ClipperUtils.cpp @@ -8,7 +8,16 @@ #include "SVG.hpp" #endif /* CLIPPER_UTILS_DEBUG */ -#include +// Profiling support using the Shiny intrusive profiler +//#define CLIPPER_UTILS_PROFILE +#if defined(SLIC3R_PROFILE) && defined(CLIPPER_UTILS_PROFILE) + #include + #define CLIPPERUTILS_PROFILE_FUNC() PROFILE_FUNC() + #define CLIPPERUTILS_PROFILE_BLOCK(name) PROFILE_BLOCK(name) +#else + #define CLIPPERUTILS_PROFILE_FUNC() + #define CLIPPERUTILS_PROFILE_BLOCK(name) +#endif #define CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR (0.005f) @@ -50,7 +59,7 @@ err: void scaleClipperPolygon(ClipperLib::Path &polygon) { - PROFILE_FUNC(); + CLIPPERUTILS_PROFILE_FUNC(); for (ClipperLib::Path::iterator pit = polygon.begin(); pit != polygon.end(); ++pit) { pit->X <<= CLIPPER_OFFSET_POWER_OF_2; pit->Y <<= CLIPPER_OFFSET_POWER_OF_2; @@ -59,7 +68,7 @@ void scaleClipperPolygon(ClipperLib::Path &polygon) void scaleClipperPolygons(ClipperLib::Paths &polygons) { - PROFILE_FUNC(); + CLIPPERUTILS_PROFILE_FUNC(); for (ClipperLib::Paths::iterator it = polygons.begin(); it != polygons.end(); ++it) for (ClipperLib::Path::iterator pit = (*it).begin(); pit != (*it).end(); ++pit) { pit->X <<= CLIPPER_OFFSET_POWER_OF_2; @@ -69,7 +78,7 @@ void scaleClipperPolygons(ClipperLib::Paths &polygons) void unscaleClipperPolygon(ClipperLib::Path &polygon) { - PROFILE_FUNC(); + CLIPPERUTILS_PROFILE_FUNC(); for (ClipperLib::Path::iterator pit = polygon.begin(); pit != polygon.end(); ++pit) { pit->X += CLIPPER_OFFSET_SCALE_ROUNDING_DELTA; pit->Y += CLIPPER_OFFSET_SCALE_ROUNDING_DELTA; @@ -80,7 +89,7 @@ void unscaleClipperPolygon(ClipperLib::Path &polygon) void unscaleClipperPolygons(ClipperLib::Paths &polygons) { - PROFILE_FUNC(); + CLIPPERUTILS_PROFILE_FUNC(); for (ClipperLib::Paths::iterator it = polygons.begin(); it != polygons.end(); ++it) for (ClipperLib::Path::iterator pit = (*it).begin(); pit != (*it).end(); ++pit) { pit->X += CLIPPER_OFFSET_SCALE_ROUNDING_DELTA; @@ -790,7 +799,7 @@ ExPolygons simplify_polygons_ex(const Polygons &subject, bool preserve_collinear void safety_offset(ClipperLib::Paths* paths) { - PROFILE_FUNC(); + CLIPPERUTILS_PROFILE_FUNC(); // scale input scaleClipperPolygons(*paths); @@ -812,11 +821,11 @@ void safety_offset(ClipperLib::Paths* paths) if (! ccw) std::reverse(path.begin(), path.end()); { - PROFILE_BLOCK(safety_offset_AddPaths); + CLIPPERUTILS_PROFILE_BLOCK(safety_offset_AddPaths); co.AddPath((*paths)[i], ClipperLib::jtMiter, ClipperLib::etClosedPolygon); } { - PROFILE_BLOCK(safety_offset_Execute); + CLIPPERUTILS_PROFILE_BLOCK(safety_offset_Execute); // offset outside by 10um ClipperLib::Paths out_this; co.Execute(out_this, ccw ? 10.f * float(CLIPPER_OFFSET_SCALE) : -10.f * float(CLIPPER_OFFSET_SCALE)); diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index f8598cea08..8a2672c774 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -181,6 +181,7 @@ set(SLIC3R_GUI_SOURCES Utils/Bonjour.hpp Utils/PresetUpdater.cpp Utils/PresetUpdater.hpp + Utils/Profile.hpp Utils/UndoRedo.cpp Utils/UndoRedo.hpp Utils/HexFile.cpp diff --git a/src/slic3r/Utils/Profile.hpp b/src/slic3r/Utils/Profile.hpp new file mode 100644 index 0000000000..5fb1e31167 --- /dev/null +++ b/src/slic3r/Utils/Profile.hpp @@ -0,0 +1,19 @@ +#ifndef slic3r_GUI_Profile_hpp_ +#define slic3r_GUI_Profile_hpp_ + +// Profiling support using the Shiny intrusive profiler +//#define SLIC3R_PROFILE_GUI +#if defined(SLIC3R_PROFILE) && defined(SLIC3R_PROFILE_GUI) + #include + #define SLIC3R_GUI_PROFILE_FUNC() PROFILE_FUNC() + #define SLIC3R_GUI_PROFILE_BLOCK(name) PROFILE_BLOCK(name) + #define SLIC3R_GUI_PROFILE_UPDATE() PROFILE_UPDATE() + #define SLIC3R_GUI_PROFILE_OUTPUT(x) PROFILE_OUTPUT(x) +#else + #define SLIC3R_GUI_PROFILE_FUNC() + #define SLIC3R_GUI_PROFILE_BLOCK(name) + #define SLIC3R_GUI_PROFILE_UPDATE() + #define SLIC3R_GUI_PROFILE_OUTPUT(x) +#endif + +#endif // slic3r_GUI_Profile_hpp_ From 8af3659e9890fd2c5d146cf9226b7517652278c5 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 27 Aug 2020 13:11:28 +0200 Subject: [PATCH 219/255] GCodeViewer -> Fixed generation of solid toolpaths --- src/slic3r/GUI/GCodeViewer.cpp | 59 +++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 23 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 64916182ad..8cb18f4e18 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -977,16 +977,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) buffer_indices.push_back(i3); }; - Vec3f dir = (curr.position - prev.position).normalized(); - Vec3f right = (std::abs(std::abs(dir.dot(Vec3f::UnitZ())) - 1.0f) < EPSILON) ? -Vec3f::UnitY() : Vec3f(dir[1], -dir[0], 0.0f).normalized(); - Vec3f up = right.cross(dir); - float prev_half_width = 0.5f * prev.width; - float prev_half_height = 0.5f * prev.height; - float curr_half_width = 0.5f * curr.width; - float curr_half_height = 0.5f * curr.height; - Vec3f prev_pos = Vec3f(prev.position[0], prev.position[1], prev.position[2]) - prev_half_height * up; - Vec3f curr_pos = Vec3f(curr.position[0], curr.position[1], curr.position[2]) - curr_half_height * up; - if (prev.type != curr.type || !buffer.paths.back().matches(curr)) { buffer.add_path(curr, static_cast(buffer_indices.size()), static_cast(move_id - 1)); buffer.paths.back().first.position = prev.position; @@ -994,17 +984,27 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) unsigned int starting_vertices_size = static_cast(buffer_vertices.size() / buffer.vertices.vertex_size_floats()); + Vec3f dir = (curr.position - prev.position).normalized(); + Vec3f right = (std::abs(std::abs(dir.dot(Vec3f::UnitZ())) - 1.0f) < EPSILON) ? -Vec3f::UnitY() : Vec3f(dir[1], -dir[0], 0.0f).normalized(); + Vec3f up = right.cross(dir); + + float half_width = 0.5f * round_to_nearest(curr.width, 2); + float half_height = 0.5f * round_to_nearest(curr.height, 2); + + Vec3f prev_pos = prev.position - half_height * up; + Vec3f curr_pos = curr.position - half_height * up; + // vertices 1st endpoint - store_vertex(buffer_vertices, prev_pos + prev_half_height * up, up); // top - store_vertex(buffer_vertices, prev_pos + prev_half_width * right, right); // right - store_vertex(buffer_vertices, prev_pos - prev_half_height * up, -up); // bottom - store_vertex(buffer_vertices, prev_pos - prev_half_width * right, -right); // left + store_vertex(buffer_vertices, prev_pos + half_height * up, up); // top + store_vertex(buffer_vertices, prev_pos + half_width * right, right); // right + store_vertex(buffer_vertices, prev_pos - half_height * up, -up); // bottom + store_vertex(buffer_vertices, prev_pos - half_width * right, -right); // left // vertices 2nd endpoint - store_vertex(buffer_vertices, curr_pos + curr_half_height * up, up); // top - store_vertex(buffer_vertices, curr_pos + curr_half_width * right, right); // right - store_vertex(buffer_vertices, curr_pos - curr_half_height * up, -up); // bottom - store_vertex(buffer_vertices, curr_pos - curr_half_width * right, -right); // left + store_vertex(buffer_vertices, curr_pos + half_height * up, up); // top + store_vertex(buffer_vertices, curr_pos + half_width * right, right); // right + store_vertex(buffer_vertices, curr_pos - half_height * up, -up); // bottom + store_vertex(buffer_vertices, curr_pos - half_width * right, -right); // left // triangles starting cap store_triangle(buffer_indices, starting_vertices_size + 0, starting_vertices_size + 2, starting_vertices_size + 1); @@ -1104,8 +1104,21 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) for (const TBuffer& buffer : m_buffers) { m_statistics.paths_size += SLIC3R_STDVEC_MEMSIZE(buffer.paths, Path); } - m_statistics.travel_segments_count = indices[buffer_id(EMoveType::Travel)].size() / 2; - m_statistics.extrude_segments_count = indices[buffer_id(EMoveType::Extrude)].size() / 2; + unsigned int travel_buffer_id = buffer_id(EMoveType::Travel); + switch (m_buffers[travel_buffer_id].primitive_type) + { + case TBuffer::EPrimitiveType::Line: { m_statistics.travel_segments_count = indices[travel_buffer_id].size() / 2; break; } + case TBuffer::EPrimitiveType::Triangle: { m_statistics.travel_segments_count = indices[travel_buffer_id].size() / 36; break; } + default: { break; } + } + + unsigned int extrude_buffer_id = buffer_id(EMoveType::Extrude); + switch (m_buffers[extrude_buffer_id].primitive_type) + { + case TBuffer::EPrimitiveType::Line: { m_statistics.extrude_segments_count = indices[extrude_buffer_id].size() / 2; break; } + case TBuffer::EPrimitiveType::Triangle: { m_statistics.extrude_segments_count = indices[extrude_buffer_id].size() / 36; break; } + default: { break; } + } #endif // ENABLE_GCODE_VIEWER_STATISTICS // layers zs / roles / extruder ids / cp color ids -> extract from result @@ -2583,17 +2596,17 @@ void GCodeViewer::render_statistics() const ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.vertices_gpu_size) + " bytes"); - imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, std::string("Vertices GPU:")); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, std::string("Indices GPU:")); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.indices_gpu_size) + " bytes"); ImGui::Separator(); - imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, std::string("Vertices GPU:")); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, std::string("Travel segments count:")); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.travel_segments_count)); - imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, std::string("Extrude segments:")); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, std::string("Extrude segments count:")); ImGui::SameLine(offset); imgui.text(std::to_string(m_statistics.extrude_segments_count)); From 19e1d877aa0c9d7517a0f5e0aca03838871e962c Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Fri, 24 Apr 2020 12:46:35 +0200 Subject: [PATCH 220/255] Don't use sla::EncodedRaster in SLAImport, revive opencsg sandbox --- sandboxes/opencsg/CMakeLists.txt | 1 + sandboxes/opencsg/main.cpp | 2 +- src/libslic3r/SLA/AGGRaster.hpp | 9 +++++---- src/slic3r/Utils/SLAImport.cpp | 21 +++++++++++---------- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/sandboxes/opencsg/CMakeLists.txt b/sandboxes/opencsg/CMakeLists.txt index ec1f4cae91..ace8f4d539 100644 --- a/sandboxes/opencsg/CMakeLists.txt +++ b/sandboxes/opencsg/CMakeLists.txt @@ -6,6 +6,7 @@ add_executable(opencsg_example WIN32 main.cpp Engine.hpp Engine.cpp ShaderCSGDisplay.hpp ShaderCSGDisplay.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/../../src/slic3r/GUI/Jobs/Job.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../src/slic3r/GUI/ProgressStatusBar.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../src/slic3r/GUI/I18N.hpp ${CMAKE_CURRENT_SOURCE_DIR}/../../src/slic3r/GUI/I18N.cpp) diff --git a/sandboxes/opencsg/main.cpp b/sandboxes/opencsg/main.cpp index adf9cc457f..f5fb124935 100644 --- a/sandboxes/opencsg/main.cpp +++ b/sandboxes/opencsg/main.cpp @@ -26,7 +26,7 @@ #include "libslic3r/Format/3mf.hpp" #include "libslic3r/SLAPrint.hpp" -#include "slic3r/GUI/Job.hpp" +#include "slic3r/GUI/Jobs/Job.hpp" #include "slic3r/GUI/ProgressStatusBar.hpp" using namespace Slic3r::GL; diff --git a/src/libslic3r/SLA/AGGRaster.hpp b/src/libslic3r/SLA/AGGRaster.hpp index 37baed9e88..917f718e98 100644 --- a/src/libslic3r/SLA/AGGRaster.hpp +++ b/src/libslic3r/SLA/AGGRaster.hpp @@ -128,12 +128,13 @@ protected: } public: - template AGGRaster(const Resolution &res, + template + AGGRaster(const Resolution &res, const PixelDim & pd, const Trafo & trafo, - const TColor & foreground, - const TColor & background, - GammaFn && gammafn) + const TColor & foreground, + const TColor & background, + GammaFn && gammafn) : m_resolution(res) , m_pxdim_scaled(SCALING_FACTOR / pd.w_mm, SCALING_FACTOR / pd.h_mm) , m_buf(res.pixels()) diff --git a/src/slic3r/Utils/SLAImport.cpp b/src/slic3r/Utils/SLAImport.cpp index 442025a77d..65ec46343d 100644 --- a/src/slic3r/Utils/SLAImport.cpp +++ b/src/slic3r/Utils/SLAImport.cpp @@ -43,9 +43,11 @@ namespace Slic3r { namespace { +struct PNGBuffer { std::vector buf; std::string fname; }; + struct ArchiveData { boost::property_tree::ptree profile, config; - std::vector images; + std::vector images; }; static const constexpr char *CONFIG_FNAME = "config.ini"; @@ -66,7 +68,7 @@ boost::property_tree::ptree read_ini(const mz_zip_archive_file_stat &entry, return tree; } -sla::EncodedRaster read_png(const mz_zip_archive_file_stat &entry, +PNGBuffer read_png(const mz_zip_archive_file_stat &entry, MZ_Archive & zip, const std::string & name) { @@ -75,9 +77,8 @@ sla::EncodedRaster read_png(const mz_zip_archive_file_stat &entry, if (!mz_zip_reader_extract_file_to_mem(&zip.arch, entry.m_filename, buf.data(), buf.size(), 0)) throw std::runtime_error(zip.get_errorstr()); - - return sla::EncodedRaster(std::move(buf), - name.empty() ? entry.m_filename : name); + + return {std::move(buf), (name.empty() ? entry.m_filename : name)}; } ArchiveData extract_sla_archive(const std::string &zipfname, @@ -113,9 +114,9 @@ ArchiveData extract_sla_archive(const std::string &zipfname, if (boost::filesystem::path(name).extension().string() == ".png") { auto it = std::lower_bound( - arch.images.begin(), arch.images.end(), sla::EncodedRaster({}, name), - [](const sla::EncodedRaster &r1, const sla::EncodedRaster &r2) { - return std::less()(r1.extension(), r2.extension()); + arch.images.begin(), arch.images.end(), PNGBuffer{{}, name}, + [](const PNGBuffer &r1, const PNGBuffer &r2) { + return std::less()(r1.fname, r2.fname); }); arch.images.insert(it, read_png(entry, zip, name)); @@ -258,8 +259,8 @@ std::vector extract_slices_from_sla_archive( } } - auto &buf = arch.images[i]; - wxMemoryInputStream stream{buf.data(), buf.size()}; + PNGBuffer &png = arch.images[i]; + wxMemoryInputStream stream{png.buf.data(), png.buf.size()}; wxImage img{stream}; auto rings = marchsq::execute(img, 128, rstp.win); From 2bcd36d155d0fce0041faac6a89a3fe211830041 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Mon, 27 Apr 2020 18:43:47 +0200 Subject: [PATCH 221/255] PNG image read with libpng --- src/libslic3r/CMakeLists.txt | 4 +++ src/libslic3r/PNGRead.cpp | 59 +++++++++++++++++++++++++++++++++ src/libslic3r/PNGRead.hpp | 30 +++++++++++++++++ src/slic3r/Utils/SLAImport.cpp | 32 +++++++++--------- tests/libslic3r/CMakeLists.txt | 2 ++ tests/libslic3r/test_png_io.cpp | 52 +++++++++++++++++++++++++++++ 6 files changed, 164 insertions(+), 15 deletions(-) create mode 100644 src/libslic3r/PNGRead.cpp create mode 100644 src/libslic3r/PNGRead.hpp create mode 100644 tests/libslic3r/test_png_io.cpp diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index 290b8953cc..aea3247220 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -161,6 +161,8 @@ add_library(libslic3r STATIC PrintConfig.hpp PrintObject.cpp PrintRegion.cpp + PNGRead.hpp + PNGRead.cpp Semver.cpp ShortestPath.cpp ShortestPath.hpp @@ -308,6 +310,8 @@ target_link_libraries(libslic3r TBB::tbb libslic3r_cgal ${CMAKE_DL_LIBS} + PNG::PNG + ZLIB::ZLIB ) if (TARGET OpenVDB::openvdb) diff --git a/src/libslic3r/PNGRead.cpp b/src/libslic3r/PNGRead.cpp new file mode 100644 index 0000000000..8bfa3cb951 --- /dev/null +++ b/src/libslic3r/PNGRead.cpp @@ -0,0 +1,59 @@ +#include "PNGRead.hpp" + +#include + +#include +#include + +namespace Slic3r { namespace png { + +struct png_deleter { void operator()(png_struct *p) { + png_destroy_read_struct( &p, nullptr, nullptr); } +}; + +using png_ptr_t = std::unique_ptr; + +bool is_png(const ReadBuf &rb) +{ + static const constexpr int PNG_SIG_BYTES = 8; + + return rb.sz >= PNG_SIG_BYTES && + !png_sig_cmp(static_cast(rb.buf), 0, PNG_SIG_BYTES); +} + +bool decode_png(const ReadBuf &rb, ImageGreyscale &img) +{ + if (!is_png(rb)) return false; + + png_ptr_t png{png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr)}; + + if(!png) return false; + + png_infop info = png_create_info_struct(png.get()); + if(!info) return {}; + + FILE *io = ::fmemopen(const_cast(rb.buf), rb.sz, "rb"); + png_init_io(png.get(), io); + + png_read_info(png.get(), info); + + img.cols = png_get_image_width(png.get(), info); + img.rows = png_get_image_height(png.get(), info); + size_t color_type = png_get_color_type(png.get(), info); + size_t bit_depth = png_get_bit_depth(png.get(), info); + + if (color_type != PNG_COLOR_TYPE_GRAY || bit_depth != 8) + return false; + + img.buf.resize(img.rows * img.cols); + + auto readbuf = static_cast(img.buf.data()); + for (size_t r = 0; r < img.rows; ++r) + png_read_row(png.get(), readbuf + r * img.cols, nullptr); + + fclose(io); + + return true; +} + +}} diff --git a/src/libslic3r/PNGRead.hpp b/src/libslic3r/PNGRead.hpp new file mode 100644 index 0000000000..88a948395b --- /dev/null +++ b/src/libslic3r/PNGRead.hpp @@ -0,0 +1,30 @@ +#ifndef PNGREAD_HPP +#define PNGREAD_HPP + +#include +#include + +namespace Slic3r { namespace png { + +struct ReadBuf { const void *buf = nullptr; const size_t sz = 0; }; + +template struct Image { + std::vector buf; + size_t rows, cols; + PxT get(size_t row, size_t col) const { return buf[row * cols + col]; } +}; + +struct RGB { uint8_t r, g, b; }; + +using ImageRGB = Image; +using ImageGreyscale = Image; + +// TODO +// bool decode_png(Buffer &&pngbuf, ImageRGB &img); + +bool is_png(const ReadBuf &pngbuf); + +bool decode_png(const ReadBuf &pngbuf, ImageGreyscale &img); + +}} +#endif // PNGREAD_HPP diff --git a/src/slic3r/Utils/SLAImport.cpp b/src/slic3r/Utils/SLAImport.cpp index 65ec46343d..13ea603396 100644 --- a/src/slic3r/Utils/SLAImport.cpp +++ b/src/slic3r/Utils/SLAImport.cpp @@ -9,32 +9,31 @@ #include "libslic3r/PrintConfig.hpp" #include "libslic3r/SLA/RasterBase.hpp" #include "libslic3r/miniz_extension.hpp" +#include "libslic3r/PNGRead.hpp" #include #include #include -#include #include namespace marchsq { -// Specialize this struct to register a raster type for the Marching squares alg -template<> struct _RasterTraits { - using Rst = wxImage; - +template<> struct _RasterTraits { + using Rst = Slic3r::png::ImageGreyscale; + // The type of pixel cell in the raster using ValueType = uint8_t; - + // Value at a given position static uint8_t get(const Rst &rst, size_t row, size_t col) { - return rst.GetRed(col, row); + return rst.get(row, col); } // Number of rows and cols of the raster - static size_t rows(const Rst &rst) { return rst.GetHeight(); } - static size_t cols(const Rst &rst) { return rst.GetWidth(); } + static size_t rows(const Rst &rst) { return rst.rows; } + static size_t cols(const Rst &rst) { return rst.cols; } }; } // namespace marchsq @@ -44,7 +43,6 @@ namespace Slic3r { namespace { struct PNGBuffer { std::vector buf; std::string fname; }; - struct ArchiveData { boost::property_tree::ptree profile, config; std::vector images; @@ -69,8 +67,8 @@ boost::property_tree::ptree read_ini(const mz_zip_archive_file_stat &entry, } PNGBuffer read_png(const mz_zip_archive_file_stat &entry, - MZ_Archive & zip, - const std::string & name) + MZ_Archive & zip, + const std::string & name) { std::vector buf(entry.m_uncomp_size); @@ -259,9 +257,13 @@ std::vector extract_slices_from_sla_archive( } } - PNGBuffer &png = arch.images[i]; - wxMemoryInputStream stream{png.buf.data(), png.buf.size()}; - wxImage img{stream}; +// PNGBuffer &png = arch.images[i]; +// wxMemoryInputStream stream{png.buf.data(), png.buf.size()}; +// wxImage img{stream}; + + png::ImageGreyscale img; + png::ReadBuf rb{arch.images[i].buf.data(), arch.images[i].buf.size()}; + png::decode_png(rb, img); auto rings = marchsq::execute(img, 128, rstp.win); ExPolygons expolys = rings_to_expolygons(rings, rstp.px_w, rstp.px_h); diff --git a/tests/libslic3r/CMakeLists.txt b/tests/libslic3r/CMakeLists.txt index 5a1e8f18b7..30b93eafc9 100644 --- a/tests/libslic3r/CMakeLists.txt +++ b/tests/libslic3r/CMakeLists.txt @@ -17,6 +17,8 @@ add_executable(${_TEST_NAME}_tests test_marchingsquares.cpp test_timeutils.cpp test_voronoi.cpp + test_png_io.cpp + test_timeutils.cpp ) if (TARGET OpenVDB::openvdb) diff --git a/tests/libslic3r/test_png_io.cpp b/tests/libslic3r/test_png_io.cpp new file mode 100644 index 0000000000..3378d0062e --- /dev/null +++ b/tests/libslic3r/test_png_io.cpp @@ -0,0 +1,52 @@ +#define NOMINMAX +#include + +#include "libslic3r/PNGRead.hpp" +#include "libslic3r/SLA/AGGRaster.hpp" + +using namespace Slic3r; + +static sla::RasterGrayscaleAA create_raster(const sla::RasterBase::Resolution &res) +{ + sla::RasterBase::PixelDim pixdim{1., 1.}; + + auto bb = BoundingBox({0, 0}, {scaled(1.), scaled(1.)}); + sla::RasterBase::Trafo trafo; + trafo.center_x = bb.center().x(); + trafo.center_y = bb.center().y(); + + return sla::RasterGrayscaleAA{res, pixdim, trafo, agg::gamma_threshold(.5)}; +} + +TEST_CASE("PNG read", "[PNG]") { + auto rst = create_raster({100, 100}); + + size_t rstsum = 0; + for (size_t r = 0; r < rst.resolution().height_px; ++r) + for (size_t c = 0; c < rst.resolution().width_px; ++c) + rstsum += rst.read_pixel(c, r); + + SECTION("Correct png buffer should be recognized as such.") { + auto enc_rst = rst.encode(sla::PNGRasterEncoder{}); + REQUIRE(Slic3r::png::is_png({enc_rst.data(), enc_rst.size()})); + } + + SECTION("Fake png buffer should be recognized as such.") { + std::vector fake(10, '\0'); + REQUIRE(!Slic3r::png::is_png({fake.data(), fake.size()})); + } + + SECTION("Decoded PNG buffer resolution should match the original") { + auto enc_rst = rst.encode(sla::PNGRasterEncoder{}); + + png::ImageGreyscale img; + png::decode_png({enc_rst.data(), enc_rst.size()}, img); + + REQUIRE(img.rows == rst.resolution().height_px); + REQUIRE(img.cols == rst.resolution().width_px); + + size_t sum = std::accumulate(img.buf.begin(), img.buf.end(), size_t(0)); + + REQUIRE(sum == rstsum); + } +} From 769ee15475a3edc10c8dd29db8e853675091677e Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 28 Apr 2020 20:21:29 +0200 Subject: [PATCH 222/255] Move SLA import to libslic3r with png reading using libpng Also fix flipped object issue --- src/libslic3r/Format/SL1.cpp | 306 ++++++++++++++++++++++++++ src/libslic3r/Format/SL1.hpp | 18 ++ src/libslic3r/PNGRead.cpp | 41 ++-- src/libslic3r/PNGRead.hpp | 10 +- src/slic3r/CMakeLists.txt | 2 - src/slic3r/GUI/GUI_ObjectList.hpp | 2 +- src/slic3r/GUI/Jobs/SLAImportJob.cpp | 3 +- src/slic3r/Utils/SLAImport.cpp | 317 --------------------------- src/slic3r/Utils/SLAImport.hpp | 35 --- 9 files changed, 359 insertions(+), 375 deletions(-) delete mode 100644 src/slic3r/Utils/SLAImport.cpp delete mode 100644 src/slic3r/Utils/SLAImport.hpp diff --git a/src/libslic3r/Format/SL1.cpp b/src/libslic3r/Format/SL1.cpp index 5c402ef5bf..3d672eccb4 100644 --- a/src/libslic3r/Format/SL1.cpp +++ b/src/libslic3r/Format/SL1.cpp @@ -8,8 +8,314 @@ #include "libslic3r/Zipper.hpp" #include "libslic3r/SLAPrint.hpp" +#include + +#include "libslic3r/SlicesToTriangleMesh.hpp" +#include "libslic3r/MarchingSquares.hpp" +#include "libslic3r/ClipperUtils.hpp" +#include "libslic3r/MTUtils.hpp" +#include "libslic3r/PrintConfig.hpp" +#include "libslic3r/SLA/RasterBase.hpp" +#include "libslic3r/miniz_extension.hpp" +#include "libslic3r/PNGRead.hpp" + +#include +#include +#include + +namespace marchsq { + +template<> struct _RasterTraits { + using Rst = Slic3r::png::ImageGreyscale; + + // The type of pixel cell in the raster + using ValueType = uint8_t; + + // Value at a given position + static uint8_t get(const Rst &rst, size_t row, size_t col) + { + return rst.get(row, col); + } + + // Number of rows and cols of the raster + static size_t rows(const Rst &rst) { return rst.rows; } + static size_t cols(const Rst &rst) { return rst.cols; } +}; + +} // namespace marchsq + namespace Slic3r { +namespace { + +struct PNGBuffer { std::vector buf; std::string fname; }; +struct ArchiveData { + boost::property_tree::ptree profile, config; + std::vector images; +}; + +static const constexpr char *CONFIG_FNAME = "config.ini"; +static const constexpr char *PROFILE_FNAME = "prusaslicer.ini"; + +boost::property_tree::ptree read_ini(const mz_zip_archive_file_stat &entry, + MZ_Archive & zip) +{ + std::string buf(size_t(entry.m_uncomp_size), '\0'); + + if (!mz_zip_reader_extract_file_to_mem(&zip.arch, entry.m_filename, + buf.data(), buf.size(), 0)) + throw std::runtime_error(zip.get_errorstr()); + + boost::property_tree::ptree tree; + std::stringstream ss(buf); + boost::property_tree::read_ini(ss, tree); + return tree; +} + +PNGBuffer read_png(const mz_zip_archive_file_stat &entry, + MZ_Archive & zip, + const std::string & name) +{ + std::vector buf(entry.m_uncomp_size); + + if (!mz_zip_reader_extract_file_to_mem(&zip.arch, entry.m_filename, + buf.data(), buf.size(), 0)) + throw std::runtime_error(zip.get_errorstr()); + + return {std::move(buf), (name.empty() ? entry.m_filename : name)}; +} + +ArchiveData extract_sla_archive(const std::string &zipfname, + const std::string &exclude) +{ + ArchiveData arch; + + // Little RAII + struct Arch: public MZ_Archive { + Arch(const std::string &fname) { + if (!open_zip_reader(&arch, fname)) + throw std::runtime_error(get_errorstr()); + } + + ~Arch() { close_zip_reader(&arch); } + } zip (zipfname); + + mz_uint num_entries = mz_zip_reader_get_num_files(&zip.arch); + + for (mz_uint i = 0; i < num_entries; ++i) + { + mz_zip_archive_file_stat entry; + + if (mz_zip_reader_file_stat(&zip.arch, i, &entry)) + { + std::string name = entry.m_filename; + boost::algorithm::to_lower(name); + + if (boost::algorithm::contains(name, exclude)) continue; + + if (name == CONFIG_FNAME) arch.config = read_ini(entry, zip); + if (name == PROFILE_FNAME) arch.profile = read_ini(entry, zip); + + if (boost::filesystem::path(name).extension().string() == ".png") { + auto it = std::lower_bound( + arch.images.begin(), arch.images.end(), PNGBuffer{{}, name}, + [](const PNGBuffer &r1, const PNGBuffer &r2) { + return std::less()(r1.fname, r2.fname); + }); + + arch.images.insert(it, read_png(entry, zip, name)); + } + } + } + + return arch; +} + +ExPolygons rings_to_expolygons(const std::vector &rings, + double px_w, double px_h) +{ + ExPolygons polys; polys.reserve(rings.size()); + + for (const marchsq::Ring &ring : rings) { + Polygon poly; Points &pts = poly.points; + pts.reserve(ring.size()); + + for (const marchsq::Coord &crd : ring) + pts.emplace_back(scaled(crd.c * px_w), scaled(crd.r * px_h)); + + polys.emplace_back(poly); + } + + // reverse the raster transformations + return union_ex(polys); +} + +template void foreach_vertex(ExPolygon &poly, Fn &&fn) +{ + for (auto &p : poly.contour.points) fn(p); + for (auto &h : poly.holes) + for (auto &p : h.points) fn(p); +} + +void invert_raster_trafo(ExPolygons & expolys, + const sla::RasterBase::Trafo &trafo, + coord_t width, + coord_t height) +{ + for (auto &expoly : expolys) { + if (trafo.mirror_y) + foreach_vertex(expoly, [height](Point &p) {p.y() = height - p.y(); }); + + if (trafo.mirror_x) + foreach_vertex(expoly, [width](Point &p) {p.x() = width - p.x(); }); + + expoly.translate(-trafo.center_x, -trafo.center_y); + + if (trafo.flipXY) + foreach_vertex(expoly, [](Point &p) { std::swap(p.x(), p.y()); }); + + if ((trafo.mirror_x + trafo.mirror_y + trafo.flipXY) % 2) { + expoly.contour.reverse(); + for (auto &h : expoly.holes) h.reverse(); + } + } +} + +struct RasterParams { + sla::RasterBase::Trafo trafo; // Raster transformations + coord_t width, height; // scaled raster dimensions (not resolution) + double px_h, px_w; // pixel dimesions + marchsq::Coord win; // marching squares window size +}; + +RasterParams get_raster_params(const DynamicPrintConfig &cfg) +{ + auto *opt_disp_cols = cfg.option("display_pixels_x"); + auto *opt_disp_rows = cfg.option("display_pixels_y"); + auto *opt_disp_w = cfg.option("display_width"); + auto *opt_disp_h = cfg.option("display_height"); + auto *opt_mirror_x = cfg.option("display_mirror_x"); + auto *opt_mirror_y = cfg.option("display_mirror_y"); + auto *opt_orient = cfg.option>("display_orientation"); + + if (!opt_disp_cols || !opt_disp_rows || !opt_disp_w || !opt_disp_h || + !opt_mirror_x || !opt_mirror_y || !opt_orient) + throw std::runtime_error("Invalid SL1 file"); + + RasterParams rstp; + + rstp.px_w = opt_disp_w->value / (opt_disp_cols->value - 1); + rstp.px_h = opt_disp_h->value / (opt_disp_rows->value - 1); + + rstp.trafo = sla::RasterBase::Trafo{opt_orient->value == sladoLandscape ? + sla::RasterBase::roLandscape : + sla::RasterBase::roPortrait, + {opt_mirror_x->value, opt_mirror_y->value}}; + + rstp.height = scaled(opt_disp_h->value); + rstp.width = scaled(opt_disp_w->value); + + return rstp; +} + +struct SliceParams { double layerh = 0., initial_layerh = 0.; }; + +SliceParams get_slice_params(const DynamicPrintConfig &cfg) +{ + auto *opt_layerh = cfg.option("layer_height"); + auto *opt_init_layerh = cfg.option("initial_layer_height"); + + if (!opt_layerh || !opt_init_layerh) + throw std::runtime_error("Invalid SL1 file"); + + return SliceParams{opt_layerh->getFloat(), opt_init_layerh->getFloat()}; +} + +std::vector extract_slices_from_sla_archive( + ArchiveData & arch, + const RasterParams & rstp, + std::function progr) +{ + auto jobdir = arch.config.get("jobDir"); + for (auto &c : jobdir) c = std::tolower(c); + + std::vector slices(arch.images.size()); + + struct Status + { + double incr, val, prev; + bool stop = false; + tbb::spin_mutex mutex; + } st {100. / slices.size(), 0., 0.}; + + tbb::parallel_for(size_t(0), arch.images.size(), + [&arch, &slices, &st, &rstp, progr](size_t i) { + // Status indication guarded with the spinlock + { + std::lock_guard lck(st.mutex); + if (st.stop) return; + + st.val += st.incr; + double curr = std::round(st.val); + if (curr > st.prev) { + st.prev = curr; + st.stop = !progr(int(curr)); + } + } + + png::ImageGreyscale img; + png::ReadBuf rb{arch.images[i].buf.data(), arch.images[i].buf.size()}; + if (!png::decode_png(rb, img)) return; + + auto rings = marchsq::execute(img, 128, rstp.win); + ExPolygons expolys = rings_to_expolygons(rings, rstp.px_w, rstp.px_h); + + // Invert the raster transformations indicated in + // the profile metadata + invert_raster_trafo(expolys, rstp.trafo, rstp.width, rstp.height); + + slices[i] = std::move(expolys); + }); + + if (st.stop) slices = {}; + + return slices; +} + +} // namespace + +void import_sla_archive(const std::string &zipfname, DynamicPrintConfig &out) +{ + ArchiveData arch = extract_sla_archive(zipfname, "png"); + out.load(arch.profile); +} + +void import_sla_archive( + const std::string & zipfname, + Vec2i windowsize, + TriangleMesh & out, + DynamicPrintConfig & profile, + std::function progr) +{ + // Ensure minimum window size for marching squares + windowsize.x() = std::max(2, windowsize.x()); + windowsize.y() = std::max(2, windowsize.y()); + + ArchiveData arch = extract_sla_archive(zipfname, "thumbnail"); + profile.load(arch.profile); + + RasterParams rstp = get_raster_params(profile); + rstp.win = {windowsize.y(), windowsize.x()}; + + SliceParams slicp = get_slice_params(profile); + + std::vector slices = + extract_slices_from_sla_archive(arch, rstp, progr); + + if (!slices.empty()) + out = slices_to_triangle_mesh(slices, 0, slicp.layerh, slicp.initial_layerh); +} + using ConfMap = std::map; namespace { diff --git a/src/libslic3r/Format/SL1.hpp b/src/libslic3r/Format/SL1.hpp index fbb6d61604..ab731ff841 100644 --- a/src/libslic3r/Format/SL1.hpp +++ b/src/libslic3r/Format/SL1.hpp @@ -38,6 +38,24 @@ public: } }; +void import_sla_archive(const std::string &zipfname, DynamicPrintConfig &out); + +void import_sla_archive( + const std::string & zipfname, + Vec2i windowsize, + TriangleMesh & out, + DynamicPrintConfig & profile, + std::function progr = [](int) { return true; }); + +inline void import_sla_archive( + const std::string & zipfname, + Vec2i windowsize, + TriangleMesh & out, + std::function progr = [](int) { return true; }) +{ + DynamicPrintConfig profile; + import_sla_archive(zipfname, windowsize, out, profile, progr); +} } // namespace Slic3r::sla diff --git a/src/libslic3r/PNGRead.cpp b/src/libslic3r/PNGRead.cpp index 8bfa3cb951..6eb7d593cc 100644 --- a/src/libslic3r/PNGRead.cpp +++ b/src/libslic3r/PNGRead.cpp @@ -7,11 +7,21 @@ namespace Slic3r { namespace png { -struct png_deleter { void operator()(png_struct *p) { - png_destroy_read_struct( &p, nullptr, nullptr); } -}; +struct PNGDescr { + png_struct *png = nullptr; png_info *info = nullptr; -using png_ptr_t = std::unique_ptr; + PNGDescr() = default; + PNGDescr(const PNGDescr&) = delete; + PNGDescr(PNGDescr&&) = delete; + PNGDescr& operator=(const PNGDescr&) = delete; + PNGDescr& operator=(PNGDescr&&) = delete; + + ~PNGDescr() + { + if (png && info) png_destroy_info_struct(png, &info); + if (png) png_destroy_read_struct( &png, nullptr, nullptr); + } +}; bool is_png(const ReadBuf &rb) { @@ -25,22 +35,23 @@ bool decode_png(const ReadBuf &rb, ImageGreyscale &img) { if (!is_png(rb)) return false; - png_ptr_t png{png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr)}; + PNGDescr dsc; + dsc.png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); - if(!png) return false; + if(!dsc.png) return false; - png_infop info = png_create_info_struct(png.get()); - if(!info) return {}; + dsc.info = png_create_info_struct(dsc.png); + if(!dsc.info) return {}; FILE *io = ::fmemopen(const_cast(rb.buf), rb.sz, "rb"); - png_init_io(png.get(), io); + png_init_io(dsc.png, io); - png_read_info(png.get(), info); + png_read_info(dsc.png, dsc.info); - img.cols = png_get_image_width(png.get(), info); - img.rows = png_get_image_height(png.get(), info); - size_t color_type = png_get_color_type(png.get(), info); - size_t bit_depth = png_get_bit_depth(png.get(), info); + img.cols = png_get_image_width(dsc.png, dsc.info); + img.rows = png_get_image_height(dsc.png, dsc.info); + size_t color_type = png_get_color_type(dsc.png, dsc.info); + size_t bit_depth = png_get_bit_depth(dsc.png, dsc.info); if (color_type != PNG_COLOR_TYPE_GRAY || bit_depth != 8) return false; @@ -49,7 +60,7 @@ bool decode_png(const ReadBuf &rb, ImageGreyscale &img) auto readbuf = static_cast(img.buf.data()); for (size_t r = 0; r < img.rows; ++r) - png_read_row(png.get(), readbuf + r * img.cols, nullptr); + png_read_row(dsc.png, readbuf + r * img.cols, nullptr); fclose(io); diff --git a/src/libslic3r/PNGRead.hpp b/src/libslic3r/PNGRead.hpp index 88a948395b..0e7311f2e5 100644 --- a/src/libslic3r/PNGRead.hpp +++ b/src/libslic3r/PNGRead.hpp @@ -19,12 +19,14 @@ struct RGB { uint8_t r, g, b; }; using ImageRGB = Image; using ImageGreyscale = Image; +bool is_png(const ReadBuf &pngbuf); + +// Only decodes true 8 bit grayscale png images. Returns false for other formats +// TODO: implement transformation of rgb images into grayscale... +bool decode_png(const ReadBuf &pngbuf, ImageGreyscale &img); + // TODO // bool decode_png(Buffer &&pngbuf, ImageRGB &img); -bool is_png(const ReadBuf &pngbuf); - -bool decode_png(const ReadBuf &pngbuf, ImageGreyscale &img); - }} #endif // PNGREAD_HPP diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 8a2672c774..b64cfdf4fc 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -187,8 +187,6 @@ set(SLIC3R_GUI_SOURCES Utils/HexFile.cpp Utils/HexFile.hpp Utils/Thread.hpp - Utils/SLAImport.hpp - Utils/SLAImport.cpp ) if (APPLE) diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index aa5264b07d..b59631d674 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -294,7 +294,7 @@ public: void load_part(ModelObject* model_object, std::vector> &volumes_info, ModelVolumeType type); void load_generic_subobject(const std::string& type_name, const ModelVolumeType type); void load_shape_object(const std::string &type_name); - void load_mesh_object(const TriangleMesh &mesh, const wxString &name); + void load_mesh_object(const TriangleMesh &mesh, const wxString &name); void del_object(const int obj_idx); void del_subobject_item(wxDataViewItem& item); void del_settings_from_config(const wxDataViewItem& parent_item); diff --git a/src/slic3r/GUI/Jobs/SLAImportJob.cpp b/src/slic3r/GUI/Jobs/SLAImportJob.cpp index 2d5d5b0729..ae92bd6989 100644 --- a/src/slic3r/GUI/Jobs/SLAImportJob.cpp +++ b/src/slic3r/GUI/Jobs/SLAImportJob.cpp @@ -1,10 +1,11 @@ #include "SLAImportJob.hpp" +#include "libslic3r/Format/SL1.hpp" + #include "slic3r/GUI/GUI.hpp" #include "slic3r/GUI/GUI_App.hpp" #include "slic3r/GUI/Plater.hpp" #include "slic3r/GUI/GUI_ObjectList.hpp" -#include "slic3r/Utils/SLAImport.hpp" #include "libslic3r/Model.hpp" #include "libslic3r/PresetBundle.hpp" diff --git a/src/slic3r/Utils/SLAImport.cpp b/src/slic3r/Utils/SLAImport.cpp deleted file mode 100644 index 13ea603396..0000000000 --- a/src/slic3r/Utils/SLAImport.cpp +++ /dev/null @@ -1,317 +0,0 @@ -#include "SLAImport.hpp" - -#include - -#include "libslic3r/SlicesToTriangleMesh.hpp" -#include "libslic3r/MarchingSquares.hpp" -#include "libslic3r/ClipperUtils.hpp" -#include "libslic3r/MTUtils.hpp" -#include "libslic3r/PrintConfig.hpp" -#include "libslic3r/SLA/RasterBase.hpp" -#include "libslic3r/miniz_extension.hpp" -#include "libslic3r/PNGRead.hpp" - -#include -#include -#include - -#include - -namespace marchsq { - -template<> struct _RasterTraits { - using Rst = Slic3r::png::ImageGreyscale; - - // The type of pixel cell in the raster - using ValueType = uint8_t; - - // Value at a given position - static uint8_t get(const Rst &rst, size_t row, size_t col) - { - return rst.get(row, col); - } - - // Number of rows and cols of the raster - static size_t rows(const Rst &rst) { return rst.rows; } - static size_t cols(const Rst &rst) { return rst.cols; } -}; - -} // namespace marchsq - -namespace Slic3r { - -namespace { - -struct PNGBuffer { std::vector buf; std::string fname; }; -struct ArchiveData { - boost::property_tree::ptree profile, config; - std::vector images; -}; - -static const constexpr char *CONFIG_FNAME = "config.ini"; -static const constexpr char *PROFILE_FNAME = "prusaslicer.ini"; - -boost::property_tree::ptree read_ini(const mz_zip_archive_file_stat &entry, - MZ_Archive & zip) -{ - std::string buf(size_t(entry.m_uncomp_size), '\0'); - - if (!mz_zip_reader_extract_file_to_mem(&zip.arch, entry.m_filename, - buf.data(), buf.size(), 0)) - throw std::runtime_error(zip.get_errorstr()); - - boost::property_tree::ptree tree; - std::stringstream ss(buf); - boost::property_tree::read_ini(ss, tree); - return tree; -} - -PNGBuffer read_png(const mz_zip_archive_file_stat &entry, - MZ_Archive & zip, - const std::string & name) -{ - std::vector buf(entry.m_uncomp_size); - - if (!mz_zip_reader_extract_file_to_mem(&zip.arch, entry.m_filename, - buf.data(), buf.size(), 0)) - throw std::runtime_error(zip.get_errorstr()); - - return {std::move(buf), (name.empty() ? entry.m_filename : name)}; -} - -ArchiveData extract_sla_archive(const std::string &zipfname, - const std::string &exclude) -{ - ArchiveData arch; - - // Little RAII - struct Arch: public MZ_Archive { - Arch(const std::string &fname) { - if (!open_zip_reader(&arch, fname)) - throw std::runtime_error(get_errorstr()); - } - - ~Arch() { close_zip_reader(&arch); } - } zip (zipfname); - - mz_uint num_entries = mz_zip_reader_get_num_files(&zip.arch); - - for (mz_uint i = 0; i < num_entries; ++i) - { - mz_zip_archive_file_stat entry; - - if (mz_zip_reader_file_stat(&zip.arch, i, &entry)) - { - std::string name = entry.m_filename; - boost::algorithm::to_lower(name); - - if (boost::algorithm::contains(name, exclude)) continue; - - if (name == CONFIG_FNAME) arch.config = read_ini(entry, zip); - if (name == PROFILE_FNAME) arch.profile = read_ini(entry, zip); - - if (boost::filesystem::path(name).extension().string() == ".png") { - auto it = std::lower_bound( - arch.images.begin(), arch.images.end(), PNGBuffer{{}, name}, - [](const PNGBuffer &r1, const PNGBuffer &r2) { - return std::less()(r1.fname, r2.fname); - }); - - arch.images.insert(it, read_png(entry, zip, name)); - } - } - } - - return arch; -} - -ExPolygons rings_to_expolygons(const std::vector &rings, - double px_w, double px_h) -{ - ExPolygons polys; polys.reserve(rings.size()); - - for (const marchsq::Ring &ring : rings) { - Polygon poly; Points &pts = poly.points; - pts.reserve(ring.size()); - - for (const marchsq::Coord &crd : ring) - pts.emplace_back(scaled(crd.c * px_w), scaled(crd.r * px_h)); - - polys.emplace_back(poly); - } - - // reverse the raster transformations - return union_ex(polys); -} - -template void foreach_vertex(ExPolygon &poly, Fn &&fn) -{ - for (auto &p : poly.contour.points) fn(p); - for (auto &h : poly.holes) - for (auto &p : h.points) fn(p); -} - -void invert_raster_trafo(ExPolygons & expolys, - const sla::RasterBase::Trafo &trafo, - coord_t width, - coord_t height) -{ - for (auto &expoly : expolys) { - if (trafo.mirror_y) - foreach_vertex(expoly, [height](Point &p) {p.y() = height - p.y(); }); - - if (trafo.mirror_x) - foreach_vertex(expoly, [width](Point &p) {p.x() = width - p.x(); }); - - expoly.translate(-trafo.center_x, -trafo.center_y); - - if (trafo.flipXY) - foreach_vertex(expoly, [](Point &p) { std::swap(p.x(), p.y()); }); - - if ((trafo.mirror_x + trafo.mirror_y + trafo.flipXY) % 2) { - expoly.contour.reverse(); - for (auto &h : expoly.holes) h.reverse(); - } - } -} - -struct RasterParams { - sla::RasterBase::Trafo trafo; // Raster transformations - coord_t width, height; // scaled raster dimensions (not resolution) - double px_h, px_w; // pixel dimesions - marchsq::Coord win; // marching squares window size -}; - -RasterParams get_raster_params(const DynamicPrintConfig &cfg) -{ - auto *opt_disp_cols = cfg.option("display_pixels_x"); - auto *opt_disp_rows = cfg.option("display_pixels_y"); - auto *opt_disp_w = cfg.option("display_width"); - auto *opt_disp_h = cfg.option("display_height"); - auto *opt_mirror_x = cfg.option("display_mirror_x"); - auto *opt_mirror_y = cfg.option("display_mirror_y"); - auto *opt_orient = cfg.option>("display_orientation"); - - if (!opt_disp_cols || !opt_disp_rows || !opt_disp_w || !opt_disp_h || - !opt_mirror_x || !opt_mirror_y || !opt_orient) - throw std::runtime_error("Invalid SL1 file"); - - RasterParams rstp; - - rstp.px_w = opt_disp_w->value / (opt_disp_cols->value - 1); - rstp.px_h = opt_disp_h->value / (opt_disp_rows->value - 1); - - sla::RasterBase::Trafo trafo{opt_orient->value == sladoLandscape ? - sla::RasterBase::roLandscape : - sla::RasterBase::roPortrait, - {opt_mirror_x->value, opt_mirror_y->value}}; - - rstp.height = scaled(opt_disp_h->value); - rstp.width = scaled(opt_disp_w->value); - - return rstp; -} - -struct SliceParams { double layerh = 0., initial_layerh = 0.; }; - -SliceParams get_slice_params(const DynamicPrintConfig &cfg) -{ - auto *opt_layerh = cfg.option("layer_height"); - auto *opt_init_layerh = cfg.option("initial_layer_height"); - - if (!opt_layerh || !opt_init_layerh) - throw std::runtime_error("Invalid SL1 file"); - - return SliceParams{opt_layerh->getFloat(), opt_init_layerh->getFloat()}; -} - -std::vector extract_slices_from_sla_archive( - ArchiveData & arch, - const RasterParams & rstp, - std::function progr) -{ - auto jobdir = arch.config.get("jobDir"); - for (auto &c : jobdir) c = std::tolower(c); - - std::vector slices(arch.images.size()); - - struct Status - { - double incr, val, prev; - bool stop = false; - tbb::spin_mutex mutex; - } st {100. / slices.size(), 0., 0.}; - - tbb::parallel_for(size_t(0), arch.images.size(), - [&arch, &slices, &st, &rstp, progr](size_t i) { - // Status indication guarded with the spinlock - { - std::lock_guard lck(st.mutex); - if (st.stop) return; - - st.val += st.incr; - double curr = std::round(st.val); - if (curr > st.prev) { - st.prev = curr; - st.stop = !progr(int(curr)); - } - } - -// PNGBuffer &png = arch.images[i]; -// wxMemoryInputStream stream{png.buf.data(), png.buf.size()}; -// wxImage img{stream}; - - png::ImageGreyscale img; - png::ReadBuf rb{arch.images[i].buf.data(), arch.images[i].buf.size()}; - png::decode_png(rb, img); - - auto rings = marchsq::execute(img, 128, rstp.win); - ExPolygons expolys = rings_to_expolygons(rings, rstp.px_w, rstp.px_h); - - // Invert the raster transformations indicated in - // the profile metadata - invert_raster_trafo(expolys, rstp.trafo, rstp.width, rstp.height); - - slices[i] = std::move(expolys); - }); - - if (st.stop) slices = {}; - - return slices; -} - -} // namespace - -void import_sla_archive(const std::string &zipfname, DynamicPrintConfig &out) -{ - ArchiveData arch = extract_sla_archive(zipfname, "png"); - out.load(arch.profile); -} - -void import_sla_archive( - const std::string & zipfname, - Vec2i windowsize, - TriangleMesh & out, - DynamicPrintConfig & profile, - std::function progr) -{ - // Ensure minimum window size for marching squares - windowsize.x() = std::max(2, windowsize.x()); - windowsize.y() = std::max(2, windowsize.y()); - - ArchiveData arch = extract_sla_archive(zipfname, "thumbnail"); - profile.load(arch.profile); - - RasterParams rstp = get_raster_params(profile); - rstp.win = {windowsize.y(), windowsize.x()}; - - SliceParams slicp = get_slice_params(profile); - - std::vector slices = - extract_slices_from_sla_archive(arch, rstp, progr); - - if (!slices.empty()) - out = slices_to_triangle_mesh(slices, 0, slicp.layerh, slicp.initial_layerh); -} - -} // namespace Slic3r diff --git a/src/slic3r/Utils/SLAImport.hpp b/src/slic3r/Utils/SLAImport.hpp deleted file mode 100644 index 73995014f4..0000000000 --- a/src/slic3r/Utils/SLAImport.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef SLAIMPORT_HPP -#define SLAIMPORT_HPP - -#include - -#include -#include - -namespace Slic3r { - -class TriangleMesh; -class DynamicPrintConfig; - -void import_sla_archive(const std::string &zipfname, DynamicPrintConfig &out); - -void import_sla_archive( - const std::string & zipfname, - Vec2i windowsize, - TriangleMesh & out, - DynamicPrintConfig & profile, - std::function progr = [](int) { return true; }); - -inline void import_sla_archive( - const std::string & zipfname, - Vec2i windowsize, - TriangleMesh & out, - std::function progr = [](int) { return true; }) -{ - DynamicPrintConfig profile; - import_sla_archive(zipfname, windowsize, out, profile, progr); -} - -} - -#endif // SLAIMPORT_HPP From 8541ce406069e2b710b22bec937d3405ed0e8316 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Wed, 29 Apr 2020 16:26:39 +0200 Subject: [PATCH 223/255] SLA archive import will now recover the model's original position. --- CMakeLists.txt | 2 +- src/libslic3r/Format/SL1.cpp | 2 ++ src/slic3r/GUI/GUI_ObjectList.cpp | 19 ++++++++++++------- src/slic3r/GUI/GUI_ObjectList.hpp | 2 +- src/slic3r/GUI/Jobs/SLAImportJob.cpp | 6 ++++-- 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 48ad5033e0..a4be182e7e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -386,7 +386,7 @@ if (NOT EXPAT_FOUND) set(EXPAT_LIBRARIES expat) endif () -find_package(PNG) +find_package(PNG REQUIRED) find_package(OpenGL REQUIRED) diff --git a/src/libslic3r/Format/SL1.cpp b/src/libslic3r/Format/SL1.cpp index 3d672eccb4..ff1af5d8b1 100644 --- a/src/libslic3r/Format/SL1.cpp +++ b/src/libslic3r/Format/SL1.cpp @@ -162,6 +162,8 @@ void invert_raster_trafo(ExPolygons & expolys, coord_t width, coord_t height) { + if (trafo.flipXY) std::swap(height, width); + for (auto &expoly : expolys) { if (trafo.mirror_y) foreach_vertex(expoly, [height](Point &p) {p.y() = height - p.y(); }); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index a326eea7b3..44b2b6186d 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2209,7 +2209,7 @@ void ObjectList::load_shape_object(const std::string& type_name) load_mesh_object(mesh, _(L("Shape")) + "-" + _(type_name)); } -void ObjectList::load_mesh_object(const TriangleMesh &mesh, const wxString &name) +void ObjectList::load_mesh_object(const TriangleMesh &mesh, const wxString &name, bool center) { // Add mesh to model as a new object Model& model = wxGetApp().plater()->model(); @@ -2219,6 +2219,7 @@ void ObjectList::load_mesh_object(const TriangleMesh &mesh, const wxString &name #endif /* _DEBUG */ std::vector object_idxs; + auto bb = mesh.bounding_box(); ModelObject* new_object = model.add_object(); new_object->name = into_u8(name); new_object->add_instance(); // each object should have at list one instance @@ -2228,13 +2229,17 @@ void ObjectList::load_mesh_object(const TriangleMesh &mesh, const wxString &name // set a default extruder value, since user can't add it manually new_volume->config.set_key_value("extruder", new ConfigOptionInt(0)); new_object->invalidate_bounding_box(); - - new_object->center_around_origin(); + new_object->translate(-bb.center()); + + if (center) { + const BoundingBoxf bed_shape = wxGetApp().plater()->bed_shape_bb(); + new_object->instances[0]->set_offset(Slic3r::to_3d(bed_shape.center().cast(), -new_object->origin_translation(2))); + } else { + new_object->instances[0]->set_offset(bb.center()); + } + new_object->ensure_on_bed(); - - const BoundingBoxf bed_shape = wxGetApp().plater()->bed_shape_bb(); - new_object->instances[0]->set_offset(Slic3r::to_3d(bed_shape.center().cast(), -new_object->origin_translation(2))); - + object_idxs.push_back(model.objects.size() - 1); #ifdef _DEBUG check_model_ids_validity(model); diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index b59631d674..9f7dcd2475 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -294,7 +294,7 @@ public: void load_part(ModelObject* model_object, std::vector> &volumes_info, ModelVolumeType type); void load_generic_subobject(const std::string& type_name, const ModelVolumeType type); void load_shape_object(const std::string &type_name); - void load_mesh_object(const TriangleMesh &mesh, const wxString &name); + void load_mesh_object(const TriangleMesh &mesh, const wxString &name, bool center = true); void del_object(const int obj_idx); void del_subobject_item(wxDataViewItem& item); void del_settings_from_config(const wxDataViewItem& parent_item); diff --git a/src/slic3r/GUI/Jobs/SLAImportJob.cpp b/src/slic3r/GUI/Jobs/SLAImportJob.cpp index ae92bd6989..adecae6ac0 100644 --- a/src/slic3r/GUI/Jobs/SLAImportJob.cpp +++ b/src/slic3r/GUI/Jobs/SLAImportJob.cpp @@ -219,8 +219,10 @@ void SLAImportJob::finalize() wxGetApp().load_current_presets(); } - if (!p->mesh.empty()) - p->plater->sidebar().obj_list()->load_mesh_object(p->mesh, name); + if (!p->mesh.empty()) { + bool is_centered = false; + p->plater->sidebar().obj_list()->load_mesh_object(p->mesh, name, is_centered); + } reset(); } From 1560e15ed90adfea2d28077f3b4b4a57ab293409 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Mon, 3 Aug 2020 15:27:58 +0200 Subject: [PATCH 224/255] Add missing includes for win --- tests/libslic3r/test_png_io.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/libslic3r/test_png_io.cpp b/tests/libslic3r/test_png_io.cpp index 3378d0062e..51f94be326 100644 --- a/tests/libslic3r/test_png_io.cpp +++ b/tests/libslic3r/test_png_io.cpp @@ -1,8 +1,11 @@ #define NOMINMAX #include +#include + #include "libslic3r/PNGRead.hpp" #include "libslic3r/SLA/AGGRaster.hpp" +#include "libslic3r/BoundingBox.hpp" using namespace Slic3r; From 3f41e4023d040777bab5b754c5423769efd52c57 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Mon, 3 Aug 2020 15:50:05 +0200 Subject: [PATCH 225/255] Try to override mac library search order to find static dep libs --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index a4be182e7e..1d4576c37d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,11 @@ option(SLIC3R_ASAN "Enable ASan on Clang and GCC" 0) set(SLIC3R_GTK "2" CACHE STRING "GTK version to use with wxWidgets on Linux") +if (APPLE) + set(CMAKE_FIND_FRAMEWORK LAST) + set(CMAKE_FIND_APPBUNDLE LAST) +endif () + # Proposal for C++ unit tests and sandboxes option(SLIC3R_BUILD_SANDBOXES "Build development sandboxes" OFF) option(SLIC3R_BUILD_TESTS "Build unit tests" ON) From b09552e56faced8580fde7c4648a5116ae578d61 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Mon, 3 Aug 2020 18:00:32 +0200 Subject: [PATCH 226/255] Don't use fmemopen, its not standard. --- src/libslic3r/PNGRead.cpp | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/src/libslic3r/PNGRead.cpp b/src/libslic3r/PNGRead.cpp index 6eb7d593cc..695ceba3dc 100644 --- a/src/libslic3r/PNGRead.cpp +++ b/src/libslic3r/PNGRead.cpp @@ -31,20 +31,46 @@ bool is_png(const ReadBuf &rb) !png_sig_cmp(static_cast(rb.buf), 0, PNG_SIG_BYTES); } +// A wrapper around ReadBuf to be read repeatedly like a stream. libpng needs +// this form for its buffer read callback. +struct ReadBufReader { + const ReadBuf &rdbuf; size_t pos; + ReadBufReader(const ReadBuf &rd): rdbuf{rd}, pos{0} {} +}; + +// Buffer read callback for libpng. It provides an allocated output buffer and +// the amount of data it desires to read from the input. +void png_read_callback(png_struct *png_ptr, + png_bytep outBytes, + png_size_t byteCountToRead) +{ + // Retrieve our input buffer through the png_ptr + auto reader = static_cast(png_get_io_ptr(png_ptr)); + + if (!reader || byteCountToRead > reader->rdbuf.sz - reader->pos) return; + + auto buf = static_cast(reader->rdbuf.buf); + size_t pos = reader->pos; + + std::copy(buf + pos, buf + (pos + byteCountToRead), outBytes); + reader->pos += byteCountToRead; +} + bool decode_png(const ReadBuf &rb, ImageGreyscale &img) { if (!is_png(rb)) return false; PNGDescr dsc; - dsc.png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); + dsc.png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, + nullptr); if(!dsc.png) return false; dsc.info = png_create_info_struct(dsc.png); if(!dsc.info) return {}; - FILE *io = ::fmemopen(const_cast(rb.buf), rb.sz, "rb"); - png_init_io(dsc.png, io); + ReadBufReader reader {rb}; + png_set_read_fn(dsc.png, static_cast(&reader), png_read_callback); png_read_info(dsc.png, dsc.info); @@ -62,9 +88,7 @@ bool decode_png(const ReadBuf &rb, ImageGreyscale &img) for (size_t r = 0; r < img.rows; ++r) png_read_row(dsc.png, readbuf + r * img.cols, nullptr); - fclose(io); - return true; } -}} +}} // namespace Slic3r::png From ad0df8fd098cfead66f9ede7456cd783a88ba049 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Mon, 3 Aug 2020 18:50:43 +0200 Subject: [PATCH 227/255] Be compatible with earlier libpng versions. --- src/libslic3r/PNGRead.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/PNGRead.cpp b/src/libslic3r/PNGRead.cpp index 695ceba3dc..5b5b9ffecb 100644 --- a/src/libslic3r/PNGRead.cpp +++ b/src/libslic3r/PNGRead.cpp @@ -27,8 +27,18 @@ bool is_png(const ReadBuf &rb) { static const constexpr int PNG_SIG_BYTES = 8; - return rb.sz >= PNG_SIG_BYTES && - !png_sig_cmp(static_cast(rb.buf), 0, PNG_SIG_BYTES); +#if PNG_LIBPNG_VER_MINOR <= 2 + // Earlier libpng versions had png_sig_cmp(png_bytep, ...) which is not + // a const pointer. It is not possible to cast away the const qualifier from + // the input buffer so... yes... life is challenging... + png_byte buf[PNG_SIG_BYTES]; + auto inbuf = static_cast(rb.buf); + std::copy(inbuf, inbuf + PNG_SIG_BYTES, buf); +#else + auto buf = static_cast(rb.buf); +#endif + + return rb.sz >= PNG_SIG_BYTES && !png_sig_cmp(buf, 0, PNG_SIG_BYTES); } // A wrapper around ReadBuf to be read repeatedly like a stream. libpng needs From 79567a1958f334e9c43208aa336e668e7da1a311 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 4 Aug 2020 10:13:01 +0200 Subject: [PATCH 228/255] Add some comments for png read interface --- src/libslic3r/PNGRead.cpp | 46 ++++++++++++++----------------- src/libslic3r/PNGRead.hpp | 58 ++++++++++++++++++++++++++++++++------- 2 files changed, 69 insertions(+), 35 deletions(-) diff --git a/src/libslic3r/PNGRead.cpp b/src/libslic3r/PNGRead.cpp index 5b5b9ffecb..e66143b845 100644 --- a/src/libslic3r/PNGRead.cpp +++ b/src/libslic3r/PNGRead.cpp @@ -41,13 +41,6 @@ bool is_png(const ReadBuf &rb) return rb.sz >= PNG_SIG_BYTES && !png_sig_cmp(buf, 0, PNG_SIG_BYTES); } -// A wrapper around ReadBuf to be read repeatedly like a stream. libpng needs -// this form for its buffer read callback. -struct ReadBufReader { - const ReadBuf &rdbuf; size_t pos; - ReadBufReader(const ReadBuf &rd): rdbuf{rd}, pos{0} {} -}; - // Buffer read callback for libpng. It provides an allocated output buffer and // the amount of data it desires to read from the input. void png_read_callback(png_struct *png_ptr, @@ -55,20 +48,21 @@ void png_read_callback(png_struct *png_ptr, png_size_t byteCountToRead) { // Retrieve our input buffer through the png_ptr - auto reader = static_cast(png_get_io_ptr(png_ptr)); + auto reader = static_cast(png_get_io_ptr(png_ptr)); - if (!reader || byteCountToRead > reader->rdbuf.sz - reader->pos) return; + if (!reader || !reader->is_ok()) return; - auto buf = static_cast(reader->rdbuf.buf); - size_t pos = reader->pos; - - std::copy(buf + pos, buf + (pos + byteCountToRead), outBytes); - reader->pos += byteCountToRead; + reader->read(static_cast(outBytes), byteCountToRead); } -bool decode_png(const ReadBuf &rb, ImageGreyscale &img) +bool decode_png(IStream &in_buf, ImageGreyscale &out_img) { - if (!is_png(rb)) return false; + static const constexpr int PNG_SIG_BYTES = 8; + + std::vector sig(PNG_SIG_BYTES, 0); + in_buf.read(sig.data(), PNG_SIG_BYTES); + if (!png_check_sig(sig.data(), PNG_SIG_BYTES)) + return false; PNGDescr dsc; dsc.png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, @@ -77,26 +71,28 @@ bool decode_png(const ReadBuf &rb, ImageGreyscale &img) if(!dsc.png) return false; dsc.info = png_create_info_struct(dsc.png); - if(!dsc.info) return {}; + if(!dsc.info) return false; - ReadBufReader reader {rb}; - png_set_read_fn(dsc.png, static_cast(&reader), png_read_callback); + png_set_read_fn(dsc.png, static_cast(&in_buf), png_read_callback); + + // Tell that we have already read the first bytes to check the signature + png_set_sig_bytes(dsc.png, PNG_SIG_BYTES); png_read_info(dsc.png, dsc.info); - img.cols = png_get_image_width(dsc.png, dsc.info); - img.rows = png_get_image_height(dsc.png, dsc.info); + out_img.cols = png_get_image_width(dsc.png, dsc.info); + out_img.rows = png_get_image_height(dsc.png, dsc.info); size_t color_type = png_get_color_type(dsc.png, dsc.info); size_t bit_depth = png_get_bit_depth(dsc.png, dsc.info); if (color_type != PNG_COLOR_TYPE_GRAY || bit_depth != 8) return false; - img.buf.resize(img.rows * img.cols); + out_img.buf.resize(out_img.rows * out_img.cols); - auto readbuf = static_cast(img.buf.data()); - for (size_t r = 0; r < img.rows; ++r) - png_read_row(dsc.png, readbuf + r * img.cols, nullptr); + auto readbuf = static_cast(out_img.buf.data()); + for (size_t r = 0; r < out_img.rows; ++r) + png_read_row(dsc.png, readbuf + r * out_img.cols, nullptr); return true; } diff --git a/src/libslic3r/PNGRead.hpp b/src/libslic3r/PNGRead.hpp index 0e7311f2e5..082edd5691 100644 --- a/src/libslic3r/PNGRead.hpp +++ b/src/libslic3r/PNGRead.hpp @@ -3,30 +3,68 @@ #include #include +#include namespace Slic3r { namespace png { -struct ReadBuf { const void *buf = nullptr; const size_t sz = 0; }; +// Interface for an input stream of encoded png image data. +struct IStream { + virtual ~IStream() = default; + virtual size_t read(std::uint8_t *outp, size_t amount) = 0; + virtual bool is_ok() const = 0; +}; +// The output format of decode_png: a 2D pixel matrix stored continuously row +// after row (row major layout). template struct Image { std::vector buf; size_t rows, cols; PxT get(size_t row, size_t col) const { return buf[row * cols + col]; } }; -struct RGB { uint8_t r, g, b; }; - -using ImageRGB = Image; using ImageGreyscale = Image; +// Only decodes true 8 bit grayscale png images. Returns false for other formats +// TODO (if needed): implement transformation of rgb images into grayscale... +bool decode_png(IStream &stream, ImageGreyscale &out_img); + +// TODO (if needed) +// struct RGB { uint8_t r, g, b; }; +// using ImageRGB = Image; +// bool decode_png(IStream &stream, ImageRGB &img); + + +// Encoded png data buffer: a simple read-only buffer and its size. +struct ReadBuf { const void *buf = nullptr; const size_t sz = 0; }; + bool is_png(const ReadBuf &pngbuf); -// Only decodes true 8 bit grayscale png images. Returns false for other formats -// TODO: implement transformation of rgb images into grayscale... -bool decode_png(const ReadBuf &pngbuf, ImageGreyscale &img); +template bool decode_png(const ReadBuf &in_buf, Img &out_img) +{ + struct ReadBufStream: public IStream { + const ReadBuf &rbuf_ref; size_t pos = 0; -// TODO -// bool decode_png(Buffer &&pngbuf, ImageRGB &img); + explicit ReadBufStream(const ReadBuf &buf): rbuf_ref{buf} {} + + size_t read(std::uint8_t *outp, size_t amount) override + { + if (amount > rbuf_ref.sz - pos) return 0; + + auto buf = static_cast(rbuf_ref.buf); + std::copy(buf + pos, buf + (pos + amount), outp); + pos += amount; + + return amount; + } + + bool is_ok() const override { return pos < rbuf_ref.sz; } + } stream{in_buf}; + + return decode_png(stream, out_img); +} + +// TODO: std::istream of FILE* could be similarly adapted in case its needed... + +}} // namespace Slic3r::png -}} #endif // PNGREAD_HPP From 93921dc7c8d975f2155bfc9d60a7c78bf8bf2745 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 28 Aug 2020 08:54:58 +0200 Subject: [PATCH 229/255] ENABLE_GCODE_VIEWER -> Experimental taskbar icon --- src/libslic3r/Technologies.hpp | 1 + src/slic3r/GUI/MainFrame.cpp | 38 ++++++++++++++++++++++++++++++++++ src/slic3r/GUI/MainFrame.hpp | 11 ++++++++++ 3 files changed, 50 insertions(+) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index af08d16401..8f5ec121aa 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -58,6 +58,7 @@ #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) #define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_DATA_CHECKING (0 && ENABLE_GCODE_VIEWER) +#define ENABLE_GCODE_VIEWER_TASKBAR_ICON (1 && ENABLE_GCODE_VIEWER) #define TIME_ESTIMATE_NONE 0 #define TIME_ESTIMATE_DEFAULT 1 diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index e46bd03fc2..aadaeece66 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -93,6 +93,28 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S // Font is already set in DPIFrame constructor */ +#if ENABLE_GCODE_VIEWER_TASKBAR_ICON + if (wxTaskBarIcon::IsAvailable()) { +#if defined(__WXOSX__) && wxOSX_USE_COCOA + m_taskbar_icon = new wxTaskBarIcon(wxTBI_DOCK); +#else + m_taskbar_icon = new wxTaskBarIcon(); +#endif + m_taskbar_icon->SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG), "PrusaSlicer"); + + m_taskbar_icon->Bind(wxEVT_TASKBAR_CLICK, [this](wxTaskBarIconEvent& evt) { + wxString msg = _L("You pressed the icon in taskbar for ") + "\n"; + if (m_mode == EMode::Editor) + msg += wxString(SLIC3R_APP_NAME); + else + msg += wxString(SLIC3R_APP_NAME) + "-GCode viewer"; + + wxMessageDialog dialog(nullptr, msg, _("Taskbar icon clicked"), wxOK); + dialog.ShowModal(); + }); + } +#endif // ENABLE_GCODE_VIEWER_TASKBAR_ICON + SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG)); // // Load the icon either from the exe, or from the ico file. //#if _WIN32 @@ -255,6 +277,14 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S } } +#if ENABLE_GCODE_VIEWER_TASKBAR_ICON +MainFrame::~MainFrame() +{ + if (m_taskbar_icon != nullptr) + delete m_taskbar_icon; +} +#endif // ENABLE_GCODE_VIEWER_TASKBAR_ICON + void MainFrame::update_layout() { auto restore_to_creation = [this]() { @@ -1388,6 +1418,10 @@ void MainFrame::set_mode(EMode mode) m_plater->Thaw(); SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG)); +#if ENABLE_GCODE_VIEWER_TASKBAR_ICON + if (m_taskbar_icon != nullptr) + m_taskbar_icon->SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG), "PrusaSlicer"); +#endif // ENABLE_GCODE_VIEWER_TASKBAR_ICON break; } @@ -1435,6 +1469,10 @@ void MainFrame::set_mode(EMode mode) m_plater->Thaw(); SetIcon(wxIcon(Slic3r::var("PrusaSlicerGCodeViewer_128px.png"), wxBITMAP_TYPE_PNG)); +#if ENABLE_GCODE_VIEWER_TASKBAR_ICON + if (m_taskbar_icon != nullptr) + m_taskbar_icon->SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG), "PrusaSlicer-GCode viewer"); +#endif // ENABLE_GCODE_VIEWER_TASKBAR_ICON break; } diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index 53d8488768..7777a053d2 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -7,6 +7,9 @@ #include #include #include +#if ENABLE_GCODE_VIEWER_TASKBAR_ICON +#include +#endif // ENABLE_GCODE_VIEWER_TASKBAR_ICON #include #include @@ -160,7 +163,11 @@ protected: public: MainFrame(); +#if ENABLE_GCODE_VIEWER_TASKBAR_ICON + ~MainFrame(); +#else ~MainFrame() = default; +#endif // ENABLE_GCODE_VIEWER_TASKBAR_ICON void update_layout(); @@ -219,6 +226,10 @@ public: wxProgressDialog* m_progress_dialog { nullptr }; std::shared_ptr m_statusbar; +#if ENABLE_GCODE_VIEWER_TASKBAR_ICON + wxTaskBarIcon* m_taskbar_icon{ nullptr }; +#endif // ENABLE_GCODE_VIEWER_TASKBAR_ICON + #ifdef _WIN32 void* m_hDeviceNotify { nullptr }; uint32_t m_ulSHChangeNotifyRegister { 0 }; From d07d5e36de2e496edfc11200a355bf793365beee Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 28 Aug 2020 11:20:18 +0200 Subject: [PATCH 230/255] Follow-up of 93921dc7c8d975f2155bfc9d60a7c78bf8bf2745 -> Remove taskbar icon before to change it --- src/slic3r/GUI/MainFrame.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index aadaeece66..886e96e1a0 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -280,8 +280,7 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S #if ENABLE_GCODE_VIEWER_TASKBAR_ICON MainFrame::~MainFrame() { - if (m_taskbar_icon != nullptr) - delete m_taskbar_icon; + delete m_taskbar_icon; } #endif // ENABLE_GCODE_VIEWER_TASKBAR_ICON @@ -1419,8 +1418,10 @@ void MainFrame::set_mode(EMode mode) SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG)); #if ENABLE_GCODE_VIEWER_TASKBAR_ICON - if (m_taskbar_icon != nullptr) + if (m_taskbar_icon != nullptr) { + m_taskbar_icon->RemoveIcon(); m_taskbar_icon->SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG), "PrusaSlicer"); + } #endif // ENABLE_GCODE_VIEWER_TASKBAR_ICON break; @@ -1470,8 +1471,10 @@ void MainFrame::set_mode(EMode mode) SetIcon(wxIcon(Slic3r::var("PrusaSlicerGCodeViewer_128px.png"), wxBITMAP_TYPE_PNG)); #if ENABLE_GCODE_VIEWER_TASKBAR_ICON - if (m_taskbar_icon != nullptr) + if (m_taskbar_icon != nullptr) { + m_taskbar_icon->RemoveIcon(); m_taskbar_icon->SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG), "PrusaSlicer-GCode viewer"); + } #endif // ENABLE_GCODE_VIEWER_TASKBAR_ICON break; From 1c2ef87cfa088adc37119118f9014d6174bc355f Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 28 Aug 2020 12:28:21 +0200 Subject: [PATCH 231/255] GCodeViewer -> Reduced vertices count when generating solid toolpaths --- src/slic3r/GUI/GCodeViewer.cpp | 86 +++++++++++++++++++++++----------- src/slic3r/GUI/GCodeViewer.hpp | 2 + 2 files changed, 61 insertions(+), 27 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 8cb18f4e18..c624fb338e 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -994,37 +994,69 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) Vec3f prev_pos = prev.position - half_height * up; Vec3f curr_pos = curr.position - half_height * up; - // vertices 1st endpoint - store_vertex(buffer_vertices, prev_pos + half_height * up, up); // top - store_vertex(buffer_vertices, prev_pos + half_width * right, right); // right - store_vertex(buffer_vertices, prev_pos - half_height * up, -up); // bottom - store_vertex(buffer_vertices, prev_pos - half_width * right, -right); // left + Path& last_path = buffer.paths.back(); + if (last_path.vertices_count() == 1) { + // vertices 1st endpoint + store_vertex(buffer_vertices, prev_pos + half_height * up, up); // top + store_vertex(buffer_vertices, prev_pos + half_width * right, right); // right + store_vertex(buffer_vertices, prev_pos - half_height * up, -up); // bottom + store_vertex(buffer_vertices, prev_pos - half_width * right, -right); // left - // vertices 2nd endpoint - store_vertex(buffer_vertices, curr_pos + half_height * up, up); // top - store_vertex(buffer_vertices, curr_pos + half_width * right, right); // right - store_vertex(buffer_vertices, curr_pos - half_height * up, -up); // bottom - store_vertex(buffer_vertices, curr_pos - half_width * right, -right); // left + // vertices 2nd endpoint + store_vertex(buffer_vertices, curr_pos + half_height * up, up); // top + store_vertex(buffer_vertices, curr_pos + half_width * right, right); // right + store_vertex(buffer_vertices, curr_pos - half_height * up, -up); // bottom + store_vertex(buffer_vertices, curr_pos - half_width * right, -right); // left - // triangles starting cap - store_triangle(buffer_indices, starting_vertices_size + 0, starting_vertices_size + 2, starting_vertices_size + 1); - store_triangle(buffer_indices, starting_vertices_size + 0, starting_vertices_size + 3, starting_vertices_size + 2); + // triangles starting cap + store_triangle(buffer_indices, starting_vertices_size + 0, starting_vertices_size + 2, starting_vertices_size + 1); + store_triangle(buffer_indices, starting_vertices_size + 0, starting_vertices_size + 3, starting_vertices_size + 2); - // triangles sides - store_triangle(buffer_indices, starting_vertices_size + 0, starting_vertices_size + 1, starting_vertices_size + 4); - store_triangle(buffer_indices, starting_vertices_size + 1, starting_vertices_size + 5, starting_vertices_size + 4); - store_triangle(buffer_indices, starting_vertices_size + 1, starting_vertices_size + 2, starting_vertices_size + 5); - store_triangle(buffer_indices, starting_vertices_size + 2, starting_vertices_size + 6, starting_vertices_size + 5); - store_triangle(buffer_indices, starting_vertices_size + 2, starting_vertices_size + 3, starting_vertices_size + 6); - store_triangle(buffer_indices, starting_vertices_size + 3, starting_vertices_size + 7, starting_vertices_size + 6); - store_triangle(buffer_indices, starting_vertices_size + 3, starting_vertices_size + 0, starting_vertices_size + 7); - store_triangle(buffer_indices, starting_vertices_size + 0, starting_vertices_size + 4, starting_vertices_size + 7); + // triangles sides + store_triangle(buffer_indices, starting_vertices_size + 0, starting_vertices_size + 1, starting_vertices_size + 4); + store_triangle(buffer_indices, starting_vertices_size + 1, starting_vertices_size + 5, starting_vertices_size + 4); + store_triangle(buffer_indices, starting_vertices_size + 1, starting_vertices_size + 2, starting_vertices_size + 5); + store_triangle(buffer_indices, starting_vertices_size + 2, starting_vertices_size + 6, starting_vertices_size + 5); + store_triangle(buffer_indices, starting_vertices_size + 2, starting_vertices_size + 3, starting_vertices_size + 6); + store_triangle(buffer_indices, starting_vertices_size + 3, starting_vertices_size + 7, starting_vertices_size + 6); + store_triangle(buffer_indices, starting_vertices_size + 3, starting_vertices_size + 0, starting_vertices_size + 7); + store_triangle(buffer_indices, starting_vertices_size + 0, starting_vertices_size + 4, starting_vertices_size + 7); - // triangles ending cap - store_triangle(buffer_indices, starting_vertices_size + 4, starting_vertices_size + 6, starting_vertices_size + 7); - store_triangle(buffer_indices, starting_vertices_size + 4, starting_vertices_size + 5, starting_vertices_size + 6); + // triangles ending cap + store_triangle(buffer_indices, starting_vertices_size + 4, starting_vertices_size + 6, starting_vertices_size + 7); + store_triangle(buffer_indices, starting_vertices_size + 4, starting_vertices_size + 5, starting_vertices_size + 6); + } + else { + // vertices 1st endpoint + store_vertex(buffer_vertices, prev_pos + half_width * right, right); // right + store_vertex(buffer_vertices, prev_pos - half_width * right, -right); // left - buffer.paths.back().last = { static_cast(buffer_indices.size() - 1), static_cast(move_id), curr.position }; + // vertices 2nd endpoint + store_vertex(buffer_vertices, curr_pos + half_height * up, up); // top + store_vertex(buffer_vertices, curr_pos + half_width * right, right); // right + store_vertex(buffer_vertices, curr_pos - half_height * up, -up); // bottom + store_vertex(buffer_vertices, curr_pos - half_width * right, -right); // left + + // triangles starting cap + store_triangle(buffer_indices, starting_vertices_size - 4, starting_vertices_size - 2, starting_vertices_size + 0); + store_triangle(buffer_indices, starting_vertices_size - 4, starting_vertices_size + 1, starting_vertices_size - 2); + + // triangles sides + store_triangle(buffer_indices, starting_vertices_size - 4, starting_vertices_size + 0, starting_vertices_size + 2); + store_triangle(buffer_indices, starting_vertices_size + 0, starting_vertices_size + 3, starting_vertices_size + 2); + store_triangle(buffer_indices, starting_vertices_size + 0, starting_vertices_size - 2, starting_vertices_size + 3); + store_triangle(buffer_indices, starting_vertices_size - 2, starting_vertices_size + 4, starting_vertices_size + 3); + store_triangle(buffer_indices, starting_vertices_size - 2, starting_vertices_size + 1, starting_vertices_size + 4); + store_triangle(buffer_indices, starting_vertices_size + 1, starting_vertices_size + 5, starting_vertices_size + 4); + store_triangle(buffer_indices, starting_vertices_size + 1, starting_vertices_size - 4, starting_vertices_size + 5); + store_triangle(buffer_indices, starting_vertices_size - 4, starting_vertices_size + 2, starting_vertices_size + 5); + + // triangles ending cap + store_triangle(buffer_indices, starting_vertices_size + 2, starting_vertices_size + 4, starting_vertices_size + 5); + store_triangle(buffer_indices, starting_vertices_size + 2, starting_vertices_size + 3, starting_vertices_size + 4); + } + + last_path.last = { static_cast(buffer_indices.size() - 1), static_cast(move_id), curr.position }; }; // toolpaths data -> extract from result @@ -1299,7 +1331,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool for (const TBuffer& buffer : m_buffers) { // searches the path containing the current position for (const Path& path : buffer.paths) { - if (path.first.s_id <= m_sequential_view.current.last && m_sequential_view.current.last <= path.last.s_id) { + if (path.contains(m_sequential_view.current.last)) { unsigned int offset = m_sequential_view.current.last - path.first.s_id; if (offset > 0) { if (buffer.primitive_type == TBuffer::EPrimitiveType::Line) diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 55c8ea1993..808c1a8ee0 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -133,6 +133,8 @@ class GCodeViewer unsigned char cp_color_id{ 0 }; bool matches(const GCodeProcessor::MoveVertex& move) const; + size_t vertices_count() const { return last.s_id - first.s_id + 1; } + bool contains(unsigned int id) const { return first.s_id <= id && id <= last.s_id; } }; // Used to batch the indices needed to render paths From bf7b952eff82a0fe3805cf3bb84d3b9bc5c636e3 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 1 Sep 2020 08:29:06 +0200 Subject: [PATCH 232/255] GCodeViewer -> Smoothed solid toolpaths corners --- src/libslic3r/Technologies.hpp | 2 +- src/slic3r/GUI/GCodeViewer.cpp | 214 +++++++++++++++++++++++++-------- src/slic3r/GUI/GCodeViewer.hpp | 13 +- 3 files changed, 175 insertions(+), 54 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 8f5ec121aa..834cebbe45 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -58,7 +58,7 @@ #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) #define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_DATA_CHECKING (0 && ENABLE_GCODE_VIEWER) -#define ENABLE_GCODE_VIEWER_TASKBAR_ICON (1 && ENABLE_GCODE_VIEWER) +#define ENABLE_GCODE_VIEWER_TASKBAR_ICON (0 && ENABLE_GCODE_VIEWER) #define TIME_ESTIMATE_NONE 0 #define TIME_ESTIMATE_DEFAULT 1 diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index c624fb338e..8853d7a754 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -297,19 +297,19 @@ bool GCodeViewer::init() case EMoveType::Retract: case EMoveType::Unretract: { - buffer.primitive_type = TBuffer::EPrimitiveType::Point; + buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Point; buffer.vertices.format = VBuffer::EFormat::Position; break; } case EMoveType::Extrude: { - buffer.primitive_type = TBuffer::EPrimitiveType::Triangle; + buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Triangle; buffer.vertices.format = VBuffer::EFormat::PositionNormal3; break; } case EMoveType::Travel: { - buffer.primitive_type = TBuffer::EPrimitiveType::Line; + buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Line; buffer.vertices.format = VBuffer::EFormat::PositionNormal1; break; } @@ -397,6 +397,8 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: if (m_vertices_count == 0) return; + wxBusyCursor busy; + if (m_view_type == EViewType::Tool && !gcode_result.extruder_colors.empty()) // update tool colors from config stored in the gcode m_tool_colors = decode_colors(gcode_result.extruder_colors); @@ -961,6 +963,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) // format data into the buffers to be rendered as solid auto add_as_solid = [](const GCodeProcessor::MoveVertex& prev, const GCodeProcessor::MoveVertex& curr, TBuffer& buffer, std::vector& buffer_vertices, std::vector& buffer_indices, size_t move_id) { + static Vec3f prev_dir; + static Vec3f prev_up; + static float prev_length; auto store_vertex = [](std::vector& buffer_vertices, const Vec3f& position, const Vec3f& normal) { // append position for (int j = 0; j < 3; ++j) { @@ -976,6 +981,18 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) buffer_indices.push_back(i2); buffer_indices.push_back(i3); }; + auto extract_position_at = [](const std::vector& vertices, size_t id) { + return Vec3f(vertices[id + 0], vertices[id + 1], vertices[id + 2]); + }; + auto update_position_at = [](std::vector& vertices, size_t id, const Vec3f& position) { + vertices[id + 0] = position[0]; + vertices[id + 1] = position[1]; + vertices[id + 2] = position[2]; + }; + auto append_dummy_cap = [store_triangle](std::vector& buffer_indices, unsigned int id) { + store_triangle(buffer_indices, id, id, id); + store_triangle(buffer_indices, id, id, id); + }; if (prev.type != curr.type || !buffer.paths.back().matches(curr)) { buffer.add_path(curr, static_cast(buffer_indices.size()), static_cast(move_id - 1)); @@ -986,32 +1003,41 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) Vec3f dir = (curr.position - prev.position).normalized(); Vec3f right = (std::abs(std::abs(dir.dot(Vec3f::UnitZ())) - 1.0f) < EPSILON) ? -Vec3f::UnitY() : Vec3f(dir[1], -dir[0], 0.0f).normalized(); + Vec3f left = -right; Vec3f up = right.cross(dir); + Vec3f bottom = -up; - float half_width = 0.5f * round_to_nearest(curr.width, 2); - float half_height = 0.5f * round_to_nearest(curr.height, 2); + Path& last_path = buffer.paths.back(); + + float half_width = 0.5f * last_path.width; + float half_height = 0.5f * last_path.height; Vec3f prev_pos = prev.position - half_height * up; Vec3f curr_pos = curr.position - half_height * up; - Path& last_path = buffer.paths.back(); + float length = (curr_pos - prev_pos).norm(); if (last_path.vertices_count() == 1) { + // 1st segment + // vertices 1st endpoint - store_vertex(buffer_vertices, prev_pos + half_height * up, up); // top - store_vertex(buffer_vertices, prev_pos + half_width * right, right); // right - store_vertex(buffer_vertices, prev_pos - half_height * up, -up); // bottom - store_vertex(buffer_vertices, prev_pos - half_width * right, -right); // left + store_vertex(buffer_vertices, prev_pos + half_height * up, up); + store_vertex(buffer_vertices, prev_pos + half_width * right, right); + store_vertex(buffer_vertices, prev_pos + half_height * bottom, bottom); + store_vertex(buffer_vertices, prev_pos + half_width * left, left); // vertices 2nd endpoint - store_vertex(buffer_vertices, curr_pos + half_height * up, up); // top - store_vertex(buffer_vertices, curr_pos + half_width * right, right); // right - store_vertex(buffer_vertices, curr_pos - half_height * up, -up); // bottom - store_vertex(buffer_vertices, curr_pos - half_width * right, -right); // left + store_vertex(buffer_vertices, curr_pos + half_height * up, up); + store_vertex(buffer_vertices, curr_pos + half_width * right, right); + store_vertex(buffer_vertices, curr_pos + half_height * bottom, bottom); + store_vertex(buffer_vertices, curr_pos + half_width * left, left); // triangles starting cap store_triangle(buffer_indices, starting_vertices_size + 0, starting_vertices_size + 2, starting_vertices_size + 1); store_triangle(buffer_indices, starting_vertices_size + 0, starting_vertices_size + 3, starting_vertices_size + 2); + // dummy triangles outer corner cap + append_dummy_cap(buffer_indices, starting_vertices_size); + // triangles sides store_triangle(buffer_indices, starting_vertices_size + 0, starting_vertices_size + 1, starting_vertices_size + 4); store_triangle(buffer_indices, starting_vertices_size + 1, starting_vertices_size + 5, starting_vertices_size + 4); @@ -1027,20 +1053,101 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) store_triangle(buffer_indices, starting_vertices_size + 4, starting_vertices_size + 5, starting_vertices_size + 6); } else { - // vertices 1st endpoint - store_vertex(buffer_vertices, prev_pos + half_width * right, right); // right - store_vertex(buffer_vertices, prev_pos - half_width * right, -right); // left + // any other segment + Vec3f med_dir = (prev_dir + dir).normalized(); + float displacement = half_width * ::tan(::acos(std::clamp(dir.dot(med_dir), -1.0f, 1.0f))); + Vec3f displacement_vec = displacement * prev_dir; + bool can_displace = displacement < prev_length && displacement < length; + + size_t prev_right_id = (starting_vertices_size - 3) * buffer.vertices.vertex_size_floats(); + size_t prev_left_id = (starting_vertices_size - 1) * buffer.vertices.vertex_size_floats(); + Vec3f prev_right_pos = extract_position_at(buffer_vertices, prev_right_id); + Vec3f prev_left_pos = extract_position_at(buffer_vertices, prev_left_id); + + bool is_right_turn = prev_up.dot(prev_dir.cross(dir)) <= 0.0f; + // whether the angle between adjacent segments is greater than 45 degrees + bool is_sharp = prev_dir.dot(dir) < 0.7071068f; + + bool right_displaced = false; + bool left_displaced = false; + + // displace the vertex (inner with respect to the corner) of the previous segment 2nd enpoint, if possible + if (can_displace) { + if (is_right_turn) { + prev_right_pos -= displacement_vec; + update_position_at(buffer_vertices, prev_right_id, prev_right_pos); + right_displaced = true; + } + else { + prev_left_pos -= displacement_vec; + update_position_at(buffer_vertices, prev_left_id, prev_left_pos); + left_displaced = true; + } + } + + if (!is_sharp) { + // displace the vertex (outer with respect to the corner) of the previous segment 2nd enpoint, if possible + if (can_displace) { + if (is_right_turn) { + prev_left_pos += displacement_vec; + update_position_at(buffer_vertices, prev_left_id, prev_left_pos); + left_displaced = true; + } + else { + prev_right_pos += displacement_vec; + update_position_at(buffer_vertices, prev_right_id, prev_right_pos); + right_displaced = true; + } + } + + // vertices 1st endpoint (top and bottom are from previous segment 2nd endpoint) + // vertices position matches that of the previous segment 2nd endpoint, if displaced + store_vertex(buffer_vertices, right_displaced ? prev_right_pos : prev_pos + half_width * right, right); + store_vertex(buffer_vertices, left_displaced ? prev_left_pos : prev_pos + half_width * left, left); + } + else { + // vertices 1st endpoint (top and bottom are from previous segment 2nd endpoint) + // the inner corner vertex position matches that of the previous segment 2nd endpoint, if displaced + if (is_right_turn) { + store_vertex(buffer_vertices, right_displaced ? prev_right_pos : prev_pos + half_width * right, right); + store_vertex(buffer_vertices, prev_pos + half_width * left, left); + } + else { + store_vertex(buffer_vertices, prev_pos + half_width * right, right); + store_vertex(buffer_vertices, left_displaced ? prev_left_pos : prev_pos + half_width * left, left); + } + } // vertices 2nd endpoint - store_vertex(buffer_vertices, curr_pos + half_height * up, up); // top - store_vertex(buffer_vertices, curr_pos + half_width * right, right); // right - store_vertex(buffer_vertices, curr_pos - half_height * up, -up); // bottom - store_vertex(buffer_vertices, curr_pos - half_width * right, -right); // left + store_vertex(buffer_vertices, curr_pos + half_height * up, up); + store_vertex(buffer_vertices, curr_pos + half_width * right, right); + store_vertex(buffer_vertices, curr_pos + half_height * bottom, bottom); + store_vertex(buffer_vertices, curr_pos + half_width * left, left); // triangles starting cap store_triangle(buffer_indices, starting_vertices_size - 4, starting_vertices_size - 2, starting_vertices_size + 0); store_triangle(buffer_indices, starting_vertices_size - 4, starting_vertices_size + 1, starting_vertices_size - 2); + // triangles outer corner cap + if (is_right_turn) { + if (left_displaced) + // dummy triangles + append_dummy_cap(buffer_indices, starting_vertices_size); + else { + store_triangle(buffer_indices, starting_vertices_size - 4, starting_vertices_size + 1, starting_vertices_size - 1); + store_triangle(buffer_indices, starting_vertices_size + 1, starting_vertices_size - 2, starting_vertices_size - 1); + } + } + else { + if (right_displaced) + // dummy triangles + append_dummy_cap(buffer_indices, starting_vertices_size); + else { + store_triangle(buffer_indices, starting_vertices_size - 4, starting_vertices_size - 3, starting_vertices_size + 0); + store_triangle(buffer_indices, starting_vertices_size - 3, starting_vertices_size - 2, starting_vertices_size + 0); + } + } + // triangles sides store_triangle(buffer_indices, starting_vertices_size - 4, starting_vertices_size + 0, starting_vertices_size + 2); store_triangle(buffer_indices, starting_vertices_size + 0, starting_vertices_size + 3, starting_vertices_size + 2); @@ -1057,6 +1164,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) } last_path.last = { static_cast(buffer_indices.size() - 1), static_cast(move_id), curr.position }; + prev_dir = dir; + prev_up = up; + prev_length = length; }; // toolpaths data -> extract from result @@ -1137,20 +1247,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) m_statistics.paths_size += SLIC3R_STDVEC_MEMSIZE(buffer.paths, Path); } unsigned int travel_buffer_id = buffer_id(EMoveType::Travel); - switch (m_buffers[travel_buffer_id].primitive_type) - { - case TBuffer::EPrimitiveType::Line: { m_statistics.travel_segments_count = indices[travel_buffer_id].size() / 2; break; } - case TBuffer::EPrimitiveType::Triangle: { m_statistics.travel_segments_count = indices[travel_buffer_id].size() / 36; break; } - default: { break; } - } - + m_statistics.travel_segments_count = indices[travel_buffer_id].size() / m_buffers[travel_buffer_id].indices_per_segment(); unsigned int extrude_buffer_id = buffer_id(EMoveType::Extrude); - switch (m_buffers[extrude_buffer_id].primitive_type) - { - case TBuffer::EPrimitiveType::Line: { m_statistics.extrude_segments_count = indices[extrude_buffer_id].size() / 2; break; } - case TBuffer::EPrimitiveType::Triangle: { m_statistics.extrude_segments_count = indices[extrude_buffer_id].size() / 36; break; } - default: { break; } - } + m_statistics.extrude_segments_count = indices[extrude_buffer_id].size() / m_buffers[extrude_buffer_id].indices_per_segment(); #endif // ENABLE_GCODE_VIEWER_STATISTICS // layers zs / roles / extruder ids / cp color ids -> extract from result @@ -1334,10 +1433,12 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool if (path.contains(m_sequential_view.current.last)) { unsigned int offset = m_sequential_view.current.last - path.first.s_id; if (offset > 0) { - if (buffer.primitive_type == TBuffer::EPrimitiveType::Line) + if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Line) offset = 2 * offset - 1; - else if (buffer.primitive_type == TBuffer::EPrimitiveType::Triangle) - offset = 36 * (offset - 1) + 30; + else if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle) { + unsigned int indices_count = buffer.indices_per_segment(); + offset = indices_count * (offset - 1) + (indices_count - 6); + } } offset += path.first.i_id; @@ -1382,11 +1483,11 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool unsigned int size_in_vertices = std::min(m_sequential_view.current.last, path.last.s_id) - std::max(m_sequential_view.current.first, path.first.s_id) + 1; unsigned int size_in_indices = 0; - switch (buffer->primitive_type) + switch (buffer->render_primitive_type) { - case TBuffer::EPrimitiveType::Point: { size_in_indices = size_in_vertices; break; } - case TBuffer::EPrimitiveType::Line: { size_in_indices = 2 * (size_in_vertices - 1); break; } - case TBuffer::EPrimitiveType::Triangle: { size_in_indices = 36 * (size_in_vertices - 1); break; } + case TBuffer::ERenderPrimitiveType::Point: { size_in_indices = size_in_vertices; break; } + case TBuffer::ERenderPrimitiveType::Line: + case TBuffer::ERenderPrimitiveType::Triangle: { size_in_indices = buffer->indices_per_segment() * (size_in_vertices - 1); break; } } it->sizes.push_back(size_in_indices); @@ -1394,8 +1495,8 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool if (path.first.s_id < m_sequential_view.current.first && m_sequential_view.current.first <= path.last.s_id) delta_1st = m_sequential_view.current.first - path.first.s_id; - if (buffer->primitive_type == TBuffer::EPrimitiveType::Triangle) - delta_1st *= 36; + if (buffer->render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle) + delta_1st *= buffer->indices_per_segment(); it->offsets.push_back(static_cast((path.first.i_id + delta_1st) * sizeof(unsigned int))); } @@ -1502,9 +1603,9 @@ void GCodeViewer::render_toolpaths() const glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.indices.id)); - switch (buffer.primitive_type) + switch (buffer.render_primitive_type) { - case TBuffer::EPrimitiveType::Point: + case TBuffer::ERenderPrimitiveType::Point: { EOptionsColors color; switch (buffer_type(i)) @@ -1519,12 +1620,12 @@ void GCodeViewer::render_toolpaths() const render_as_points(buffer, color, *shader); break; } - case TBuffer::EPrimitiveType::Line: + case TBuffer::ERenderPrimitiveType::Line: { render_as_lines(buffer, *shader); break; } - case TBuffer::EPrimitiveType::Triangle: + case TBuffer::ERenderPrimitiveType::Triangle: { render_as_triangles(buffer, *shader); break; @@ -1819,7 +1920,19 @@ void GCodeViewer::render_legend() const if (time_mode.time > 0.0f && (m_view_type == EViewType::FeatureType || (m_view_type == EViewType::ColorPrint && !time_mode.custom_gcode_times.empty()))) { ImGui::AlignTextToFramePadding(); - imgui.text(_u8L("Estimated printing time") + ":"); + switch (m_time_estimate_mode) + { + case PrintEstimatedTimeStatistics::ETimeMode::Normal: + { + imgui.text(_u8L("Estimated printing time") + " [" + _u8L("Normal mode") + "]:"); + break; + } + case PrintEstimatedTimeStatistics::ETimeMode::Stealth: + { + imgui.text(_u8L("Estimated printing time") + " [" + _u8L("Stealth mode") + "]:"); + break; + } + } ImGui::SameLine(); imgui.text(short_time(get_time_dhms(time_mode.time))); @@ -1833,7 +1946,6 @@ void GCodeViewer::render_legend() const } } if (show && m_time_statistics.modes[static_cast(mode)].roles_times.size() > 0) { - ImGui::SameLine(0.0f, 10.0f); if (imgui.button(label)) { m_time_estimate_mode = mode; wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); @@ -1846,12 +1958,12 @@ void GCodeViewer::render_legend() const { case PrintEstimatedTimeStatistics::ETimeMode::Normal: { - show_mode_button(_u8L("Stealth mode"), PrintEstimatedTimeStatistics::ETimeMode::Stealth); + show_mode_button(_u8L("Show stealth mode"), PrintEstimatedTimeStatistics::ETimeMode::Stealth); break; } case PrintEstimatedTimeStatistics::ETimeMode::Stealth: { - show_mode_button(_u8L("Normal mode"), PrintEstimatedTimeStatistics::ETimeMode::Normal); + show_mode_button(_u8L("Show normal mode"), PrintEstimatedTimeStatistics::ETimeMode::Normal); break; } } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 808c1a8ee0..e49a1f08bf 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -149,14 +149,14 @@ class GCodeViewer // buffer containing data for rendering a specific toolpath type struct TBuffer { - enum class EPrimitiveType : unsigned char + enum class ERenderPrimitiveType : unsigned char { Point, Line, Triangle }; - EPrimitiveType primitive_type; + ERenderPrimitiveType render_primitive_type; VBuffer vertices; IBuffer indices; @@ -167,6 +167,15 @@ class GCodeViewer void reset(); void add_path(const GCodeProcessor::MoveVertex& move, unsigned int i_id, unsigned int s_id); + unsigned int indices_per_segment() const { + switch (render_primitive_type) + { + case ERenderPrimitiveType::Point: { return 1; } + case ERenderPrimitiveType::Line: { return 2; } + case ERenderPrimitiveType::Triangle: { return 42; } // 3 indices x 14 triangles + default: { return 0; } + } + } }; // helper to render shells From e32930aa6c5008a86323a6d2c9a7d6a4a67be930 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 1 Sep 2020 09:28:02 +0200 Subject: [PATCH 233/255] Code cleanup --- src/libslic3r/Technologies.hpp | 6 - src/slic3r/GUI/GCodeViewer.cpp | 439 +-------------------------- src/slic3r/GUI/GCodeViewer.hpp | 18 -- src/slic3r/GUI/GLCanvas3D.cpp | 12 - src/slic3r/GUI/GLCanvas3D.hpp | 3 - src/slic3r/GUI/GUI_Preview.cpp | 14 +- src/slic3r/GUI/GUI_Preview.hpp | 5 +- src/slic3r/GUI/KBShortcutsDialog.cpp | 9 - 8 files changed, 3 insertions(+), 503 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 834cebbe45..a0484b259c 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -60,10 +60,4 @@ #define ENABLE_GCODE_VIEWER_DATA_CHECKING (0 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_TASKBAR_ICON (0 && ENABLE_GCODE_VIEWER) -#define TIME_ESTIMATE_NONE 0 -#define TIME_ESTIMATE_DEFAULT 1 -#define TIME_ESTIMATE_MODAL 2 -#define TIME_ESTIMATE_LEGEND 3 -#define GCODE_VIEWER_TIME_ESTIMATE TIME_ESTIMATE_LEGEND - #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 8853d7a754..24ed5be9b4 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -383,9 +383,7 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& wxGetApp().plater()->set_bed_shape(bed_shape, texture, model, gcode_result.bed_shape.empty()); } -#if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE m_time_statistics = gcode_result.time_statistics; -#endif // GCODE_VIEWER_TIME_ESTIMATE } void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors) @@ -461,12 +459,8 @@ void GCodeViewer::reset() m_layers_zs = std::vector(); m_layers_z_range = { 0.0, 0.0 }; m_roles = std::vector(); -#if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE m_time_statistics.reset(); -#endif // GCODE_VIEWER_TIME_ESTIMATE -#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND m_time_estimate_mode = PrintEstimatedTimeStatistics::ETimeMode::Normal; -#endif // GCODE_VIEWER_TIME_ESTIMATE #if ENABLE_GCODE_VIEWER_STATISTICS m_statistics.reset_all(); @@ -479,15 +473,8 @@ void GCodeViewer::render() const m_statistics.reset_opengl(); #endif // ENABLE_GCODE_VIEWER_STATISTICS -#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_MODAL - if (m_roles.empty()) { - m_time_estimate_frames_count = 0; - return; - } -#else if (m_roles.empty()) return; -#endif // GCODE_VIEWER_TIME_ESTIMATE glsafe(::glEnable(GL_DEPTH_TEST)); render_toolpaths(); @@ -495,9 +482,6 @@ void GCodeViewer::render() const m_sequential_view.marker.render(); render_shells(); render_legend(); -#if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE - render_time_estimate(); -#endif // GCODE_VIEWER_TIME_ESTIMATE #if ENABLE_GCODE_VIEWER_STATISTICS render_statistics(); #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -533,9 +517,6 @@ unsigned int GCodeViewer::get_options_visibility_flags() const flags = set_flag(flags, static_cast(Preview::OptionType::Shells), m_shells.visible); flags = set_flag(flags, static_cast(Preview::OptionType::ToolMarker), m_sequential_view.marker.is_visible()); flags = set_flag(flags, static_cast(Preview::OptionType::Legend), is_legend_enabled()); -#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_DEFAULT - flags = set_flag(flags, static_cast(Preview::OptionType::TimeEstimate), is_time_estimate_enabled()); -#endif // GCODE_VIEWER_TIME_ESTIMATE return flags; } @@ -555,9 +536,6 @@ void GCodeViewer::set_options_visibility_from_flags(unsigned int flags) m_shells.visible = is_flag_set(static_cast(Preview::OptionType::Shells)); m_sequential_view.marker.set_visible(is_flag_set(static_cast(Preview::OptionType::ToolMarker))); enable_legend(is_flag_set(static_cast(Preview::OptionType::Legend))); -#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_DEFAULT - enable_time_estimate(is_flag_set(static_cast(Preview::OptionType::TimeEstimate))); -#endif // GCODE_VIEWER_TIME_ESTIMATE } void GCodeViewer::set_layers_z_range(const std::array& layers_z_range) @@ -569,16 +547,6 @@ void GCodeViewer::set_layers_z_range(const std::array& layers_z_range wxGetApp().plater()->update_preview_moves_slider(); } -#if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE -void GCodeViewer::enable_time_estimate(bool enable) -{ - m_time_estimate_enabled = enable; - wxGetApp().update_ui_from_settings(); - wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); - wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); -} -#endif // GCODE_VIEWER_TIME_ESTIMATE - void GCodeViewer::export_toolpaths_to_obj(const char* filename) const { if (filename == nullptr) @@ -1685,7 +1653,6 @@ void GCodeViewer::render_legend() const Line }; -#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND const PrintEstimatedTimeStatistics::Mode& time_mode = m_time_statistics.modes[static_cast(m_time_estimate_mode)]; float icon_size = ImGui::GetTextLineHeight(); @@ -1696,10 +1663,6 @@ void GCodeViewer::render_legend() const std::function callback = nullptr) { if (!visible) ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.3333f); -#else - auto append_item = [this, draw_list, &imgui](EItemType type, const Color& color, const std::string& label, std::function callback = nullptr) { - float icon_size = ImGui::GetTextLineHeight(); -#endif // GCODE_VIEWER_TIME_ESTIMATE ImVec2 pos = ImGui::GetCursorScreenPos(); switch (type) { @@ -1745,7 +1708,6 @@ void GCodeViewer::render_legend() const if (callback != nullptr) { if (ImGui::MenuItem(label.c_str())) callback(); -#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND else { // show tooltip if (ImGui::IsItemHovered()) { @@ -1779,15 +1741,12 @@ void GCodeViewer::render_legend() const ::sprintf(buf, "%.1f%%", 100.0f * percent); ImGui::TextUnformatted((percent > 0.0f) ? buf : ""); } -#endif // GCODE_VIEWER_TIME_ESTIMATE } else imgui.text(label); -#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND if (!visible) ImGui::PopStyleVar(); -#endif // GCODE_VIEWER_TIME_ESTIMATE }; auto append_range = [this, draw_list, &imgui, append_item](const Extrusions::Range& range, unsigned int decimals) { @@ -1812,7 +1771,6 @@ void GCodeViewer::render_legend() const } }; -#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND auto append_headers = [&imgui](const std::array& texts, const std::array& offsets) { imgui.text(texts[0]); ImGui::SameLine(offsets[0]); @@ -1838,7 +1796,6 @@ void GCodeViewer::render_legend() const ret[1] = ret[0] + max_width(times, titles[1]) + style.ItemSpacing.x; return ret; }; -#endif // GCODE_VIEWER_TIME_ESTIMATE auto color_print_ranges = [this](unsigned char extruder_id, const std::vector& custom_gcode_per_print_z) { std::vector>> ret; @@ -1887,7 +1844,6 @@ void GCodeViewer::render_legend() const return _u8L("from") + " " + std::string(buf1) + " " + _u8L("to") + " " + std::string(buf2) + " " + _u8L("mm"); }; -#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND auto role_time_and_percent = [this, time_mode](ExtrusionRole role) { auto it = std::find_if(time_mode.roles_times.begin(), time_mode.roles_times.end(), [role](const std::pair& item) { return role == item.first; }); return (it != time_mode.roles_times.end()) ? std::make_pair(it->second, it->second / time_mode.time) : std::make_pair(0.0f, 0.0f); @@ -1969,20 +1925,15 @@ void GCodeViewer::render_legend() const } ImGui::Spacing(); } -#endif // GCODE_VIEWER_TIME_ESTIMATE // extrusion paths section -> title switch (m_view_type) { -#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND case EViewType::FeatureType: { append_headers({ _u8L("Feature type"), _u8L("Time"), _u8L("Percentage") }, offsets); break; } -#else - case EViewType::FeatureType: { imgui.title(_u8L("Feature type")); break; } -#endif // GCODE_VIEWER_TIME_ESTIMATE case EViewType::Height: { imgui.title(_u8L("Height (mm)")); break; } case EViewType::Width: { imgui.title(_u8L("Width (mm)")); break; } case EViewType::Feedrate: { imgui.title(_u8L("Speed (mm/s)")); break; } @@ -2003,28 +1954,15 @@ void GCodeViewer::render_legend() const if (role >= erCount) continue; bool visible = is_visible(role); -#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND append_item(EItemType::Rect, Extrusion_Role_Colors[static_cast(role)], labels[i], visible, times[i], percents[i], max_percent, offsets, [this, role, visible]() { -#else - if (!visible) - ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.3333f); - - append_item(EItemType::Rect, Extrusion_Role_Colors[static_cast(role)], _u8L(ExtrusionEntity::role_to_string(role)), - [this, role, visible]() { -#endif // GCODE_VIEWER_TIME_ESTIMATE - m_extrusions.role_visibility_flags = visible ? m_extrusions.role_visibility_flags & ~(1 << role) : m_extrusions.role_visibility_flags | (1 << role); + m_extrusions.role_visibility_flags = visible ? m_extrusions.role_visibility_flags & ~(1 << role) : m_extrusions.role_visibility_flags | (1 << role); // update buffers' render paths refresh_render_paths(false, false); wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); wxGetApp().plater()->update_preview_bottom_toolbar(); } ); - -#if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_LEGEND - if (!visible) - ImGui::PopStyleVar(); -#endif // GCODE_VIEWER_TIME_ESTIMATE } break; } @@ -2102,7 +2040,6 @@ void GCodeViewer::render_legend() const default: { break; } } -#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND // partial estimated printing time section if (m_view_type == EViewType::ColorPrint) { using Times = std::pair; @@ -2185,11 +2122,6 @@ void GCodeViewer::render_legend() const draw_list->AddRectFilled({ pos.x + 1.0f, pos.y + 1.0f }, { pos.x + icon_size - 1.0f, pos.y + icon_size - 1.0f }, ImGui::GetColorU32({ color2[0], color2[1], color2[2], 1.0f })); -// ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size)); -// draw_list->AddNgonFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color1[0], color1[1], color1[2], 1.0f }), 6); -// center.x += icon_size; -// draw_list->AddNgonFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color2[0], color2[1], color2[2], 1.0f }), 6); - ImGui::SameLine(offsets[0]); imgui.text(short_time(get_time_dhms(times.second - times.first))); }; @@ -2240,7 +2172,6 @@ void GCodeViewer::render_legend() const } } } -#endif // GCODE_VIEWER_TIME_ESTIMATE // travel paths section if (m_buffers[buffer_id(EMoveType::Travel)].visible) { @@ -2307,374 +2238,6 @@ void GCodeViewer::render_legend() const ImGui::PopStyleVar(); } -#if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE -void GCodeViewer::render_time_estimate() const -{ - if (!m_time_estimate_enabled) { -#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_MODAL - m_time_estimate_frames_count = 0; -#endif // GCODE_VIEWER_TIME_ESTIMATE - return; - } - - ImGuiWrapper& imgui = *wxGetApp().imgui(); - -#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_MODAL - // esc - if (ImGui::GetIO().KeysDown[27]) { - m_time_estimate_enabled = false; - return; - } -#endif // GCODE_VIEWER_TIME_ESTIMATE - - using Times = std::pair; - using TimesList = std::vector>; - using Headers = std::vector; - using ColumnOffsets = std::array; - - // helper structure containig the data needed to render the time items - struct PartialTime - { - enum class EType : unsigned char - { - Print, - ColorChange, - Pause - }; - EType type; - int extruder_id; - Color color1; - Color color2; - Times times; - }; - using PartialTimes = std::vector; - - auto append_headers = [&imgui](const Headers& headers, const ColumnOffsets& offsets) { - imgui.text(headers[0]); - ImGui::SameLine(offsets[0]); - imgui.text(headers[1]); - ImGui::SameLine(offsets[1]); - imgui.text(headers[2]); - ImGui::Separator(); - }; - - auto append_mode = [this, &imgui, append_headers](float total_time, const PartialTimes& items, - const Headers& partial_times_headers, - const std::vector>& moves_time, - const Headers& moves_headers, - const std::vector>& roles_time, - const Headers& roles_headers) { - auto append_partial_times = [this, &imgui, append_headers](const PartialTimes& items, const Headers& headers) { - auto calc_offsets = [this, &headers](const PartialTimes& items) { - ColumnOffsets ret = { ImGui::CalcTextSize(headers[0].c_str()).x, ImGui::CalcTextSize(headers[1].c_str()).x }; - for (const PartialTime& item : items) { - std::string label; - switch (item.type) - { - case PartialTime::EType::Print: { label = _u8L("Print"); break; } - case PartialTime::EType::Pause: { label = _u8L("Pause"); break; } - case PartialTime::EType::ColorChange: { label = _u8L("Color change"); break; } - } - - ret[0] = std::max(ret[0], ImGui::CalcTextSize(label.c_str()).x); - ret[1] = std::max(ret[1], ImGui::CalcTextSize(short_time(get_time_dhms(item.times.second)).c_str()).x); - } - - const ImGuiStyle& style = ImGui::GetStyle(); - ret[0] += 2.0f * (ImGui::GetTextLineHeight() + style.ItemSpacing.x); - ret[1] += ret[0] + style.ItemSpacing.x; - return ret; - }; - auto append_color = [this, &imgui](const Color& color1, const Color& color2, ColumnOffsets& offsets, const Times& times) { - imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Color change")); - ImGui::SameLine(); - - float icon_size = ImGui::GetTextLineHeight(); - ImDrawList* draw_list = ImGui::GetWindowDrawList(); - ImVec2 pos = ImGui::GetCursorScreenPos(); - pos.x -= 0.5f * ImGui::GetStyle().ItemSpacing.x; - ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size)); - draw_list->AddNgonFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color1[0], color1[1], color1[2], 1.0f }), 6); - center.x += icon_size; - draw_list->AddNgonFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color2[0], color2[1], color2[2], 1.0f }), 6); - ImGui::SameLine(offsets[0]); - imgui.text(short_time(get_time_dhms(times.second - times.first))); - }; - - if (items.empty()) - return; - - ColumnOffsets offsets = calc_offsets(items); - - ImGui::Spacing(); - append_headers(headers, offsets); - - for (const PartialTime& item : items) { - switch (item.type) - { - case PartialTime::EType::Print: - { - imgui.text(_u8L("Print")); - ImGui::SameLine(offsets[0]); - imgui.text(short_time(get_time_dhms(item.times.second))); - ImGui::SameLine(offsets[1]); - imgui.text(short_time(get_time_dhms(item.times.first))); - break; - } - case PartialTime::EType::Pause: - { - imgui.text(_u8L("Pause")); - ImGui::SameLine(offsets[0]); - imgui.text(short_time(get_time_dhms(item.times.second - item.times.first))); - break; - } - case PartialTime::EType::ColorChange: - { - append_color(item.color1, item.color2, offsets, item.times); - break; - } - } - } - }; - - auto move_type_label = [](EMoveType type) { - switch (type) - { - case EMoveType::Noop: { return _u8L("Noop"); } - case EMoveType::Retract: { return _u8L("Retraction"); } - case EMoveType::Unretract: { return _u8L("Unretraction"); } - case EMoveType::Tool_change: { return _u8L("Tool change"); } - case EMoveType::Color_change: { return _u8L("Color change"); } - case EMoveType::Pause_Print: { return _u8L("Pause print"); } - case EMoveType::Custom_GCode: { return _u8L("Custom GCode"); } - case EMoveType::Travel: { return _u8L("Travel"); } - case EMoveType::Extrude: { return _u8L("Extrusion"); } - default: { return _u8L("Unknown"); } - } - }; - - auto append_time_item = [&imgui] (const std::string& label, float time, float percentage, const ImVec4& color, const ColumnOffsets& offsets) { - imgui.text(label); - ImGui::SameLine(offsets[0]); - imgui.text(short_time(get_time_dhms(time))); - ImGui::SameLine(offsets[1]); - char buf[64]; - ::sprintf(buf, "%.1f%%", 100.0f * percentage); - ImGuiWindow* window = ImGui::GetCurrentWindow(); - ImRect frame_bb; - frame_bb.Min = { ImGui::GetCursorScreenPos().x, window->DC.CursorPos.y }; - frame_bb.Max = { frame_bb.Min.x + percentage * (window->WorkRect.Max.x - frame_bb.Min.x), window->DC.CursorPos.y + ImGui::CalcTextSize(buf, nullptr, false).y }; - frame_bb.Min.x -= IM_FLOOR(window->WindowPadding.x * 0.5f - 1.0f); - frame_bb.Max.x += IM_FLOOR(window->WindowPadding.x * 0.5f); - window->DrawList->AddRectFilled(frame_bb.Min, frame_bb.Max, ImGui::GetColorU32({ color.x, color.y, color.z, 1.0f }), 0.0f, 0); - ImGui::TextUnformatted(buf); - }; - - auto append_move_times = [this, &imgui, move_type_label, append_headers, append_time_item](float total_time, - const std::vector>& moves_time, - const Headers& headers, const ColumnOffsets& offsets) { - - if (moves_time.empty()) - return; - - if (!ImGui::CollapsingHeader(_u8L("Moves Time").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) - return; - - append_headers(headers, offsets); - - std::vector> sorted_moves_time(moves_time); - std::sort(sorted_moves_time.begin(), sorted_moves_time.end(), [](const auto& p1, const auto& p2) { return p2.second < p1.second; }); - - for (const auto& [type, time] : sorted_moves_time) { - append_time_item(move_type_label(type), time, time / total_time, ImGuiWrapper::COL_ORANGE_LIGHT, offsets); - } - }; - - auto append_role_times = [this, &imgui, append_headers, append_time_item](float total_time, - const std::vector>& roles_time, - const Headers& headers, const ColumnOffsets& offsets) { - - if (roles_time.empty()) - return; - - if (!ImGui::CollapsingHeader(_u8L("Features Time").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) - return; - - append_headers(headers, offsets); - - std::vector> sorted_roles_time(roles_time); - std::sort(sorted_roles_time.begin(), sorted_roles_time.end(), [](const auto& p1, const auto& p2) { return p2.second < p1.second; }); - - for (const auto& [role, time] : sorted_roles_time) { - Color color = Extrusion_Role_Colors[static_cast(role)]; - append_time_item(_u8L(ExtrusionEntity::role_to_string(role)), time, time / total_time, { 0.666f * color[0], 0.666f * color[1], 0.666f * color[2], 1.0f}, offsets); - } - }; - - auto calc_common_offsets = [move_type_label]( - const std::vector>& moves_time, const Headers& moves_headers, - const std::vector>& roles_time, const Headers& roles_headers) { - ColumnOffsets ret = { std::max(ImGui::CalcTextSize(moves_headers[0].c_str()).x, ImGui::CalcTextSize(roles_headers[0].c_str()).x), - std::max(ImGui::CalcTextSize(moves_headers[1].c_str()).x, ImGui::CalcTextSize(roles_headers[1].c_str()).x) }; - - for (const auto& [type, time] : moves_time) { - ret[0] = std::max(ret[0], ImGui::CalcTextSize(move_type_label(type).c_str()).x); - ret[1] = std::max(ret[1], ImGui::CalcTextSize(short_time(get_time_dhms(time)).c_str()).x); - } - - for (const auto& [role, time] : roles_time) { - ret[0] = std::max(ret[0], ImGui::CalcTextSize(_u8L(ExtrusionEntity::role_to_string(role)).c_str()).x); - ret[1] = std::max(ret[1], ImGui::CalcTextSize(short_time(get_time_dhms(time)).c_str()).x); - } - - const ImGuiStyle& style = ImGui::GetStyle(); - ret[0] += 2.0f * style.ItemSpacing.x; - ret[1] += ret[0] + style.ItemSpacing.x; - return ret; - }; - - imgui.text(_u8L("Time") + ":"); - ImGui::SameLine(); - imgui.text(short_time(get_time_dhms(total_time))); - append_partial_times(items, partial_times_headers); - ColumnOffsets common_offsets = calc_common_offsets(moves_time, moves_headers, roles_time, roles_headers); - append_move_times(total_time, moves_time, moves_headers, common_offsets); - append_role_times(total_time, roles_time, roles_headers, common_offsets); - }; - - auto generate_partial_times = [this](const TimesList& times) { - PartialTimes items; - - std::vector custom_gcode_per_print_z = wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes; - int extruders_count = wxGetApp().extruders_edited_cnt(); - std::vector last_color(extruders_count); - for (int i = 0; i < extruders_count; ++i) { - last_color[i] = m_tool_colors[i]; - } - int last_extruder_id = 1; - for (const auto& time_rec : times) { - switch (time_rec.first) - { - case CustomGCode::PausePrint: - { - auto it = std::find_if(custom_gcode_per_print_z.begin(), custom_gcode_per_print_z.end(), [time_rec](const CustomGCode::Item& item) { return item.type == time_rec.first; }); - if (it != custom_gcode_per_print_z.end()) { - items.push_back({ PartialTime::EType::Print, it->extruder, Color(), Color(), time_rec.second }); - items.push_back({ PartialTime::EType::Pause, it->extruder, Color(), Color(), time_rec.second }); - custom_gcode_per_print_z.erase(it); - } - break; - } - case CustomGCode::ColorChange: - { - auto it = std::find_if(custom_gcode_per_print_z.begin(), custom_gcode_per_print_z.end(), [time_rec](const CustomGCode::Item& item) { return item.type == time_rec.first; }); - if (it != custom_gcode_per_print_z.end()) { - items.push_back({ PartialTime::EType::Print, it->extruder, Color(), Color(), time_rec.second }); - items.push_back({ PartialTime::EType::ColorChange, it->extruder, last_color[it->extruder - 1], decode_color(it->color), time_rec.second }); - last_color[it->extruder - 1] = decode_color(it->color); - last_extruder_id = it->extruder; - custom_gcode_per_print_z.erase(it); - } - else - items.push_back({ PartialTime::EType::Print, last_extruder_id, Color(), Color(), time_rec.second }); - - break; - } - default: { break; } - } - } - - return items; - }; - - const Headers partial_times_headers = { - _u8L("Event"), - _u8L("Remaining"), - _u8L("Duration") - }; - const Headers moves_headers = { - _u8L("Type"), - _u8L("Time"), - _u8L("Percentage") - }; - const Headers roles_headers = { - _u8L("Feature"), - _u8L("Time"), - _u8L("Percentage") - }; - - Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size(); -#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_MODAL - std::string title = _u8L("Estimated printing time"); - ImGui::OpenPopup(title.c_str()); - - imgui.set_next_window_pos(0.5f * static_cast(cnv_size.get_width()), 0.5f * static_cast(cnv_size.get_height()), ImGuiCond_Always, 0.5f, 0.5f); - ImGui::SetNextWindowSize({ -1.0f, 0.666f * static_cast(cnv_size.get_height()) }); - ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); - ImGui::SetNextWindowBgAlpha(0.6f); - if (ImGui::BeginPopupModal(title.c_str(), &m_time_estimate_enabled, ImGuiWindowFlags_AlwaysAutoResize)) { - if (m_time_estimate_enabled) { - // imgui takes several frames to grayout the content of the canvas - if (m_time_estimate_frames_count < 10) { - wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); - wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); - ++m_time_estimate_frames_count; - } -#else - imgui.set_next_window_pos(static_cast(cnv_size.get_width()), static_cast(cnv_size.get_height()), ImGuiCond_Always, 1.0f, 1.0f); - ImGui::SetNextWindowSizeConstraints({ 0.0f, 0.0f }, { -1.0f, 0.5f * static_cast(cnv_size.get_height()) }); - ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); - ImGui::SetNextWindowBgAlpha(0.6f); - imgui.begin(std::string("Time_estimate"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove); - - // title - imgui.title(_u8L("Estimated printing time")); -#endif // GCODE_VIEWER_TIME_ESTIMATE - - // mode tabs - ImGui::BeginTabBar("mode_tabs"); - const PrintEstimatedTimeStatistics::Mode& normal_mode = m_time_statistics.modes[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Normal)]; - if (normal_mode.time > 0.0f) { - if (ImGui::BeginTabItem(_u8L("Normal").c_str())) { - append_mode(normal_mode.time, - generate_partial_times(normal_mode.custom_gcode_times), partial_times_headers, - normal_mode.moves_times, moves_headers, - normal_mode.roles_times, roles_headers); - ImGui::EndTabItem(); - } - } - const PrintEstimatedTimeStatistics::Mode& stealth_mode = m_time_statistics.modes[static_cast(PrintEstimatedTimeStatistics::ETimeMode::Stealth)]; - if (stealth_mode.time > 0.0f) { - if (ImGui::BeginTabItem(_u8L("Stealth").c_str())) { - append_mode(stealth_mode.time, - generate_partial_times(stealth_mode.custom_gcode_times), partial_times_headers, - stealth_mode.moves_times, moves_headers, - stealth_mode.roles_times, roles_headers); - ImGui::EndTabItem(); - } - } - ImGui::EndTabBar(); - -#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_MODAL - // this is ugly, but it is the only way to ensure that the dialog is large - // enough to show enterely the title - // see: https://github.com/ocornut/imgui/issues/3239 - float width = std::max(ImGui::CalcTextSize(title.c_str()).x + 2.0f * ImGui::GetStyle().WindowPadding.x, 300.0f); - ImGui::SetCursorPosX(width); - ImGui::SetCursorPosX(0.0f); - } - else - m_time_estimate_enabled = false; - - ImGui::EndPopup(); - } -#else - imgui.end(); -#endif // GCODE_VIEWER_TIME_ESTIMATE - ImGui::PopStyleVar(); -} -#endif // GCODE_VIEWER_TIME_ESTIMATE - #if ENABLE_GCODE_VIEWER_STATISTICS void GCodeViewer::render_statistics() const { diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index e49a1f08bf..302296c412 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -369,18 +369,8 @@ private: Shells m_shells; EViewType m_view_type{ EViewType::FeatureType }; bool m_legend_enabled{ true }; -#if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE PrintEstimatedTimeStatistics m_time_statistics; -#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_MODAL - mutable bool m_time_estimate_enabled{ false }; - mutable unsigned int m_time_estimate_frames_count{ 0 }; -#else - bool m_time_estimate_enabled{ false }; -#endif // GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_MODAL -#endif // GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE -#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND mutable PrintEstimatedTimeStatistics::ETimeMode m_time_estimate_mode{ PrintEstimatedTimeStatistics::ETimeMode::Normal }; -#endif // GCODE_VIEWER_TIME_ESTIMATE #if ENABLE_GCODE_VIEWER_STATISTICS mutable Statistics m_statistics; #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -433,11 +423,6 @@ public: bool is_legend_enabled() const { return m_legend_enabled; } void enable_legend(bool enable) { m_legend_enabled = enable; } -#if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE - bool is_time_estimate_enabled() const { return m_time_estimate_enabled; } - void enable_time_estimate(bool enable); -#endif // GCODE_VIEWER_TIME_ESTIMATE - void export_toolpaths_to_obj(const char* filename) const; private: @@ -448,9 +433,6 @@ private: void render_toolpaths() const; void render_shells() const; void render_legend() const; -#if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE - void render_time_estimate() const; -#endif // GCODE_VIEWER_TIME_ESTIMATE #if ENABLE_GCODE_VIEWER_STATISTICS void render_statistics() const; #endif // ENABLE_GCODE_VIEWER_STATISTICS diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index c0da110d92..7ae6f42945 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3109,18 +3109,6 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) break; } #endif // ENABLE_RENDER_PICKING_PASS -#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_DEFAULT || GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_MODAL - case 'T': - case 't': - { - if (!m_main_toolbar.is_enabled()) { - m_gcode_viewer.enable_time_estimate(!m_gcode_viewer.is_time_estimate_enabled()); - m_dirty = true; - wxGetApp().plater()->update_preview_bottom_toolbar(); - } - break; - } -#endif // GCODE_VIEWER_TIME_ESTIMATE case 'Z': #if ENABLE_GCODE_VIEWER case 'z': diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index ee1d32abb8..03d42089b8 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -558,9 +558,6 @@ public: void reset_gcode_toolpaths() { m_gcode_viewer.reset(); } const GCodeViewer::SequentialView& get_gcode_sequential_view() const { return m_gcode_viewer.get_sequential_view(); } void update_gcode_sequential_view_current(unsigned int first, unsigned int last) { m_gcode_viewer.update_sequential_view_current(first, last); } -#if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE - bool is_time_estimate_enabled() const { return m_gcode_viewer.is_time_estimate_enabled(); } -#endif // GCODE_VIEWER_TIME_ESTIMATE #endif // ENABLE_GCODE_VIEWER void toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 57b1158f65..5dcd26a877 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -331,13 +331,8 @@ bool Preview::init(wxWindow* parent, Model* model) get_option_type_string(OptionType::CustomGCodes) + "|0|" + get_option_type_string(OptionType::Shells) + "|0|" + get_option_type_string(OptionType::ToolMarker) + "|0|" + -#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_DEFAULT - get_option_type_string(OptionType::Legend) + "|1|" + - get_option_type_string(OptionType::TimeEstimate) + "|1" -#else get_option_type_string(OptionType::Legend) + "|1" -#endif // GCODE_VIEWER_TIME_ESTIMATE - ); +); Slic3r::GUI::create_combochecklist(m_combochecklist_options, GUI::into_u8(_L("Options")), options_items); #else m_checkbox_travel = new wxCheckBox(this, wxID_ANY, _(L("Travel"))); @@ -1472,14 +1467,7 @@ wxString Preview::get_option_type_string(OptionType type) const case OptionType::CustomGCodes: { return _L("Custom GCodes"); } case OptionType::Shells: { return _L("Shells"); } case OptionType::ToolMarker: { return _L("Tool marker"); } -#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND case OptionType::Legend: { return _L("Legend/Estimated printing time"); } -#else - case OptionType::Legend: { return _L("Legend"); } -#endif // GCODE_VIEWER_TIME_ESTIMATE -#if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE - case OptionType::TimeEstimate: { return _L("Estimated printing time"); } -#endif // GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE default: { return ""; } } } diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index ddb7af86fb..d9ce44bd62 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -150,10 +150,7 @@ public: CustomGCodes, Shells, ToolMarker, - Legend, -#if GCODE_VIEWER_TIME_ESTIMATE != TIME_ESTIMATE_NONE - TimeEstimate -#endif // GCODE_VIEWER_TIME_ESTIMATE + Legend }; Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process, diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index 1a551216e7..1eceea22e4 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -206,16 +206,7 @@ void KBShortcutsDialog::fill_shortcuts() { L("Arrow Down"), L("Lower Layer") }, { "U", L("Upper Layer") }, { "D", L("Lower Layer") }, -#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_LEGEND { "L", L("Show/Hide Legend/Estimated printing time") }, -#else - { "L", L("Show/Hide Legend") }, -#endif // GCODE_VIEWER_TIME_ESTIMATE -#if GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_DEFAULT - { "T", L("Show/Hide Estimated printing time") } -#elif GCODE_VIEWER_TIME_ESTIMATE == TIME_ESTIMATE_MODAL - { "T", L("Show Estimated printing time") } -#endif // GCODE_VIEWER_TIME_ESTIMATE }; m_full_shortcuts.push_back(std::make_pair(_L("Preview"), preview_shortcuts)); From 683af51685ec21d09be4c0ef9ac8228b38bcb56d Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Tue, 1 Sep 2020 14:15:19 +0200 Subject: [PATCH 234/255] Replaced boost::filesystem::canonical() with boost::filesystem::absolute(), as canonical() is broken on Windows (reparse points aka symbolic links are not processed correctly). Fixes https://github.com/prusa3d/PrusaSlicer/issues/732 https://github.com/prusa3d/PrusaSlicer/issues/3956 https://github.com/prusa3d/PrusaSlicer/issues/4557 --- src/libslic3r/Preset.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index a5160d2db3..7aaa96c8cf 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -634,7 +634,9 @@ void PresetCollection::add_default_preset(const std::vector &keys, // Throws an exception on error. void PresetCollection::load_presets(const std::string &dir_path, const std::string &subdir) { - boost::filesystem::path dir = boost::filesystem::canonical(boost::filesystem::path(dir_path) / subdir).make_preferred(); + // Don't use boost::filesystem::canonical() on Windows, it is broken in regard to reparse points, + // see https://github.com/prusa3d/PrusaSlicer/issues/732 + boost::filesystem::path dir = boost::filesystem::absolute(boost::filesystem::path(dir_path) / subdir).make_preferred(); m_dir_path = dir.string(); std::string errors_cummulative; // Store the loaded presets into a new vector, otherwise the binary search for already existing presets would be broken. @@ -1518,7 +1520,9 @@ PhysicalPrinterCollection::PhysicalPrinterCollection( const std::vector Date: Tue, 1 Sep 2020 14:35:42 +0200 Subject: [PATCH 235/255] Fixed export of toolpaths to obj files --- src/slic3r/GUI/GCodeViewer.cpp | 25 +++++++++++++++++-------- src/slic3r/GUI/GCodeViewer.hpp | 18 ++++++++++++++++++ 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 24ed5be9b4..772b290ea8 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -608,9 +608,15 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, 0, buffer.vertices.data_size_bytes(), vertices.data())); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - auto get_vertex = [&vertices, floats_per_vertex](size_t id) { + // get indices data from index buffer on gpu + std::vector indices = std::vector(buffer.indices.count); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.indices.id)); + glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, static_cast(indices.size() * sizeof(unsigned int)), indices.data())); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + + auto get_vertex = [&vertices, floats_per_vertex](unsigned int id) { // extract vertex from vector of floats - size_t base_id = id * floats_per_vertex; + unsigned int base_id = id * floats_per_vertex; return Vec3f(vertices[base_id + 0], vertices[base_id + 1], vertices[base_id + 2]); }; @@ -626,7 +632,7 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const float length; }; - auto generate_segment = [get_vertex](size_t start_id, float half_width, float half_height) { + auto generate_segment = [get_vertex](unsigned int start_id, unsigned int end_id, float half_width, float half_height) { auto local_basis = [](const Vec3f& dir) { // calculate local basis (dir, right, up) on given segment std::array ret; @@ -650,13 +656,16 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const }; Vec3f v1 = get_vertex(start_id) - half_height * Vec3f::UnitZ(); - Vec3f v2 = get_vertex(start_id + 1) - half_height * Vec3f::UnitZ(); + Vec3f v2 = get_vertex(end_id) - half_height * Vec3f::UnitZ(); float length = (v2 - v1).norm(); const auto&& [dir, right, up] = local_basis(v2 - v1); return Segment({ v1, v2, dir, right, up, half_width * right, half_height * up, length }); }; size_t out_vertices_count = 0; + unsigned int indices_per_segment = buffer.indices_per_segment(); + unsigned int start_vertex_offset = buffer.start_segment_vertex_offset(); + unsigned int end_vertex_offset = buffer.end_segment_vertex_offset(); for (size_t i = 0; i < buffer.render_paths.size(); ++i) { // get paths segments from buffer paths @@ -675,9 +684,8 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const unsigned int start = static_cast(render_path.offsets[j] / sizeof(unsigned int)); unsigned int end = start + render_path.sizes[j]; - for (size_t k = start; k < end; k += 2) { - Segment curr = generate_segment(k, half_width, half_height); - + for (size_t k = start; k < end; k += static_cast(indices_per_segment)) { + Segment curr = generate_segment(indices[k + start_vertex_offset], indices[k + end_vertex_offset], half_width, half_height); if (k == start) { // starting endpoint vertices/normals out_vertices.push_back(curr.v1 + curr.rl_displacement); out_normals.push_back(curr.right); // right @@ -699,7 +707,8 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const out_vertices.push_back(curr.v1 - curr.rl_displacement); out_normals.push_back(-curr.right); // left out_vertices_count += 2; - Segment prev = generate_segment(k - 2, half_width, half_height); + size_t first_vertex_id = k - static_cast(indices_per_segment); + Segment prev = generate_segment(indices[first_vertex_id + start_vertex_offset], indices[first_vertex_id + end_vertex_offset], half_width, half_height); Vec3f med_dir = (prev.dir + curr.dir).normalized(); float disp = half_width * ::tan(::acos(std::clamp(curr.dir.dot(med_dir), -1.0f, 1.0f))); Vec3f disp_vec = disp * prev.dir; diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 302296c412..68fed6f334 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -176,6 +176,24 @@ class GCodeViewer default: { return 0; } } } + unsigned int start_segment_vertex_offset() const { + switch (render_primitive_type) + { + case ERenderPrimitiveType::Point: + case ERenderPrimitiveType::Line: + case ERenderPrimitiveType::Triangle: + default: { return 0; } + } + } + unsigned int end_segment_vertex_offset() const { + switch (render_primitive_type) + { + case ERenderPrimitiveType::Point: { return 0; } + case ERenderPrimitiveType::Line: { return 1; } + case ERenderPrimitiveType::Triangle: { return 36; } // 1 vertex of 13th triangle + default: { return 0; } + } + } }; // helper to render shells From 2455df4017e4000347dc77b543c8674bd052b145 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 24 Aug 2020 13:53:18 +0200 Subject: [PATCH 236/255] notifiactions: new icons + deleting old warnings&errors --- resources/icons/notification_close.svg | 18 +++++ resources/icons/notification_close_hover.svg | 66 +++++++++++++++++ resources/icons/notification_error.svg | 71 +++++++++++++++++++ resources/icons/notification_minimalize.svg | 14 ++++ .../icons/notification_minimalize_hover.svg | 58 +++++++++++++++ resources/icons/notification_warning.svg | 70 ++++++++++++++++++ src/imgui/imconfig.h | 24 ++++--- src/slic3r/GUI/ImGuiWrapper.cpp | 24 ++++--- src/slic3r/GUI/NotificationManager.cpp | 4 +- src/slic3r/GUI/Plater.cpp | 4 ++ 10 files changed, 329 insertions(+), 24 deletions(-) create mode 100644 resources/icons/notification_close.svg create mode 100644 resources/icons/notification_close_hover.svg create mode 100644 resources/icons/notification_error.svg create mode 100644 resources/icons/notification_minimalize.svg create mode 100644 resources/icons/notification_minimalize_hover.svg create mode 100644 resources/icons/notification_warning.svg diff --git a/resources/icons/notification_close.svg b/resources/icons/notification_close.svg new file mode 100644 index 0000000000..708d8bfef1 --- /dev/null +++ b/resources/icons/notification_close.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + diff --git a/resources/icons/notification_close_hover.svg b/resources/icons/notification_close_hover.svg new file mode 100644 index 0000000000..a04dce21ad --- /dev/null +++ b/resources/icons/notification_close_hover.svg @@ -0,0 +1,66 @@ + +image/svg+xml + + + + + + + + + + diff --git a/resources/icons/notification_error.svg b/resources/icons/notification_error.svg new file mode 100644 index 0000000000..5356e7af6e --- /dev/null +++ b/resources/icons/notification_error.svg @@ -0,0 +1,71 @@ + +image/svg+xml + + + + + + + + + + diff --git a/resources/icons/notification_minimalize.svg b/resources/icons/notification_minimalize.svg new file mode 100644 index 0000000000..bb3ae9b7a1 --- /dev/null +++ b/resources/icons/notification_minimalize.svg @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/resources/icons/notification_minimalize_hover.svg b/resources/icons/notification_minimalize_hover.svg new file mode 100644 index 0000000000..bc5bc6cca1 --- /dev/null +++ b/resources/icons/notification_minimalize_hover.svg @@ -0,0 +1,58 @@ + +image/svg+xml + + + + + + + diff --git a/resources/icons/notification_warning.svg b/resources/icons/notification_warning.svg new file mode 100644 index 0000000000..6ba7a046d8 --- /dev/null +++ b/resources/icons/notification_warning.svg @@ -0,0 +1,70 @@ + +image/svg+xml + + + + + + + + + + diff --git a/src/imgui/imconfig.h b/src/imgui/imconfig.h index feda857ae2..4a1d1faa0c 100644 --- a/src/imgui/imconfig.h +++ b/src/imgui/imconfig.h @@ -108,17 +108,19 @@ namespace ImGui const char ColorMarkerEnd = 0x3; // ETX // Special ASCII characters are used here as an ikons markers - const char PrintIconMarker = 0x4; - const char PrinterIconMarker = 0x5; - const char PrinterSlaIconMarker = 0x6; - const char FilamentIconMarker = 0x7; - const char MaterialIconMarker = 0x8; - const char CloseIconMarker = 0xB; - const char CloseIconHoverMarker = 0xC; - const char TimerDotMarker = 0xE; - const char TimerDotEmptyMarker = 0xF; - const char WarningMarker = 0x10; - const char ErrorMarker = 0x11; + const char PrintIconMarker = 0x4; + const char PrinterIconMarker = 0x5; + const char PrinterSlaIconMarker = 0x6; + const char FilamentIconMarker = 0x7; + const char MaterialIconMarker = 0x8; + const char CloseIconMarker = 0xB; + const char CloseIconHoverMarker = 0xC; +// const char TimerDotMarker = 0xE; +// const char TimerDotEmptyMarker = 0xF; + const char MinimalizeMarker = 0xE; + const char MinimalizeHoverMarker = 0xF; + const char WarningMarker = 0x10; + const char ErrorMarker = 0x11; // void MyFunction(const char* name, const MyMatrix44& v); } diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 7c27545026..e839fdf9b2 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -37,17 +37,19 @@ namespace GUI { static const std::map font_icons = { - {ImGui::PrintIconMarker , "cog" }, - {ImGui::PrinterIconMarker , "printer" }, - {ImGui::PrinterSlaIconMarker, "sla_printer" }, - {ImGui::FilamentIconMarker , "spool" }, - {ImGui::MaterialIconMarker , "resin" }, - {ImGui::CloseIconMarker , "cross" }, - {ImGui::CloseIconHoverMarker, "cross_focus_large" }, - {ImGui::TimerDotMarker , "timer_dot" }, - {ImGui::TimerDotEmptyMarker , "timer_dot_empty" }, - {ImGui::WarningMarker , "flag_green" }, - {ImGui::ErrorMarker , "flag_red" } + {ImGui::PrintIconMarker , "cog" }, + {ImGui::PrinterIconMarker , "printer" }, + {ImGui::PrinterSlaIconMarker , "sla_printer" }, + {ImGui::FilamentIconMarker , "spool" }, + {ImGui::MaterialIconMarker , "resin" }, + {ImGui::CloseIconMarker , "notification_close" }, + {ImGui::CloseIconHoverMarker , "notification_close_hover" }, + //{ImGui::TimerDotMarker , "timer_dot" }, + //{ImGui::TimerDotEmptyMarker , "timer_dot_empty" }, + {ImGui::MinimalizeMarker , "notification_minimalize" }, + {ImGui::MinimalizeHoverMarker , "notification_minimalize_hover" }, + {ImGui::WarningMarker , "notification_warning" }, + {ImGui::ErrorMarker , "notification_error" } }; const ImVec4 ImGuiWrapper::COL_GREY_DARK = { 0.333f, 0.333f, 0.333f, 1.0f }; diff --git a/src/slic3r/GUI/NotificationManager.cpp b/src/slic3r/GUI/NotificationManager.cpp index b7301f3d82..e90557a65e 100644 --- a/src/slic3r/GUI/NotificationManager.cpp +++ b/src/slic3r/GUI/NotificationManager.cpp @@ -492,12 +492,12 @@ void NotificationManager::PopNotification::render_minimize_button(ImGuiWrapper& //button - if part if treggered std::string button_text; - button_text = ImGui::CloseIconMarker; + button_text = ImGui::MinimalizeMarker; if (ImGui::IsMouseHoveringRect(ImVec2(win_pos_x - m_window_width / 10.f, win_pos_y + m_window_height - 2 * m_line_height + 1), ImVec2(win_pos_x, win_pos_y + m_window_height), true)) { - button_text = ImGui::CloseIconHoverMarker; + button_text = ImGui::MinimalizeHoverMarker; } ImVec2 button_pic_size = ImGui::CalcTextSize(button_text.c_str()); ImVec2 button_size(button_pic_size.x * 1.25f, button_pic_size.y * 1.25f); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 1fe32fd2dc..1e4b344899 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3481,6 +3481,10 @@ void Plater::priv::add_warning(const Slic3r::PrintStateBase::Warning& warning, s } void Plater::priv::actualizate_warnings(const Model& model, size_t print_oid) { + if (model.objects.size() == 0) { + clear_warnings(); + return; + } std::vector living_oids; living_oids.push_back(model.id().id); living_oids.push_back(print_oid); From 25fb569017741eb89422dcb25316af96012409c0 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 25 Aug 2020 09:55:29 +0200 Subject: [PATCH 237/255] notifications: plater warning not visible in preview --- src/slic3r/GUI/NotificationManager.cpp | 8 ++++++++ src/slic3r/GUI/NotificationManager.hpp | 3 +++ src/slic3r/GUI/Plater.cpp | 6 +++++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/NotificationManager.cpp b/src/slic3r/GUI/NotificationManager.cpp index e90557a65e..387a4d5deb 100644 --- a/src/slic3r/GUI/NotificationManager.cpp +++ b/src/slic3r/GUI/NotificationManager.cpp @@ -909,6 +909,14 @@ bool NotificationManager::find_older(NotificationManager::PopNotification* notif return false; } +void NotificationManager::set_in_preview(bool preview) +{ + m_in_preview = preview; + for (PopNotification* notification : m_pop_notifications) { + if (notification->get_type() == NotificationType::PlaterWarning) + notification->hide(preview); + } +} void NotificationManager::dpi_changed() { diff --git a/src/slic3r/GUI/NotificationManager.hpp b/src/slic3r/GUI/NotificationManager.hpp index d7037c53e4..2bd0ae86d0 100644 --- a/src/slic3r/GUI/NotificationManager.hpp +++ b/src/slic3r/GUI/NotificationManager.hpp @@ -94,6 +94,7 @@ public: void set_gray(bool g) { m_is_gray = g; } void set_paused(bool p) { m_paused = p; } bool compare_text(const std::string& text); + void hide(bool h) { m_hidden = h; } protected: // Call after every size change void init(); @@ -230,6 +231,7 @@ public: // finds and closes all notifications of given type void close_notification_of_type(const NotificationType type); void dpi_changed(); + void set_in_preview(bool preview); private: //pushes notification into the queue of notifications that are rendered //can be used to create custom notification @@ -246,6 +248,7 @@ private: bool m_hovered { false }; //timestamps used for slining finished - notification could be gone so it needs to be stored here std::unordered_set m_used_timestamps; + bool m_in_preview; //prepared (basic) notifications const std::vector basic_notifications = { diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 1e4b344899..45a1f6ea82 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1512,7 +1512,7 @@ struct Plater::priv GLToolbar view_toolbar; GLToolbar collapse_toolbar; Preview *preview; - NotificationManager* notification_manager; + NotificationManager* notification_manager { nullptr }; BackgroundSlicingProcess background_process; bool suppressed_backround_processing_update { false }; @@ -3304,6 +3304,8 @@ void Plater::priv::set_current_panel(wxPanel* panel) // sets the canvas as dirty to force a render at the 1st idle event (wxWidgets IsShownOnScreen() is buggy and cannot be used reliably) view3D->set_as_dirty(); view_toolbar.select_item("3D"); + if(notification_manager != nullptr) + notification_manager->set_in_preview(false); } else if (current_panel == preview) { @@ -3318,6 +3320,8 @@ void Plater::priv::set_current_panel(wxPanel* panel) preview->set_as_dirty(); view_toolbar.select_item("Preview"); + if (notification_manager != nullptr) + notification_manager->set_in_preview(true); } current_panel->SetFocusFromKbd(); From bca60821d8246a5bcf1e129c6599579347dc823e Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 25 Aug 2020 16:28:03 +0200 Subject: [PATCH 238/255] notifications: plater warning refactor --- src/slic3r/GUI/GLCanvas3D.cpp | 66 +++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 7ae6f42945..81f63cb4d4 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -620,53 +620,57 @@ GLCanvas3D::WarningTexture::WarningTexture() void GLCanvas3D::WarningTexture::activate(WarningTexture::Warning warning, bool state, const GLCanvas3D& canvas) { + // Since we have NotificationsManager.hpp the warning textures are no loger needed. + // However i have left the infrastructure here and only commented the rendering. + // The plater warning / error notifications are added and closed from here. + + std::string text; + bool error = false; + switch (warning) { + case ObjectOutside: text = L("An object outside the print area was detected."); break; + case ToolpathOutside: text = L("A toolpath outside the print area was detected."); break; + case SlaSupportsOutside: text = L("SLA supports outside the print area were detected."); break; + case SomethingNotShown: text = L("Some objects are not visible."); break; + case ObjectClashed: + text = L( "An object outside the print area was detected.\n" + "Resolve the current problem to continue slicing."); + error = true; + break; + } + if(state) { + if(error) + wxGetApp().plater()->get_notification_manager()->push_plater_error_notification(text,*(wxGetApp().plater()->get_current_canvas3D())); + else + wxGetApp().plater()->get_notification_manager()->push_plater_warning_notification(text, *(wxGetApp().plater()->get_current_canvas3D())); + } else { + if (error) + wxGetApp().plater()->get_notification_manager()->close_plater_error_notification(); + else + wxGetApp().plater()->get_notification_manager()->close_plater_warning_notification(text); + } + + /* auto it = std::find(m_warnings.begin(), m_warnings.end(), warning); if (state) { if (it != m_warnings.end()) // this warning is already set to be shown return; - m_warnings.emplace_back(warning); + m_warnings.push_back(warning); std::sort(m_warnings.begin(), m_warnings.end()); - - std::string text; - switch (warning) { - case ObjectOutside: text = L("An object outside the print area was detected."); break; - case ToolpathOutside: text = L("A toolpath outside the print area was detected."); break; - case SlaSupportsOutside: text = L("SLA supports outside the print area were detected."); break; - case SomethingNotShown: text = L("Some objects are not visible."); break; - case ObjectClashed: wxGetApp().plater()->get_notification_manager()->push_plater_error_notification(L("An object outside the print area was detected.\n" - "Resolve the current problem to continue slicing."), - *(wxGetApp().plater()->get_current_canvas3D())); - break; - } - if (!text.empty()) - wxGetApp().plater()->get_notification_manager()->push_plater_warning_notification(text, *(wxGetApp().plater()->get_current_canvas3D())); } else { if (it == m_warnings.end()) // deactivating something that is not active is an easy task return; m_warnings.erase(it); - - std::string text; - switch (warning) { - case ObjectOutside: text = L("An object outside the print area was detected."); break; - case ToolpathOutside: text = L("A toolpath outside the print area was detected."); break; - case SlaSupportsOutside: text = L("SLA supports outside the print area were detected."); break; - case SomethingNotShown: text = L("Some objects are not visibl.e"); break; - case ObjectClashed: wxGetApp().plater()->get_notification_manager()->close_plater_error_notification(); break; - } - if (!text.empty()) - wxGetApp().plater()->get_notification_manager()->close_plater_warning_notification(text); - - /*if (m_warnings.empty()) { // nothing remains to be shown + if (m_warnings.empty()) { // nothing remains to be shown reset(); m_msg_text = "";// save information for rescaling return; - }*/ + } } - /* + // Look at the end of our vector and generate proper texture. std::string text; bool red_colored = false; @@ -674,7 +678,7 @@ void GLCanvas3D::WarningTexture::activate(WarningTexture::Warning warning, bool case ObjectOutside : text = L("An object outside the print area was detected"); break; case ToolpathOutside : text = L("A toolpath outside the print area was detected"); break; case SlaSupportsOutside : text = L("SLA supports outside the print area were detected"); break; - case SomethingNotShown : text = L("Some objects are not visible"); break; + case SomethingNotShown : text = L("Some objects are not visible when editing supports"); break; case ObjectClashed: { text = L("An object outside the print area was detected\n" "Resolve the current problem to continue slicing"); From a81afce1b83681f14995f20f1ef9ef684139039f Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 25 Aug 2020 17:59:51 +0200 Subject: [PATCH 239/255] notifications not showing slicing finished when error --- src/slic3r/GUI/NotificationManager.cpp | 17 +++++++++++++---- src/slic3r/GUI/NotificationManager.hpp | 1 + 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/NotificationManager.cpp b/src/slic3r/GUI/NotificationManager.cpp index 387a4d5deb..e27a4215cd 100644 --- a/src/slic3r/GUI/NotificationManager.cpp +++ b/src/slic3r/GUI/NotificationManager.cpp @@ -730,16 +730,16 @@ void NotificationManager::push_slicing_complete_notification(GLCanvas3D& canvas, { std::string hypertext; int time = 10; - if(large) - { + if (has_error_notification()) + return; + if (large) { hypertext = _u8L("Export G-Code."); time = 0; } NotificationData data{ NotificationType::SlicingComplete, NotificationLevel::RegularNotification, time, _u8L("Slicing finished."), hypertext }; NotificationManager::SlicingCompleteLargeNotification* notification = new NotificationManager::SlicingCompleteLargeNotification(data, m_next_id++, m_evt_handler, large); - if (push_notification_data(notification, canvas, timestamp)) { - } else { + if (!push_notification_data(notification, canvas, timestamp)) { delete notification; } } @@ -917,6 +917,15 @@ void NotificationManager::set_in_preview(bool preview) notification->hide(preview); } } +bool NotificationManager::has_error_notification() +{ + for (PopNotification* notification : m_pop_notifications) { + if (notification->get_data().level == NotificationLevel::ErrorNotification) + return true; + } + return false; +} + void NotificationManager::dpi_changed() { diff --git a/src/slic3r/GUI/NotificationManager.hpp b/src/slic3r/GUI/NotificationManager.hpp index 2bd0ae86d0..0b066a3a04 100644 --- a/src/slic3r/GUI/NotificationManager.hpp +++ b/src/slic3r/GUI/NotificationManager.hpp @@ -240,6 +240,7 @@ private: //finds older notification of same type and moves it to the end of queue. returns true if found bool find_older(NotificationManager::PopNotification* notification); void sort_notifications(); + bool has_error_notification(); wxEvtHandler* m_evt_handler; std::deque m_pop_notifications; From 3984326ee335da301f6d1c2440a2f176ba57a65b Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 26 Aug 2020 10:49:42 +0200 Subject: [PATCH 240/255] notification init() at first render, not notification creation. Hopefully a fix of issue #4647. --- src/slic3r/GUI/NotificationManager.cpp | 7 ++++++- src/slic3r/GUI/NotificationManager.hpp | 11 ++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/NotificationManager.cpp b/src/slic3r/GUI/NotificationManager.cpp index e27a4215cd..47962f4b2a 100644 --- a/src/slic3r/GUI/NotificationManager.cpp +++ b/src/slic3r/GUI/NotificationManager.cpp @@ -49,13 +49,17 @@ NotificationManager::PopNotification::PopNotification(const NotificationData &n, , m_text2 (n.text2) , m_evt_handler (evt_handler) { - init(); + //init(); } NotificationManager::PopNotification::~PopNotification() { } NotificationManager::PopNotification::RenderResult NotificationManager::PopNotification::render(GLCanvas3D& canvas, const float& initial_y) { + if (!m_initialized) + { + init(); + } if (m_finished) return RenderResult::Finished; if (m_close_pending) { @@ -228,6 +232,7 @@ void NotificationManager::PopNotification::init() } m_lines_count++; } + m_initialized = true; } void NotificationManager::PopNotification::set_next_window_size(ImGuiWrapper& imgui) { diff --git a/src/slic3r/GUI/NotificationManager.hpp b/src/slic3r/GUI/NotificationManager.hpp index 0b066a3a04..a11d08394c 100644 --- a/src/slic3r/GUI/NotificationManager.hpp +++ b/src/slic3r/GUI/NotificationManager.hpp @@ -121,6 +121,7 @@ public: const NotificationData m_data; int m_id; + bool m_initialized { false }; // Main text std::string m_text1; // Clickable text @@ -131,12 +132,12 @@ public: long m_remaining_time; bool m_counting_down; long m_last_remaining_time; - bool m_paused{ false }; - int m_countdown_frame{ 0 }; - bool m_fading_out{ false }; + bool m_paused { false }; + int m_countdown_frame { 0 }; + bool m_fading_out { false }; // total time left when fading beggins - float m_fading_time{ 0.0f }; - float m_current_fade_opacity{ 1.f }; + float m_fading_time { 0.0f }; + float m_current_fade_opacity { 1.f }; // If hidden the notif is alive but not visible to user bool m_hidden { false }; // m_finished = true - does not render, marked to delete From ac9e1e8e4aa8661ca79013650637cdcc42b79d13 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 1 Sep 2020 16:14:18 +0200 Subject: [PATCH 241/255] Extract app icon from exe on Windows --- src/slic3r/GUI/MainFrame.cpp | 59 +++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 886e96e1a0..bab5d7502e 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -115,18 +115,18 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S } #endif // ENABLE_GCODE_VIEWER_TASKBAR_ICON - SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG)); -// // Load the icon either from the exe, or from the ico file. -//#if _WIN32 -// { -// -// TCHAR szExeFileName[MAX_PATH]; -// GetModuleFileName(nullptr, szExeFileName, MAX_PATH); -// SetIcon(wxIcon(szExeFileName, wxBITMAP_TYPE_ICO)); -// } -//#else // SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG)); -//#endif // _WIN32 + // Load the icon either from the exe, or from the ico file. +#if _WIN32 + { + + TCHAR szExeFileName[MAX_PATH]; + GetModuleFileName(nullptr, szExeFileName, MAX_PATH); + SetIcon(wxIcon(szExeFileName, wxBITMAP_TYPE_ICO)); + } +#else + SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG)); +#endif // _WIN32 // initialize status bar m_statusbar = std::make_shared(this); @@ -1416,7 +1416,18 @@ void MainFrame::set_mode(EMode mode) m_plater->Thaw(); +// SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG)); + // Load the icon either from the exe, or from the ico file. +#if _WIN32 + { + + TCHAR szExeFileName[MAX_PATH]; + GetModuleFileName(nullptr, szExeFileName, MAX_PATH); + SetIcon(wxIcon(szExeFileName, wxBITMAP_TYPE_ICO)); + } +#else SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG)); +#endif // _WIN32 #if ENABLE_GCODE_VIEWER_TASKBAR_ICON if (m_taskbar_icon != nullptr) { m_taskbar_icon->RemoveIcon(); @@ -1473,7 +1484,7 @@ void MainFrame::set_mode(EMode mode) #if ENABLE_GCODE_VIEWER_TASKBAR_ICON if (m_taskbar_icon != nullptr) { m_taskbar_icon->RemoveIcon(); - m_taskbar_icon->SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG), "PrusaSlicer-GCode viewer"); + m_taskbar_icon->SetIcon(wxIcon(Slic3r::var("PrusaSlicerGCodeViewer_128px.png"), wxBITMAP_TYPE_PNG), "PrusaSlicer-GCode viewer"); } #endif // ENABLE_GCODE_VIEWER_TASKBAR_ICON @@ -1981,18 +1992,18 @@ SettingsDialog::SettingsDialog(MainFrame* mainframe) this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); - SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG)); -// // Load the icon either from the exe, or from the ico file. -//#if _WIN32 -// { -// -// TCHAR szExeFileName[MAX_PATH]; -// GetModuleFileName(nullptr, szExeFileName, MAX_PATH); -// SetIcon(wxIcon(szExeFileName, wxBITMAP_TYPE_ICO)); -// } -//#else -// SetIcon(wxIcon(var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG)); -//#endif // _WIN32 +// SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG)); + // Load the icon either from the exe, or from the ico file. +#if _WIN32 + { + + TCHAR szExeFileName[MAX_PATH]; + GetModuleFileName(nullptr, szExeFileName, MAX_PATH); + SetIcon(wxIcon(szExeFileName, wxBITMAP_TYPE_ICO)); + } +#else + SetIcon(wxIcon(var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG)); +#endif // _WIN32 this->Bind(wxEVT_SHOW, [this](wxShowEvent& evt) { From 08580a9b1800c30f0673bacc7c8049278dace7ff Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 1 Sep 2020 16:56:12 +0200 Subject: [PATCH 242/255] WIP: prusa-gcodeviewer command line wrapper to start the PrusaSlicer in standalone G-code viewer mode. Linux and OSX stuff will follow. --- resources/icons/PrusaSlicer-gcodeviewer.ico | Bin 0 -> 113976 bytes src/CMakeLists.txt | 13 ++++++++- src/PrusaSlicer.cpp | 4 +++ src/PrusaSlicer_app_msvc.cpp | 5 ++++ src/libslic3r/PrintConfig.cpp | 6 +++++ .../msw/PrusaSlicer-gcodeviewer.rc.in | 25 ++++++++++++++++++ 6 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 resources/icons/PrusaSlicer-gcodeviewer.ico create mode 100644 src/platform/msw/PrusaSlicer-gcodeviewer.rc.in diff --git a/resources/icons/PrusaSlicer-gcodeviewer.ico b/resources/icons/PrusaSlicer-gcodeviewer.ico new file mode 100644 index 0000000000000000000000000000000000000000..2c9272369fd5617beefe7847ab2264a40f033ab4 GIT binary patch literal 113976 zcmeDk2RxPQ`xBwG_aMh!*@?<(iiXl46_PC~N~x@FdmxD>rKBYqXrfYR&_X3q8I?`; zc>nKna@>Q1bBx2i|NHzrzVE!>JD&CKMG!0mJ27MkfuAJ8f{h@|2!bGy{`|g#-4n2z zj7-CCA%buiNf7Gle}0S3AczUm2*TC1;WsA>F~9o*m>2dy};`&f)eF&2^x#v{P`di<*?6yl%YXDoFb z@EhX|jHtY-o*dTD^AeJ=)*!zN8S|r+`}NV|chRV>z7D*BUveDy$&L}?L^b%+p5S6~ z7?P0!nqYDo@mPFB;_Kg_W%~{zIcsSY9CH=C0zeoDtA#NiBN-^P^O}bvKI?oklC1I( z|GF$R&&2}myS$s?6~aK+OB4r6SXxhB%Pb^mZHAlzc2T^;6T*UQ$v`ul)eppH^%;?@ zlE{479{-Et9i9-jhT=d8FFsuaY0lL^JG}1wkwt?(;QKnCCgCA$i|`UN#gMG5Y-1c# zb`&8V%Y1TNUw+n-pABh3*cS9dczJpGCUGcjFGAac%BaIa6cDyiepxwLCqo}k9IiK8tWX&WS{oA^)BfrCU42||n$p_f2 zG5?T#H2kY?nu%!UAF4PyoPQ~CF#3dYhJ;ZaBa}Y?u2ArF05HpJ7{xK#V!Vzq6=Nwz zC`ka}9o*m>_yND|lxpo00&!qe!gvB>21Y3N+5_+dejyBm?GPO}+<1%!G3H|IC_q?< zV|@GE{_O+%SHu{Dv1Lh(9T^0O1LDFpQ2T)W&BXW#V-tY9UQu0-Qgdq2!*|u>JQMP~ z3dMY=Mw$6_^UMCsZ#OEhxpc-B9iGb#AhCc z_{;(k$;1i!0h#=%EFfb*Gzk~lJ1YmB1eKO<@yDCtu_DKx`#>)G?PqNlh)ebJ<> zq0m$KyAUn?>yO( zB;4@))QUSQD9K0jo#v9`5nM(>a+75n+fEc3bUkpJ#2Dv8oK9JpusZXnKS9k8nZc(2$mI`qYPI}565`QF1N2=e=~14Pv?=sZXmIe| z(iko#iCm>OP5IBS^oF#d4uHC#1wcB~C^uQIkp}9tso!N3WRR@kpL{cGt2+Aj>uZa6 z8yv{>PeUC@u78_*EUzj@wmw!(XrQD;O9t?bA}9F1?uaF-s;O!oE&Oh*e<^h^c7rxS z3rP6<3Q1Y~kv-pPZX`ZS6v-?6DFZ09ke`#}(Zrb&h;Jn~nO^=CJZSxPTU1j6YHk6L zR%834fdr;(?OpCl#nm-SnIfzP2X%=e`H_i6v9}37c%%nvFc0(0a z73ksX2gv-$S~PXTS-I~t=iMo6o> z0OE!;M$uEEI=BN7Np5S4~?z)!Qr8tHNx1PGRM)=1V|Io z?&vrnI}U4)vDHB*{H+O8*3_fCk~#$K^YmY}D660j6_?eM$9tN1r2hw`4K%Q~CSzLe z*gwd96GoZ?RoJ}|O3LfeOwjx+ zZmaS&wpW|dirv@D!s93wcnot3;#)KS&+k_Kk4L(DmY|=7P))ZA(fCWNWh?&Xg0a;) z38r=q-zvvrYk7!db_UZ;)wjTM1p4{btiWSWkMMXT9)qGW2FPcfi^oEf5ueFHL^70W z!Tah1`Uu9jS^=QVg<9tD-XL=s{0-{VHsLq6dz(|w5uf3oF{DPB8{)ib9)M}a^ubsu z@IsURzsFNyyqC1rqzMnx>=Y4<(X;_TBQ)(A0sn?}fma)08b84p{#y67P0}P`+WE|H zVS2GmwMTQa?<9-6P2!@1exL=fqT>^T%Xsg?w zF)iRhU>(l46uM|UY4XyH{z*2I+snTcI)P@O9r{A;_C2WQ4S)_nVQm5ObMKzr=vRIT zSr6^;&|E)!&FGi1qMLr8nbPOOuWdtdSut95U`3;y0R3W`B1le74o#Xg2{Fn;qb{1! zFK$jZ{Xj7EMWIjHF2K0)A~#%zHpm{Hlyx6%@?iCWTt1OZ|H4lixVGsyq^Rj+^x<2Z ze6f#)&EEN~!!A4{nPGek;c47c;~1|4z63fp%z9v-P9U_snIDma zu}Bj;ZjFB6r7a$4(vNAEv@bv}(`u;5Yxfmsrz`({_?Cji*9bSEUs8Qyqx^v;Y8|x4 zLv#7V-1jovmxKN&0|2zsRet`${R-K&fAT9?*HqCpNr>g8s=>&&$jdc-)Pm-Ap3>;i_y=v=TvFY2(;7Het>yL9Y^gZ z_9L=D5Xs~DB?|4$pVYii^w69Kn2(j%Sb)M3s>pHEBC-`XO8Y?xf2XVcw(a=VCiDv~ z#p?%JnZIq$3;YHifPP9_!wt9jgl$rh?Wz0d(c8x;=KW(7oAL~mw!Y4ZniWd>Z4h>h zr2f#_dw3jPQ)KXG9uMf?Tg8KZ#2O=nItkqNBrXrup2O&ZWl z9)HJAy816a3V)!f>zcM9#O4WO`;lwahN$@f+9`Sf9(L|>MJDb>P3VWUG0@hf1IYcC zhCYlq_TO&*5yqJIT-enlJ(y2zJ_k=tGv%E^JLNanl9ZYx5;AH!{u2KDHXWpsX%(mH zKhoWQr`3)STFQrH8OR5~1NawQLTVz51umKhbW8^{>AyGVfUfZq(1BNoXOnb6w!(`A z$ZL@(@@?xWi`NW^ED~%H2gE}Mv=~33(t`^Q-);p6{dj9HJg$b*qegzbo=83DXFcb;9I-nw^VvC!v0~*x?O<%9nX@VB5kL64DleSOF|2c z7NC&O5L8mqZc^aEh(cd`PwbcO`3nkzkgvb~$UujK4x;%EbCHy>coTkvR`Ma~l@e&K z$!z4j&j~$=d4h_Iiz&g|deS|A0XnAeh9hLh2=gB83Wt(7gr@-HLy&7uP7eC^?HkI> z%tZP5`KYpzuI>gU8c3Vr`6DVGKo4L`V0&bsrjg>-O;1P@(x!Xfh(b5@6NmrD&Yw2p z;~zPH-HZolXHeD;fPUMp>#(2p0OEkSx^?|PGd@^xdSV!%-5QDUAF+Oeng_}|rXBhZ z&kz+ zc^F1mD{F=EBt}?&l7 z4`aLYFxXFXfG`ji;()jy&f(1Dh2FFr0qHn?Kta*t~|bkU~aLt zw!=jX(A+5*;P7DcAWMcIzqB6Rcu|Gcoi0I2j_(k^=_b6UuIU^vh3EF3u$I&Q*4P|S5G3su2Vm-<& zf@w0k0C=!uB=2MY(=axUjkT2uby1CKsk|?O?T4^c$r3z z46r|F*WGQ4XX(DS;pdZ8d)vYYLM5sT7ALm zbff>QZ8B1CJuaLMgE9b~+HEIdKXw?gR_TN5@s&t=b3Wp2W!>=~S>U-m)BSkuaV8C( zsn+ebSbKoi{9533A-0#9~r*#Q0y{i;;@IRE1d)?T~ch{NZ5v{Jqs zO(pBI`MMB>ep`LT>zQ#KLc_M!`(uFB~p8F&+EO$PWI^r;vESods(_jl5wjf8n8 zS>iR_E%e%!&RhA`%6d5l`3K(i(c&MwgYMHYG6c={`Zme|>U)d7&;IJP47!g0bj)B2 z8^CVc7-AfIhV>Bo`&|E?bjj;lg4n+v*52CeXK z>%&m_2c!c4ubLDa!0*sTWC-A#1UN5&!ZYP5VI+c%pF58GEp=ThgI4%o>tV%6`A^NG zJMfPk!1m*)KhX0I=TuO5rhW>~7eFd%Dk%8cwXT&xEBx#1vg|1Tz%%d;<3=#f%n-nN zS=4+}-Y3oyC!h18s;b(xGH8YW8II;1wdVr#FQ7L8$xM-MT(j4uGH8W=>2+o(yP!k-1KYqm z%r`LvwDxQO|J3IWQPya+D+AbXxCWok+8&boLM_Jx3=;>by?6= zGT_I3BN%(^1OV?HD*vWzXu4+w$|6Si@2m{qEb+;Xh3I28Lru5lq5|GKRR47a|DBNm z?Cr5QS&G}D%~@jTH}KAI`v>fw7XPr;UQU7bxrfc|pZYhgdZE3(v#@PGd2bLy+_v-# zyq|38+_npx(L2uxx7nJtTWGcasQGN`oe>#;?pGcuVRTO&EvA5XhWkIz{)Msk7W^+K zwb*L`e%j)j`WrnmfP6pEt^mP#C7lFH|7R+WhoSy2j5ou$Yjgf-ox4fRA3g8w$pFUG zT(6X&>P{7VWXVzbzYLFmz?%HsL3q!3Gy8|%)O$zi;g^=5)?~nKk&jk*mY{adh^5yo z$m1UkV?Yd#e_fBcMw5S9dpBwE*q&Q+8C;F6BJ-Z~z4MB15DTwN*8ylU{@q{$+Zc%l%7CLcj?kn@Ohbh3GM}2)*4}01Wzj?(+VhKWzG?@c z$^1tH{|wK6z5MioW*&fhQ)H(8Jr33yU-Y`mOp`{ipR~E{YwehWatd-7Wj`GUXfglQ zAOnWxKU=E@flko{LbT5v#^V6=^8Lr39Qo|v=Dfr2T^HRtvObFD{3n$SFf{)S^8mEU zLDW8sYP+EO-9pVHbNDPk;uo_~mERQGMpe>cd0q4f{2Cd=)Da|_!f>kG>O_N~&p zkGr|7U>`K)eCp=dtUJwcg<;}{D!;$_aQXr zueIMWh6wElIKP_`2lbO*cLJKEDv$j9{MtL;kXk-;t$%5d!89C@uJuop1U}-mij=!I zsA;9V11};A1(B5MM4J1UfoCY^#PQipP<~RvHGhIVOq)LyUA=l0Raev92cUcX6Yvj! z`Le`F*ZMb#44&gN$7zj=H|L?lzj1z=Z=!`>zI@4u-Wgv1*1$g}=8K{Ak01xI16qB< z4)cu5c?c`CnuOerx}d^BhK8%^8hBuM{bPd+I<)>3?h%4^8LVCHEZ-1*q2oOC=F=Mx zFQd@m^{>D`08X&O>!0DwheOx)BWcT~d$#G3iO?DnGTOfiz54W$k@c?B^0@}I|KXx@ z{~KfgvIKi#7@&@XwcO|K`;*UUgmt`dwkx$9W^REqc$YGI1}`mIfJUITOL(V94#x+1 z!2=^hWg_;^OaR(|#tyCdrtsR@6UPf>BGe067<(H4O+Z_R%DUEgZtjlbXTb<#X7@05 zZuA*P&;| z@PE1gm0AXrcPtASOVh*%ZO3?wFwP8pFGc~vKv;+a;(|CE*KAVK>#a{rE94E3#T1N` zbyhIn1aofCh^@v*0eA;D_y&GXVuUad7UE!9xz=0d`5#@~BLPtytt&*0Ev)gJ2z(d% zzZD=aVdTQdhfy7)F~;2(q0JnPF$p8IrHV0DVWi%s3h&?s-@p&}g)k6yH%5pH;)J*% zjeoBo{~-nfI>0ytqddkn7-7QX0Y+#$6=CekHY~&iaYEdX2BZaPLfSyXfA+uxyTNj1 z!$`uo45K$jI5(sKV~6_hI9z7{(uA~u2A~CK0@^xt{uvX*_>W2g%M7Ne31MmVo4f(%QD4h&r*$l zUgZtT0{TYFe+Q5O$by%N*{?^E!aTBLgnn`&M(Xi5{PX`BKo%eqkPSn32lt2~JCG>m ziyPxnjHMX=1KJV**?^3=J0Rj-83gmff)U2fpJDtj&toC910W-i70B!#J${7gr>v{V z#_#_DV-f(FSz_$gbwAxzXkfZw9gPRZ|HrmHX1hxOWCt?rk##^FwGB)!FUD&a>oEQY zos$5_5M=p}=pSG@B``)~{13WT0w7a~j^;^bgv0d7V|>}QZ2uP|Vx^32dBqiJBe z6fwS`qLt~dc4ALDblpQo zsi>?TC8pP)^N%ahmcZZSJE>Ki@mUfZ-y#8XPsF!I3+uS)o(yU|cl2GwehT?K|2r=u z5bPO;ebY?{K9gT+6F#RLpP9sCfzReQIfT!s z|8wtgM|IngaIitbxeNBwY4`kk>?E#!V31bw-ZU@L-UvulwsfQJ4$>Cxo zj_(kM^KvFw=Hc_G;}M^+VYlS-j@Sb11A}`$V838DLllmm)SYE}YjNXrhhv0(Nw)&% zJ?&>LI(V}jsks!A^Ev1p@;jf^n_i{&=C%U+BVoTNoF(6l06Jjm{t28O2S(Vt(XIXa zU&VFk*qw5u>WuH;z~>`1o;!~3TY!5PNCr*sQg1H*-tt?)MuuD-RMm9L@&?cW=z^oQ zyxP_7I4u~L?6z?|I0NhMn<}*EU@`fe`9{54=ixg>9{)L07w@0$E&8RG4!Bbw{l^z9 zx-JLM1w(h?bkrtrIxsKMZR7cH2AJE`G9-b|f`f9t@ty&zpNP-w_&+Akw`LPiCxkq^ z-W_d3(206S^-51T96!wAKEv280C!C-cP~b879il?y8n*viP`**%kQn(0Gts3eT8nQ z4?s8FGIxyQWyc6}(_Id5ci`<;RY=*XuxXwrxAD@j?oGN+_eRPs&uDMuO!n6F*-`gB zmv*6wDmdDpO96D$H15OmQkVB#t$Vn)$apobLjv*L zO|Nm;LhGI~sxk-CC*wEV=6H|z%)<~L`Aq+1U0MgZUq955v(DO51L$ZOJ>@yQesFxe z7!xpdIb6c`DvIKJ=KgNuHOSoxm-)sPozC}sYgXWU%I@O6;*Y=UlSbWAbj;ur+9HEA_)g|+VI38Avhq_$x4H3qEtS0yCo455yrnJwYrMs+M zi}SiA9v6Z>Lud8fX80Ujrd&m&cJ4H6i*9HW!g+&T44^Ysdh>W|{%{;>7;`ap8-NX{ zyB0On{dhdD%{v#{>Gv7o^Xtt+vCi=wi*4$S!93q?TsfHT(;dDKw*&Y6wWklznObXl zrNPcsirX%$7~-Rw^bfkzrKQ{U z+;BKpzsIz7Jkb8}x#i7}%o^)d6F01PTo1QfMz^A`ZU{#%2N;-#>?Zv~J_8*xynYae zF~G>QJ=gEj-y%g@ImY$hoAN!i9kp_=U8Bu5s~@^i|DZ#I_VPRRckF)%MyBO`7zf+t zzoi4Z$8CJ;ue~bYHxrWL?s|_Z<6&z3Q-EnJLiPdHb#96|#F*-oZ_sZ@cQf zcj+H=xs*DOxAurd=f!>Qpx&A9DfZL5^bev2owj=p3HGCm zu@ECuAmQ^X#?O&nYlU@B@AxhA+I)>=KiEL;(?95RT5I{9;*R~mnKeuSI6oWi`e?J9 zZ`MvC8Oq@C+?d{-_j{-QL8pf)dZzWn-(h|?89Xur;Eo%(>xL2iOWSNiycT%;ol?&B z)@Sd_|DaOPZL9Oc_?sTa8jMVVo3Wt`=^pxrm!G_)8Y}LhvYj5A>z(=s-RiZH_hFtV zfGLW{iFBmh2kk@%*Em+(e7=|-y)es9@6RU^iIb!L+g;?)PJ)-WOXTgl>d4?Uwdx8|c0I2OYOq zAA;TB3|poEjP)P5vX>$Ki_R578X6iXGBUCWjlI?edawRLe%{piAO9YT5$+CU3KW+W zqg4l1FrT*J~(s0Dg!2444K%QFsk* z^Krd4ev9F|Lz~~J+Usqgck3T??FIVBPcDoPz=0V6ZNJ??jIHgQID__m%e~qLdcXcb z=b(FjjH%4fJ*3gr-QqOM1bjEHw2EYl{7)$ldaVsGsDB$DYqD&Zr3ai2=p1yfj*)5e zeFY`?Xp!4|y32pKGg@ZqpSB-G=gptJ(gqmRzm+%B^$$7+-5Xr=X?a0k&xWv z_U~Bllnq!!x7-7^Mx%3X4DKPb@Umid{s*0d?%{qjra@}fCx-4)7h1xP^)J_I`A=OI zbl3*){veulPaAF0uJ&(sgz5SRorCTJnWlW4(EE&cNPe9(-SQUE7C>?e^ywdLp+h#% z3-oX5*(3S~-A6N1|8Xg?bn71S7^C{{kPY+#{hRcR{z3Oiy;=XFTEcXd{nYgU!#2}&&Aii$g{{>=i z4VbEXAfl)A-;{$a6uW$c>&YNRz%zFqx_y6kt zUvs@v|L$oU0R1~%`rSjSCnpQK|JRQHQ0uz2_nx$YUQqXg?tAt4Z&&pHThl$oy(eq{ z&O3xN&oc2{H9ZKR`(8c&!wmg{9WdJlpzPm@@2kPf;d&B4_kqkLfYJ89$U;FRH;MlF zUrL_t$dg$%0C!i2;WJO+eySb@(EV;^(vbK$0g0Om(>({=k@??_=$;aW88!fUU)Q4; z-wV>SnZH5zOkMv4>wl(hoZM^m4|dSqHXyJrAHliDJq(ofU+S0+rmg>ky+5k>?lgMG zQ0ZO&N6Eik_3SPip!E6kN_w>22c}0^{|Re=nYR9$(e=NA%SlL9sr~hzU8Q&Gc)G&| zgz$Lpm1jMk_d)-Z_1{e0|H0_qPkPpWQ|qj&-@DQVAnzM^m-L2uAM{V&|Ix4qh-v%3 zDyu7z-HG*dm;X>tNVT#5qpS5zE55F<0T}C-*<65PKJ<8-A9N2u-v8C0f2QvLg!^>q zt^dJaYx}=w>8iWjI%@;a=i47zhU$8}+9&HCIv&*fKbgA!`|_h8hV)Ns|7UmUxvh9R zY6DR2>vK%GAk-(v`O(DyQEa{fz${+D4InPQ}j_5nzE z4{%Sn0h`-Fdp5v>%Y0$meB^Vt0@cz{?AO)Tb@d%kt(hF?nAZ7EBT%LbrveJJ=OL;S&+C`^I?&^5L0Deu^wY3IK(x(}F7p9e`#lj?P40N6!y z8>p_SMqB;pzpobV0DSQ=o*C+gvY+PpuV4fC8#hL#od5j0q7<2W8Z(qf#57u-1Jqi+ zWVSoC4KRAf0i1&h=bR?Z%>~e7PZS&Q2ykbJFUSXw zAD94bp8wvUe`QPuQ|1Fxz9ln!=hMXLw9kT~M?cK)BP%D1q?b)(NdMk9nKJwiI#mW8 zw*}Y_)9!y^_$(+q7A&-c56RMT9t<;dO)CvJs|e<-=pEmNx*x{Fm;iL${{pswX<^#^ zPmJCH0CJU>Db_37fnX2NMxj^t;7@1gLX=;U*WK!e0Vulee`?VG5bQs?yNQDM3x5|P z{e8be<4Hb`1BKKpUu=0d&aF{f`a$ABMv*r40C0^b0ND&G@~)60>_x zJs>$<0>L;nBV|A3K9g?NKj@I*`(GPufNA$XhsEDQ&=z7uetfIB(ZrcO-ye|1brIA_ zjL~4k*-~Zg8f2Q64URLoN+4xv7Btwul-%4x)J=iCNI$sc%rPj0qUK9iSdybbTnb?D_FLk@y@@hRzJ7nIhBq zv7$-xNJ>=_>z%(-G(j6tYKjz^HfpR-gEj{0Goa`8nVq^+@ z%>0O^JE(L@-jsYPu!0wf&KE+G>JqqqkZHGUfb*uIO%G)}Utb@^#l>~!cpvDd)%$%J)i*8wIDU1E*%+AupKv)a$8mc1=?2#oU83Vw;sG0z z(U3x}uC6FEGqXEo20BrvrL(Sf!|7OJEbmTcsN>Gg&qAvY=y$80y2A#bEjmYU7P@`= zc6ZhF6fuD=EW29It;L7a;=t&Rk&czE*jE=oS!Ef5HIj^u5q5`O>4{Txg&=Y{;DWNV zyS=Cc9e^%4TGLl|xa0JOW4wluX#nE`kKRTjwawFdZ&`rrdTqP;==Hlqyw{5<*#mSi zygPKTuOa&+lV9kuk+RpXI=*h>7_))Q$iXvjdQEhE4v*Zzl6C$;zr|$fY z)0e==w7p|EtwzYj^M;46?MKp<;yqd(%-p1g!eehE*u%j@0GUg4r*7$u8`B|=@eLDs zZ<16=c?o&kc!9Gf)9hd(p1-p@z8)oIyl1xFfp?H~Zv>ZVR{rB=)#Yl0caom zDExtfW3H0dmUngiFvoEQxefaA(+dP^{CfyM_ln)A%Z|p4>4I|LWe>@vMY2#HLmlxn zDF&U2IDvMYbwt{(^UypejaJ(ZD)?+7@MGa+g50kkLbu{>kjJ55t!gg-kZrHZ_swku z(+BMVrmP$41^Qqn2_Vy6QQtS$dGp_xPF{@AFJWqf2&eaN1dt)fvPy**>Fx{LOVXU~@2f=U}|26=bf$TULm3wdUkLhQ@ z2y;fyFxF%I589Rh$OvQwGGpmYy6g-sm=~BkhPmldjQ;^`34m-sM%_Ax+ZjD}CM@QQ z9V4tGO2qhIS%8Jm03ZvH3CN~f)^2o0Z(SW0^T>|M8L)L$p8wSFn0GFW%P~H}$ke;YaC$ufz$5SqJahe1_14vN zV_6KvxEdqKrdt-q;&^)!fG6M$cpTc*^82^Mhh+nM&*A(5s22(`{?h??0A7G6hW23p zTXfnHKCrCd9Fl1m;XI-gj6F8thSO#gfL5RxXa^qpbwmdLg(06s!h+>D9-|({^BB`G z_C{L(nt(Q-5oiUP|25+`y}=f-JfY7(!U+9jIIkGiz!YGt!^muaG$C!E0cZi5fVThJ zwmdU!1j`x91!yzMV_bs~4$*pm@iWFEj5Qd$3Lq|s6XJ$6AT3A}(gqs-%je8gK8>_M z2Ny1C(J^w zvb$tP5F|o#*7T)Y4f4-$oE|Z|JT^+b77dv_|I*$m zeh2#V+s%2uWT=Wt*2|woFIOnb64|@hScLWp*?c*18RZOoSi8k{;L&Xt?+5w$*SW6S zvRk*zx$ajISO1yUzq=++ z*H4FSVqqD&VW=(3o~53g_lVuZF3u?8$uOg#GU?S-JVRVRob?`NB%7%|XbiC-F2Ew# zRC3mb*`bIt&#EquShv>c)$F)4k!GLzaIowNj9!(Yk-?EM8k0IAbIMH1Y}a>+OHO`V zYgpkE{UYT)M<_?==+J4QDz68{g@;t!zP*aeyAPLZq3en0l<1Iv*<;k_zBs8=Z|ybV z`iJ*dll2q621FM2Vg*KB1T#In$y5*`(RM{WV(aIaVM<<%)Jj;id zCc$Bs%BHb!uh1%dxsFkb8c4)Enijm-eY4N#b85-=!b?vksSZlG@O$Ll zWuDegbtPpg7m6)A`gZ8nv+}Hj?8Ja%{iW4^xh@I5<+OK1+hY8T$v~+;+;9qbe1P0(7*LhYeJKm=?%99aj4&`b6?bzq_}#1Xb=^@3u;) zo@?tP;*rlm3*zhq?TO0_+0ZJ1$^!37vpK6d*gW*qjojHsoyW&%`9yp%bY1MT-S$er zFJ&Q9spE%c$sV|0%o;86?1tzQm3P;2l{db5IO2!-?)UeMcu(;O$Fb~J7{a@AdrX$n z(U8INI;^4GTOHV?*cXP+uo?b&N%rQ^cIq>H{5c9(ouALz8*qq~2o5uOK85wp>;4Zn ze~na_xloQna8{LbM!!IB6V>Nqo{u3y-&$x+`V!_N?=dCE{N-d1s{mu($}z`DZ}y$= z`Z7^~P`8#`;V>&rEmkXhXp+0kU{gU3LCbixEWNYdUX#rIgtb{+%aYXk-+A=>&i9{H z+qMN=bg&z?NpS4JXDsU-SBx*Zrfv}|q*W+qbV0TxaQQan_ov46<7F2X4-{OnKPS$f zFj`S5l;(4`f@SP+s~7gCCcPT&_1@I$`uy8*$T9z7^b+E1n9r&zbJi5SDJAb7Y?)s% z;hXFG8FvP5T`IOL`w{KnU*{m^ zW%=f+OgGmIwu##iZ98b6+oId^?@Ddj?8K_e>UwPNdbSNm7gyzfDZN-Xhuc%&kzU3| z#T=1Ml7!v_rxcc)m4P>24pQKrtH5z#(x;ix!M0_jO+ti4aNwLT`O&1cS=wcOiggO# zTt5$+-}m}*EzQ-lbdTg>sXbKOARQWVRmp}uck`efgH{E2pZt1p|2=kM;#&XARNo;9 z2DZjG$67zzpx*zSmPOSmTiHSP`ViOTK6>rfomh89-fY^5{r8Tr8gqM(-x-v)XjED; zNMc9LXuVOomoHk2_TzqiuPjv}kUL7nE4tsxlS4)u-#u~ig0~l2pu3PpNa(T!75yc4 zMMU3Nwdr-V_!SAgP-8yRW2UvgYu05;p3$(mG-_z}CnHJu?3X4ppU$~i_wk5}wL2Th zYNx_&G0`=JYI(DlFZa2y@Zf`pCzDk^-c4ONg1!I8$hBKa>`QrKSYihRe(o+h1Hi;XL+jUQ&n%4IUm(8lSvq@#^@1 zV+YrL|LCxCy@s=`>!7FkKf{+PhNoJs3{Ts(GCcqFVRxH|iwmZYx4UJ(l5K1%d(P=S zLS-M)qPGTmuNphmox305qaDR&xNrK?J7xN*7q47Az&olgE>_L?F>MmT(QFfXx_8};O=(^mcs2ZyiaYoUAuG4V2`w%F$+~pL{o2<-oCnb4EuVPf(P$rio(-zeVuKX{3>d-p#S>O9Yp_S>E4FJ9o#;dv;q;R&B`Eyfd+mYm-;*+nv7X z1@|J+ZCgGb=5kl@IA6h&G26e-#__5eVr6sgmCyJD`D?ID-^!Wyg#E8LKRsXYC`Cjg zvU=fz2O%JUOOg81uq^)|Yu)gkEv2w%LriA(yIB zl%09h>dNi;b4|V+yCyv~I`rXQyRWaK-bOxLy0vtGrf9L{&o~iJJ0euBYVP&2;mWsm zESNv*T1}!$3IFh*FE6f?U45vWM1tv#-c= z1&$!DaXTC5j~;E9Xi$A!!Z0>)u;EbI^07Dfvbx<|RlQkt*U+HDXV<4k9x)Q~J*xMY zP|DNImtV>rw<0`iowhhm*_-~`Uo|V+{8{Pu^=fx_s7-aLTye~Ks_l>H{d>qH3$-OXNkgNL~GLv{bIakdpE zZE}=%%?oE^yDeP4?=weYJc>cr7_Od-39-GxrQw^C5K2h|!~i zwp$ecmUf$&A{rPYV=?|?e?mX^FE{fC$K#eL*JK_jEV%sbX`a-u>BUJ`;&gAV&>51D z9Oq(t-Yal-=CSOI(ki9OjKA&{J?8rP<>CF*i+tZlYCk%sb=lHk;Frn7YyB-Z6YBc( z@e^2FBl3V0rpY~b+z!6oQOO=r$)l^@jsDHYE^ny!m8)t|A3`!XlKo6@znUkz>Pmuy zPmdJ#=Hd6|5%wNAr$*sZj=JmXS(DtNt5-e#Dl@I%j)3oKhq2r9v$TeLb4Gn&^+~<) zZXF9D@p%1%rSr~Z*_g$iUbnt9%J9K6L*55*<=Akd4Zn*-@Si$;bKT7sb(MdWpK*Dz z;-rzS=gFP=SGcS$zuKa=?yo(;*1mjFKsk!&9LpUA3RG;2=;M9^MX(cOEpGuG>|7A3N-}7%)SG277qdgb)zxE<< zt0jxp)w#3GY;C2U>>ZqQNIroyg!6*E#f@^wM>9mk0!PJG8_!D=8A(h`GF;^}yR2e_ z=9T=Twko?FU%b^tixUdm-mdDeRmyL^E%qpXpFZOwuJ8LW=J zzaca3NM_FcD;M3k`^GF&vV1vzGVwd&TD@QYBroIfDXOw3eJ>&r$?YFTmk-rDHSdv? zFQ>DB)c$j!J94$2r!Jj6VDDvNS!aji>1Og4{W;?XK02mr5HA*V+UwU>!MEw-a+hbM z%^G(Z*}f&B50q>l^uzbsqbY%B#CVnCH*3$0eEWWh!|YMBB}x=8S4#z*tR;<~c5KP` zxep)7+!sISz;$rw{rw+Uw^bCp`tj!c&yP#QU)?|Og=3-S^7lq^Eb8Kw`wkfU|C}-~ z_jlHV5Ty#<(V=!}&)=6{KWAa8T4i0rpQ9V%x%}jTLCe;CzQUhXG1G37xZbd{+Wx9T zzZSlksr-JmMnJt`u(#KU@BNnOIQS%Q)6EzeeT>`2{h&ga0=Im*l5@S2!{bBlfh>l> z9+SVlSzb^d;%r}fUFy;rr<9U?>!)9t>)vO3PF{Sz;^*w;UqjX&i{a!B@~-Av{6%O0 zvApa{jnIkd0e@}$RCDyp@t2i3^?q;H#IJU)+5ME0bL*KIEBLgwuiK|ID)2ycp@R~- zS8`OyYh;qgK~CDjFK(No_l>azW0ox^9vk!c@4?p-(kM&AcV=Zf@WaZT0_m>82{ zc(Z2Pf$RQu0@@G!Pab;p?G&%x(RsxO`e>y646>R&bIKa62t(eD(hK|Mm&QJHti7or z*8h&`nd2tIee~S!NW=*DCxTX3KD1wQW5eZN-*;;pd^_M`aOP&wm&eOk`s?2Nr8@QJ zyrBt$Ze6TlpCvH2uZmMrl)$lrs~761Eqr@m-p;f;qPDo$SU+%n-|~Z3&G$wMe%!I} zL77Rm)EQr|p$8NVi@g^3S)EuI=J;se0(IN|c^B&(KKYKW7k+*<_ouv(r;hk_>nnG* zoJrPy?x;EOTF~`6;ixjs?|wtg=hSEh{Qi_Ev47T&v7chxemx$SYDwL?Pjoq*l;zLQ$Iacqv)FN>EU;My(gi8GK<7UmOeW?nh<>9VNy}{esz-2 zU_-xgTMP&0kMLgvR-`A@>-@~&*({YZxN5v=R`vRi z5z(?YtXPVP=%>-MLY(SiRh_sz9@JT^I;G&_Yxm-&WzEWsa||k;J{ECwSe+twMJumw z=7clh=FhWG!1maDV;;YEexoHb65eXIJpEu?+}IaNFmiUQrgly}!ZaAI8^}zKqp0(9h92sQvQhIu?ll84v-!1?vMabN zcivgz7v#Nd;-?$42jV(un0lXYgAa#qR8$_Fye8pc;f^o$;+A~L3l^??t7D@O5sahy zJmS&kA%UsuLltf8blE0vG);TI$ zWlfi5y(yB2G{0c+^uW%!79r=xOgU?`Hn#usRNZHl#_K%NWqwbMA^l+Ss#y}xUu!kV zet&=HEln@(XQ^~@PTKE7G1XC1awS*pow%hw-$gS163O30?zV8$8ZvC=qo>gvW>O?XA^=Gc$ zeEsRU$MNyHq4#p8W-1wt&N9gnFq|={Jdtkw@ymfSxb@OJ$KB`qWGY{o*4C$X5v|P*7 zZ;-v#{0oN4I_n<_JT~-wQh0f6qFmL2nwwR%jzM)>E#BANmay`T-p5mVWmP}-MOrE& z6>+~%D8X=?(i_=#T5r|sOFu4^+7@S!8+>%1V8@d)xF}}x+0gmQeLR+GX`WU; z`hFY{=k{arw9!*}Y(n%RcJf7>F|&T_ar*Gb+bdR?7}tH*%ec79@TAz)iQn_KC$6nd zEO*T3iApEcZ;ae^Z|k1xi?tM1KD)O9XQk_W5X2p5mr-*lb5VxEezJ0DpTs07+>OO zmM^$HRFLb$1PS6Z+oAoYENMm8c9d1zFH!e7CKX|G$F3s%YszHLlY$Z9uLO<_)DWnZ z^Skm^C~sTRxut!rZN?h-s2!9psNdyoqik9}?!5Q7@d||A&q$%H6u0mVQw|@Nl3YDX zvv!ThiHT7+HY)0W9lUiiEugT(^J z?O+*C;P$}dvoRIvOIEn#DmiAIPbtcaO-z0CVeY9TQ(fk9EzYiY;hK;tUVCc$yG$Or zowd_bX834Ezm1vW%f>fseCQO`g=>i+k46(kvy@HNvU4jI%!)bsQcA8MYJvS^g~z-mpyFdc(3~0xbYlv=JBUL z7##Zg6F2zcW#70ARPvF-{4d*EY?E{*z<$D{a#zWU>)xv;T=uRuPYW5x>Y7>0JNAj+ zmRIMwmQT#gjPiee^Q~$4;T3P4Yphop8jD-jYThkMxy6y0C+oWNUE!>(6A~Zia8-xu z{CXfsL_e>Qz8n?9_1gY7?)2UHdHK}kOW{GkuDv}FY#yO-!X^03(aB#!Qtzs&Rf(+P zz0q%sRWwU6yZ6#HNA9tl!sTk2RCJBO{Cd7M7d#?MrJpIQB!oZA2q}BF#&*27=!&rm zEk`?ljpFY6Y0G(w%qNxi3%tKdyfv!!61?EA^DFilu|b(6W~Z!sXCYzq?fv$<+kZU_ zw_#iI+kUt;4_|GWN1vM0>W?lDU-Z#0uEPINox~dNAkn}J&vjV`X3RMo@A=5&_sN9G zcnE61!@5a$5aOcE6V7X|&YM`8rPSGb7ilclKYx>T#A#=aDK1l=g@5sSI6MS1fP4GtV6o`_y4eD2qEBcg40pB`ddzooTY2DyOp_h6 zdE_=bj!RrQ$w_n6xGSv0-3s4d$8o2A@8qTHj50n$Z`|G~iIFlJR!;VDI($HWzRN~V9JU|fbtT|TUaq{8WXP%rue$5X`+j{gyConp zNy+84M*KH^yXW%Kf=R`Xc^7YdQaLSO{Y_twuellf`$zZ7*HwSJhDY3O`ex#Fx)$+E za~_P2eL&(hcBjminZL1JJT&st%Mz9iyNgoxA4q0%kK7e4>nkj-Y_QdE#!jKdKkjcP zNRQNpv1Mvjn-+6duXed$WB)=bF`zDB*o`Ts1MX^7N=injteJLTP8}CYR*^G1qksHI zU#-h~e-RmjGPFYMW#I73mhHb#cAe~?0 zfnh#>UHwc9C>LK6xw1$_!=vh;&AX$&)Vw%I!{fpp8>Wwv`L%IJ{ynqDc43oZN4qZR zO9;B9<+?t+Z1*m%z*p_e^QTAiud*JGP!-YX8<(4D^))0ysY>LF`j>O&+nny|pYr$C zojQj&JFRHY>#JdkpR2cTWc5)Z?u$lE8r-jMxt!zd${V$P4kWmYSmyaAeq~M{4NfA@ z)ROR9aK0oXckssC((+?Uzqj!aiJUGxGt9FVZOwj|`8zyOCU2+5qbpMf8j*@7W_;8> z&f;1baXx34q2ACzM{ZRVkMMIg7Y-UO&9P@6J1NYQ*W0_ic>QqmC`;TpDJ#BEq;be? zoZ%_=5v!H@y5y+E#Bx_e2_4&r#EFcLq_g)F4XM!Vi*@;Er;y(~@` zuh@@>OG*E->Z7F@PVvL2=$gk-KgW1Jd^i0FiBC+*>)a$wLcM@hyF`w405L1--dMic zWLb4vmIHHC7A8A9Ja6t9;kRQkk-^$;KvD98aS6`|^-Wh#$v!rW9TXg|R|$~C zNs$uR9aV1=JzIOuScKCck z{mSm!WhHq7iAfLdjg`h!k}5LfMU|ea>TcwCk*v=`6mypRR@ukmDj9KhsPjRQVdGz) zU!OTyz3&6w*GU#4OF4;s8lE{?ZYlnkSX}qKu-z3kK`lli^peW#(Q5l$#>XG>T|8nK zQM6;icvb>MT|Qi-$d{q2wp*YeKJNWjcEXFOwB64>>2dl?+jM{yc98xfAXM(_H%r*q(Dbvh-!?q}kV54ht;WX`MF- zi>EShVV*A^o(mewMhw*;eea*gN9@zB+})R*m~69aKp)qA5~2OrOE?KZ{#tgT-etJS z5MtI&xA{t;90Y0cS4G0}2r;A|$K-y~R}CWKhd8qmWBUW_j&Ac{@Xj&DDe}ipBL1o9kTt4NJzvm=Z>Ni^daibBTQ; z*kuDBtzsh_`hf>l*H?j$=5Ji&OSqnaD8Ca%_8S)^`f{MytAjVB9^4`Swjk&Jb8|O9g7ro^)1D0|{4XDW(a(YF-k@~|o z7|jVCH}ITbaYUe*92-%vRBQDz4kCy3s7`e1?M-VGiOQ=^xHo#iQiq^9^9UL>D3wB;(X?; z%RN_gU1G(P(Z3hpyx{ryX5KDyuZ3T=w-$+6sAoFQA2~lbtniW-3$dtg?QF3!TOMMr zruSgCg<^V7ytmxAzJq74!FIN*$uC~*9eClK$qGKVu)F;fY5zDOo zwcS>2cEu{DehsVTk4pP#O9zbHjFXNS#7=zseyVJFutl}jWi*N1b+v1Sn|nWn!q>h} z$6Cb1*o&r#YI^3M3(mg%)G+tpm5lSM@1gZEllQZ@?y9VqvcX%&%88ZmL~r!9+2;tq zfAE)~s@cnpJML#pOP!;4o8NzDlG~_M#mD|iH3JF3m?wLW>EtAZy^cBgVqfqs{8Qs z`At0FP~lSWwcv8avsVw34ZM%LPCj_BC}o``hs@*jaTNjRA&ct|$D|*cvaURry-y}_ z6Z9SMl+t&pV#&+ZGvW@?$E%gG=tiRG8x`V~_l~0l6re(ol zY<)F1c;?Kt?UQgXXVvocdTUcZk4weM74c8P63+f97`XJWm@x}jqAy2}AWb=Ev(ZDL zO8P*C;qTW%wS}=iQ}(j(wB#|PfABE7%-U_GJ0*u zVy(0&h+i~{}hm_dclIu=7&B@n3RLD*k zXQ%7G`Eg9=Ti*|^Cs~R34OQbd7`^=f9hb9wJt3}daH5H_24PUUd( z`z)@<9Yr@5vEo$|0euL^xzGI8c?+95IFP%MmAE)m{qwlK!^O1zXpkxjMTB`pJ0vyR0`Fvfvl@{qVxa-+fh{ zyQkHUu}tA~DfwVckc17c--@hX@Wm;DjhMYW;Pp)7UkO5k{r_~n%?8!{D4FiNp{m$- z+*fV6gIIDguRX4@on3I{zGSv@d5KLlm;ZwpQ;!cT`=8SY%C9P_&bhp!YLtBj%6 zsx^4Yh3qZOT$j~c!7S?QB_>DPYt9gyS#)+Kd+JGE_2ad11vNJkcP1V>sy%-@)|}S| zp?I~J3Y41t$r@*k#4tfF6BF!pz8EzFkJ)+Jz;qBc4QKj=og&Z*wtFhRkrhI~TEl= zCoEozbNTm8SfmxEuO=o=gx+>t%VMci-)C#E`!tooJ8E*bz+isrwDmz5k*+gtv&<~E zk0#U)KDg>RI85hPl7$jC7cn=DxGZdEF=^oapJRg+d{yoGN-yvjG4IAP_qaXNO5P)1 zlbd0R>nGb1XP<69CY~Ofl2y0fhGW)1!e`WmQKT?dW%Gn;yDz$@W$I04tcgEu!fPt_ zG-=97zHHGUidYttUQE4PJxyC|XiD&>1>e5h*(^Ou zd~2lo8wKG4kA<79}}c{8-Rj@Tgto!3;;B_=2G_hGNn{Z2`}RT07(}5Iv{ZZ zo}%j7YDP`E#MbIT^%*8N0&+88C^ill0BDk5;>~u9QYxnV?3e+-vIR(Wjk~<41cj_jFPYa6-udlqGaLb$KnM5(E`L4&?nXo z-SE6r50WZEsi1&@DFMYF&DCJk>^1D)@J;)VZ{Wj_x~v2_tTyeUU3lWXiSG zB}%CW;^9Uj0I)SM71%GHj-CF_6Yu|<>!;k9vSIGvgGm8JN6(p7lh49itKeA!0CkL& zWD|pwQY+)(bld=7X#uAJQfk<9rmXd=7IDt_!F;w>+^SPU+xg(`fTEWHfo2&l-~G#~ zG#}Vk)&Uo3021eaj#BE$cz0-`03hkZpYd81p}GW~^Jcul$rXwUZJ)Z?c;R;O!?-+! zXat5DazIw$#aft9r4f%8yU0ZVAOU(qn@aZ`EpHM6080xv0+2`=Ph<~noV|B)4Ln$_ zNgV`0Hy=z6D7qRDXt0l8uF;IE277%qaf=2Z*?vz^O1%@Uus8KwG5{bOxE~mq$UvO% zZd0kd%QReFrTN6pPfin)7YCt>^AtmcyBSU!HQZ38`7lUIfY>D(z{9|WN~wenLkRa*x}2ya+T#Y^L;`SQQ5xP{?@I4fPpKhcJ?QfJ$fO!VjZZK zt!|YXMptRxP1D8{hW7Qt**S{+J?K8XM#B>|npcCcMx0yIKpl$P^WONkkv|YiUOEv(A`Y#DYuTItgZEq(WqI&wXRQ&gLbjA8sK_I9#Lo4Bz6rM?&;=%rYxFFXX z*@fnZb>w3bWu)r4v$_unL~GXY&ASNVqd3}O4{yADgemBX|21;buF+@x)w6# zegy<(PNm{M6VMx0gRf;xU~UL5snje^<7SmPN*uv1J{X*>*f&cf#{@T!C{QcHupkU? z1T`NAVMCgEDSUhIum9jL`wVm{3%>wPQc5jO<^XNkFn_|is!#20i?itaw>;oIb8Sga(eqb8sfeznQDCK_*N*(~ChB)6fWvWqHT zt)UzcXB`pxrD0g6VR=~ou37FtzSQ40{rBj{_~GN&rd?;dwo{_*PP4N7E>EYbpld2yG!9M=!c|oo@fvgk$u(j`Q}Dw!aqNKE zA;kgSVQFcqB&j zQA(*YI~is>09Z!>i4l;hLVMXc89Un!m#v}tqbI2P_}}QV(q^@R-@`Dr8fFCDsTSMG zLnpL7pzl#UaKXLgWI4K4^Gxg9FFyaaQc3{80)fMTe*;o(+?^B-Q9I`|D&Km5;Jg{2 zLrvNSMD}m5hUaQi8%FF-rlw}pKILQl@S8dPuwkj`F#cYoocHNUsSo0BBKkK|1^^Za zoCin{gRAQc>asOdefk{LA3sUBbjcchvV`Q~kOSZEqoBv zj`WXjZGKMreUDDtGiu-k^y__?Q{(uXW0!dPNm_5o?wb}$D*#v^aJp4t$UTvRu`E@n z7Kts8NWF)IX;X=sr#62`*S$g?8&7aV;aC+&X%*;%g3o+=T3 zQqf0_!f7KX0DwdeN|`aa9dKk4wq&i2E?Y}*;aAlB@FBsupA%aBJJeRORx92ODc%Ue z4IC-*Wl=^lgPhamIy%}=gV2<5qpi?9GT4RjFPhBS-vUWuHwbpt4-=`e_EGTLS<>g(hHp4O&c1>6GMp_EEH);j_KED#XEzX7l!H!Yz@A4^oG*o_TumbI zcLL*-QUU~NC&vJQ1p?wBC>1#+#klJZbxB#xaENgETEc48qA7 zx4Mcop>RryV3clPSlmqT_xIP&-WTvt1e)^S1dNsAZk%}Ocp z_;Um~3IHq+km$j2mR%q-L7?&02-PCji$Bl%lK;+pled5RjQOQ2@B$P_7M^X|Z^Lfe z?ZP3u9n1l{>`%82l2+1FB*HHdu{YQq-4`p@90vgPKtSvPmu1v(AcoajvSumYE%=TZ zb7nDf&P;yz?MH&4q$P`uVI;9VD#G2fb5C~bzH3Cim!uqR3%z*(WN}8+{)uw#cbf3a z_#6oU^^ODATgL(K8wO*Oqs>p(hJvhGzlwz`7BXkaTz>lfXBMsejWrwAu)bmgt2VcifIH?Yq#Sqyz1X+NEMR>Fz_$`J(oZ zcaqv)pDB(701E^}@UH-__4*ZIvUh4Q9AeRmMa*9O3+v0*GjG{^W-p%2hKh}pRhCg+ zUCxTND+%k^91!H3F2405*jj7ya`Gt2FJ|X$ca9|35D&aQJ$gsJ^7**|#E_SvB#1i! zxXUR9zoyo~(Ewn9fY<>p0LFTy1bI3HLWEU7AruM{l55CNh{~Eus%xtWg~giCvR|^_ z=OfFXjQ~JSRyKa0pHL`--|r_UI~Si)ME-M+3$C5ZAf>x+0wyI|z1Pk`I{FAuf8th} z@l&nbf}V35wtJCH`zhssxc6QIJe_VQpJ-<7cnzR#5?V)U#161xrh7#*IrEI+K#Dmq z*UEMArc%lkp5fOsZ&K5pJsgmbUh(apVNdh+wCXwlu^?rj7$*MV%^Du+kCFpXfAQ2>=!dNM<1ks5sy4IR+D5MDu>yI3ON<4@n?f zsx$c{YsRhx01E^p$KVLd;%bb8$=VgBooF~9#y+{3dOVdm{Gu6HEYG+a04xxYIY>cw zsXpY|x&yH+nt3+u9FV;IV(I_LEylj)IOci)sAnA99vCA96^#3E+6Ba`0}!`fDR47J zDYd{0lk^M#SlWOD5}j?KvpEuYVTU?r4x;jlmied?efr~NlcxZn-jU!yE28iKb4w8K z)-dl`91tu2CswYC|G8b|Z@j9W1Aux*f=*U6;Yi~`Y=k*Z4v0&y)UcSSlv*BV8;*X> zvjAXe16jaP7J7?;(9`pE^iFfv;KYkh41JQ9;w`0A&|SliezX}O5L)Xlz{Qe+8OVq@ z)abW>d9o1)O087&_bH{8c%3^L0RZ*10l6-e(Bgvt(GCn54%Bf#zVaViA-r-508mdGka`3MTOpi>WkgMaXm*A7pOI8uA6TK~)0~i>KV2-( zXaJ}O1VzAcRwm-U#y*g)?Pzd^o|4C|$}F0q`5BtvmOV5=BjH;>xKfz`l!l8ING zd6ZJ??d!^0EgJxcV?DLja(%cPa3XLl@JDkzh=Y-dy&`J!({nFL(LNGtq%3S?o0%HA$S*T1$Sy z9f2dQ`UQIca%3=+I0rA~YCF#a@l57*02K=m)+7JiZ%_~uIzyLs$j7r91T5G9xydAJ7AnD2^Nr@CW5$zz; z%IHd}E&0mNw~}v2+O02vMNY1!n~Z(nq&5ryq-ixQ17aJX2O#zW0RzzvBt%(~mPl1( zFOgX7CE13A-pW^AGVaK^{#Rg~G32FZsSN<6hwoeTY5{^A7bJU;Tq{Z}!Y+UmLKW9! z0ShrSI(^OL{9Y|W4T$Tl6wLh5I?v0son+bBUV^j1Zs@MmE}mH>O{z;G?oau1lNdQFS1m6QR{yPR#?I==X*mA:/DEBUG>") + target_link_options(PrusaSlicer_app_console PUBLIC "$<$:/DEBUG>") endif () target_compile_definitions(PrusaSlicer_app_console PRIVATE -DSLIC3R_WRAPPER_CONSOLE) add_dependencies(PrusaSlicer_app_console PrusaSlicer) set_target_properties(PrusaSlicer_app_console PROPERTIES OUTPUT_NAME "prusa-slicer-console") target_link_libraries(PrusaSlicer_app_console PRIVATE boost_headeronly) + + add_executable(PrusaSlicer_app_gcodeviewer WIN32 PrusaSlicer_app_msvc.cpp ${CMAKE_CURRENT_BINARY_DIR}/PrusaSlicer-gcodeviewer.rc) + # Generate debug symbols even in release mode. + if (MSVC) + target_link_options(PrusaSlicer_app_gcodeviewer PUBLIC "$<$:/DEBUG>") + endif () + target_compile_definitions(PrusaSlicer_app_gcodeviewer PRIVATE -DSLIC3R_WRAPPER_NOCONSOLE -DSLIC3R_WRAPPER_GCODEVIEWER) + add_dependencies(PrusaSlicer_app_gcodeviewer PrusaSlicer) + set_target_properties(PrusaSlicer_app_gcodeviewer PROPERTIES OUTPUT_NAME "prusa-gcodeviewer") + target_link_libraries(PrusaSlicer_app_gcodeviewer PRIVATE boost_headeronly) endif () # Link the resources dir to where Slic3r GUI expects it diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp index aaf3db9158..2962f0cdfe 100644 --- a/src/PrusaSlicer.cpp +++ b/src/PrusaSlicer.cpp @@ -101,6 +101,7 @@ int CLI::run(int argc, char **argv) std::find(m_transforms.begin(), m_transforms.end(), "cut") == m_transforms.end() && std::find(m_transforms.begin(), m_transforms.end(), "cut_x") == m_transforms.end() && std::find(m_transforms.begin(), m_transforms.end(), "cut_y") == m_transforms.end(); + bool start_as_gcodeviewer = false; const std::vector &load_configs = m_config.option("load", true)->values; @@ -521,6 +522,9 @@ int CLI::run(int argc, char **argv) << " (" << print.total_extruded_volume()/1000 << "cm3)" << std::endl; */ } + } else if (opt_key == "gcodeviewer") { + start_gui = true; + start_as_gcodeviewer = true; } else { boost::nowide::cerr << "error: option not supported yet: " << opt_key << std::endl; return 1; diff --git a/src/PrusaSlicer_app_msvc.cpp b/src/PrusaSlicer_app_msvc.cpp index 712cff687d..5f12c91479 100644 --- a/src/PrusaSlicer_app_msvc.cpp +++ b/src/PrusaSlicer_app_msvc.cpp @@ -221,6 +221,11 @@ int wmain(int argc, wchar_t **argv) std::vector argv_extended; argv_extended.emplace_back(argv[0]); +#ifdef SLIC3R_WRAPPER_GCODEVIEWER + wchar_t gcodeviewer_param[] = L"--gcodeviewer"; + argv_extended.emplace_back(gcodeviewer_param); +#endif /* SLIC3R_WRAPPER_GCODEVIEWER */ + #ifdef SLIC3R_GUI // Here one may push some additional parameters based on the wrapper type. bool force_mesa = false; diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 3401dcc020..770983ad59 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -3530,6 +3530,12 @@ CLIActionsConfigDef::CLIActionsConfigDef() def->cli = "export-gcode|gcode|g"; def->set_default_value(new ConfigOptionBool(false)); + def = this->add("gcodeviewer", coBool); + def->label = L("G-code viewer"); + def->tooltip = L("Visualize an already sliced and saved G-code"); + def->cli = "gcodeviewer"; + def->set_default_value(new ConfigOptionBool(false)); + def = this->add("slice", coBool); def->label = L("Slice"); def->tooltip = L("Slice the model as FFF or SLA based on the printer_technology configuration value."); diff --git a/src/platform/msw/PrusaSlicer-gcodeviewer.rc.in b/src/platform/msw/PrusaSlicer-gcodeviewer.rc.in new file mode 100644 index 0000000000..7f4e5a15c3 --- /dev/null +++ b/src/platform/msw/PrusaSlicer-gcodeviewer.rc.in @@ -0,0 +1,25 @@ +1 VERSIONINFO +FILEVERSION @SLIC3R_RC_VERSION@ +PRODUCTVERSION @SLIC3R_RC_VERSION@ +{ + BLOCK "StringFileInfo" + { + BLOCK "040904E4" + { + VALUE "CompanyName", "Prusa Research" + VALUE "FileDescription", "@SLIC3R_APP_NAME@ G-code Viewer" + VALUE "FileVersion", "@SLIC3R_BUILD_ID@" + VALUE "ProductName", "@SLIC3R_APP_NAME@ G-code Viewer" + VALUE "ProductVersion", "@SLIC3R_BUILD_ID@" + VALUE "InternalName", "@SLIC3R_APP_NAME@ G-code Viewer" + VALUE "LegalCopyright", "Copyright \251 2016-2020 Prusa Research, \251 2011-2018 Alessandro Ranelucci" + VALUE "OriginalFilename", "prusa-gcodeviewer.exe" + } + } + BLOCK "VarFileInfo" + { + VALUE "Translation", 0x409, 1252 + } +} +2 ICON "@SLIC3R_RESOURCES_DIR@/icons/PrusaSlicer-gcodeviewer.ico" +1 24 "PrusaSlicer.manifest" From 6033e6990671d2ccc535058b5e0a8f8da862f832 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 1 Sep 2020 17:56:19 +0200 Subject: [PATCH 243/255] filaments selecting: sorting via printer, showing printers for filament --- src/slic3r/GUI/ConfigWizard.cpp | 484 ++++++++++++++++++------ src/slic3r/GUI/ConfigWizard_private.hpp | 150 ++++++-- 2 files changed, 476 insertions(+), 158 deletions(-) diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index 60323976c8..f8abfb1788 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -561,30 +561,37 @@ const std::string PageMaterials::EMPTY; PageMaterials::PageMaterials(ConfigWizard *parent, Materials *materials, wxString title, wxString shortname, wxString list1name) : ConfigWizardPage(parent, std::move(title), std::move(shortname)) , materials(materials) - , list_l1(new StringList(this)) - , list_l2(new StringList(this)) - , list_l3(new PresetList(this)) + , list_printer(new StringList(this, wxLB_MULTIPLE)) + , list_type(new StringList(this)) + , list_vendor(new StringList(this)) + , list_profile(new PresetList(this)) + , compatible_printers(new wxStaticText(this, wxID_ANY, _(L("")))) { append_spacer(VERTICAL_SPACING); const int em = parent->em_unit(); const int list_h = 30*em; - list_l1->SetMinSize(wxSize(8*em, list_h)); - list_l2->SetMinSize(wxSize(13*em, list_h)); - list_l3->SetMinSize(wxSize(25*em, list_h)); + list_printer->SetWindowStyle(wxLB_EXTENDED); - auto *grid = new wxFlexGridSizer(3, em/2, em); - grid->AddGrowableCol(2, 1); + list_printer->SetMinSize(wxSize(23*em, list_h)); + list_type->SetMinSize(wxSize(8*em, list_h)); + list_vendor->SetMinSize(wxSize(13*em, list_h)); + list_profile->SetMinSize(wxSize(23*em, list_h)); + + grid = new wxFlexGridSizer(4, em/2, em); + grid->AddGrowableCol(3, 1); grid->AddGrowableRow(1, 1); + grid->Add(new wxStaticText(this, wxID_ANY, _(L("Printer:")))); grid->Add(new wxStaticText(this, wxID_ANY, list1name)); grid->Add(new wxStaticText(this, wxID_ANY, _(L("Vendor:")))); grid->Add(new wxStaticText(this, wxID_ANY, _(L("Profile:")))); - grid->Add(list_l1, 0, wxEXPAND); - grid->Add(list_l2, 0, wxEXPAND); - grid->Add(list_l3, 1, wxEXPAND); + grid->Add(list_printer, 0, wxEXPAND); + grid->Add(list_type, 0, wxEXPAND); + grid->Add(list_vendor, 0, wxEXPAND); + grid->Add(list_profile, 1, wxEXPAND); auto *btn_sizer = new wxBoxSizer(wxHORIZONTAL); auto *sel_all = new wxButton(this, wxID_ANY, _(L("All"))); @@ -592,121 +599,342 @@ PageMaterials::PageMaterials(ConfigWizard *parent, Materials *materials, wxStrin btn_sizer->Add(sel_all, 0, wxRIGHT, em / 2); btn_sizer->Add(sel_none); + grid->Add(new wxBoxSizer(wxHORIZONTAL)); grid->Add(new wxBoxSizer(wxHORIZONTAL)); grid->Add(btn_sizer, 0, wxALIGN_RIGHT); + + auto* notes_sizer = new wxBoxSizer(wxHORIZONTAL); + notes_sizer->Add(compatible_printers); + grid->Add(notes_sizer); + append(grid, 1, wxEXPAND); - list_l1->Bind(wxEVT_LISTBOX, [this](wxCommandEvent &) { - update_lists(list_l1->GetSelection(), list_l2->GetSelection()); + list_printer->Bind(wxEVT_LISTBOX, [this](wxCommandEvent& evt) { + update_lists(evt.GetInt(), list_type->GetSelection(), list_vendor->GetSelection()); + }); + list_type->Bind(wxEVT_LISTBOX, [this](wxCommandEvent &) { + update_lists(list_printer->GetSelection(), list_type->GetSelection(), list_vendor->GetSelection()); }); - list_l2->Bind(wxEVT_LISTBOX, [this](wxCommandEvent &) { - update_lists(list_l1->GetSelection(), list_l2->GetSelection()); + list_vendor->Bind(wxEVT_LISTBOX, [this](wxCommandEvent &) { + update_lists(list_printer->GetSelection(), list_type->GetSelection(), list_vendor->GetSelection()); }); - list_l3->Bind(wxEVT_CHECKLISTBOX, [this](wxCommandEvent &evt) { select_material(evt.GetInt()); }); + list_profile->Bind(wxEVT_CHECKLISTBOX, [this](wxCommandEvent &evt) { select_material(evt.GetInt()); }); + list_profile->Bind(wxEVT_LISTBOX, [this](wxCommandEvent& evt) { on_material_highlighted(evt.GetInt()); }); sel_all->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { select_all(true); }); sel_none->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { select_all(false); }); + Bind(wxEVT_PAINT, [this](wxPaintEvent& evt) {on_paint();}); + + list_profile->Bind(wxEVT_MOTION, [this](wxMouseEvent& evt) { on_mouse_move_on_profiles(evt); }); + list_profile->Bind(wxEVT_ENTER_WINDOW, [this](wxMouseEvent& evt) { on_mouse_enter_profiles(evt); }); + list_profile->Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent& evt) { on_mouse_leave_profiles(evt); }); + reload_presets(); } - +void PageMaterials::on_paint() +{ + if (first_paint) { + first_paint = false; + prepare_compatible_printers_label(); + } +} +void PageMaterials::on_mouse_move_on_profiles(wxMouseEvent& evt) +{ + const wxClientDC dc(list_profile); + const wxPoint pos = evt.GetLogicalPosition(dc); + int item = list_profile->HitTest(pos); + BOOST_LOG_TRIVIAL(error) << "hit test: " << item; + on_material_hovered(item); +} +void PageMaterials::on_mouse_enter_profiles(wxMouseEvent& evt) +{} +void PageMaterials::on_mouse_leave_profiles(wxMouseEvent& evt) +{ + on_material_hovered(-1); +} void PageMaterials::reload_presets() { clear(); - list_l1->append(_(L("(All)")), &EMPTY); + list_printer->append(_(L("(All)")), &EMPTY); + list_printer->SetLabelMarkup("bald"); + for (const Preset* printer : materials->printers) { + list_printer->append(printer->name, &printer->name); + } - for (const std::string &type : materials->types) { - list_l1->append(type, &type); - } - - if (list_l1->GetCount() > 0) { - list_l1->SetSelection(0); - sel1_prev = wxNOT_FOUND; - sel2_prev = wxNOT_FOUND; - update_lists(0, 0); + if (list_printer->GetCount() > 0) { + list_printer->SetSelection(0); + sel_printer_prev = wxNOT_FOUND; + sel_type_prev = wxNOT_FOUND; + sel_vendor_prev = wxNOT_FOUND; + update_lists(0, 0, 0); } presets_loaded = true; } -void PageMaterials::update_lists(int sel1, int sel2) +void PageMaterials::prepare_compatible_printers_label() { - wxWindowUpdateLocker freeze_guard(this); - (void)freeze_guard; - - if (sel1 != sel1_prev) { - // Refresh the second list - - // XXX: The vendor list is created with quadratic complexity here, - // but the number of vendors is going to be very small this shouldn't be a problem. - - list_l2->Clear(); - list_l2->append(_(L("(All)")), &EMPTY); - if (sel1 != wxNOT_FOUND) { - const std::string &type = list_l1->get_data(sel1); - - materials->filter_presets(type, EMPTY, [this](const Preset *p) { - const std::string &vendor = this->materials->get_vendor(p); - - if (list_l2->find(vendor) == wxNOT_FOUND) { - list_l2->append(vendor, &vendor); - } - }); - } - - sel1_prev = sel1; - sel2 = 0; - sel2_prev = wxNOT_FOUND; - list_l2->SetSelection(sel2); - list_l3->Clear(); + assert(grid->GetColWidths().size() == 4); + compatible_printers_width = grid->GetColWidths()[3]; + empty_printers_label = "Compatible printers:"; + for (const Preset* printer : materials->printers) { + empty_printers_label += "\n"; } + clear_compatible_printers_label(); +} - if (sel2 != sel2_prev) { - // Refresh the third list +void PageMaterials::clear_compatible_printers_label() +{ + compatible_printers->SetLabel(boost::nowide::widen(empty_printers_label)); + compatible_printers->Wrap(compatible_printers_width); + Layout(); +} - list_l3->Clear(); - if (sel1 != wxNOT_FOUND && sel2 != wxNOT_FOUND) { - const std::string &type = list_l1->get_data(sel1); - const std::string &vendor = list_l2->get_data(sel2); - - materials->filter_presets(type, vendor, [this](const Preset *p) { - bool was_checked = false; - - int cur_i = list_l3->find(p->alias); - if (cur_i == wxNOT_FOUND) - cur_i = list_l3->append(p->alias, &p->alias); +void PageMaterials::on_material_hovered(int sel_material) +{ + if ( sel_material == last_hovered_item) + return; + if (sel_material == -1) { + clear_compatible_printers_label(); + return; + } + last_hovered_item = sel_material; + std::string compatible_printers_label = "compatible printers:\n"; + //selected material string + std::string material_name = list_profile->get_data(sel_material); + // get material preset + const std::vector matching_materials = materials->get_presets_by_alias(material_name); + if (matching_materials.empty()) + { + clear_compatible_printers_label(); + return; + } + //find matching printers + bool first = true; + for (const Preset* printer : materials->printers) { + bool compatible = false; + for (const Preset* material : matching_materials) { + if (is_compatible_with_printer(PresetWithVendorProfile(*material, material->vendor), PresetWithVendorProfile(*printer, printer->vendor))) { + if (first) + first = false; else - was_checked = list_l3->IsChecked(cur_i); - - const std::string& section = materials->appconfig_section(); - - const bool checked = wizard_p()->appconfig_new.has(section, p->name); - list_l3->Check(cur_i, checked | was_checked); - - /* Update preset selection in config. - * If one preset from aliases bundle is selected, - * than mark all presets with this aliases as selected - * */ - if (checked && !was_checked) - wizard_p()->update_presets_in_config(section, p->alias, true); - else if (!checked && was_checked) - wizard_p()->appconfig_new.set(section, p->name, "1"); - } ); + compatible_printers_label += "\n";//", "; + compatible_printers_label += printer->name; + compatible = true; + break; + } } - - sel2_prev = sel2; } + this->compatible_printers->SetLabel(boost::nowide::widen(compatible_printers_label)); + this->compatible_printers->Wrap(compatible_printers_width); +} + +void PageMaterials::on_material_highlighted(int sel_material) +{ + wxWindowUpdateLocker freeze_guard(this); + (void)freeze_guard; + + //std::string compatible_printers_label = "compatible printers:\n"; + //std::string empty_suplement = std::string(); + //unselect all printers + list_printer->SetSelection(wxNOT_FOUND); + //selected material string + std::string material_name = list_profile->get_data(sel_material); + // get material preset + const std::vector matching_materials = materials->get_presets_by_alias(material_name); + if (matching_materials.empty()) + return; + //find matching printers + //bool first = true; + for (const Preset* printer : materials->printers) { + bool compatible = false; + for (const Preset* material : matching_materials) { + if (is_compatible_with_printer(PresetWithVendorProfile(*material, material->vendor), PresetWithVendorProfile(*printer, printer->vendor))) { + //select printer + int index = list_printer->find(printer->name); + list_printer->SetSelection(index); + /*if (first) + first = false; + else + compatible_printers_label += "\n";//", "; + compatible_printers_label += printer->name; + compatible = true; + break;*/ + } + } + //if(!compatible) + // empty_suplement += std::string(printer->name.length() + 2, ' '); + } + // fill rest of label with blanks so it maintains legth + //compatible_printers_label += empty_suplement; + + update_lists(0,0,0); + list_profile->SetSelection(list_profile->find(material_name)); + + //this->compatible_printers->SetLabel(boost::nowide::widen(compatible_printers_label)); + //this->compatible_printers->Wrap(compatible_printers_width); + //Refresh(); +} + +void PageMaterials::update_lists(int sel_printer, int sel_type, int sel_vendor) +{ + wxWindowUpdateLocker freeze_guard(this); + (void)freeze_guard; + + wxArrayInt sel_printers; + int sel_printers_count = list_printer->GetSelections(sel_printers); + + if (sel_printers_count != sel_printer_prev) { + // Refresh type list + list_type->Clear(); + list_type->append(_(L("(All)")), &EMPTY); + if (sel_printers_count > 0) { + // If all is selected with other printers + // unselect "all" or all printers depending on last value + if (sel_printers[0] == 0 && sel_printers_count > 1) { + if (sel_printer == 0) { + list_printer->SetSelection(wxNOT_FOUND); + list_printer->SetSelection(0); + } else { + list_printer->SetSelection(0, false); + sel_printers_count = list_printer->GetSelections(sel_printers); + } + } + if (sel_printers[0] != 0) { + for (size_t i = 0; i < sel_printers_count; i++) { + const std::string& printer_name = list_printer->get_data(sel_printers[i]); + const Preset* printer = nullptr; + for (const Preset* it : materials->printers) { + if (it->name == printer_name) { + printer = it; + break; + } + } + materials->filter_presets(printer, EMPTY, EMPTY, [this](const Preset* p) { + const std::string& type = this->materials->get_type(p); + if (list_type->find(type) == wxNOT_FOUND) { + list_type->append(type, &type); + } + }); + } + } else { + //clear selection except "ALL" + list_printer->SetSelection(wxNOT_FOUND); + list_printer->SetSelection(0); + + materials->filter_presets(nullptr, EMPTY, EMPTY, [this](const Preset* p) { + const std::string& type = this->materials->get_type(p); + if (list_type->find(type) == wxNOT_FOUND) { + list_type->append(type, &type); + } + }); + } + + } + + sel_printer_prev = sel_printers_count; + sel_type = 0; + sel_type_prev = wxNOT_FOUND; + list_type->SetSelection(sel_type); + list_profile->Clear(); + } + + if (sel_type != sel_type_prev) { + // Refresh vendor list + + // XXX: The vendor list is created with quadratic complexity here, + // but the number of vendors is going to be very small this shouldn't be a problem. + + list_vendor->Clear(); + list_vendor->append(_(L("(All)")), &EMPTY); + if (sel_printers_count != 0 && sel_type != wxNOT_FOUND) { + const std::string& type = list_type->get_data(sel_type); + // find printer preset + for (size_t i = 0; i < sel_printers_count; i++) { + const std::string& printer_name = list_printer->get_data(sel_printers[i]); + const Preset* printer = nullptr; + for (const Preset* it : materials->printers) { + if (it->name == printer_name) { + printer = it; + break; + } + } + materials->filter_presets(printer, type, EMPTY, [this](const Preset* p) { + const std::string& vendor = this->materials->get_vendor(p); + if (list_vendor->find(vendor) == wxNOT_FOUND) { + list_vendor->append(vendor, &vendor); + } + }); + } + } + + sel_type_prev = sel_type; + sel_vendor = 0; + sel_vendor_prev = wxNOT_FOUND; + list_vendor->SetSelection(sel_vendor); + list_profile->Clear(); + } + + if (sel_vendor != sel_vendor_prev) { + // Refresh material list + + list_profile->Clear(); + clear_compatible_printers_label(); + if (sel_printers_count != 0 && sel_type != wxNOT_FOUND && sel_vendor != wxNOT_FOUND) { + const std::string& type = list_type->get_data(sel_type); + const std::string& vendor = list_vendor->get_data(sel_vendor); + // finst printer preset + for (size_t i = 0; i < sel_printers_count; i++) { + const std::string& printer_name = list_printer->get_data(sel_printers[i]); + const Preset* printer = nullptr; + for (const Preset* it : materials->printers) { + if (it->name == printer_name) { + printer = it; + break; + } + } + + materials->filter_presets(printer, type, vendor, [this](const Preset* p) { + bool was_checked = false; + //size_t printer_counter = materials->get_printer_counter(p); + int cur_i = list_profile->find(p->alias); + if (cur_i == wxNOT_FOUND) + //cur_i = list_profile->append(p->alias + " " + std::to_string(printer_counter)/*+ (omnipresent ? "" : " ONLY SOME PRINTERS")*/, &p->alias); + cur_i = list_profile->append(p->alias + (materials->get_omnipresent(p) ? "" : " *"), &p->alias); + else + was_checked = list_profile->IsChecked(cur_i); + + const std::string& section = materials->appconfig_section(); + + const bool checked = wizard_p()->appconfig_new.has(section, p->name); + list_profile->Check(cur_i, checked | was_checked); + + /* Update preset selection in config. + * If one preset from aliases bundle is selected, + * than mark all presets with this aliases as selected + * */ + if (checked && !was_checked) + wizard_p()->update_presets_in_config(section, p->alias, true); + else if (!checked && was_checked) + wizard_p()->appconfig_new.set(section, p->name, "1"); + }); + } + } + + sel_vendor_prev = sel_vendor; + } } void PageMaterials::select_material(int i) { - const bool checked = list_l3->IsChecked(i); + const bool checked = list_profile->IsChecked(i); - const std::string& alias_key = list_l3->get_data(i); + const std::string& alias_key = list_profile->get_data(i); wizard_p()->update_presets_in_config(materials->appconfig_section(), alias_key, checked); } @@ -715,10 +943,10 @@ void PageMaterials::select_all(bool select) wxWindowUpdateLocker freeze_guard(this); (void)freeze_guard; - for (unsigned i = 0; i < list_l3->GetCount(); i++) { - const bool current = list_l3->IsChecked(i); + for (unsigned i = 0; i < list_profile->GetCount(); i++) { + const bool current = list_profile->IsChecked(i); if (current != select) { - list_l3->Check(i, select); + list_profile->Check(i, select); select_material(i); } } @@ -726,11 +954,13 @@ void PageMaterials::select_all(bool select) void PageMaterials::clear() { - list_l1->Clear(); - list_l2->Clear(); - list_l3->Clear(); - sel1_prev = wxNOT_FOUND; - sel2_prev = wxNOT_FOUND; + list_printer->Clear(); + list_type->Clear(); + list_vendor->Clear(); + list_profile->Clear(); + sel_printer_prev = wxNOT_FOUND; + sel_type_prev = wxNOT_FOUND; + sel_vendor_prev = wxNOT_FOUND; presets_loaded = false; } @@ -740,6 +970,7 @@ void PageMaterials::on_activate() wizard_p()->update_materials(materials->technology); reload_presets(); } + first_paint = true; } @@ -1314,16 +1545,22 @@ const std::string Materials::UNKNOWN = "(Unknown)"; void Materials::push(const Preset *preset) { - presets.push_back(preset); + presets.emplace_back(preset, 0); types.insert(technology & T_FFF ? Materials::get_filament_type(preset) : Materials::get_material_type(preset)); } +void Materials::add_printer(const Preset* preset) +{ + printers.insert(preset); +} + void Materials::clear() { presets.clear(); types.clear(); + printers.clear(); } const std::string& Materials::appconfig_section() const @@ -1373,7 +1610,6 @@ const std::string& Materials::get_material_vendor(const Preset *preset) return opt != nullptr ? opt->value : UNKNOWN; } - // priv static const std::unordered_map> legacy_preset_map {{ @@ -1601,26 +1837,28 @@ void ConfigWizard::priv::update_materials(Technology technology) if (any_fff_selected && (technology & T_FFF)) { filaments.clear(); aliases_fff.clear(); - // Iterate filaments in all bundles for (const auto &pair : bundles) { for (const auto &filament : pair.second.preset_bundle->filaments) { // Check if filament is already added - if (filaments.containts(&filament)) - continue; + if (filaments.containts(&filament)) + continue; // Iterate printers in all bundles - // For now, we only allow the profiles to be compatible with another profiles inside the same bundle. -// for (const auto &pair : bundles) - for (const auto &printer : pair.second.preset_bundle->printers) - // Filter out inapplicable printers - if (printer.is_visible && printer.printer_technology() == ptFFF && - is_compatible_with_printer(PresetWithVendorProfile(filament, nullptr), PresetWithVendorProfile(printer, nullptr)) && - // Check if filament is already added - ! filaments.containts(&filament)) { - filaments.push(&filament); - if (!filament.alias.empty()) - aliases_fff[filament.alias].insert(filament.name); - } + for (const auto &printer : pair.second.preset_bundle->printers) { + if (!printer.is_visible || printer.printer_technology() != ptFFF) + continue; + // Filter out inapplicable printers + if (is_compatible_with_printer(PresetWithVendorProfile(filament, filament.vendor), PresetWithVendorProfile(printer, printer.vendor))) { + if (!filaments.containts(&filament)) { + filaments.push(&filament); + if (!filament.alias.empty()) + aliases_fff[filament.alias].insert(filament.name); + } + filaments.add_printer_counter(&filament); + filaments.add_printer(&printer); + } + } + } } } @@ -1637,17 +1875,21 @@ void ConfigWizard::priv::update_materials(Technology technology) continue; // Iterate printers in all bundles // For now, we only allow the profiles to be compatible with another profiles inside the same bundle. -// for (const auto &pair : bundles) - for (const auto &printer : pair.second.preset_bundle->printers) - // Filter out inapplicable printers - if (printer.is_visible && printer.printer_technology() == ptSLA && - is_compatible_with_printer(PresetWithVendorProfile(material, nullptr), PresetWithVendorProfile(printer, nullptr)) && - // Check if material is already added - ! sla_materials.containts(&material)) { + for (const auto& printer : pair.second.preset_bundle->printers) { + if(!printer.is_visible || printer.printer_technology() != ptSLA) + continue; + // Filter out inapplicable printers + if (is_compatible_with_printer(PresetWithVendorProfile(material, nullptr), PresetWithVendorProfile(printer, nullptr))) { + // Check if material is already added + if(!sla_materials.containts(&material)) { sla_materials.push(&material); if (!material.alias.empty()) aliases_sla[material.alias].insert(material.name); } + sla_materials.add_printer_counter(&material); + sla_materials.add_printer(&printer); + } + } } } } diff --git a/src/slic3r/GUI/ConfigWizard_private.hpp b/src/slic3r/GUI/ConfigWizard_private.hpp index 9921552a73..f7987a8908 100644 --- a/src/slic3r/GUI/ConfigWizard_private.hpp +++ b/src/slic3r/GUI/ConfigWizard_private.hpp @@ -57,32 +57,98 @@ enum Technology { T_ANY = ~0, }; +struct Bundle +{ + std::unique_ptr preset_bundle; + VendorProfile* vendor_profile{ nullptr }; + bool is_in_resources{ false }; + bool is_prusa_bundle{ false }; + + Bundle() = default; + Bundle(Bundle&& other); + + // Returns false if not loaded. Reason for that is logged as boost::log error. + bool load(fs::path source_path, bool is_in_resources, bool is_prusa_bundle = false); + + const std::string& vendor_id() const { return vendor_profile->id; } +}; + +struct BundleMap : std::unordered_map +{ + static BundleMap load(); + + Bundle& prusa_bundle(); + const Bundle& prusa_bundle() const; +}; + struct Materials { Technology technology; // use vector for the presets to purpose of save of presets sorting in the bundle - std::vector presets; + // bool is true if material is present in all printers (omnipresent) + // size_t is counter of printers compatible with material + std::vector> presets; std::set types; + std::set printers; Materials(Technology technology) : technology(technology) {} void push(const Preset *preset); + void add_printer(const Preset* preset); void clear(); bool containts(const Preset *preset) const { - return std::find(presets.begin(), presets.end(), preset) != presets.end(); + //return std::find(presets.begin(), presets.end(), preset) != presets.end(); + return std::find_if(presets.begin(), presets.end(), + [preset](const std::pair& element) { return element.first == preset; }) != presets.end(); + } + + bool get_omnipresent(const Preset* preset) { + return get_printer_counter(preset) == printers.size(); + } + + const std::vector get_presets_by_alias(const std::string name) { + std::vector ret_vec; + for (auto it = presets.begin(); it != presets.end(); ++it) { + if ((*it).first->alias == name) + ret_vec.push_back((*it).first); + } + return ret_vec; + } + + void add_printer_counter(const Preset* preset) { + for (auto it = presets.begin(); it != presets.end(); ++it) { + if ((*it).first->alias == preset->alias) + (*it).second += 1; + } + } + + size_t get_printer_counter(const Preset* preset) { + size_t highest = 0; + for (auto it : presets) { + if (it.first->alias == preset->alias && it.second > highest) + highest = it.second; + } + return highest; + } const std::string& appconfig_section() const; const std::string& get_type(const Preset *preset) const; const std::string& get_vendor(const Preset *preset) const; + - template void filter_presets(const std::string &type, const std::string &vendor, F cb) { - for (const Preset *preset : presets) { - if ((type.empty() || get_type(preset) == type) && (vendor.empty() || get_vendor(preset) == vendor)) { - cb(preset); - } - } - } + template void filter_presets(const Preset* printer, const std::string& type, const std::string& vendor, F cb) { + for (auto preset : presets) { + const Preset& prst = *(preset.first); + const Preset& prntr = *printer; + if ((printer == nullptr || is_compatible_with_printer(PresetWithVendorProfile(prst, prst.vendor), PresetWithVendorProfile(prntr, prntr.vendor))) && + (type.empty() || get_type(preset.first) == type) && + (vendor.empty() || get_vendor(preset.first) == vendor)) { + + cb(preset.first); + } + } + } static const std::string UNKNOWN; static const std::string& get_filament_type(const Preset *preset); @@ -91,33 +157,9 @@ struct Materials static const std::string& get_material_vendor(const Preset *preset); }; -struct Bundle -{ - std::unique_ptr preset_bundle; - VendorProfile *vendor_profile { nullptr }; - bool is_in_resources { false }; - bool is_prusa_bundle { false }; - - Bundle() = default; - Bundle(Bundle &&other); - - // Returns false if not loaded. Reason for that is logged as boost::log error. - bool load(fs::path source_path, bool is_in_resources, bool is_prusa_bundle = false); - - const std::string& vendor_id() const { return vendor_profile->id; } -}; - -struct BundleMap: std::unordered_map -{ - static BundleMap load(); - - Bundle& prusa_bundle(); - const Bundle& prusa_bundle() const; -}; struct PrinterPickerEvent; - // GUI elements typedef std::function ModelFilter; @@ -225,6 +267,7 @@ struct PagePrinters: ConfigWizardPage template struct DataList : public T { DataList(wxWindow *parent) : T(parent, wxID_ANY) {} + DataList(wxWindow* parent, int style) : T(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, style) {} // Note: We're _not_ using wxLB_SORT here because it doesn't do the right thing, // eg. "ABS" is sorted before "(All)" @@ -252,6 +295,25 @@ template struct DataList : public T } int size() { return this->GetCount(); } + + void on_mouse_move(const wxPoint& position) { + int item = T::HitTest(position); + + if(item == wxHitTest::wxHT_WINDOW_INSIDE) + BOOST_LOG_TRIVIAL(error) << "hit test wxHT_WINDOW_INSIDE"; + else if (item == wxHitTest::wxHT_WINDOW_OUTSIDE) + BOOST_LOG_TRIVIAL(error) << "hit test wxHT_WINDOW_OUTSIDE"; + else if(item == wxHitTest::wxHT_WINDOW_CORNER) + BOOST_LOG_TRIVIAL(error) << "hit test wxHT_WINDOW_CORNER"; + else if (item == wxHitTest::wxHT_WINDOW_VERT_SCROLLBAR) + BOOST_LOG_TRIVIAL(error) << "hit test wxHT_WINDOW_VERT_SCROLLBAR"; + else if (item == wxHitTest::wxHT_NOWHERE) + BOOST_LOG_TRIVIAL(error) << "hit test wxHT_NOWHERE"; + else if (item == wxHitTest::wxHT_MAX) + BOOST_LOG_TRIVIAL(error) << "hit test wxHT_MAX"; + else + BOOST_LOG_TRIVIAL(error) << "hit test: " << item; + } }; typedef DataList StringList; @@ -260,21 +322,35 @@ typedef DataList PresetList; struct PageMaterials: ConfigWizardPage { Materials *materials; - StringList *list_l1, *list_l2; - PresetList *list_l3; - int sel1_prev, sel2_prev; + StringList *list_printer, *list_type, *list_vendor; + PresetList *list_profile; + int sel_printer_prev, sel_type_prev, sel_vendor_prev; bool presets_loaded; + wxFlexGridSizer *grid; + wxStaticText *compatible_printers; + int compatible_printers_width = { 100 }; + std::string empty_printers_label; + bool first_paint = { false }; static const std::string EMPTY; + int last_hovered_item = { -1 } ; PageMaterials(ConfigWizard *parent, Materials *materials, wxString title, wxString shortname, wxString list1name); void reload_presets(); - void update_lists(int sel1, int sel2); + void update_lists(int sel1, int sel2, int sel3); + void on_material_highlighted(int sel_material); + void on_material_hovered(int sel_material); void select_material(int i); void select_all(bool select); void clear(); + void prepare_compatible_printers_label(); + void clear_compatible_printers_label(); + void on_paint(); + void on_mouse_move_on_profiles(wxMouseEvent& evt); + void on_mouse_enter_profiles(wxMouseEvent& evt); + void on_mouse_leave_profiles(wxMouseEvent& evt); virtual void on_activate() override; }; From 1eef1d32a08bf12c99d088d2783fcfe53d8a70bc Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 1 Sep 2020 18:04:56 +0200 Subject: [PATCH 244/255] Added two missing includes to fix build on gcc --- src/libslic3r/GCode/GCodeProcessor.cpp | 1 + src/slic3r/GUI/GLShader.hpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 54addbd979..13b1ed1a8d 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include diff --git a/src/slic3r/GUI/GLShader.hpp b/src/slic3r/GUI/GLShader.hpp index a1160f8e98..84fdf5ebad 100644 --- a/src/slic3r/GUI/GLShader.hpp +++ b/src/slic3r/GUI/GLShader.hpp @@ -4,6 +4,8 @@ #include #include +#include "libslic3r/Point.hpp" + namespace Slic3r { class GLShaderProgram From 761e71eb634e3af52da6b5ee3cb0f06e96d4892a Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 18 Aug 2020 13:45:18 +0200 Subject: [PATCH 245/255] Fix build on msvc --- src/libslic3r/Point.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/Point.hpp b/src/libslic3r/Point.hpp index 84010c7eb1..30a1a4942c 100644 --- a/src/libslic3r/Point.hpp +++ b/src/libslic3r/Point.hpp @@ -88,7 +88,7 @@ inline std::string to_string(const Vec3d &pt) { return std::string("[") + std: std::vector transform(const std::vector& points, const Transform3f& t); Pointf3s transform(const Pointf3s& points, const Transform3d& t); -template using Vec = Eigen::Matrix; +template using Vec = Eigen::Matrix; class Point : public Vec2crd { From 255469347f92a8342974fe4a61ee6cd04c6af3bd Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 19 Aug 2020 17:15:01 +0200 Subject: [PATCH 246/255] Fixed several indentation-related warnings --- src/libslic3r/PrintBase.hpp | 12 ++++++------ src/slic3r/GUI/Plater.cpp | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/libslic3r/PrintBase.hpp b/src/libslic3r/PrintBase.hpp index 5e94e011a7..647c24c1ce 100644 --- a/src/libslic3r/PrintBase.hpp +++ b/src/libslic3r/PrintBase.hpp @@ -507,9 +507,9 @@ protected: bool set_started(PrintStepEnum step) { return m_state.set_started(step, this->state_mutex(), [this](){ this->throw_if_canceled(); }); } PrintStateBase::TimeStamp set_done(PrintStepEnum step) { std::pair status = m_state.set_done(step, this->state_mutex(), [this](){ this->throw_if_canceled(); }); - if (status.second) - this->status_update_warnings(this->id(), static_cast(step), PrintStateBase::WarningLevel::NON_CRITICAL, std::string()); - return status.first; + if (status.second) + this->status_update_warnings(this->id(), static_cast(step), PrintStateBase::WarningLevel::NON_CRITICAL, std::string()); + return status.first; } bool invalidate_step(PrintStepEnum step) { return m_state.invalidate(step, this->cancel_callback()); } @@ -556,9 +556,9 @@ protected: { return m_state.set_started(step, PrintObjectBase::state_mutex(m_print), [this](){ this->throw_if_canceled(); }); } PrintStateBase::TimeStamp set_done(PrintObjectStepEnum step) { std::pair status = m_state.set_done(step, PrintObjectBase::state_mutex(m_print), [this](){ this->throw_if_canceled(); }); - if (status.second) - this->status_update_warnings(m_print, static_cast(step), PrintStateBase::WarningLevel::NON_CRITICAL, std::string()); - return status.first; + if (status.second) + this->status_update_warnings(m_print, static_cast(step), PrintStateBase::WarningLevel::NON_CRITICAL, std::string()); + return status.first; } bool invalidate_step(PrintObjectStepEnum step) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 2c330b60e6..027611750a 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2841,7 +2841,7 @@ void Plater::priv::export_gcode(fs::path output_path, bool output_path_on_remova if ((state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) != 0) return; - show_warning_dialog = true; + show_warning_dialog = true; if (! output_path.empty()) { background_process.schedule_export(output_path.string(), output_path_on_removable_media); } else { @@ -4697,8 +4697,8 @@ void Plater::export_gcode(bool prefer_removable) if (p->model.objects.empty()) return; - if (p->process_completed_with_error)//here - return; + if (p->process_completed_with_error)//here + return; // If possible, remove accents from accented latin characters. // This function is useful for generating file names to be processed by legacy firmwares. From d3e7684a5a47e34cb2cf94f194b75158bfe07068 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 18 Aug 2020 15:17:26 +0200 Subject: [PATCH 247/255] Forbid translation of objects when SLA/Hollow/FDM gizmos are active --- src/slic3r/GUI/GLCanvas3D.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 9bed5fde7c..94f6f6ef32 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3658,6 +3658,13 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) { m_mouse.dragging = true; + // Translation of objects is forbidden when SLA supports/hollowing/fdm + // supports gizmo is active. + if (m_gizmos.get_current_type() == GLGizmosManager::SlaSupports + || m_gizmos.get_current_type() == GLGizmosManager::FdmSupports + || m_gizmos.get_current_type() == GLGizmosManager::Hollow) + return; + Vec3d cur_pos = m_mouse.drag.start_position_3D; // we do not want to translate objects if the user just clicked on an object while pressing shift to remove it from the selection and then drag if (m_selection.contains_volume(get_first_hover_volume_idx())) From 223eb6933c602a1c01fc2c14f3092504b05858f8 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 18 Aug 2020 15:18:00 +0200 Subject: [PATCH 248/255] TriangleSelector paints continuously when dragging fast Previously there would be distinct circles with gaps in between --- src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp | 195 +++++++++++-------- src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp | 1 + 2 files changed, 110 insertions(+), 86 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index f3b6db4f26..62854ab465 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -314,106 +314,128 @@ bool GLGizmoFdmSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous const ModelInstance* mi = mo->instances[selection.get_instance_idx()]; const Transform3d& instance_trafo = mi->get_transformation().get_matrix(); - std::vector>> hit_positions_and_facet_ids; - bool clipped_mesh_was_hit = false; + // List of mouse positions that will be used as seeds for painting. + std::vector mouse_positions{mouse_position}; - Vec3f normal = Vec3f::Zero(); - Vec3f hit = Vec3f::Zero(); - size_t facet = 0; - Vec3f closest_hit = Vec3f::Zero(); - double closest_hit_squared_distance = std::numeric_limits::max(); - size_t closest_facet = 0; - int closest_hit_mesh_id = -1; + // In case current mouse position is far from the last one, + // add several positions from between into the list, so there + // are no gaps in the painted region. + { + if (m_last_mouse_position == Vec2d::Zero()) + m_last_mouse_position = mouse_position; + // resolution describes minimal distance limit using circle radius + // as a unit (e.g., 2 would mean the patches will be touching). + double resolution = 0.7; + double diameter_px = resolution * m_cursor_radius * camera.get_zoom(); + int patches_in_between = int(((mouse_position - m_last_mouse_position).norm() - diameter_px) / diameter_px); + if (patches_in_between > 0) { + Vec2d diff = (mouse_position - m_last_mouse_position)/(patches_in_between+1); + for (int i=1; i<=patches_in_between; ++i) + mouse_positions.emplace_back(m_last_mouse_position + i*diff); + } + } + m_last_mouse_position = Vec2d::Zero(); // only actual hits should be saved - // Transformations of individual meshes - std::vector trafo_matrices; + // Now "click" into all the prepared points and spill paint around them. + for (const Vec2d& mp : mouse_positions) { + std::vector>> hit_positions_and_facet_ids; + bool clipped_mesh_was_hit = false; - int mesh_id = -1; - // Cast a ray on all meshes, pick the closest hit and save it for the respective mesh - for (const ModelVolume* mv : mo->volumes) { - if (! mv->is_model_part()) - continue; + Vec3f normal = Vec3f::Zero(); + Vec3f hit = Vec3f::Zero(); + size_t facet = 0; + Vec3f closest_hit = Vec3f::Zero(); + double closest_hit_squared_distance = std::numeric_limits::max(); + size_t closest_facet = 0; + int closest_hit_mesh_id = -1; - ++mesh_id; + // Transformations of individual meshes + std::vector trafo_matrices; - trafo_matrices.push_back(instance_trafo * mv->get_matrix()); - hit_positions_and_facet_ids.push_back(std::vector>()); - - if (m_c->raycaster()->raycasters()[mesh_id]->unproject_on_mesh( - mouse_position, - trafo_matrices[mesh_id], - camera, - hit, - normal, - m_clipping_plane.get(), - &facet)) - { - // In case this hit is clipped, skip it. - if (is_mesh_point_clipped(hit.cast())) { - clipped_mesh_was_hit = true; + int mesh_id = -1; + // Cast a ray on all meshes, pick the closest hit and save it for the respective mesh + for (const ModelVolume* mv : mo->volumes) { + if (! mv->is_model_part()) continue; - } - // Is this hit the closest to the camera so far? - double hit_squared_distance = (camera.get_position()-trafo_matrices[mesh_id]*hit.cast()).squaredNorm(); - if (hit_squared_distance < closest_hit_squared_distance) { - closest_hit_squared_distance = hit_squared_distance; - closest_facet = facet; - closest_hit_mesh_id = mesh_id; - closest_hit = hit; + ++mesh_id; + + trafo_matrices.push_back(instance_trafo * mv->get_matrix()); + hit_positions_and_facet_ids.push_back(std::vector>()); + + if (m_c->raycaster()->raycasters()[mesh_id]->unproject_on_mesh( + mp, + trafo_matrices[mesh_id], + camera, + hit, + normal, + m_clipping_plane.get(), + &facet)) + { + // In case this hit is clipped, skip it. + if (is_mesh_point_clipped(hit.cast())) { + clipped_mesh_was_hit = true; + continue; + } + + // Is this hit the closest to the camera so far? + double hit_squared_distance = (camera.get_position()-trafo_matrices[mesh_id]*hit.cast()).squaredNorm(); + if (hit_squared_distance < closest_hit_squared_distance) { + closest_hit_squared_distance = hit_squared_distance; + closest_facet = facet; + closest_hit_mesh_id = mesh_id; + closest_hit = hit; + } } } - } - bool dragging_while_painting = (action == SLAGizmoEventType::Dragging && m_button_down != Button::None); + bool dragging_while_painting = (action == SLAGizmoEventType::Dragging && m_button_down != Button::None); - // The mouse button click detection is enabled when there is a valid hit - // or when the user clicks the clipping plane. Missing the object entirely - // shall not capture the mouse. - if (closest_hit_mesh_id != -1 || clipped_mesh_was_hit) { - if (m_button_down == Button::None) - m_button_down = ((action == SLAGizmoEventType::LeftDown) ? Button::Left : Button::Right); - } - - if (closest_hit_mesh_id == -1) { - // In case we have no valid hit, we can return. The event will - // be stopped in following two cases: - // 1. clicking the clipping plane - // 2. dragging while painting (to prevent scene rotations and moving the object) - return clipped_mesh_was_hit - || dragging_while_painting; - } - - // Find respective mesh id. - // FIXME We need a separate TriangleSelector for each volume mesh. - mesh_id = -1; - //const TriangleMesh* mesh = nullptr; - for (const ModelVolume* mv : mo->volumes) { - if (! mv->is_model_part()) - continue; - ++mesh_id; - if (mesh_id == closest_hit_mesh_id) { - //mesh = &mv->mesh(); - break; + // The mouse button click detection is enabled when there is a valid hit + // or when the user clicks the clipping plane. Missing the object entirely + // shall not capture the mouse. + if (closest_hit_mesh_id != -1 || clipped_mesh_was_hit) { + if (m_button_down == Button::None) + m_button_down = ((action == SLAGizmoEventType::LeftDown) ? Button::Left : Button::Right); } + + if (closest_hit_mesh_id == -1) { + // In case we have no valid hit, we can return. The event will + // be stopped in following two cases: + // 1. clicking the clipping plane + // 2. dragging while painting (to prevent scene rotations and moving the object) + return clipped_mesh_was_hit + || dragging_while_painting; + } + + // Find respective mesh id. + mesh_id = -1; + for (const ModelVolume* mv : mo->volumes) { + if (! mv->is_model_part()) + continue; + ++mesh_id; + if (mesh_id == closest_hit_mesh_id) + break; + } + + const Transform3d& trafo_matrix = trafo_matrices[mesh_id]; + + // Calculate how far can a point be from the line (in mesh coords). + // FIXME: The scaling of the mesh can be non-uniform. + const Vec3d sf = Geometry::Transformation(trafo_matrix).get_scaling_factor(); + const float avg_scaling = (sf(0) + sf(1) + sf(2))/3.; + const float limit = m_cursor_radius/avg_scaling; + + // Calculate direction from camera to the hit (in mesh coords): + Vec3f camera_pos = (trafo_matrix.inverse() * camera.get_position()).cast(); + Vec3f dir = (closest_hit - camera_pos).normalized(); + + assert(mesh_id < int(m_triangle_selectors.size())); + m_triangle_selectors[mesh_id]->select_patch(closest_hit, closest_facet, camera_pos, + dir, limit, new_state); + m_last_mouse_position = mouse_position; } - const Transform3d& trafo_matrix = trafo_matrices[mesh_id]; - - // Calculate how far can a point be from the line (in mesh coords). - // FIXME: The scaling of the mesh can be non-uniform. - const Vec3d sf = Geometry::Transformation(trafo_matrix).get_scaling_factor(); - const float avg_scaling = (sf(0) + sf(1) + sf(2))/3.; - const float limit = m_cursor_radius/avg_scaling; - - // Calculate direction from camera to the hit (in mesh coords): - Vec3f camera_pos = (trafo_matrix.inverse() * camera.get_position()).cast(); - Vec3f dir = (closest_hit - camera_pos).normalized(); - - assert(mesh_id < int(m_triangle_selectors.size())); - m_triangle_selectors[mesh_id]->select_patch(closest_hit, closest_facet, camera_pos, - dir, limit, new_state); - return true; } @@ -430,6 +452,7 @@ bool GLGizmoFdmSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous update_model_object(); m_button_down = Button::None; + m_last_mouse_position = Vec2d::Zero(); return true; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp index e1dee373f2..c3f920e2f0 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp @@ -92,6 +92,7 @@ private: bool m_setting_angle = false; bool m_internal_stack_active = false; bool m_schedule_update = false; + Vec2d m_last_mouse_position = Vec2d::Zero(); // This map holds all translated description texts, so they can be easily referenced during layout calculations // etc. When language changes, GUI is recreated and this class constructed again, so the change takes effect. From 7a6531ede7bd7d2b60e777a76b93a529a3079d27 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Thu, 20 Aug 2020 16:35:56 +0200 Subject: [PATCH 249/255] Started work on separating FDM gizmo into base and child classes --- src/slic3r/CMakeLists.txt | 2 + src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp | 883 ------------------- src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp | 115 +-- src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp | 883 +++++++++++++++++++ src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp | 127 +++ 5 files changed, 1018 insertions(+), 992 deletions(-) create mode 100644 src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp create mode 100644 src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index f8598cea08..f1089ae935 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -51,6 +51,8 @@ set(SLIC3R_GUI_SOURCES GUI/Gizmos/GLGizmoCut.hpp GUI/Gizmos/GLGizmoHollow.cpp GUI/Gizmos/GLGizmoHollow.hpp + GUI/Gizmos/GLGizmoPainterBase.cpp + GUI/Gizmos/GLGizmoPainterBase.hpp GUI/GLSelectionRectangle.cpp GUI/GLSelectionRectangle.hpp GUI/GLTexture.hpp diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index 62854ab465..e69de29bb2 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -1,883 +0,0 @@ -// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro. -#include "GLGizmoFdmSupports.hpp" -#include "slic3r/GUI/GLCanvas3D.hpp" -#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp" - -#include - -#include "slic3r/GUI/GUI_App.hpp" -#include "slic3r/GUI/Camera.hpp" -#include "slic3r/GUI/Plater.hpp" -#include "libslic3r/PresetBundle.hpp" -#include "libslic3r/Model.hpp" - - - -namespace Slic3r { -namespace GUI { - - -GLGizmoFdmSupports::GLGizmoFdmSupports(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) - : GLGizmoBase(parent, icon_filename, sprite_id) - , m_quadric(nullptr) -{ - m_clipping_plane.reset(new ClippingPlane()); - m_quadric = ::gluNewQuadric(); - if (m_quadric != nullptr) - // using GLU_FILL does not work when the instance's transformation - // contains mirroring (normals are reverted) - ::gluQuadricDrawStyle(m_quadric, GLU_FILL); -} - -GLGizmoFdmSupports::~GLGizmoFdmSupports() -{ - if (m_quadric != nullptr) - ::gluDeleteQuadric(m_quadric); -} - -bool GLGizmoFdmSupports::on_init() -{ - m_shortcut_key = WXK_CONTROL_L; - - m_desc["clipping_of_view"] = _L("Clipping of view") + ": "; - m_desc["reset_direction"] = _L("Reset direction"); - m_desc["cursor_size"] = _L("Cursor size") + ": "; - m_desc["enforce_caption"] = _L("Left mouse button") + ": "; - m_desc["enforce"] = _L("Enforce supports"); - m_desc["block_caption"] = _L("Right mouse button") + " "; - m_desc["block"] = _L("Block supports"); - m_desc["remove_caption"] = _L("Shift + Left mouse button") + ": "; - m_desc["remove"] = _L("Remove selection"); - m_desc["remove_all"] = _L("Remove all selection"); - - return true; -} - - -void GLGizmoFdmSupports::activate_internal_undo_redo_stack(bool activate) -{ - if (activate && ! m_internal_stack_active) { - Plater::TakeSnapshot(wxGetApp().plater(), _L("FDM gizmo turned on")); - wxGetApp().plater()->enter_gizmos_stack(); - m_internal_stack_active = true; - } - if (! activate && m_internal_stack_active) { - wxGetApp().plater()->leave_gizmos_stack(); - Plater::TakeSnapshot(wxGetApp().plater(), _L("FDM gizmo turned off")); - m_internal_stack_active = false; - } -} - -void GLGizmoFdmSupports::set_fdm_support_data(ModelObject* model_object, const Selection& selection) -{ - if (m_state != On) - return; - - const ModelObject* mo = m_c->selection_info() ? m_c->selection_info()->model_object() : nullptr; - - if (mo && selection.is_from_single_instance() - && (m_schedule_update || mo->id() != m_old_mo_id || mo->volumes.size() != m_old_volumes_size)) - { - update_from_model_object(); - m_old_mo_id = mo->id(); - m_old_volumes_size = mo->volumes.size(); - m_schedule_update = false; - } -} - - - -void GLGizmoFdmSupports::on_render() const -{ - const Selection& selection = m_parent.get_selection(); - - glsafe(::glEnable(GL_BLEND)); - glsafe(::glEnable(GL_DEPTH_TEST)); - - render_triangles(selection); - - m_c->object_clipper()->render_cut(); - render_cursor_circle(); - - glsafe(::glDisable(GL_BLEND)); -} - -void GLGizmoFdmSupports::render_triangles(const Selection& selection) const -{ - if (m_setting_angle) - return; - - const ModelObject* mo = m_c->selection_info()->model_object(); - - glsafe(::glEnable(GL_POLYGON_OFFSET_FILL)); - ScopeGuard offset_fill_guard([]() { glsafe(::glDisable(GL_POLYGON_OFFSET_FILL)); } ); - glsafe(::glPolygonOffset(-1.0, 1.0)); - - // Take care of the clipping plane. The normal of the clipping plane is - // saved with opposite sign than we need to pass to OpenGL (FIXME) - bool clipping_plane_active = m_c->object_clipper()->get_position() != 0.; - if (clipping_plane_active) { - const ClippingPlane* clp = m_c->object_clipper()->get_clipping_plane(); - double clp_data[4]; - memcpy(clp_data, clp->get_data(), 4 * sizeof(double)); - for (int i=0; i<3; ++i) - clp_data[i] = -1. * clp_data[i]; - - glsafe(::glClipPlane(GL_CLIP_PLANE0, (GLdouble*)clp_data)); - glsafe(::glEnable(GL_CLIP_PLANE0)); - } - - int mesh_id = -1; - for (const ModelVolume* mv : mo->volumes) { - if (! mv->is_model_part()) - continue; - - ++mesh_id; - - const Transform3d trafo_matrix = - mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix() * - mv->get_matrix(); - - bool is_left_handed = trafo_matrix.matrix().determinant() < 0.; - if (is_left_handed) - glsafe(::glFrontFace(GL_CW)); - - glsafe(::glPushMatrix()); - glsafe(::glMultMatrixd(trafo_matrix.data())); - - if (! m_setting_angle) - m_triangle_selectors[mesh_id]->render(m_imgui); - - glsafe(::glPopMatrix()); - if (is_left_handed) - glsafe(::glFrontFace(GL_CCW)); - } - if (clipping_plane_active) - glsafe(::glDisable(GL_CLIP_PLANE0)); -} - - -void GLGizmoFdmSupports::render_cursor_circle() const -{ - const Camera& camera = wxGetApp().plater()->get_camera(); - float zoom = (float)camera.get_zoom(); - float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; - - Size cnv_size = m_parent.get_canvas_size(); - float cnv_half_width = 0.5f * (float)cnv_size.get_width(); - float cnv_half_height = 0.5f * (float)cnv_size.get_height(); - if ((cnv_half_width == 0.0f) || (cnv_half_height == 0.0f)) - return; - Vec2d mouse_pos(m_parent.get_local_mouse_position()(0), m_parent.get_local_mouse_position()(1)); - Vec2d center(mouse_pos(0) - cnv_half_width, cnv_half_height - mouse_pos(1)); - center = center * inv_zoom; - - glsafe(::glLineWidth(1.5f)); - float color[3]; - color[0] = 0.f; - color[1] = 1.f; - color[2] = 0.3f; - glsafe(::glColor3fv(color)); - glsafe(::glDisable(GL_DEPTH_TEST)); - - glsafe(::glPushMatrix()); - glsafe(::glLoadIdentity()); - // ensure that the circle is renderered inside the frustrum - glsafe(::glTranslated(0.0, 0.0, -(camera.get_near_z() + 0.5))); - // ensure that the overlay fits the frustrum near z plane - double gui_scale = camera.get_gui_scale(); - glsafe(::glScaled(gui_scale, gui_scale, 1.0)); - - glsafe(::glPushAttrib(GL_ENABLE_BIT)); - glsafe(::glLineStipple(4, 0xAAAA)); - glsafe(::glEnable(GL_LINE_STIPPLE)); - - ::glBegin(GL_LINE_LOOP); - for (double angle=0; angle<2*M_PI; angle+=M_PI/20.) - ::glVertex2f(GLfloat(center.x()+m_cursor_radius*cos(angle)), GLfloat(center.y()+m_cursor_radius*sin(angle))); - glsafe(::glEnd()); - - glsafe(::glPopAttrib()); - glsafe(::glPopMatrix()); -} - - -void GLGizmoFdmSupports::update_model_object() const -{ - bool updated = false; - ModelObject* mo = m_c->selection_info()->model_object(); - int idx = -1; - for (ModelVolume* mv : mo->volumes) { - if (! mv->is_model_part()) - continue; - ++idx; - updated |= mv->m_supported_facets.set(*m_triangle_selectors[idx].get()); - } - - if (updated) - m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); -} - - -void GLGizmoFdmSupports::update_from_model_object() -{ - wxBusyCursor wait; - - const ModelObject* mo = m_c->selection_info()->model_object(); - m_triangle_selectors.clear(); - - int volume_id = -1; - for (const ModelVolume* mv : mo->volumes) { - if (! mv->is_model_part()) - continue; - - ++volume_id; - - // This mesh does not account for the possible Z up SLA offset. - const TriangleMesh* mesh = &mv->mesh(); - - m_triangle_selectors.emplace_back(std::make_unique(*mesh)); - m_triangle_selectors.back()->deserialize(mv->m_supported_facets.get_data()); - } -} - - - -bool GLGizmoFdmSupports::is_mesh_point_clipped(const Vec3d& point) const -{ - if (m_c->object_clipper()->get_position() == 0.) - return false; - - auto sel_info = m_c->selection_info(); - int active_inst = m_c->selection_info()->get_active_instance(); - const ModelInstance* mi = sel_info->model_object()->instances[active_inst]; - const Transform3d& trafo = mi->get_transformation().get_matrix(); - - Vec3d transformed_point = trafo * point; - transformed_point(2) += sel_info->get_sla_shift(); - return m_c->object_clipper()->get_clipping_plane()->is_point_clipped(transformed_point); -} - - -// Following function is called from GLCanvas3D to inform the gizmo about a mouse/keyboard event. -// The gizmo has an opportunity to react - if it does, it should return true so that the Canvas3D is -// aware that the event was reacted to and stops trying to make different sense of it. If the gizmo -// concludes that the event was not intended for it, it should return false. -bool GLGizmoFdmSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down) -{ - if (action == SLAGizmoEventType::MouseWheelUp - || action == SLAGizmoEventType::MouseWheelDown) { - if (control_down) { - double pos = m_c->object_clipper()->get_position(); - pos = action == SLAGizmoEventType::MouseWheelDown - ? std::max(0., pos - 0.01) - : std::min(1., pos + 0.01); - m_c->object_clipper()->set_position(pos, true); - return true; - } - else if (alt_down) { - m_cursor_radius = action == SLAGizmoEventType::MouseWheelDown - ? std::max(m_cursor_radius - CursorRadiusStep, CursorRadiusMin) - : std::min(m_cursor_radius + CursorRadiusStep, CursorRadiusMax); - m_parent.set_as_dirty(); - return true; - } - } - - if (action == SLAGizmoEventType::ResetClippingPlane) { - m_c->object_clipper()->set_position(-1., false); - return true; - } - - if (action == SLAGizmoEventType::LeftDown - || action == SLAGizmoEventType::RightDown - || (action == SLAGizmoEventType::Dragging && m_button_down != Button::None)) { - - if (m_triangle_selectors.empty()) - return false; - - EnforcerBlockerType new_state = EnforcerBlockerType::NONE; - if (! shift_down) { - if (action == SLAGizmoEventType::Dragging) - new_state = m_button_down == Button::Left - ? EnforcerBlockerType::ENFORCER - : EnforcerBlockerType::BLOCKER; - else - new_state = action == SLAGizmoEventType::LeftDown - ? EnforcerBlockerType::ENFORCER - : EnforcerBlockerType::BLOCKER; - } - - const Camera& camera = wxGetApp().plater()->get_camera(); - const Selection& selection = m_parent.get_selection(); - const ModelObject* mo = m_c->selection_info()->model_object(); - const ModelInstance* mi = mo->instances[selection.get_instance_idx()]; - const Transform3d& instance_trafo = mi->get_transformation().get_matrix(); - - // List of mouse positions that will be used as seeds for painting. - std::vector mouse_positions{mouse_position}; - - // In case current mouse position is far from the last one, - // add several positions from between into the list, so there - // are no gaps in the painted region. - { - if (m_last_mouse_position == Vec2d::Zero()) - m_last_mouse_position = mouse_position; - // resolution describes minimal distance limit using circle radius - // as a unit (e.g., 2 would mean the patches will be touching). - double resolution = 0.7; - double diameter_px = resolution * m_cursor_radius * camera.get_zoom(); - int patches_in_between = int(((mouse_position - m_last_mouse_position).norm() - diameter_px) / diameter_px); - if (patches_in_between > 0) { - Vec2d diff = (mouse_position - m_last_mouse_position)/(patches_in_between+1); - for (int i=1; i<=patches_in_between; ++i) - mouse_positions.emplace_back(m_last_mouse_position + i*diff); - } - } - m_last_mouse_position = Vec2d::Zero(); // only actual hits should be saved - - // Now "click" into all the prepared points and spill paint around them. - for (const Vec2d& mp : mouse_positions) { - std::vector>> hit_positions_and_facet_ids; - bool clipped_mesh_was_hit = false; - - Vec3f normal = Vec3f::Zero(); - Vec3f hit = Vec3f::Zero(); - size_t facet = 0; - Vec3f closest_hit = Vec3f::Zero(); - double closest_hit_squared_distance = std::numeric_limits::max(); - size_t closest_facet = 0; - int closest_hit_mesh_id = -1; - - // Transformations of individual meshes - std::vector trafo_matrices; - - int mesh_id = -1; - // Cast a ray on all meshes, pick the closest hit and save it for the respective mesh - for (const ModelVolume* mv : mo->volumes) { - if (! mv->is_model_part()) - continue; - - ++mesh_id; - - trafo_matrices.push_back(instance_trafo * mv->get_matrix()); - hit_positions_and_facet_ids.push_back(std::vector>()); - - if (m_c->raycaster()->raycasters()[mesh_id]->unproject_on_mesh( - mp, - trafo_matrices[mesh_id], - camera, - hit, - normal, - m_clipping_plane.get(), - &facet)) - { - // In case this hit is clipped, skip it. - if (is_mesh_point_clipped(hit.cast())) { - clipped_mesh_was_hit = true; - continue; - } - - // Is this hit the closest to the camera so far? - double hit_squared_distance = (camera.get_position()-trafo_matrices[mesh_id]*hit.cast()).squaredNorm(); - if (hit_squared_distance < closest_hit_squared_distance) { - closest_hit_squared_distance = hit_squared_distance; - closest_facet = facet; - closest_hit_mesh_id = mesh_id; - closest_hit = hit; - } - } - } - - bool dragging_while_painting = (action == SLAGizmoEventType::Dragging && m_button_down != Button::None); - - // The mouse button click detection is enabled when there is a valid hit - // or when the user clicks the clipping plane. Missing the object entirely - // shall not capture the mouse. - if (closest_hit_mesh_id != -1 || clipped_mesh_was_hit) { - if (m_button_down == Button::None) - m_button_down = ((action == SLAGizmoEventType::LeftDown) ? Button::Left : Button::Right); - } - - if (closest_hit_mesh_id == -1) { - // In case we have no valid hit, we can return. The event will - // be stopped in following two cases: - // 1. clicking the clipping plane - // 2. dragging while painting (to prevent scene rotations and moving the object) - return clipped_mesh_was_hit - || dragging_while_painting; - } - - // Find respective mesh id. - mesh_id = -1; - for (const ModelVolume* mv : mo->volumes) { - if (! mv->is_model_part()) - continue; - ++mesh_id; - if (mesh_id == closest_hit_mesh_id) - break; - } - - const Transform3d& trafo_matrix = trafo_matrices[mesh_id]; - - // Calculate how far can a point be from the line (in mesh coords). - // FIXME: The scaling of the mesh can be non-uniform. - const Vec3d sf = Geometry::Transformation(trafo_matrix).get_scaling_factor(); - const float avg_scaling = (sf(0) + sf(1) + sf(2))/3.; - const float limit = m_cursor_radius/avg_scaling; - - // Calculate direction from camera to the hit (in mesh coords): - Vec3f camera_pos = (trafo_matrix.inverse() * camera.get_position()).cast(); - Vec3f dir = (closest_hit - camera_pos).normalized(); - - assert(mesh_id < int(m_triangle_selectors.size())); - m_triangle_selectors[mesh_id]->select_patch(closest_hit, closest_facet, camera_pos, - dir, limit, new_state); - m_last_mouse_position = mouse_position; - } - - return true; - } - - if ((action == SLAGizmoEventType::LeftUp || action == SLAGizmoEventType::RightUp) - && m_button_down != Button::None) { - // Take snapshot and update ModelVolume data. - wxString action_name = shift_down - ? _L("Remove selection") - : (m_button_down == Button::Left - ? _L("Add supports") - : _L("Block supports")); - activate_internal_undo_redo_stack(true); - Plater::TakeSnapshot(wxGetApp().plater(), action_name); - update_model_object(); - - m_button_down = Button::None; - m_last_mouse_position = Vec2d::Zero(); - return true; - } - - return false; -} - - - -void GLGizmoFdmSupports::select_facets_by_angle(float threshold_deg, bool block) -{ - float threshold = (M_PI/180.)*threshold_deg; - const Selection& selection = m_parent.get_selection(); - const ModelObject* mo = m_c->selection_info()->model_object(); - const ModelInstance* mi = mo->instances[selection.get_instance_idx()]; - - int mesh_id = -1; - for (const ModelVolume* mv : mo->volumes) { - if (! mv->is_model_part()) - continue; - - ++mesh_id; - - const Transform3d trafo_matrix = mi->get_matrix(true) * mv->get_matrix(true); - Vec3f down = (trafo_matrix.inverse() * (-Vec3d::UnitZ())).cast().normalized(); - Vec3f limit = (trafo_matrix.inverse() * Vec3d(std::sin(threshold), 0, -std::cos(threshold))).cast().normalized(); - - float dot_limit = limit.dot(down); - - // Now calculate dot product of vert_direction and facets' normals. - int idx = -1; - for (const stl_facet& facet : mv->mesh().stl.facet_start) { - ++idx; - if (facet.normal.dot(down) > dot_limit) - m_triangle_selectors[mesh_id]->set_facet(idx, - block - ? EnforcerBlockerType::BLOCKER - : EnforcerBlockerType::ENFORCER); - } - } - - activate_internal_undo_redo_stack(true); - - Plater::TakeSnapshot(wxGetApp().plater(), block ? _L("Block supports by angle") - : _L("Add supports by angle")); - update_model_object(); - m_parent.set_as_dirty(); - m_setting_angle = false; -} - - -void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_limit) -{ - if (! m_c->selection_info()->model_object()) - return; - - const float approx_height = m_imgui->scaled(18.0f); - y = std::min(y, bottom_limit - approx_height); - m_imgui->set_next_window_pos(x, y, ImGuiCond_Always); - - if (! m_setting_angle) { - m_imgui->begin(on_get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); - - // First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that: - const float clipping_slider_left = std::max(m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x, m_imgui->calc_text_size(m_desc.at("reset_direction")).x) + m_imgui->scaled(1.5f); - const float cursor_slider_left = m_imgui->calc_text_size(m_desc.at("cursor_size")).x + m_imgui->scaled(1.f); - const float button_width = m_imgui->calc_text_size(m_desc.at("remove_all")).x + m_imgui->scaled(1.f); - const float minimal_slider_width = m_imgui->scaled(4.f); - - float caption_max = 0.f; - float total_text_max = 0.; - for (const std::string& t : {"enforce", "block", "remove"}) { - caption_max = std::max(caption_max, m_imgui->calc_text_size(m_desc.at(t+"_caption")).x); - total_text_max = std::max(total_text_max, caption_max + m_imgui->calc_text_size(m_desc.at(t)).x); - } - caption_max += m_imgui->scaled(1.f); - total_text_max += m_imgui->scaled(1.f); - - float window_width = minimal_slider_width + std::max(cursor_slider_left, clipping_slider_left); - window_width = std::max(window_width, total_text_max); - window_width = std::max(window_width, button_width); - - auto draw_text_with_caption = [this, &caption_max](const wxString& caption, const wxString& text) { - static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); - m_imgui->text_colored(ORANGE, caption); - ImGui::SameLine(caption_max); - m_imgui->text(text); - }; - - for (const std::string& t : {"enforce", "block", "remove"}) - draw_text_with_caption(m_desc.at(t + "_caption"), m_desc.at(t)); - - m_imgui->text(""); - - if (m_imgui->button("Autoset by angle...")) { - m_setting_angle = true; - } - - ImGui::SameLine(); - - if (m_imgui->button(m_desc.at("remove_all"))) { - Plater::TakeSnapshot(wxGetApp().plater(), wxString(_L("Reset selection"))); - ModelObject* mo = m_c->selection_info()->model_object(); - int idx = -1; - for (ModelVolume* mv : mo->volumes) { - if (mv->is_model_part()) { - ++idx; - m_triangle_selectors[idx]->reset(); - } - } - update_model_object(); - m_parent.set_as_dirty(); - } - - const float max_tooltip_width = ImGui::GetFontSize() * 20.0f; - - m_imgui->text(m_desc.at("cursor_size")); - ImGui::SameLine(clipping_slider_left); - ImGui::PushItemWidth(window_width - clipping_slider_left); - ImGui::SliderFloat(" ", &m_cursor_radius, CursorRadiusMin, CursorRadiusMax, "%.2f"); - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip(); - ImGui::PushTextWrapPos(max_tooltip_width); - ImGui::TextUnformatted(_L("Alt + Mouse wheel").ToUTF8().data()); - ImGui::PopTextWrapPos(); - ImGui::EndTooltip(); - } - - ImGui::Separator(); - if (m_c->object_clipper()->get_position() == 0.f) - m_imgui->text(m_desc.at("clipping_of_view")); - else { - if (m_imgui->button(m_desc.at("reset_direction"))) { - wxGetApp().CallAfter([this](){ - m_c->object_clipper()->set_position(-1., false); - }); - } - } - - ImGui::SameLine(clipping_slider_left); - ImGui::PushItemWidth(window_width - clipping_slider_left); - float clp_dist = m_c->object_clipper()->get_position(); - if (ImGui::SliderFloat(" ", &clp_dist, 0.f, 1.f, "%.2f")) - m_c->object_clipper()->set_position(clp_dist, true); - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip(); - ImGui::PushTextWrapPos(max_tooltip_width); - ImGui::TextUnformatted(_L("Ctrl + Mouse wheel").ToUTF8().data()); - ImGui::PopTextWrapPos(); - ImGui::EndTooltip(); - } - - m_imgui->end(); - if (m_setting_angle) { - m_parent.show_slope(false); - m_parent.set_slope_range({90.f - m_angle_threshold_deg, 90.f - m_angle_threshold_deg}); - m_parent.use_slope(true); - m_parent.set_as_dirty(); - } - } - else { - std::string name = "Autoset custom supports"; - m_imgui->begin(wxString(name), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); - m_imgui->text("Threshold:"); - ImGui::SameLine(); - if (m_imgui->slider_float("", &m_angle_threshold_deg, 0.f, 90.f, "%.f")) - m_parent.set_slope_range({90.f - m_angle_threshold_deg, 90.f - m_angle_threshold_deg}); - if (m_imgui->button("Enforce")) - select_facets_by_angle(m_angle_threshold_deg, false); - ImGui::SameLine(); - if (m_imgui->button("Block")) - select_facets_by_angle(m_angle_threshold_deg, true); - ImGui::SameLine(); - if (m_imgui->button("Cancel")) - m_setting_angle = false; - m_imgui->end(); - if (! m_setting_angle) { - m_parent.use_slope(false); - m_parent.set_as_dirty(); - } - } -} - -bool GLGizmoFdmSupports::on_is_activable() const -{ - const Selection& selection = m_parent.get_selection(); - - if (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptFFF - || !selection.is_single_full_instance()) - return false; - - // Check that none of the selected volumes is outside. Only SLA auxiliaries (supports) are allowed outside. - const Selection::IndicesList& list = selection.get_volume_idxs(); - for (const auto& idx : list) - if (selection.get_volume(idx)->is_outside) - return false; - - return true; -} - -bool GLGizmoFdmSupports::on_is_selectable() const -{ - return (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptFFF - && wxGetApp().get_mode() != comSimple ); -} - -std::string GLGizmoFdmSupports::on_get_name() const -{ - return (_(L("FDM Support Editing")) + " [L]").ToUTF8().data(); -} - - -CommonGizmosDataID GLGizmoFdmSupports::on_get_requirements() const -{ - return CommonGizmosDataID( - int(CommonGizmosDataID::SelectionInfo) - | int(CommonGizmosDataID::InstancesHider) - | int(CommonGizmosDataID::Raycaster) - | int(CommonGizmosDataID::ObjectClipper)); -} - - -void GLGizmoFdmSupports::on_set_state() -{ - if (m_state == m_old_state) - return; - - if (m_state == On && m_old_state != On) { // the gizmo was just turned on - if (! m_parent.get_gizmos_manager().is_serializing()) { - wxGetApp().CallAfter([this]() { - activate_internal_undo_redo_stack(true); - }); - } - } - if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off - // we are actually shutting down - if (m_setting_angle) { - m_setting_angle = false; - m_parent.use_slope(false); - } - activate_internal_undo_redo_stack(false); - m_old_mo_id = -1; - //m_iva.release_geometry(); - m_triangle_selectors.clear(); - } - m_old_state = m_state; -} - - - -void GLGizmoFdmSupports::on_start_dragging() -{ - -} - - -void GLGizmoFdmSupports::on_stop_dragging() -{ - -} - - - -void GLGizmoFdmSupports::on_load(cereal::BinaryInputArchive&) -{ - // We should update the gizmo from current ModelObject, but it is not - // possible at this point. That would require having updated selection and - // common gizmos data, which is not done at this point. Instead, save - // a flag to do the update in set_fdm_support_data, which will be called - // soon after. - m_schedule_update = true; -} - - - -void GLGizmoFdmSupports::on_save(cereal::BinaryOutputArchive&) const -{ - -} - - -void TriangleSelectorGUI::render(ImGuiWrapper* imgui) -{ - int enf_cnt = 0; - int blc_cnt = 0; - - m_iva_enforcers.release_geometry(); - m_iva_blockers.release_geometry(); - - for (const Triangle& tr : m_triangles) { - if (! tr.valid || tr.is_split() || tr.get_state() == EnforcerBlockerType::NONE) - continue; - - GLIndexedVertexArray& va = tr.get_state() == EnforcerBlockerType::ENFORCER - ? m_iva_enforcers - : m_iva_blockers; - int& cnt = tr.get_state() == EnforcerBlockerType::ENFORCER - ? enf_cnt - : blc_cnt; - - for (int i=0; i<3; ++i) - va.push_geometry(double(m_vertices[tr.verts_idxs[i]].v[0]), - double(m_vertices[tr.verts_idxs[i]].v[1]), - double(m_vertices[tr.verts_idxs[i]].v[2]), - 0., 0., 1.); - va.push_triangle(cnt, - cnt+1, - cnt+2); - cnt += 3; - } - - m_iva_enforcers.finalize_geometry(true); - m_iva_blockers.finalize_geometry(true); - - if (m_iva_enforcers.has_VBOs()) { - ::glColor4f(0.f, 0.f, 1.f, 0.2f); - m_iva_enforcers.render(); - } - - - if (m_iva_blockers.has_VBOs()) { - ::glColor4f(1.f, 0.f, 0.f, 0.2f); - m_iva_blockers.render(); - } - - -#ifdef PRUSASLICER_TRIANGLE_SELECTOR_DEBUG - if (imgui) - render_debug(imgui); - else - assert(false); // If you want debug output, pass ptr to ImGuiWrapper. -#endif -} - - - -#ifdef PRUSASLICER_TRIANGLE_SELECTOR_DEBUG -void TriangleSelectorGUI::render_debug(ImGuiWrapper* imgui) -{ - imgui->begin(std::string("TriangleSelector dialog (DEV ONLY)"), - ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); - static float edge_limit = 1.f; - imgui->text("Edge limit (mm): "); - imgui->slider_float("", &edge_limit, 0.1f, 8.f); - set_edge_limit(edge_limit); - imgui->checkbox("Show split triangles: ", m_show_triangles); - imgui->checkbox("Show invalid triangles: ", m_show_invalid); - - int valid_triangles = m_triangles.size() - m_invalid_triangles; - imgui->text("Valid triangles: " + std::to_string(valid_triangles) + - "/" + std::to_string(m_triangles.size())); - imgui->text("Vertices: " + std::to_string(m_vertices.size())); - if (imgui->button("Force garbage collection")) - garbage_collect(); - - if (imgui->button("Serialize - deserialize")) { - auto map = serialize(); - deserialize(map); - } - - imgui->end(); - - if (! m_show_triangles) - return; - - enum vtype { - ORIGINAL = 0, - SPLIT, - INVALID - }; - - for (auto& va : m_varrays) - va.release_geometry(); - - std::array cnts; - - ::glScalef(1.01f, 1.01f, 1.01f); - - for (int tr_id=0; tr_idpush_geometry(double(m_vertices[tr.verts_idxs[i]].v[0]), - double(m_vertices[tr.verts_idxs[i]].v[1]), - double(m_vertices[tr.verts_idxs[i]].v[2]), - 0., 0., 1.); - va->push_triangle(*cnt, - *cnt+1, - *cnt+2); - *cnt += 3; - } - - ::glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); - for (vtype i : {ORIGINAL, SPLIT, INVALID}) { - GLIndexedVertexArray& va = m_varrays[i]; - va.finalize_geometry(true); - if (va.has_VBOs()) { - switch (i) { - case ORIGINAL : ::glColor3f(0.f, 0.f, 1.f); break; - case SPLIT : ::glColor3f(1.f, 0.f, 0.f); break; - case INVALID : ::glColor3f(1.f, 1.f, 0.f); break; - } - va.render(); - } - } - ::glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); -} -#endif - - - -} // namespace GUI -} // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp index c3f920e2f0..196a21bc03 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp @@ -1,127 +1,24 @@ #ifndef slic3r_GLGizmoFdmSupports_hpp_ #define slic3r_GLGizmoFdmSupports_hpp_ -#include "GLGizmoBase.hpp" - -#include "slic3r/GUI/3DScene.hpp" - -#include "libslic3r/ObjectID.hpp" -#include "libslic3r/TriangleSelector.hpp" - -#include - - - +#include "GLGizmoPainterBase.hpp" namespace Slic3r { -enum class EnforcerBlockerType : int8_t; - namespace GUI { -enum class SLAGizmoEventType : unsigned char; -class ClippingPlane; - - - -class TriangleSelectorGUI : public TriangleSelector { -public: - explicit TriangleSelectorGUI(const TriangleMesh& mesh) - : TriangleSelector(mesh) {} - - // Render current selection. Transformation matrices are supposed - // to be already set. - void render(ImGuiWrapper* imgui = nullptr); - -#ifdef PRUSASLICER_TRIANGLE_SELECTOR_DEBUG - void render_debug(ImGuiWrapper* imgui); - bool m_show_triangles{false}; - bool m_show_invalid{false}; -#endif - -private: - GLIndexedVertexArray m_iva_enforcers; - GLIndexedVertexArray m_iva_blockers; - std::array m_varrays; -}; - - - -class GLGizmoFdmSupports : public GLGizmoBase +class GLGizmoFdmSupports : public GLGizmoPainterBase { -private: - ObjectID m_old_mo_id; - size_t m_old_volumes_size = 0; - - GLUquadricObj* m_quadric; - - float m_cursor_radius = 2.f; - static constexpr float CursorRadiusMin = 0.4f; // cannot be zero - static constexpr float CursorRadiusMax = 8.f; - static constexpr float CursorRadiusStep = 0.2f; - - // For each model-part volume, store status and division of the triangles. - std::vector> m_triangle_selectors; - public: - GLGizmoFdmSupports(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); - ~GLGizmoFdmSupports() override; - void set_fdm_support_data(ModelObject* model_object, const Selection& selection); - bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down); + GLGizmoFdmSupports(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) + : GLGizmoPainterBase(parent, icon_filename, sprite_id) {} - -private: - bool on_init() override; - void on_render() const override; - void on_render_for_picking() const override {} - - void render_triangles(const Selection& selection) const; - void render_cursor_circle() const; - - void update_model_object() const; - void update_from_model_object(); - void activate_internal_undo_redo_stack(bool activate); - - void select_facets_by_angle(float threshold, bool block); - float m_angle_threshold_deg = 45.f; - - bool is_mesh_point_clipped(const Vec3d& point) const; - - float m_clipping_plane_distance = 0.f; - std::unique_ptr m_clipping_plane; - bool m_setting_angle = false; - bool m_internal_stack_active = false; - bool m_schedule_update = false; - Vec2d m_last_mouse_position = Vec2d::Zero(); - - // This map holds all translated description texts, so they can be easily referenced during layout calculations - // etc. When language changes, GUI is recreated and this class constructed again, so the change takes effect. - std::map m_desc; - - enum class Button { - None, - Left, - Right - }; - - Button m_button_down = Button::None; - EState m_old_state = Off; // to be able to see that the gizmo has just been closed (see on_set_state) - -protected: - void on_set_state() override; - void on_start_dragging() override; - void on_stop_dragging() override; - void on_render_input_window(float x, float y, float bottom_limit) override; - std::string on_get_name() const override; - bool on_is_activable() const override; - bool on_is_selectable() const override; - void on_load(cereal::BinaryInputArchive& ar) override; - void on_save(cereal::BinaryOutputArchive& ar) const override; - CommonGizmosDataID on_get_requirements() const override; }; + } // namespace GUI } // namespace Slic3r + #endif // slic3r_GLGizmoFdmSupports_hpp_ diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp new file mode 100644 index 0000000000..37792a48e0 --- /dev/null +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp @@ -0,0 +1,883 @@ +// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro. +#include "GLGizmoPainterBase.hpp" +#include "slic3r/GUI/GLCanvas3D.hpp" +#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp" + +#include + +#include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/Camera.hpp" +#include "slic3r/GUI/Plater.hpp" +#include "libslic3r/PresetBundle.hpp" +#include "libslic3r/Model.hpp" + + + +namespace Slic3r { +namespace GUI { + + +GLGizmoPainterBase::GLGizmoPainterBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) + : GLGizmoBase(parent, icon_filename, sprite_id) + , m_quadric(nullptr) +{ + m_clipping_plane.reset(new ClippingPlane()); + m_quadric = ::gluNewQuadric(); + if (m_quadric != nullptr) + // using GLU_FILL does not work when the instance's transformation + // contains mirroring (normals are reverted) + ::gluQuadricDrawStyle(m_quadric, GLU_FILL); +} + +GLGizmoPainterBase::~GLGizmoPainterBase() +{ + if (m_quadric != nullptr) + ::gluDeleteQuadric(m_quadric); +} + +bool GLGizmoPainterBase::on_init() +{ + m_shortcut_key = WXK_CONTROL_L; + + m_desc["clipping_of_view"] = _L("Clipping of view") + ": "; + m_desc["reset_direction"] = _L("Reset direction"); + m_desc["cursor_size"] = _L("Cursor size") + ": "; + m_desc["enforce_caption"] = _L("Left mouse button") + ": "; + m_desc["enforce"] = _L("Enforce supports"); + m_desc["block_caption"] = _L("Right mouse button") + " "; + m_desc["block"] = _L("Block supports"); + m_desc["remove_caption"] = _L("Shift + Left mouse button") + ": "; + m_desc["remove"] = _L("Remove selection"); + m_desc["remove_all"] = _L("Remove all selection"); + + return true; +} + + +void GLGizmoPainterBase::activate_internal_undo_redo_stack(bool activate) +{ + if (activate && ! m_internal_stack_active) { + Plater::TakeSnapshot(wxGetApp().plater(), _L("FDM gizmo turned on")); + wxGetApp().plater()->enter_gizmos_stack(); + m_internal_stack_active = true; + } + if (! activate && m_internal_stack_active) { + wxGetApp().plater()->leave_gizmos_stack(); + Plater::TakeSnapshot(wxGetApp().plater(), _L("FDM gizmo turned off")); + m_internal_stack_active = false; + } +} + +void GLGizmoPainterBase::set_fdm_support_data(ModelObject* model_object, const Selection& selection) +{ + if (m_state != On) + return; + + const ModelObject* mo = m_c->selection_info() ? m_c->selection_info()->model_object() : nullptr; + + if (mo && selection.is_from_single_instance() + && (m_schedule_update || mo->id() != m_old_mo_id || mo->volumes.size() != m_old_volumes_size)) + { + update_from_model_object(); + m_old_mo_id = mo->id(); + m_old_volumes_size = mo->volumes.size(); + m_schedule_update = false; + } +} + + + +void GLGizmoPainterBase::on_render() const +{ + const Selection& selection = m_parent.get_selection(); + + glsafe(::glEnable(GL_BLEND)); + glsafe(::glEnable(GL_DEPTH_TEST)); + + render_triangles(selection); + + m_c->object_clipper()->render_cut(); + render_cursor_circle(); + + glsafe(::glDisable(GL_BLEND)); +} + +void GLGizmoPainterBase::render_triangles(const Selection& selection) const +{ + if (m_setting_angle) + return; + + const ModelObject* mo = m_c->selection_info()->model_object(); + + glsafe(::glEnable(GL_POLYGON_OFFSET_FILL)); + ScopeGuard offset_fill_guard([]() { glsafe(::glDisable(GL_POLYGON_OFFSET_FILL)); } ); + glsafe(::glPolygonOffset(-1.0, 1.0)); + + // Take care of the clipping plane. The normal of the clipping plane is + // saved with opposite sign than we need to pass to OpenGL (FIXME) + bool clipping_plane_active = m_c->object_clipper()->get_position() != 0.; + if (clipping_plane_active) { + const ClippingPlane* clp = m_c->object_clipper()->get_clipping_plane(); + double clp_data[4]; + memcpy(clp_data, clp->get_data(), 4 * sizeof(double)); + for (int i=0; i<3; ++i) + clp_data[i] = -1. * clp_data[i]; + + glsafe(::glClipPlane(GL_CLIP_PLANE0, (GLdouble*)clp_data)); + glsafe(::glEnable(GL_CLIP_PLANE0)); + } + + int mesh_id = -1; + for (const ModelVolume* mv : mo->volumes) { + if (! mv->is_model_part()) + continue; + + ++mesh_id; + + const Transform3d trafo_matrix = + mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix() * + mv->get_matrix(); + + bool is_left_handed = trafo_matrix.matrix().determinant() < 0.; + if (is_left_handed) + glsafe(::glFrontFace(GL_CW)); + + glsafe(::glPushMatrix()); + glsafe(::glMultMatrixd(trafo_matrix.data())); + + if (! m_setting_angle) + m_triangle_selectors[mesh_id]->render(m_imgui); + + glsafe(::glPopMatrix()); + if (is_left_handed) + glsafe(::glFrontFace(GL_CCW)); + } + if (clipping_plane_active) + glsafe(::glDisable(GL_CLIP_PLANE0)); +} + + +void GLGizmoPainterBase::render_cursor_circle() const +{ + const Camera& camera = wxGetApp().plater()->get_camera(); + float zoom = (float)camera.get_zoom(); + float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; + + Size cnv_size = m_parent.get_canvas_size(); + float cnv_half_width = 0.5f * (float)cnv_size.get_width(); + float cnv_half_height = 0.5f * (float)cnv_size.get_height(); + if ((cnv_half_width == 0.0f) || (cnv_half_height == 0.0f)) + return; + Vec2d mouse_pos(m_parent.get_local_mouse_position()(0), m_parent.get_local_mouse_position()(1)); + Vec2d center(mouse_pos(0) - cnv_half_width, cnv_half_height - mouse_pos(1)); + center = center * inv_zoom; + + glsafe(::glLineWidth(1.5f)); + float color[3]; + color[0] = 0.f; + color[1] = 1.f; + color[2] = 0.3f; + glsafe(::glColor3fv(color)); + glsafe(::glDisable(GL_DEPTH_TEST)); + + glsafe(::glPushMatrix()); + glsafe(::glLoadIdentity()); + // ensure that the circle is renderered inside the frustrum + glsafe(::glTranslated(0.0, 0.0, -(camera.get_near_z() + 0.5))); + // ensure that the overlay fits the frustrum near z plane + double gui_scale = camera.get_gui_scale(); + glsafe(::glScaled(gui_scale, gui_scale, 1.0)); + + glsafe(::glPushAttrib(GL_ENABLE_BIT)); + glsafe(::glLineStipple(4, 0xAAAA)); + glsafe(::glEnable(GL_LINE_STIPPLE)); + + ::glBegin(GL_LINE_LOOP); + for (double angle=0; angle<2*M_PI; angle+=M_PI/20.) + ::glVertex2f(GLfloat(center.x()+m_cursor_radius*cos(angle)), GLfloat(center.y()+m_cursor_radius*sin(angle))); + glsafe(::glEnd()); + + glsafe(::glPopAttrib()); + glsafe(::glPopMatrix()); +} + + +void GLGizmoPainterBase::update_model_object() const +{ + bool updated = false; + ModelObject* mo = m_c->selection_info()->model_object(); + int idx = -1; + for (ModelVolume* mv : mo->volumes) { + if (! mv->is_model_part()) + continue; + ++idx; + updated |= mv->m_supported_facets.set(*m_triangle_selectors[idx].get()); + } + + if (updated) + m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); +} + + +void GLGizmoPainterBase::update_from_model_object() +{ + wxBusyCursor wait; + + const ModelObject* mo = m_c->selection_info()->model_object(); + m_triangle_selectors.clear(); + + int volume_id = -1; + for (const ModelVolume* mv : mo->volumes) { + if (! mv->is_model_part()) + continue; + + ++volume_id; + + // This mesh does not account for the possible Z up SLA offset. + const TriangleMesh* mesh = &mv->mesh(); + + m_triangle_selectors.emplace_back(std::make_unique(*mesh)); + m_triangle_selectors.back()->deserialize(mv->m_supported_facets.get_data()); + } +} + + + +bool GLGizmoPainterBase::is_mesh_point_clipped(const Vec3d& point) const +{ + if (m_c->object_clipper()->get_position() == 0.) + return false; + + auto sel_info = m_c->selection_info(); + int active_inst = m_c->selection_info()->get_active_instance(); + const ModelInstance* mi = sel_info->model_object()->instances[active_inst]; + const Transform3d& trafo = mi->get_transformation().get_matrix(); + + Vec3d transformed_point = trafo * point; + transformed_point(2) += sel_info->get_sla_shift(); + return m_c->object_clipper()->get_clipping_plane()->is_point_clipped(transformed_point); +} + + +// Following function is called from GLCanvas3D to inform the gizmo about a mouse/keyboard event. +// The gizmo has an opportunity to react - if it does, it should return true so that the Canvas3D is +// aware that the event was reacted to and stops trying to make different sense of it. If the gizmo +// concludes that the event was not intended for it, it should return false. +bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down) +{ + if (action == SLAGizmoEventType::MouseWheelUp + || action == SLAGizmoEventType::MouseWheelDown) { + if (control_down) { + double pos = m_c->object_clipper()->get_position(); + pos = action == SLAGizmoEventType::MouseWheelDown + ? std::max(0., pos - 0.01) + : std::min(1., pos + 0.01); + m_c->object_clipper()->set_position(pos, true); + return true; + } + else if (alt_down) { + m_cursor_radius = action == SLAGizmoEventType::MouseWheelDown + ? std::max(m_cursor_radius - CursorRadiusStep, CursorRadiusMin) + : std::min(m_cursor_radius + CursorRadiusStep, CursorRadiusMax); + m_parent.set_as_dirty(); + return true; + } + } + + if (action == SLAGizmoEventType::ResetClippingPlane) { + m_c->object_clipper()->set_position(-1., false); + return true; + } + + if (action == SLAGizmoEventType::LeftDown + || action == SLAGizmoEventType::RightDown + || (action == SLAGizmoEventType::Dragging && m_button_down != Button::None)) { + + if (m_triangle_selectors.empty()) + return false; + + EnforcerBlockerType new_state = EnforcerBlockerType::NONE; + if (! shift_down) { + if (action == SLAGizmoEventType::Dragging) + new_state = m_button_down == Button::Left + ? EnforcerBlockerType::ENFORCER + : EnforcerBlockerType::BLOCKER; + else + new_state = action == SLAGizmoEventType::LeftDown + ? EnforcerBlockerType::ENFORCER + : EnforcerBlockerType::BLOCKER; + } + + const Camera& camera = wxGetApp().plater()->get_camera(); + const Selection& selection = m_parent.get_selection(); + const ModelObject* mo = m_c->selection_info()->model_object(); + const ModelInstance* mi = mo->instances[selection.get_instance_idx()]; + const Transform3d& instance_trafo = mi->get_transformation().get_matrix(); + + // List of mouse positions that will be used as seeds for painting. + std::vector mouse_positions{mouse_position}; + + // In case current mouse position is far from the last one, + // add several positions from between into the list, so there + // are no gaps in the painted region. + { + if (m_last_mouse_position == Vec2d::Zero()) + m_last_mouse_position = mouse_position; + // resolution describes minimal distance limit using circle radius + // as a unit (e.g., 2 would mean the patches will be touching). + double resolution = 0.7; + double diameter_px = resolution * m_cursor_radius * camera.get_zoom(); + int patches_in_between = int(((mouse_position - m_last_mouse_position).norm() - diameter_px) / diameter_px); + if (patches_in_between > 0) { + Vec2d diff = (mouse_position - m_last_mouse_position)/(patches_in_between+1); + for (int i=1; i<=patches_in_between; ++i) + mouse_positions.emplace_back(m_last_mouse_position + i*diff); + } + } + m_last_mouse_position = Vec2d::Zero(); // only actual hits should be saved + + // Now "click" into all the prepared points and spill paint around them. + for (const Vec2d& mp : mouse_positions) { + std::vector>> hit_positions_and_facet_ids; + bool clipped_mesh_was_hit = false; + + Vec3f normal = Vec3f::Zero(); + Vec3f hit = Vec3f::Zero(); + size_t facet = 0; + Vec3f closest_hit = Vec3f::Zero(); + double closest_hit_squared_distance = std::numeric_limits::max(); + size_t closest_facet = 0; + int closest_hit_mesh_id = -1; + + // Transformations of individual meshes + std::vector trafo_matrices; + + int mesh_id = -1; + // Cast a ray on all meshes, pick the closest hit and save it for the respective mesh + for (const ModelVolume* mv : mo->volumes) { + if (! mv->is_model_part()) + continue; + + ++mesh_id; + + trafo_matrices.push_back(instance_trafo * mv->get_matrix()); + hit_positions_and_facet_ids.push_back(std::vector>()); + + if (m_c->raycaster()->raycasters()[mesh_id]->unproject_on_mesh( + mp, + trafo_matrices[mesh_id], + camera, + hit, + normal, + m_clipping_plane.get(), + &facet)) + { + // In case this hit is clipped, skip it. + if (is_mesh_point_clipped(hit.cast())) { + clipped_mesh_was_hit = true; + continue; + } + + // Is this hit the closest to the camera so far? + double hit_squared_distance = (camera.get_position()-trafo_matrices[mesh_id]*hit.cast()).squaredNorm(); + if (hit_squared_distance < closest_hit_squared_distance) { + closest_hit_squared_distance = hit_squared_distance; + closest_facet = facet; + closest_hit_mesh_id = mesh_id; + closest_hit = hit; + } + } + } + + bool dragging_while_painting = (action == SLAGizmoEventType::Dragging && m_button_down != Button::None); + + // The mouse button click detection is enabled when there is a valid hit + // or when the user clicks the clipping plane. Missing the object entirely + // shall not capture the mouse. + if (closest_hit_mesh_id != -1 || clipped_mesh_was_hit) { + if (m_button_down == Button::None) + m_button_down = ((action == SLAGizmoEventType::LeftDown) ? Button::Left : Button::Right); + } + + if (closest_hit_mesh_id == -1) { + // In case we have no valid hit, we can return. The event will + // be stopped in following two cases: + // 1. clicking the clipping plane + // 2. dragging while painting (to prevent scene rotations and moving the object) + return clipped_mesh_was_hit + || dragging_while_painting; + } + + // Find respective mesh id. + mesh_id = -1; + for (const ModelVolume* mv : mo->volumes) { + if (! mv->is_model_part()) + continue; + ++mesh_id; + if (mesh_id == closest_hit_mesh_id) + break; + } + + const Transform3d& trafo_matrix = trafo_matrices[mesh_id]; + + // Calculate how far can a point be from the line (in mesh coords). + // FIXME: The scaling of the mesh can be non-uniform. + const Vec3d sf = Geometry::Transformation(trafo_matrix).get_scaling_factor(); + const float avg_scaling = (sf(0) + sf(1) + sf(2))/3.; + const float limit = m_cursor_radius/avg_scaling; + + // Calculate direction from camera to the hit (in mesh coords): + Vec3f camera_pos = (trafo_matrix.inverse() * camera.get_position()).cast(); + Vec3f dir = (closest_hit - camera_pos).normalized(); + + assert(mesh_id < int(m_triangle_selectors.size())); + m_triangle_selectors[mesh_id]->select_patch(closest_hit, closest_facet, camera_pos, + dir, limit, new_state); + m_last_mouse_position = mouse_position; + } + + return true; + } + + if ((action == SLAGizmoEventType::LeftUp || action == SLAGizmoEventType::RightUp) + && m_button_down != Button::None) { + // Take snapshot and update ModelVolume data. + wxString action_name = shift_down + ? _L("Remove selection") + : (m_button_down == Button::Left + ? _L("Add supports") + : _L("Block supports")); + activate_internal_undo_redo_stack(true); + Plater::TakeSnapshot(wxGetApp().plater(), action_name); + update_model_object(); + + m_button_down = Button::None; + m_last_mouse_position = Vec2d::Zero(); + return true; + } + + return false; +} + + + +void GLGizmoPainterBase::select_facets_by_angle(float threshold_deg, bool block) +{ + float threshold = (M_PI/180.)*threshold_deg; + const Selection& selection = m_parent.get_selection(); + const ModelObject* mo = m_c->selection_info()->model_object(); + const ModelInstance* mi = mo->instances[selection.get_instance_idx()]; + + int mesh_id = -1; + for (const ModelVolume* mv : mo->volumes) { + if (! mv->is_model_part()) + continue; + + ++mesh_id; + + const Transform3d trafo_matrix = mi->get_matrix(true) * mv->get_matrix(true); + Vec3f down = (trafo_matrix.inverse() * (-Vec3d::UnitZ())).cast().normalized(); + Vec3f limit = (trafo_matrix.inverse() * Vec3d(std::sin(threshold), 0, -std::cos(threshold))).cast().normalized(); + + float dot_limit = limit.dot(down); + + // Now calculate dot product of vert_direction and facets' normals. + int idx = -1; + for (const stl_facet& facet : mv->mesh().stl.facet_start) { + ++idx; + if (facet.normal.dot(down) > dot_limit) + m_triangle_selectors[mesh_id]->set_facet(idx, + block + ? EnforcerBlockerType::BLOCKER + : EnforcerBlockerType::ENFORCER); + } + } + + activate_internal_undo_redo_stack(true); + + Plater::TakeSnapshot(wxGetApp().plater(), block ? _L("Block supports by angle") + : _L("Add supports by angle")); + update_model_object(); + m_parent.set_as_dirty(); + m_setting_angle = false; +} + + +void GLGizmoPainterBase::on_render_input_window(float x, float y, float bottom_limit) +{ + if (! m_c->selection_info()->model_object()) + return; + + const float approx_height = m_imgui->scaled(18.0f); + y = std::min(y, bottom_limit - approx_height); + m_imgui->set_next_window_pos(x, y, ImGuiCond_Always); + + if (! m_setting_angle) { + m_imgui->begin(on_get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); + + // First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that: + const float clipping_slider_left = std::max(m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x, m_imgui->calc_text_size(m_desc.at("reset_direction")).x) + m_imgui->scaled(1.5f); + const float cursor_slider_left = m_imgui->calc_text_size(m_desc.at("cursor_size")).x + m_imgui->scaled(1.f); + const float button_width = m_imgui->calc_text_size(m_desc.at("remove_all")).x + m_imgui->scaled(1.f); + const float minimal_slider_width = m_imgui->scaled(4.f); + + float caption_max = 0.f; + float total_text_max = 0.; + for (const std::string& t : {"enforce", "block", "remove"}) { + caption_max = std::max(caption_max, m_imgui->calc_text_size(m_desc.at(t+"_caption")).x); + total_text_max = std::max(total_text_max, caption_max + m_imgui->calc_text_size(m_desc.at(t)).x); + } + caption_max += m_imgui->scaled(1.f); + total_text_max += m_imgui->scaled(1.f); + + float window_width = minimal_slider_width + std::max(cursor_slider_left, clipping_slider_left); + window_width = std::max(window_width, total_text_max); + window_width = std::max(window_width, button_width); + + auto draw_text_with_caption = [this, &caption_max](const wxString& caption, const wxString& text) { + static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); + m_imgui->text_colored(ORANGE, caption); + ImGui::SameLine(caption_max); + m_imgui->text(text); + }; + + for (const std::string& t : {"enforce", "block", "remove"}) + draw_text_with_caption(m_desc.at(t + "_caption"), m_desc.at(t)); + + m_imgui->text(""); + + if (m_imgui->button("Autoset by angle...")) { + m_setting_angle = true; + } + + ImGui::SameLine(); + + if (m_imgui->button(m_desc.at("remove_all"))) { + Plater::TakeSnapshot(wxGetApp().plater(), wxString(_L("Reset selection"))); + ModelObject* mo = m_c->selection_info()->model_object(); + int idx = -1; + for (ModelVolume* mv : mo->volumes) { + if (mv->is_model_part()) { + ++idx; + m_triangle_selectors[idx]->reset(); + } + } + update_model_object(); + m_parent.set_as_dirty(); + } + + const float max_tooltip_width = ImGui::GetFontSize() * 20.0f; + + m_imgui->text(m_desc.at("cursor_size")); + ImGui::SameLine(clipping_slider_left); + ImGui::PushItemWidth(window_width - clipping_slider_left); + ImGui::SliderFloat(" ", &m_cursor_radius, CursorRadiusMin, CursorRadiusMax, "%.2f"); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::PushTextWrapPos(max_tooltip_width); + ImGui::TextUnformatted(_L("Alt + Mouse wheel").ToUTF8().data()); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } + + ImGui::Separator(); + if (m_c->object_clipper()->get_position() == 0.f) + m_imgui->text(m_desc.at("clipping_of_view")); + else { + if (m_imgui->button(m_desc.at("reset_direction"))) { + wxGetApp().CallAfter([this](){ + m_c->object_clipper()->set_position(-1., false); + }); + } + } + + ImGui::SameLine(clipping_slider_left); + ImGui::PushItemWidth(window_width - clipping_slider_left); + float clp_dist = m_c->object_clipper()->get_position(); + if (ImGui::SliderFloat(" ", &clp_dist, 0.f, 1.f, "%.2f")) + m_c->object_clipper()->set_position(clp_dist, true); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::PushTextWrapPos(max_tooltip_width); + ImGui::TextUnformatted(_L("Ctrl + Mouse wheel").ToUTF8().data()); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } + + m_imgui->end(); + if (m_setting_angle) { + m_parent.show_slope(false); + m_parent.set_slope_range({90.f - m_angle_threshold_deg, 90.f - m_angle_threshold_deg}); + m_parent.use_slope(true); + m_parent.set_as_dirty(); + } + } + else { + std::string name = "Autoset custom supports"; + m_imgui->begin(wxString(name), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); + m_imgui->text("Threshold:"); + ImGui::SameLine(); + if (m_imgui->slider_float("", &m_angle_threshold_deg, 0.f, 90.f, "%.f")) + m_parent.set_slope_range({90.f - m_angle_threshold_deg, 90.f - m_angle_threshold_deg}); + if (m_imgui->button("Enforce")) + select_facets_by_angle(m_angle_threshold_deg, false); + ImGui::SameLine(); + if (m_imgui->button("Block")) + select_facets_by_angle(m_angle_threshold_deg, true); + ImGui::SameLine(); + if (m_imgui->button("Cancel")) + m_setting_angle = false; + m_imgui->end(); + if (! m_setting_angle) { + m_parent.use_slope(false); + m_parent.set_as_dirty(); + } + } +} + +bool GLGizmoPainterBase::on_is_activable() const +{ + const Selection& selection = m_parent.get_selection(); + + if (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptFFF + || !selection.is_single_full_instance()) + return false; + + // Check that none of the selected volumes is outside. Only SLA auxiliaries (supports) are allowed outside. + const Selection::IndicesList& list = selection.get_volume_idxs(); + for (const auto& idx : list) + if (selection.get_volume(idx)->is_outside) + return false; + + return true; +} + +bool GLGizmoPainterBase::on_is_selectable() const +{ + return (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptFFF + && wxGetApp().get_mode() != comSimple ); +} + +std::string GLGizmoPainterBase::on_get_name() const +{ + return (_(L("FDM Support Editing")) + " [L]").ToUTF8().data(); +} + + +CommonGizmosDataID GLGizmoPainterBase::on_get_requirements() const +{ + return CommonGizmosDataID( + int(CommonGizmosDataID::SelectionInfo) + | int(CommonGizmosDataID::InstancesHider) + | int(CommonGizmosDataID::Raycaster) + | int(CommonGizmosDataID::ObjectClipper)); +} + + +void GLGizmoPainterBase::on_set_state() +{ + if (m_state == m_old_state) + return; + + if (m_state == On && m_old_state != On) { // the gizmo was just turned on + if (! m_parent.get_gizmos_manager().is_serializing()) { + wxGetApp().CallAfter([this]() { + activate_internal_undo_redo_stack(true); + }); + } + } + if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off + // we are actually shutting down + if (m_setting_angle) { + m_setting_angle = false; + m_parent.use_slope(false); + } + activate_internal_undo_redo_stack(false); + m_old_mo_id = -1; + //m_iva.release_geometry(); + m_triangle_selectors.clear(); + } + m_old_state = m_state; +} + + + +void GLGizmoPainterBase::on_start_dragging() +{ + +} + + +void GLGizmoPainterBase::on_stop_dragging() +{ + +} + + + +void GLGizmoPainterBase::on_load(cereal::BinaryInputArchive&) +{ + // We should update the gizmo from current ModelObject, but it is not + // possible at this point. That would require having updated selection and + // common gizmos data, which is not done at this point. Instead, save + // a flag to do the update in set_fdm_support_data, which will be called + // soon after. + m_schedule_update = true; +} + + + +void GLGizmoPainterBase::on_save(cereal::BinaryOutputArchive&) const +{ + +} + + +void TriangleSelectorGUI::render(ImGuiWrapper* imgui) +{ + int enf_cnt = 0; + int blc_cnt = 0; + + m_iva_enforcers.release_geometry(); + m_iva_blockers.release_geometry(); + + for (const Triangle& tr : m_triangles) { + if (! tr.valid || tr.is_split() || tr.get_state() == EnforcerBlockerType::NONE) + continue; + + GLIndexedVertexArray& va = tr.get_state() == EnforcerBlockerType::ENFORCER + ? m_iva_enforcers + : m_iva_blockers; + int& cnt = tr.get_state() == EnforcerBlockerType::ENFORCER + ? enf_cnt + : blc_cnt; + + for (int i=0; i<3; ++i) + va.push_geometry(double(m_vertices[tr.verts_idxs[i]].v[0]), + double(m_vertices[tr.verts_idxs[i]].v[1]), + double(m_vertices[tr.verts_idxs[i]].v[2]), + 0., 0., 1.); + va.push_triangle(cnt, + cnt+1, + cnt+2); + cnt += 3; + } + + m_iva_enforcers.finalize_geometry(true); + m_iva_blockers.finalize_geometry(true); + + if (m_iva_enforcers.has_VBOs()) { + ::glColor4f(0.f, 0.f, 1.f, 0.2f); + m_iva_enforcers.render(); + } + + + if (m_iva_blockers.has_VBOs()) { + ::glColor4f(1.f, 0.f, 0.f, 0.2f); + m_iva_blockers.render(); + } + + +#ifdef PRUSASLICER_TRIANGLE_SELECTOR_DEBUG + if (imgui) + render_debug(imgui); + else + assert(false); // If you want debug output, pass ptr to ImGuiWrapper. +#endif +} + + + +#ifdef PRUSASLICER_TRIANGLE_SELECTOR_DEBUG +void TriangleSelectorGUI::render_debug(ImGuiWrapper* imgui) +{ + imgui->begin(std::string("TriangleSelector dialog (DEV ONLY)"), + ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); + static float edge_limit = 1.f; + imgui->text("Edge limit (mm): "); + imgui->slider_float("", &edge_limit, 0.1f, 8.f); + set_edge_limit(edge_limit); + imgui->checkbox("Show split triangles: ", m_show_triangles); + imgui->checkbox("Show invalid triangles: ", m_show_invalid); + + int valid_triangles = m_triangles.size() - m_invalid_triangles; + imgui->text("Valid triangles: " + std::to_string(valid_triangles) + + "/" + std::to_string(m_triangles.size())); + imgui->text("Vertices: " + std::to_string(m_vertices.size())); + if (imgui->button("Force garbage collection")) + garbage_collect(); + + if (imgui->button("Serialize - deserialize")) { + auto map = serialize(); + deserialize(map); + } + + imgui->end(); + + if (! m_show_triangles) + return; + + enum vtype { + ORIGINAL = 0, + SPLIT, + INVALID + }; + + for (auto& va : m_varrays) + va.release_geometry(); + + std::array cnts; + + ::glScalef(1.01f, 1.01f, 1.01f); + + for (int tr_id=0; tr_idpush_geometry(double(m_vertices[tr.verts_idxs[i]].v[0]), + double(m_vertices[tr.verts_idxs[i]].v[1]), + double(m_vertices[tr.verts_idxs[i]].v[2]), + 0., 0., 1.); + va->push_triangle(*cnt, + *cnt+1, + *cnt+2); + *cnt += 3; + } + + ::glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + for (vtype i : {ORIGINAL, SPLIT, INVALID}) { + GLIndexedVertexArray& va = m_varrays[i]; + va.finalize_geometry(true); + if (va.has_VBOs()) { + switch (i) { + case ORIGINAL : ::glColor3f(0.f, 0.f, 1.f); break; + case SPLIT : ::glColor3f(1.f, 0.f, 0.f); break; + case INVALID : ::glColor3f(1.f, 1.f, 0.f); break; + } + va.render(); + } + } + ::glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); +} +#endif + + + +} // namespace GUI +} // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp new file mode 100644 index 0000000000..1770c96a7d --- /dev/null +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp @@ -0,0 +1,127 @@ +#ifndef slic3r_GLGizmoPainterBase_hpp_ +#define slic3r_GLGizmoPainterBase_hpp_ + +#include "GLGizmoBase.hpp" + +#include "slic3r/GUI/3DScene.hpp" + +#include "libslic3r/ObjectID.hpp" +#include "libslic3r/TriangleSelector.hpp" + +#include + + + + +namespace Slic3r { + +enum class EnforcerBlockerType : int8_t; + +namespace GUI { + +enum class SLAGizmoEventType : unsigned char; +class ClippingPlane; + + + +class TriangleSelectorGUI : public TriangleSelector { +public: + explicit TriangleSelectorGUI(const TriangleMesh& mesh) + : TriangleSelector(mesh) {} + + // Render current selection. Transformation matrices are supposed + // to be already set. + void render(ImGuiWrapper* imgui = nullptr); + +#ifdef PRUSASLICER_TRIANGLE_SELECTOR_DEBUG + void render_debug(ImGuiWrapper* imgui); + bool m_show_triangles{false}; + bool m_show_invalid{false}; +#endif + +private: + GLIndexedVertexArray m_iva_enforcers; + GLIndexedVertexArray m_iva_blockers; + std::array m_varrays; +}; + + + +class GLGizmoPainterBase : public GLGizmoBase +{ +private: + ObjectID m_old_mo_id; + size_t m_old_volumes_size = 0; + + GLUquadricObj* m_quadric; + + float m_cursor_radius = 2.f; + static constexpr float CursorRadiusMin = 0.4f; // cannot be zero + static constexpr float CursorRadiusMax = 8.f; + static constexpr float CursorRadiusStep = 0.2f; + + // For each model-part volume, store status and division of the triangles. + std::vector> m_triangle_selectors; + +public: + GLGizmoPainterBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); + ~GLGizmoPainterBase() override; + void set_fdm_support_data(ModelObject* model_object, const Selection& selection); + bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down); + + +private: + bool on_init() override; + void on_render() const override; + void on_render_for_picking() const override {} + + void render_triangles(const Selection& selection) const; + void render_cursor_circle() const; + + void update_model_object() const; + void update_from_model_object(); + void activate_internal_undo_redo_stack(bool activate); + + void select_facets_by_angle(float threshold, bool block); + float m_angle_threshold_deg = 45.f; + + bool is_mesh_point_clipped(const Vec3d& point) const; + + float m_clipping_plane_distance = 0.f; + std::unique_ptr m_clipping_plane; + bool m_setting_angle = false; + bool m_internal_stack_active = false; + bool m_schedule_update = false; + Vec2d m_last_mouse_position = Vec2d::Zero(); + + // This map holds all translated description texts, so they can be easily referenced during layout calculations + // etc. When language changes, GUI is recreated and this class constructed again, so the change takes effect. + std::map m_desc; + + enum class Button { + None, + Left, + Right + }; + + Button m_button_down = Button::None; + EState m_old_state = Off; // to be able to see that the gizmo has just been closed (see on_set_state) + +protected: + void on_set_state() override; + void on_start_dragging() override; + void on_stop_dragging() override; + void on_render_input_window(float x, float y, float bottom_limit) override; + std::string on_get_name() const override; + bool on_is_activable() const override; + bool on_is_selectable() const override; + void on_load(cereal::BinaryInputArchive& ar) override; + void on_save(cereal::BinaryOutputArchive& ar) const override; + CommonGizmosDataID on_get_requirements() const override; +}; + + +} // namespace GUI +} // namespace Slic3r + +#endif // slic3r_GLGizmoPainterBase_hpp_ From a9435cccb8f9a93c7ab03b40a4ed75232c0af7d6 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 26 Aug 2020 11:33:41 +0200 Subject: [PATCH 250/255] Finished separation of FDM gizmo into base and child --- src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp | 296 +++++++++++++++++++ src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp | 23 ++ src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp | 290 +----------------- src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp | 54 ++-- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 12 +- src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 2 +- 6 files changed, 356 insertions(+), 321 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index e69de29bb2..cc08f86a73 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -0,0 +1,296 @@ +#include "GLGizmoFdmSupports.hpp" + +#include "libslic3r/Model.hpp" + +//#include "slic3r/GUI/3DScene.hpp" +#include "slic3r/GUI/GLCanvas3D.hpp" +#include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/ImGuiWrapper.hpp" +#include "slic3r/GUI/Plater.hpp" + + +#include + + +namespace Slic3r { + +namespace GUI { + + + +void GLGizmoFdmSupports::on_opening() +{ + +} + + + +void GLGizmoFdmSupports::on_shutdown() +{ + if (m_setting_angle) { + m_setting_angle = false; + m_parent.use_slope(false); + } +} + + + +bool GLGizmoFdmSupports::on_init() +{ + m_shortcut_key = WXK_CONTROL_L; + + m_desc["clipping_of_view"] = _L("Clipping of view") + ": "; + m_desc["reset_direction"] = _L("Reset direction"); + m_desc["cursor_size"] = _L("Cursor size") + ": "; + m_desc["enforce_caption"] = _L("Left mouse button") + ": "; + m_desc["enforce"] = _L("Enforce supports"); + m_desc["block_caption"] = _L("Right mouse button") + " "; + m_desc["block"] = _L("Block supports"); + m_desc["remove_caption"] = _L("Shift + Left mouse button") + ": "; + m_desc["remove"] = _L("Remove selection"); + m_desc["remove_all"] = _L("Remove all selection"); + + return true; +} + + + +void GLGizmoFdmSupports::on_render() const +{ + const Selection& selection = m_parent.get_selection(); + + glsafe(::glEnable(GL_BLEND)); + glsafe(::glEnable(GL_DEPTH_TEST)); + + if (! m_setting_angle) + render_triangles(selection); + + m_c->object_clipper()->render_cut(); + render_cursor_circle(); + + glsafe(::glDisable(GL_BLEND)); +} + + + +void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_limit) +{ + if (! m_c->selection_info()->model_object()) + return; + + const float approx_height = m_imgui->scaled(18.0f); + y = std::min(y, bottom_limit - approx_height); + m_imgui->set_next_window_pos(x, y, ImGuiCond_Always); + + if (! m_setting_angle) { + m_imgui->begin(on_get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); + + // First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that: + const float clipping_slider_left = std::max(m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x, m_imgui->calc_text_size(m_desc.at("reset_direction")).x) + m_imgui->scaled(1.5f); + const float cursor_slider_left = m_imgui->calc_text_size(m_desc.at("cursor_size")).x + m_imgui->scaled(1.f); + const float button_width = m_imgui->calc_text_size(m_desc.at("remove_all")).x + m_imgui->scaled(1.f); + const float minimal_slider_width = m_imgui->scaled(4.f); + + float caption_max = 0.f; + float total_text_max = 0.; + for (const std::string& t : {"enforce", "block", "remove"}) { + caption_max = std::max(caption_max, m_imgui->calc_text_size(m_desc.at(t+"_caption")).x); + total_text_max = std::max(total_text_max, caption_max + m_imgui->calc_text_size(m_desc.at(t)).x); + } + caption_max += m_imgui->scaled(1.f); + total_text_max += m_imgui->scaled(1.f); + + float window_width = minimal_slider_width + std::max(cursor_slider_left, clipping_slider_left); + window_width = std::max(window_width, total_text_max); + window_width = std::max(window_width, button_width); + + auto draw_text_with_caption = [this, &caption_max](const wxString& caption, const wxString& text) { + static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); + m_imgui->text_colored(ORANGE, caption); + ImGui::SameLine(caption_max); + m_imgui->text(text); + }; + + for (const std::string& t : {"enforce", "block", "remove"}) + draw_text_with_caption(m_desc.at(t + "_caption"), m_desc.at(t)); + + m_imgui->text(""); + + if (m_imgui->button("Autoset by angle...")) { + m_setting_angle = true; + } + + ImGui::SameLine(); + + if (m_imgui->button(m_desc.at("remove_all"))) { + Plater::TakeSnapshot(wxGetApp().plater(), wxString(_L("Reset selection"))); + ModelObject* mo = m_c->selection_info()->model_object(); + int idx = -1; + for (ModelVolume* mv : mo->volumes) { + if (mv->is_model_part()) { + ++idx; + m_triangle_selectors[idx]->reset(); + } + } + + update_model_object(); + m_parent.set_as_dirty(); + } + + const float max_tooltip_width = ImGui::GetFontSize() * 20.0f; + + m_imgui->text(m_desc.at("cursor_size")); + ImGui::SameLine(clipping_slider_left); + ImGui::PushItemWidth(window_width - clipping_slider_left); + ImGui::SliderFloat(" ", &m_cursor_radius, CursorRadiusMin, CursorRadiusMax, "%.2f"); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::PushTextWrapPos(max_tooltip_width); + ImGui::TextUnformatted(_L("Alt + Mouse wheel").ToUTF8().data()); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } + + ImGui::Separator(); + if (m_c->object_clipper()->get_position() == 0.f) + m_imgui->text(m_desc.at("clipping_of_view")); + else { + if (m_imgui->button(m_desc.at("reset_direction"))) { + wxGetApp().CallAfter([this](){ + m_c->object_clipper()->set_position(-1., false); + }); + } + } + + ImGui::SameLine(clipping_slider_left); + ImGui::PushItemWidth(window_width - clipping_slider_left); + float clp_dist = m_c->object_clipper()->get_position(); + if (ImGui::SliderFloat(" ", &clp_dist, 0.f, 1.f, "%.2f")) + m_c->object_clipper()->set_position(clp_dist, true); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::PushTextWrapPos(max_tooltip_width); + ImGui::TextUnformatted(_L("Ctrl + Mouse wheel").ToUTF8().data()); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } + + m_imgui->end(); + if (m_setting_angle) { + m_parent.show_slope(false); + m_parent.set_slope_range({90.f - m_angle_threshold_deg, 90.f - m_angle_threshold_deg}); + m_parent.use_slope(true); + m_parent.set_as_dirty(); + } + } + else { + std::string name = "Autoset custom supports"; + m_imgui->begin(wxString(name), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); + m_imgui->text("Threshold:"); + ImGui::SameLine(); + if (m_imgui->slider_float("", &m_angle_threshold_deg, 0.f, 90.f, "%.f")) + m_parent.set_slope_range({90.f - m_angle_threshold_deg, 90.f - m_angle_threshold_deg}); + if (m_imgui->button("Enforce")) + select_facets_by_angle(m_angle_threshold_deg, false); + ImGui::SameLine(); + if (m_imgui->button("Block")) + select_facets_by_angle(m_angle_threshold_deg, true); + ImGui::SameLine(); + if (m_imgui->button("Cancel")) + m_setting_angle = false; + m_imgui->end(); + if (! m_setting_angle) { + m_parent.use_slope(false); + m_parent.set_as_dirty(); + } + } +} + + + +void GLGizmoFdmSupports::select_facets_by_angle(float threshold_deg, bool block) +{ + float threshold = (M_PI/180.)*threshold_deg; + const Selection& selection = m_parent.get_selection(); + const ModelObject* mo = m_c->selection_info()->model_object(); + const ModelInstance* mi = mo->instances[selection.get_instance_idx()]; + + int mesh_id = -1; + for (const ModelVolume* mv : mo->volumes) { + if (! mv->is_model_part()) + continue; + + ++mesh_id; + + const Transform3d trafo_matrix = mi->get_matrix(true) * mv->get_matrix(true); + Vec3f down = (trafo_matrix.inverse() * (-Vec3d::UnitZ())).cast().normalized(); + Vec3f limit = (trafo_matrix.inverse() * Vec3d(std::sin(threshold), 0, -std::cos(threshold))).cast().normalized(); + + float dot_limit = limit.dot(down); + + // Now calculate dot product of vert_direction and facets' normals. + int idx = -1; + for (const stl_facet& facet : mv->mesh().stl.facet_start) { + ++idx; + if (facet.normal.dot(down) > dot_limit) + m_triangle_selectors[mesh_id]->set_facet(idx, + block + ? EnforcerBlockerType::BLOCKER + : EnforcerBlockerType::ENFORCER); + } + } + + activate_internal_undo_redo_stack(true); + + Plater::TakeSnapshot(wxGetApp().plater(), block ? _L("Block supports by angle") + : _L("Add supports by angle")); + update_model_object(); + m_parent.set_as_dirty(); + m_setting_angle = false; +} + + + +void GLGizmoFdmSupports::update_model_object() const +{ + bool updated = false; + ModelObject* mo = m_c->selection_info()->model_object(); + int idx = -1; + for (ModelVolume* mv : mo->volumes) { + if (! mv->is_model_part()) + continue; + ++idx; + updated |= mv->m_supported_facets.set(*m_triangle_selectors[idx].get()); + } + + if (updated) + m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); +} + + + +void GLGizmoFdmSupports::update_from_model_object() +{ + wxBusyCursor wait; + + const ModelObject* mo = m_c->selection_info()->model_object(); + m_triangle_selectors.clear(); + + int volume_id = -1; + for (const ModelVolume* mv : mo->volumes) { + if (! mv->is_model_part()) + continue; + + ++volume_id; + + // This mesh does not account for the possible Z up SLA offset. + const TriangleMesh* mesh = &mv->mesh(); + + m_triangle_selectors.emplace_back(std::make_unique(*mesh)); + m_triangle_selectors.back()->deserialize(mv->m_supported_facets.get_data()); + } +} + + +} // namespace GUI +} // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp index 196a21bc03..dc0788c2c8 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp @@ -13,6 +13,29 @@ public: GLGizmoFdmSupports(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : GLGizmoPainterBase(parent, icon_filename, sprite_id) {} +protected: + void on_render_input_window(float x, float y, float bottom_limit) override; + +private: + bool on_init() override; + void on_render() const override; + void on_render_for_picking() const override {} + + void update_model_object() const override; + void update_from_model_object() override; + + void on_opening() override; + void on_shutdown() override; + + void select_facets_by_angle(float threshold, bool block); + float m_angle_threshold_deg = 45.f; + bool m_setting_angle = false; + + + + // This map holds all translated description texts, so they can be easily referenced during layout calculations + // etc. When language changes, GUI is recreated and this class constructed again, so the change takes effect. + std::map m_desc; }; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp index 37792a48e0..365d71316c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp @@ -19,39 +19,10 @@ namespace GUI { GLGizmoPainterBase::GLGizmoPainterBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id) - , m_quadric(nullptr) { m_clipping_plane.reset(new ClippingPlane()); - m_quadric = ::gluNewQuadric(); - if (m_quadric != nullptr) - // using GLU_FILL does not work when the instance's transformation - // contains mirroring (normals are reverted) - ::gluQuadricDrawStyle(m_quadric, GLU_FILL); } -GLGizmoPainterBase::~GLGizmoPainterBase() -{ - if (m_quadric != nullptr) - ::gluDeleteQuadric(m_quadric); -} - -bool GLGizmoPainterBase::on_init() -{ - m_shortcut_key = WXK_CONTROL_L; - - m_desc["clipping_of_view"] = _L("Clipping of view") + ": "; - m_desc["reset_direction"] = _L("Reset direction"); - m_desc["cursor_size"] = _L("Cursor size") + ": "; - m_desc["enforce_caption"] = _L("Left mouse button") + ": "; - m_desc["enforce"] = _L("Enforce supports"); - m_desc["block_caption"] = _L("Right mouse button") + " "; - m_desc["block"] = _L("Block supports"); - m_desc["remove_caption"] = _L("Shift + Left mouse button") + ": "; - m_desc["remove"] = _L("Remove selection"); - m_desc["remove_all"] = _L("Remove all selection"); - - return true; -} void GLGizmoPainterBase::activate_internal_undo_redo_stack(bool activate) @@ -68,7 +39,9 @@ void GLGizmoPainterBase::activate_internal_undo_redo_stack(bool activate) } } -void GLGizmoPainterBase::set_fdm_support_data(ModelObject* model_object, const Selection& selection) + + +void GLGizmoPainterBase::set_painter_gizmo_data(const Selection& selection) { if (m_state != On) return; @@ -87,26 +60,8 @@ void GLGizmoPainterBase::set_fdm_support_data(ModelObject* model_object, const S -void GLGizmoPainterBase::on_render() const -{ - const Selection& selection = m_parent.get_selection(); - - glsafe(::glEnable(GL_BLEND)); - glsafe(::glEnable(GL_DEPTH_TEST)); - - render_triangles(selection); - - m_c->object_clipper()->render_cut(); - render_cursor_circle(); - - glsafe(::glDisable(GL_BLEND)); -} - void GLGizmoPainterBase::render_triangles(const Selection& selection) const { - if (m_setting_angle) - return; - const ModelObject* mo = m_c->selection_info()->model_object(); glsafe(::glEnable(GL_POLYGON_OFFSET_FILL)); @@ -145,8 +100,7 @@ void GLGizmoPainterBase::render_triangles(const Selection& selection) const glsafe(::glPushMatrix()); glsafe(::glMultMatrixd(trafo_matrix.data())); - if (! m_setting_angle) - m_triangle_selectors[mesh_id]->render(m_imgui); + m_triangle_selectors[mesh_id]->render(m_imgui); glsafe(::glPopMatrix()); if (is_left_handed) @@ -202,46 +156,6 @@ void GLGizmoPainterBase::render_cursor_circle() const } -void GLGizmoPainterBase::update_model_object() const -{ - bool updated = false; - ModelObject* mo = m_c->selection_info()->model_object(); - int idx = -1; - for (ModelVolume* mv : mo->volumes) { - if (! mv->is_model_part()) - continue; - ++idx; - updated |= mv->m_supported_facets.set(*m_triangle_selectors[idx].get()); - } - - if (updated) - m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); -} - - -void GLGizmoPainterBase::update_from_model_object() -{ - wxBusyCursor wait; - - const ModelObject* mo = m_c->selection_info()->model_object(); - m_triangle_selectors.clear(); - - int volume_id = -1; - for (const ModelVolume* mv : mo->volumes) { - if (! mv->is_model_part()) - continue; - - ++volume_id; - - // This mesh does not account for the possible Z up SLA offset. - const TriangleMesh* mesh = &mv->mesh(); - - m_triangle_selectors.emplace_back(std::make_unique(*mesh)); - m_triangle_selectors.back()->deserialize(mv->m_supported_facets.get_data()); - } -} - - bool GLGizmoPainterBase::is_mesh_point_clipped(const Vec3d& point) const { @@ -461,179 +375,10 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous -void GLGizmoPainterBase::select_facets_by_angle(float threshold_deg, bool block) -{ - float threshold = (M_PI/180.)*threshold_deg; - const Selection& selection = m_parent.get_selection(); - const ModelObject* mo = m_c->selection_info()->model_object(); - const ModelInstance* mi = mo->instances[selection.get_instance_idx()]; - - int mesh_id = -1; - for (const ModelVolume* mv : mo->volumes) { - if (! mv->is_model_part()) - continue; - - ++mesh_id; - - const Transform3d trafo_matrix = mi->get_matrix(true) * mv->get_matrix(true); - Vec3f down = (trafo_matrix.inverse() * (-Vec3d::UnitZ())).cast().normalized(); - Vec3f limit = (trafo_matrix.inverse() * Vec3d(std::sin(threshold), 0, -std::cos(threshold))).cast().normalized(); - - float dot_limit = limit.dot(down); - - // Now calculate dot product of vert_direction and facets' normals. - int idx = -1; - for (const stl_facet& facet : mv->mesh().stl.facet_start) { - ++idx; - if (facet.normal.dot(down) > dot_limit) - m_triangle_selectors[mesh_id]->set_facet(idx, - block - ? EnforcerBlockerType::BLOCKER - : EnforcerBlockerType::ENFORCER); - } - } - - activate_internal_undo_redo_stack(true); - - Plater::TakeSnapshot(wxGetApp().plater(), block ? _L("Block supports by angle") - : _L("Add supports by angle")); - update_model_object(); - m_parent.set_as_dirty(); - m_setting_angle = false; -} -void GLGizmoPainterBase::on_render_input_window(float x, float y, float bottom_limit) -{ - if (! m_c->selection_info()->model_object()) - return; - const float approx_height = m_imgui->scaled(18.0f); - y = std::min(y, bottom_limit - approx_height); - m_imgui->set_next_window_pos(x, y, ImGuiCond_Always); - if (! m_setting_angle) { - m_imgui->begin(on_get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); - - // First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that: - const float clipping_slider_left = std::max(m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x, m_imgui->calc_text_size(m_desc.at("reset_direction")).x) + m_imgui->scaled(1.5f); - const float cursor_slider_left = m_imgui->calc_text_size(m_desc.at("cursor_size")).x + m_imgui->scaled(1.f); - const float button_width = m_imgui->calc_text_size(m_desc.at("remove_all")).x + m_imgui->scaled(1.f); - const float minimal_slider_width = m_imgui->scaled(4.f); - - float caption_max = 0.f; - float total_text_max = 0.; - for (const std::string& t : {"enforce", "block", "remove"}) { - caption_max = std::max(caption_max, m_imgui->calc_text_size(m_desc.at(t+"_caption")).x); - total_text_max = std::max(total_text_max, caption_max + m_imgui->calc_text_size(m_desc.at(t)).x); - } - caption_max += m_imgui->scaled(1.f); - total_text_max += m_imgui->scaled(1.f); - - float window_width = minimal_slider_width + std::max(cursor_slider_left, clipping_slider_left); - window_width = std::max(window_width, total_text_max); - window_width = std::max(window_width, button_width); - - auto draw_text_with_caption = [this, &caption_max](const wxString& caption, const wxString& text) { - static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); - m_imgui->text_colored(ORANGE, caption); - ImGui::SameLine(caption_max); - m_imgui->text(text); - }; - - for (const std::string& t : {"enforce", "block", "remove"}) - draw_text_with_caption(m_desc.at(t + "_caption"), m_desc.at(t)); - - m_imgui->text(""); - - if (m_imgui->button("Autoset by angle...")) { - m_setting_angle = true; - } - - ImGui::SameLine(); - - if (m_imgui->button(m_desc.at("remove_all"))) { - Plater::TakeSnapshot(wxGetApp().plater(), wxString(_L("Reset selection"))); - ModelObject* mo = m_c->selection_info()->model_object(); - int idx = -1; - for (ModelVolume* mv : mo->volumes) { - if (mv->is_model_part()) { - ++idx; - m_triangle_selectors[idx]->reset(); - } - } - update_model_object(); - m_parent.set_as_dirty(); - } - - const float max_tooltip_width = ImGui::GetFontSize() * 20.0f; - - m_imgui->text(m_desc.at("cursor_size")); - ImGui::SameLine(clipping_slider_left); - ImGui::PushItemWidth(window_width - clipping_slider_left); - ImGui::SliderFloat(" ", &m_cursor_radius, CursorRadiusMin, CursorRadiusMax, "%.2f"); - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip(); - ImGui::PushTextWrapPos(max_tooltip_width); - ImGui::TextUnformatted(_L("Alt + Mouse wheel").ToUTF8().data()); - ImGui::PopTextWrapPos(); - ImGui::EndTooltip(); - } - - ImGui::Separator(); - if (m_c->object_clipper()->get_position() == 0.f) - m_imgui->text(m_desc.at("clipping_of_view")); - else { - if (m_imgui->button(m_desc.at("reset_direction"))) { - wxGetApp().CallAfter([this](){ - m_c->object_clipper()->set_position(-1., false); - }); - } - } - - ImGui::SameLine(clipping_slider_left); - ImGui::PushItemWidth(window_width - clipping_slider_left); - float clp_dist = m_c->object_clipper()->get_position(); - if (ImGui::SliderFloat(" ", &clp_dist, 0.f, 1.f, "%.2f")) - m_c->object_clipper()->set_position(clp_dist, true); - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip(); - ImGui::PushTextWrapPos(max_tooltip_width); - ImGui::TextUnformatted(_L("Ctrl + Mouse wheel").ToUTF8().data()); - ImGui::PopTextWrapPos(); - ImGui::EndTooltip(); - } - - m_imgui->end(); - if (m_setting_angle) { - m_parent.show_slope(false); - m_parent.set_slope_range({90.f - m_angle_threshold_deg, 90.f - m_angle_threshold_deg}); - m_parent.use_slope(true); - m_parent.set_as_dirty(); - } - } - else { - std::string name = "Autoset custom supports"; - m_imgui->begin(wxString(name), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); - m_imgui->text("Threshold:"); - ImGui::SameLine(); - if (m_imgui->slider_float("", &m_angle_threshold_deg, 0.f, 90.f, "%.f")) - m_parent.set_slope_range({90.f - m_angle_threshold_deg, 90.f - m_angle_threshold_deg}); - if (m_imgui->button("Enforce")) - select_facets_by_angle(m_angle_threshold_deg, false); - ImGui::SameLine(); - if (m_imgui->button("Block")) - select_facets_by_angle(m_angle_threshold_deg, true); - ImGui::SameLine(); - if (m_imgui->button("Cancel")) - m_setting_angle = false; - m_imgui->end(); - if (! m_setting_angle) { - m_parent.use_slope(false); - m_parent.set_as_dirty(); - } - } -} bool GLGizmoPainterBase::on_is_activable() const { @@ -680,6 +425,7 @@ void GLGizmoPainterBase::on_set_state() return; if (m_state == On && m_old_state != On) { // the gizmo was just turned on + on_opening(); if (! m_parent.get_gizmos_manager().is_serializing()) { wxGetApp().CallAfter([this]() { activate_internal_undo_redo_stack(true); @@ -688,10 +434,7 @@ void GLGizmoPainterBase::on_set_state() } if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off // we are actually shutting down - if (m_setting_angle) { - m_setting_angle = false; - m_parent.use_slope(false); - } + on_shutdown(); activate_internal_undo_redo_stack(false); m_old_mo_id = -1; //m_iva.release_geometry(); @@ -702,37 +445,18 @@ void GLGizmoPainterBase::on_set_state() -void GLGizmoPainterBase::on_start_dragging() -{ - -} - - -void GLGizmoPainterBase::on_stop_dragging() -{ - -} - - - void GLGizmoPainterBase::on_load(cereal::BinaryInputArchive&) { // We should update the gizmo from current ModelObject, but it is not // possible at this point. That would require having updated selection and // common gizmos data, which is not done at this point. Instead, save - // a flag to do the update in set_fdm_support_data, which will be called + // a flag to do the update in set_painter_gizmo_data, which will be called // soon after. m_schedule_update = true; } -void GLGizmoPainterBase::on_save(cereal::BinaryOutputArchive&) const -{ - -} - - void TriangleSelectorGUI::render(ImGuiWrapper* imgui) { int enf_cnt = 0; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp index 1770c96a7d..886807b6a5 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp @@ -46,14 +46,27 @@ private: }; - +// Following class is a base class for a gizmo with ability to paint on mesh +// using circular blush (such as FDM supports gizmo and seam painting gizmo). +// The purpose is not to duplicate code related to mesh painting. class GLGizmoPainterBase : public GLGizmoBase { private: ObjectID m_old_mo_id; size_t m_old_volumes_size = 0; - GLUquadricObj* m_quadric; +public: + GLGizmoPainterBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); + ~GLGizmoPainterBase() override {} + void set_painter_gizmo_data(const Selection& selection); + bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down); + +protected: + void render_triangles(const Selection& selection) const; + void render_cursor_circle() const; + virtual void update_model_object() const = 0; + virtual void update_from_model_object() = 0; + void activate_internal_undo_redo_stack(bool activate); float m_cursor_radius = 2.f; static constexpr float CursorRadiusMin = 0.4f; // cannot be zero @@ -63,41 +76,17 @@ private: // For each model-part volume, store status and division of the triangles. std::vector> m_triangle_selectors; -public: - GLGizmoPainterBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); - ~GLGizmoPainterBase() override; - void set_fdm_support_data(ModelObject* model_object, const Selection& selection); - bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down); - private: - bool on_init() override; - void on_render() const override; - void on_render_for_picking() const override {} - - void render_triangles(const Selection& selection) const; - void render_cursor_circle() const; - - void update_model_object() const; - void update_from_model_object(); - void activate_internal_undo_redo_stack(bool activate); - - void select_facets_by_angle(float threshold, bool block); - float m_angle_threshold_deg = 45.f; - bool is_mesh_point_clipped(const Vec3d& point) const; float m_clipping_plane_distance = 0.f; std::unique_ptr m_clipping_plane; - bool m_setting_angle = false; + bool m_internal_stack_active = false; bool m_schedule_update = false; Vec2d m_last_mouse_position = Vec2d::Zero(); - // This map holds all translated description texts, so they can be easily referenced during layout calculations - // etc. When language changes, GUI is recreated and this class constructed again, so the change takes effect. - std::map m_desc; - enum class Button { None, Left, @@ -109,14 +98,17 @@ private: protected: void on_set_state() override; - void on_start_dragging() override; - void on_stop_dragging() override; - void on_render_input_window(float x, float y, float bottom_limit) override; + void on_start_dragging() override {} + void on_stop_dragging() override {} + + virtual void on_opening() = 0; + virtual void on_shutdown() = 0; + std::string on_get_name() const override; bool on_is_activable() const override; bool on_is_selectable() const override; void on_load(cereal::BinaryInputArchive& ar) override; - void on_save(cereal::BinaryOutputArchive& ar) const override; + void on_save(cereal::BinaryOutputArchive& ar) const override {} CommonGizmosDataID on_get_requirements() const override; }; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 78998b92d9..089e2c6ffc 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -221,7 +221,7 @@ void GLGizmosManager::update_data() ModelObject* model_object = selection.get_model()->objects[selection.get_object_idx()]; set_flattening_data(model_object); set_sla_support_data(model_object); - set_fdm_support_data(model_object); + set_painter_gizmo_data(); } else if (selection.is_single_volume() || selection.is_single_modifier()) { @@ -230,7 +230,7 @@ void GLGizmosManager::update_data() set_rotation(Vec3d::Zero()); set_flattening_data(nullptr); set_sla_support_data(nullptr); - set_fdm_support_data(nullptr); + set_painter_gizmo_data(); } else if (is_wipe_tower) { @@ -239,7 +239,7 @@ void GLGizmosManager::update_data() set_rotation(Vec3d(0., 0., (M_PI/180.) * dynamic_cast(config.option("wipe_tower_rotation_angle"))->value)); set_flattening_data(nullptr); set_sla_support_data(nullptr); - set_fdm_support_data(nullptr); + set_painter_gizmo_data(); } else { @@ -247,7 +247,7 @@ void GLGizmosManager::update_data() set_rotation(Vec3d::Zero()); set_flattening_data(selection.is_from_single_object() ? selection.get_model()->objects[selection.get_object_idx()] : nullptr); set_sla_support_data(selection.is_from_single_instance() ? selection.get_model()->objects[selection.get_object_idx()] : nullptr); - set_fdm_support_data(selection.is_from_single_instance() ? selection.get_model()->objects[selection.get_object_idx()] : nullptr); + set_painter_gizmo_data(); } } @@ -382,12 +382,12 @@ void GLGizmosManager::set_sla_support_data(ModelObject* model_object) gizmo_supports->set_sla_support_data(model_object, m_parent.get_selection()); } -void GLGizmosManager::set_fdm_support_data(ModelObject* model_object) +void GLGizmosManager::set_painter_gizmo_data() { if (!m_enabled || m_gizmos.empty()) return; - dynamic_cast(m_gizmos[FdmSupports].get())->set_fdm_support_data(model_object, m_parent.get_selection()); + dynamic_cast(m_gizmos[FdmSupports].get())->set_painter_gizmo_data(m_parent.get_selection()); } // Returns true if the gizmo used the event to do something, false otherwise. diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index 4ad46a2a92..b8b78eceb0 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -203,7 +203,7 @@ public: void set_sla_support_data(ModelObject* model_object); - void set_fdm_support_data(ModelObject* model_object); + void set_painter_gizmo_data(); bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position = Vec2d::Zero(), bool shift_down = false, bool alt_down = false, bool control_down = false); ClippingPlane get_clipping_plane() const; From db7559157ca6b4e06481dfbf4eb3d8f823977da7 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 26 Aug 2020 13:15:15 +0200 Subject: [PATCH 251/255] Revert "Forbid translation of objects when SLA/Hollow/FDM gizmos are active" This reverts commit c29171790930a1a9f9b0374b6a5ab8ccec1e88a9. Translation of object when those gizmos are active should already be supressed by previous commit (ba97ebb0). The FDM gizmo was erroneously not blocking the translation, the commit that is reverted is therefore needless after this was fixed the way it should have been fixed in the first place. --- src/slic3r/GUI/GLCanvas3D.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 94f6f6ef32..04ce89a80e 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3657,14 +3657,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) if (!m_mouse.drag.move_requires_threshold) { m_mouse.dragging = true; - - // Translation of objects is forbidden when SLA supports/hollowing/fdm - // supports gizmo is active. - if (m_gizmos.get_current_type() == GLGizmosManager::SlaSupports - || m_gizmos.get_current_type() == GLGizmosManager::FdmSupports - || m_gizmos.get_current_type() == GLGizmosManager::Hollow) - return; - Vec3d cur_pos = m_mouse.drag.start_position_3D; // we do not want to translate objects if the user just clicked on an object while pressing shift to remove it from the selection and then drag if (m_selection.contains_volume(get_first_hover_volume_idx())) From 01b59ff57b7fdb85a25b623a0ebf6cb7dc02a1c7 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Mon, 31 Aug 2020 07:25:12 +0200 Subject: [PATCH 252/255] Seam gizmo created on frontend --- resources/icons/seam.svg | 42 ++++ src/slic3r/CMakeLists.txt | 2 + src/slic3r/GUI/GLCanvas3D.cpp | 6 +- src/slic3r/GUI/Gizmos/GLGizmoBase.hpp | 1 - src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp | 20 +- src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp | 3 +- src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp | 10 - src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp | 1 - src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp | 208 +++++++++++++++++++ src/slic3r/GUI/Gizmos/GLGizmoSeam.hpp | 42 ++++ src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 24 ++- src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 1 + 12 files changed, 323 insertions(+), 37 deletions(-) create mode 100644 resources/icons/seam.svg create mode 100644 src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp create mode 100644 src/slic3r/GUI/Gizmos/GLGizmoSeam.hpp diff --git a/resources/icons/seam.svg b/resources/icons/seam.svg new file mode 100644 index 0000000000..119fb6afcc --- /dev/null +++ b/resources/icons/seam.svg @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index f1089ae935..33994fe8ec 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -53,6 +53,8 @@ set(SLIC3R_GUI_SOURCES GUI/Gizmos/GLGizmoHollow.hpp GUI/Gizmos/GLGizmoPainterBase.cpp GUI/Gizmos/GLGizmoPainterBase.hpp + GUI/Gizmos/GLGizmoSeam.cpp + GUI/Gizmos/GLGizmoSeam.hpp GUI/GLSelectionRectangle.cpp GUI/GLSelectionRectangle.hpp GUI/GLTexture.hpp diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 04ce89a80e..6646a12579 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3582,7 +3582,8 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) else if (evt.LeftDown() && (evt.ShiftDown() || evt.AltDown()) && m_picking_enabled) { if (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports - && m_gizmos.get_current_type() != GLGizmosManager::FdmSupports) + && m_gizmos.get_current_type() != GLGizmosManager::FdmSupports + && m_gizmos.get_current_type() != GLGizmosManager::Seam) { m_rectangle_selection.start_dragging(m_mouse.position, evt.ShiftDown() ? GLSelectionRectangle::Select : GLSelectionRectangle::Deselect); m_dirty = true; @@ -5317,7 +5318,8 @@ void GLCanvas3D::_render_bed(bool bottom, bool show_axes) const bool show_texture = ! bottom || (m_gizmos.get_current_type() != GLGizmosManager::FdmSupports - && m_gizmos.get_current_type() != GLGizmosManager::SlaSupports); + && m_gizmos.get_current_type() != GLGizmosManager::SlaSupports + && m_gizmos.get_current_type() != GLGizmosManager::Seam); wxGetApp().plater()->get_bed().render(const_cast(*this), bottom, scale_factor, show_axes, show_texture); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index 3ab58c2585..44f0a69729 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -124,7 +124,6 @@ public: void set_state(EState state) { m_state = state; on_set_state(); } int get_shortcut_key() const { return m_shortcut_key; } - void set_shortcut_key(int key) { m_shortcut_key = key; } const std::string& get_icon_filename() const { return m_icon_filename; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index cc08f86a73..a34eca1a66 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -18,13 +18,6 @@ namespace GUI { -void GLGizmoFdmSupports::on_opening() -{ - -} - - - void GLGizmoFdmSupports::on_shutdown() { if (m_setting_angle) { @@ -35,6 +28,13 @@ void GLGizmoFdmSupports::on_shutdown() +std::string GLGizmoFdmSupports::on_get_name() const +{ + return (_(L("FDM Support Editing")) + " [L]").ToUTF8().data(); +} + + + bool GLGizmoFdmSupports::on_init() { m_shortcut_key = WXK_CONTROL_L; @@ -176,12 +176,6 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l } m_imgui->end(); - if (m_setting_angle) { - m_parent.show_slope(false); - m_parent.set_slope_range({90.f - m_angle_threshold_deg, 90.f - m_angle_threshold_deg}); - m_parent.use_slope(true); - m_parent.set_as_dirty(); - } } else { std::string name = "Autoset custom supports"; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp index dc0788c2c8..7100d611e6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp @@ -15,6 +15,7 @@ public: protected: void on_render_input_window(float x, float y, float bottom_limit) override; + std::string on_get_name() const override; private: bool on_init() override; @@ -24,7 +25,7 @@ private: void update_model_object() const override; void update_from_model_object() override; - void on_opening() override; + void on_opening() override {} void on_shutdown() override; void select_facets_by_angle(float threshold, bool block); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp index 365d71316c..1809b417cc 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp @@ -375,11 +375,6 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous - - - - - bool GLGizmoPainterBase::on_is_activable() const { const Selection& selection = m_parent.get_selection(); @@ -403,11 +398,6 @@ bool GLGizmoPainterBase::on_is_selectable() const && wxGetApp().get_mode() != comSimple ); } -std::string GLGizmoPainterBase::on_get_name() const -{ - return (_(L("FDM Support Editing")) + " [L]").ToUTF8().data(); -} - CommonGizmosDataID GLGizmoPainterBase::on_get_requirements() const { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp index 886807b6a5..da9b378957 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp @@ -104,7 +104,6 @@ protected: virtual void on_opening() = 0; virtual void on_shutdown() = 0; - std::string on_get_name() const override; bool on_is_activable() const override; bool on_is_selectable() const override; void on_load(cereal::BinaryInputArchive& ar) override; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp new file mode 100644 index 0000000000..8a08f5ebe7 --- /dev/null +++ b/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp @@ -0,0 +1,208 @@ +#include "GLGizmoSeam.hpp" + +#include "libslic3r/Model.hpp" + +//#include "slic3r/GUI/3DScene.hpp" +#include "slic3r/GUI/GLCanvas3D.hpp" +#include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/ImGuiWrapper.hpp" +#include "slic3r/GUI/Plater.hpp" + + +#include + + +namespace Slic3r { + +namespace GUI { + + + +bool GLGizmoSeam::on_init() +{ + m_shortcut_key = WXK_CONTROL_P; + + m_desc["clipping_of_view"] = _L("Clipping of view") + ": "; + m_desc["reset_direction"] = _L("Reset direction"); + m_desc["cursor_size"] = _L("Cursor size") + ": "; + m_desc["enforce_caption"] = _L("Left mouse button") + ": "; + m_desc["enforce"] = _L("Enforce seam"); + m_desc["block_caption"] = _L("Right mouse button") + " "; + m_desc["block"] = _L("Block seam"); + m_desc["remove_caption"] = _L("Shift + Left mouse button") + ": "; + m_desc["remove"] = _L("Remove selection"); + m_desc["remove_all"] = _L("Remove all selection"); + + return true; +} + + + +std::string GLGizmoSeam::on_get_name() const +{ + return (_(L("Seam Editing")) + " [P]").ToUTF8().data(); +} + + + +void GLGizmoSeam::on_render() const +{ + const Selection& selection = m_parent.get_selection(); + + glsafe(::glEnable(GL_BLEND)); + glsafe(::glEnable(GL_DEPTH_TEST)); + + render_triangles(selection); + + m_c->object_clipper()->render_cut(); + render_cursor_circle(); + + glsafe(::glDisable(GL_BLEND)); +} + + + +void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit) +{ + if (! m_c->selection_info()->model_object()) + return; + + const float approx_height = m_imgui->scaled(18.0f); + y = std::min(y, bottom_limit - approx_height); + m_imgui->set_next_window_pos(x, y, ImGuiCond_Always); + + + m_imgui->begin(on_get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); + + // First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that: + const float clipping_slider_left = std::max(m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x, m_imgui->calc_text_size(m_desc.at("reset_direction")).x) + m_imgui->scaled(1.5f); + const float cursor_slider_left = m_imgui->calc_text_size(m_desc.at("cursor_size")).x + m_imgui->scaled(1.f); + const float button_width = m_imgui->calc_text_size(m_desc.at("remove_all")).x + m_imgui->scaled(1.f); + const float minimal_slider_width = m_imgui->scaled(4.f); + + float caption_max = 0.f; + float total_text_max = 0.; + for (const std::string& t : {"enforce", "block", "remove"}) { + caption_max = std::max(caption_max, m_imgui->calc_text_size(m_desc.at(t+"_caption")).x); + total_text_max = std::max(total_text_max, caption_max + m_imgui->calc_text_size(m_desc.at(t)).x); + } + caption_max += m_imgui->scaled(1.f); + total_text_max += m_imgui->scaled(1.f); + + float window_width = minimal_slider_width + std::max(cursor_slider_left, clipping_slider_left); + window_width = std::max(window_width, total_text_max); + window_width = std::max(window_width, button_width); + + auto draw_text_with_caption = [this, &caption_max](const wxString& caption, const wxString& text) { + static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); + m_imgui->text_colored(ORANGE, caption); + ImGui::SameLine(caption_max); + m_imgui->text(text); + }; + + for (const std::string& t : {"enforce", "block", "remove"}) + draw_text_with_caption(m_desc.at(t + "_caption"), m_desc.at(t)); + + m_imgui->text(""); + + if (m_imgui->button(m_desc.at("remove_all"))) { + Plater::TakeSnapshot(wxGetApp().plater(), wxString(_L("Reset selection"))); + ModelObject* mo = m_c->selection_info()->model_object(); + int idx = -1; + for (ModelVolume* mv : mo->volumes) { + if (mv->is_model_part()) { + ++idx; + m_triangle_selectors[idx]->reset(); + } + } + + update_model_object(); + m_parent.set_as_dirty(); + } + + const float max_tooltip_width = ImGui::GetFontSize() * 20.0f; + + m_imgui->text(m_desc.at("cursor_size")); + ImGui::SameLine(clipping_slider_left); + ImGui::PushItemWidth(window_width - clipping_slider_left); + ImGui::SliderFloat(" ", &m_cursor_radius, CursorRadiusMin, CursorRadiusMax, "%.2f"); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::PushTextWrapPos(max_tooltip_width); + ImGui::TextUnformatted(_L("Alt + Mouse wheel").ToUTF8().data()); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } + + ImGui::Separator(); + if (m_c->object_clipper()->get_position() == 0.f) + m_imgui->text(m_desc.at("clipping_of_view")); + else { + if (m_imgui->button(m_desc.at("reset_direction"))) { + wxGetApp().CallAfter([this](){ + m_c->object_clipper()->set_position(-1., false); + }); + } + } + + ImGui::SameLine(clipping_slider_left); + ImGui::PushItemWidth(window_width - clipping_slider_left); + float clp_dist = m_c->object_clipper()->get_position(); + if (ImGui::SliderFloat(" ", &clp_dist, 0.f, 1.f, "%.2f")) + m_c->object_clipper()->set_position(clp_dist, true); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::PushTextWrapPos(max_tooltip_width); + ImGui::TextUnformatted(_L("Ctrl + Mouse wheel").ToUTF8().data()); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } + + m_imgui->end(); +} + + + +void GLGizmoSeam::update_model_object() const +{ + bool updated = false; + ModelObject* mo = m_c->selection_info()->model_object(); + int idx = -1; + for (ModelVolume* mv : mo->volumes) { + if (! mv->is_model_part()) + continue; + ++idx; + updated |= mv->m_supported_facets.set(*m_triangle_selectors[idx].get()); + } + + if (updated) + m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); +} + + + +void GLGizmoSeam::update_from_model_object() +{ + wxBusyCursor wait; + + const ModelObject* mo = m_c->selection_info()->model_object(); + m_triangle_selectors.clear(); + + int volume_id = -1; + for (const ModelVolume* mv : mo->volumes) { + if (! mv->is_model_part()) + continue; + + ++volume_id; + + // This mesh does not account for the possible Z up SLA offset. + const TriangleMesh* mesh = &mv->mesh(); + + m_triangle_selectors.emplace_back(std::make_unique(*mesh)); + m_triangle_selectors.back()->deserialize(mv->m_supported_facets.get_data()); + } +} + + +} // namespace GUI +} // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSeam.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSeam.hpp new file mode 100644 index 0000000000..469ec9180c --- /dev/null +++ b/src/slic3r/GUI/Gizmos/GLGizmoSeam.hpp @@ -0,0 +1,42 @@ +#ifndef slic3r_GLGizmoSeam_hpp_ +#define slic3r_GLGizmoSeam_hpp_ + +#include "GLGizmoPainterBase.hpp" + +namespace Slic3r { + +namespace GUI { + +class GLGizmoSeam : public GLGizmoPainterBase +{ +public: + GLGizmoSeam(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) + : GLGizmoPainterBase(parent, icon_filename, sprite_id) {} + +protected: + void on_render_input_window(float x, float y, float bottom_limit) override; + std::string on_get_name() const override; + +private: + bool on_init() override; + void on_render() const override; + void on_render_for_picking() const override {} + + void update_model_object() const override; + void update_from_model_object() override; + + void on_opening() override {} + void on_shutdown() override {} + + // This map holds all translated description texts, so they can be easily referenced during layout calculations + // etc. When language changes, GUI is recreated and this class constructed again, so the change takes effect. + std::map m_desc; +}; + + + +} // namespace GUI +} // namespace Slic3r + + +#endif // slic3r_GLGizmoSeam_hpp_ diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 089e2c6ffc..1087c64d5a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -16,6 +16,7 @@ #include "slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp" #include "slic3r/GUI/Gizmos/GLGizmoCut.hpp" #include "slic3r/GUI/Gizmos/GLGizmoHollow.hpp" +#include "slic3r/GUI/Gizmos/GLGizmoSeam.hpp" #include "libslic3r/Model.hpp" #include "libslic3r/PresetBundle.hpp" @@ -104,6 +105,7 @@ bool GLGizmosManager::init() m_gizmos.emplace_back(new GLGizmoHollow(m_parent, "hollow.svg", 5)); m_gizmos.emplace_back(new GLGizmoSlaSupports(m_parent, "sla_supports.svg", 6)); m_gizmos.emplace_back(new GLGizmoFdmSupports(m_parent, "sla_supports.svg", 7)); + m_gizmos.emplace_back(new GLGizmoSeam(m_parent, "seam.svg", 8)); m_common_gizmos_data.reset(new CommonGizmosDataPool(&m_parent)); @@ -388,6 +390,7 @@ void GLGizmosManager::set_painter_gizmo_data() return; dynamic_cast(m_gizmos[FdmSupports].get())->set_painter_gizmo_data(m_parent.get_selection()); + dynamic_cast(m_gizmos[Seam].get())->set_painter_gizmo_data(m_parent.get_selection()); } // Returns true if the gizmo used the event to do something, false otherwise. @@ -402,6 +405,8 @@ bool GLGizmosManager::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_p return dynamic_cast(m_gizmos[Hollow].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down); else if (m_current == FdmSupports) return dynamic_cast(m_gizmos[FdmSupports].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down); + else if (m_current == Seam) + return dynamic_cast(m_gizmos[Seam].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down); else return false; } @@ -465,7 +470,7 @@ bool GLGizmosManager::on_mouse_wheel(wxMouseEvent& evt) { bool processed = false; - if (m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports) { + if (m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports || m_current == Seam) { float rot = (float)evt.GetWheelRotation() / (float)evt.GetWheelDelta(); if (gizmo_event((rot > 0.f ? SLAGizmoEventType::MouseWheelUp : SLAGizmoEventType::MouseWheelDown), Vec2d::Zero(), evt.ShiftDown(), evt.AltDown(), evt.ControlDown())) processed = true; @@ -607,7 +612,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt) if (evt.LeftDown()) { - if ((m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports) + if ((m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports ||m_current == Seam) && gizmo_event(SLAGizmoEventType::LeftDown, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown())) // the gizmo got the event and took some action, there is no need to do anything more processed = true; @@ -634,23 +639,24 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt) // event was taken care of by the SlaSupports gizmo processed = true; } - else if (evt.RightDown() && (selected_object_idx != -1) && m_current == FdmSupports + else if (evt.RightDown() && (selected_object_idx != -1) && (m_current == FdmSupports || m_current == Seam) && gizmo_event(SLAGizmoEventType::RightDown, mouse_pos)) { - // event was taken care of by the FdmSupports gizmo + // event was taken care of by the FdmSupports / Seam gizmo processed = true; } - else if (evt.Dragging() && (m_parent.get_move_volume_id() != -1) && (m_current == SlaSupports || m_current == Hollow)) + else if (evt.Dragging() && (m_parent.get_move_volume_id() != -1) + && (m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports || m_current == Seam)) // don't allow dragging objects with the Sla gizmo on processed = true; - else if (evt.Dragging() && (m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports ) + else if (evt.Dragging() && (m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports || m_current == Seam ) && gizmo_event(SLAGizmoEventType::Dragging, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown())) { // the gizmo got the event and took some action, no need to do anything more here m_parent.set_as_dirty(); processed = true; } - else if (evt.LeftUp() && (m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports) && !m_parent.is_mouse_dragging()) + else if (evt.LeftUp() && (m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports || m_current == Seam) && !m_parent.is_mouse_dragging()) { // in case SLA/FDM gizmo is selected, we just pass the LeftUp event and stop processing - neither // object moving or selecting is suppressed in that case @@ -662,7 +668,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt) // to avoid to loose the selection when user clicks an the white faces of a different object while the Flatten gizmo is active processed = true; } - else if (evt.RightUp() && m_current == FdmSupports && !m_parent.is_mouse_dragging()) + else if (evt.RightUp() && (m_current == FdmSupports || m_current == Seam) && !m_parent.is_mouse_dragging()) { gizmo_event(SLAGizmoEventType::RightUp, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown()); processed = true; @@ -752,7 +758,7 @@ bool GLGizmosManager::on_char(wxKeyEvent& evt) case 'r' : case 'R' : { - if ((m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports) && gizmo_event(SLAGizmoEventType::ResetClippingPlane)) + if ((m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports || m_current == Seam) && gizmo_event(SLAGizmoEventType::ResetClippingPlane)) processed = true; break; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index b8b78eceb0..6b965525d5 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -67,6 +67,7 @@ public: Hollow, SlaSupports, FdmSupports, + Seam, Undefined }; From d904862bc708ee3571480cc97b84c2def389c84e Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 1 Sep 2020 19:04:22 +0200 Subject: [PATCH 253/255] Build libpng as part of deps on Linux - We've found counter case where the system provided one is missing or is too old. --- deps/deps-linux.cmake | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/deps/deps-linux.cmake b/deps/deps-linux.cmake index 3ad3cca64f..ae972327f8 100644 --- a/deps/deps-linux.cmake +++ b/deps/deps-linux.cmake @@ -3,10 +3,11 @@ set(DEP_CMAKE_OPTS "-DCMAKE_POSITION_INDEPENDENT_CODE=ON") include("deps-unix-common.cmake") -find_package(PNG QUIET) -if (NOT PNG_FOUND) - message(WARNING "No PNG dev package found in system, building static library. You should install the system package.") -endif () +# Some Linuxes may have very old libpng, so it's best to bundle it instead of relying on the system version. +# find_package(PNG QUIET) +# if (NOT PNG_FOUND) +# message(WARNING "No PNG dev package found in system, building static library. You should install the system package.") +# endif () #TODO UDEV From 9c59b4f9305bab09af75eb1b2d61efff177efeab Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Mon, 31 Aug 2020 07:25:43 +0200 Subject: [PATCH 254/255] Custom seam: Model integration, backend invalidation, 3MF loading/saving --- src/libslic3r/Format/3mf.cpp | 14 +++++++++++++- src/libslic3r/Model.cpp | 12 ++++++++++++ src/libslic3r/Model.hpp | 14 +++++++++++--- src/libslic3r/Print.cpp | 4 ++++ src/libslic3r/Print.hpp | 6 ++---- src/libslic3r/PrintObject.cpp | 12 +++++++----- src/libslic3r/SupportMaterial.cpp | 4 ++-- src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp | 4 ++-- 8 files changed, 53 insertions(+), 17 deletions(-) diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index 59dc85a0ae..92119f91c0 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -87,6 +87,7 @@ const char* TRANSFORM_ATTR = "transform"; const char* PRINTABLE_ATTR = "printable"; const char* INSTANCESCOUNT_ATTR = "instances_count"; const char* CUSTOM_SUPPORTS_ATTR = "slic3rpe:custom_supports"; +const char* CUSTOM_SEAM_ATTR = "slic3rpe:custom_seam"; const char* KEY_ATTR = "key"; const char* VALUE_ATTR = "value"; @@ -285,6 +286,7 @@ namespace Slic3r { std::vector vertices; std::vector triangles; std::vector custom_supports; + std::vector custom_seam; bool empty() { @@ -296,6 +298,7 @@ namespace Slic3r { vertices.clear(); triangles.clear(); custom_supports.clear(); + custom_seam.clear(); } }; @@ -1544,6 +1547,7 @@ namespace Slic3r { m_curr_object.geometry.triangles.push_back((unsigned int)get_attribute_value_int(attributes, num_attributes, V3_ATTR)); m_curr_object.geometry.custom_supports.push_back(get_attribute_value_string(attributes, num_attributes, CUSTOM_SUPPORTS_ATTR)); + m_curr_object.geometry.custom_seam.push_back(get_attribute_value_string(attributes, num_attributes, CUSTOM_SEAM_ATTR)); return true; } @@ -1877,14 +1881,18 @@ namespace Slic3r { volume->source.transform = Slic3r::Geometry::Transformation(volume_matrix_to_object); volume->calculate_convex_hull(); - // recreate custom supports from previously loaded attribute + // recreate custom supports and seam from previously loaded attribute for (unsigned i=0; im_supported_facets.set_triangle_from_string(i, geometry.custom_supports[index]); + if (! geometry.custom_seam[index].empty()) + volume->m_seam_facets.set_triangle_from_string(i, geometry.custom_seam[index]); } + // apply the remaining volume's metadata for (const Metadata& metadata : volume_data.metadata) { @@ -2401,6 +2409,10 @@ namespace Slic3r { if (! custom_supports_data_string.empty()) stream << CUSTOM_SUPPORTS_ATTR << "=\"" << custom_supports_data_string << "\" "; + std::string custom_seam_data_string = volume->m_seam_facets.get_triangle_as_string(i); + if (! custom_seam_data_string.empty()) + stream << CUSTOM_SEAM_ATTR << "=\"" << custom_seam_data_string << "\" "; + stream << "/>\n"; } } diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 196e9c213b..d12dc7a0f4 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -1007,6 +1007,7 @@ void ModelObject::convert_units(ModelObjectPtrs& new_objects, bool from_imperial for (ModelVolume* volume : volumes) { volume->m_supported_facets.clear(); + volume->m_seam_facets.clear(); if (!volume->mesh().empty()) { TriangleMesh mesh(volume->mesh()); mesh.require_shared_vertices(); @@ -1112,6 +1113,7 @@ ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z, bool keep_upper, b const auto volume_matrix = volume->get_matrix(); volume->m_supported_facets.clear(); + volume->m_seam_facets.clear(); if (! volume->is_model_part()) { // Modifiers are not cut, but we still need to add the instance transformation @@ -1993,6 +1995,16 @@ bool model_custom_supports_data_changed(const ModelObject& mo, const ModelObject return false; } +bool model_custom_seam_data_changed(const ModelObject& mo, const ModelObject& mo_new) { + assert(! model_volume_list_changed(mo, mo_new, ModelVolumeType::MODEL_PART)); + assert(mo.volumes.size() == mo_new.volumes.size()); + for (size_t i=0; im_seam_facets.is_same_as(mo.volumes[i]->m_seam_facets)) + return true; + } + return false; +} + extern bool model_has_multi_part_objects(const Model &model) { for (const ModelObject *model_object : model.objects) diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 608ce670f6..a623f5cca0 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -464,6 +464,9 @@ public: // List of mesh facets to be supported/unsupported. FacetsAnnotation m_supported_facets; + // List of seam enforcers/blockers. + FacetsAnnotation m_seam_facets; + // A parent object owning this modifier volume. ModelObject* get_object() const { return this->object; } ModelVolumeType type() const { return m_type; } @@ -593,7 +596,7 @@ private: ObjectBase(other), name(other.name), source(other.source), m_mesh(other.m_mesh), m_convex_hull(other.m_convex_hull), config(other.config), m_type(other.m_type), object(object), m_transformation(other.m_transformation), - m_supported_facets(other.m_supported_facets) + m_supported_facets(other.m_supported_facets), m_seam_facets(other.m_seam_facets) { assert(this->id().valid()); assert(this->config.id().valid()); assert(this->id() != this->config.id()); assert(this->id() == other.id() && this->config.id() == other.config.id()); @@ -612,6 +615,7 @@ private: assert(this->config.id().valid()); assert(this->config.id() != other.config.id()); assert(this->id() != this->config.id()); m_supported_facets.clear(); + m_seam_facets.clear(); } ModelVolume& operator=(ModelVolume &rhs) = delete; @@ -625,7 +629,7 @@ private: template void load(Archive &ar) { bool has_convex_hull; ar(name, source, m_mesh, m_type, m_material_id, m_transformation, - m_is_splittable, has_convex_hull, m_supported_facets); + m_is_splittable, has_convex_hull, m_supported_facets, m_seam_facets); cereal::load_by_value(ar, config); assert(m_mesh); if (has_convex_hull) { @@ -639,7 +643,7 @@ private: template void save(Archive &ar) const { bool has_convex_hull = m_convex_hull.get() != nullptr; ar(name, source, m_mesh, m_type, m_material_id, m_transformation, - m_is_splittable, has_convex_hull, m_supported_facets); + m_is_splittable, has_convex_hull, m_supported_facets, m_seam_facets); cereal::save_by_value(ar, config); if (has_convex_hull) cereal::save_optional(ar, m_convex_hull); @@ -904,6 +908,10 @@ extern bool model_volume_list_changed(const ModelObject &model_object_old, const // The function assumes that volumes list is synchronized. extern bool model_custom_supports_data_changed(const ModelObject& mo, const ModelObject& mo_new); +// Test whether the now ModelObject has newer custom seam data than the old one. +// The function assumes that volumes list is synchronized. +extern bool model_custom_seam_data_changed(const ModelObject& mo, const ModelObject& mo_new); + // If the model has multi-part objects, then it is currently not supported by the SLA mode. // Either the model cannot be loaded, or a SLA printer has to be activated. extern bool model_has_multi_part_objects(const Model &model); diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 0c8a11fcf0..37c0a7d154 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -404,6 +404,7 @@ static inline void model_volume_list_copy_configs(ModelObject &model_object_dst, mv_dst.name = mv_src.name; static_cast(mv_dst.config) = static_cast(mv_src.config); mv_dst.m_supported_facets = mv_src.m_supported_facets; + mv_dst.m_seam_facets = mv_src.m_seam_facets; //FIXME what to do with the materials? // mv_dst.m_material_id = mv_src.m_material_id; ++ i_src; @@ -867,6 +868,9 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ model_volume_list_update_supports(model_object, model_object_new); } } + if (model_custom_seam_data_changed(model_object, model_object_new)) { + update_apply_status(this->invalidate_step(psGCodeExport)); + } if (! model_parts_differ && ! modifiers_differ) { // Synchronize Object's config. bool object_config_changed = model_object.config != model_object_new.config; diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 08acb7a105..6cb80c1f44 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -186,10 +186,8 @@ public: std::vector slice_support_blockers() const { return this->slice_support_volumes(ModelVolumeType::SUPPORT_BLOCKER); } std::vector slice_support_enforcers() const { return this->slice_support_volumes(ModelVolumeType::SUPPORT_ENFORCER); } - // Helpers to project custom supports on slices - void project_and_append_custom_supports(EnforcerBlockerType type, std::vector& expolys) const; - void project_and_append_custom_enforcers(std::vector& enforcers) const { project_and_append_custom_supports(EnforcerBlockerType::ENFORCER, enforcers); } - void project_and_append_custom_blockers(std::vector& blockers) const { project_and_append_custom_supports(EnforcerBlockerType::BLOCKER, blockers); } + // Helpers to project custom facets on slices + void project_and_append_custom_facets(bool seam, EnforcerBlockerType type, std::vector& expolys) const; private: // to be called from Print only. diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index ddeee1e778..aecf907710 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -2669,12 +2669,14 @@ void PrintObject::_generate_support_material() } -void PrintObject::project_and_append_custom_supports( - EnforcerBlockerType type, std::vector& expolys) const +void PrintObject::project_and_append_custom_facets( + bool seam, EnforcerBlockerType type, std::vector& expolys) const { for (const ModelVolume* mv : this->model_object()->volumes) { - const indexed_triangle_set custom_facets = mv->m_supported_facets.get_facets(*mv, type); - if (custom_facets.indices.empty()) + const indexed_triangle_set custom_facets = seam + ? mv->m_seam_facets.get_facets(*mv, type) + : mv->m_supported_facets.get_facets(*mv, type); + if (! mv->is_model_part() || custom_facets.indices.empty()) continue; const Transform3f& tr1 = mv->get_matrix().cast(); @@ -2721,7 +2723,7 @@ void PrintObject::project_and_append_custom_supports( // Ignore triangles with upward-pointing normal. Don't forget about mirroring. float z_comp = (facet[1]-facet[0]).cross(facet[2]-facet[0]).z(); - if (tr_det_sign * z_comp > 0.) + if (! seam && tr_det_sign * z_comp > 0.) continue; // Sort the three vertices according to z-coordinate. diff --git a/src/libslic3r/SupportMaterial.cpp b/src/libslic3r/SupportMaterial.cpp index 95b4c334b1..1669f60d21 100644 --- a/src/libslic3r/SupportMaterial.cpp +++ b/src/libslic3r/SupportMaterial.cpp @@ -972,8 +972,8 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_ std::vector blockers = object.slice_support_blockers(); // Append custom supports. - object.project_and_append_custom_enforcers(enforcers); - object.project_and_append_custom_blockers(blockers); + object.project_and_append_custom_facets(false, EnforcerBlockerType::ENFORCER, enforcers); + object.project_and_append_custom_facets(false, EnforcerBlockerType::BLOCKER, blockers); // Output layers, sorted by top Z. MyLayersPtr contact_out; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp index 8a08f5ebe7..3c7d180a7b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp @@ -172,7 +172,7 @@ void GLGizmoSeam::update_model_object() const if (! mv->is_model_part()) continue; ++idx; - updated |= mv->m_supported_facets.set(*m_triangle_selectors[idx].get()); + updated |= mv->m_seam_facets.set(*m_triangle_selectors[idx].get()); } if (updated) @@ -199,7 +199,7 @@ void GLGizmoSeam::update_from_model_object() const TriangleMesh* mesh = &mv->mesh(); m_triangle_selectors.emplace_back(std::make_unique(*mesh)); - m_triangle_selectors.back()->deserialize(mv->m_supported_facets.get_data()); + m_triangle_selectors.back()->deserialize(mv->m_seam_facets.get_data()); } } From 46eb96e84fac3e38734c9b0aefaf829a3e028538 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 1 Sep 2020 23:26:08 +0200 Subject: [PATCH 255/255] Added two missing icons to fix build on Linux --- src/slic3r/GUI/ConfigWizard.cpp | 1 + src/slic3r/GUI/ConfigWizard_private.hpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index f8abfb1788..2cedbfdf78 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include diff --git a/src/slic3r/GUI/ConfigWizard_private.hpp b/src/slic3r/GUI/ConfigWizard_private.hpp index f7987a8908..260eeb22cb 100644 --- a/src/slic3r/GUI/ConfigWizard_private.hpp +++ b/src/slic3r/GUI/ConfigWizard_private.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include