diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp index 048aea886..4557caa7c 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 6717e961d..701ca4377 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -698,11 +698,13 @@ std::vector<std::pair<coordf_t, std::vector<GCode::LayerToPrint>>> 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<unsigned int>(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 e3da956c2..4b66d1521 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 08066ee57..493321a6e 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 0a3dae032..7fa1733b7 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<MoveStep>; + public: + typedef std::map<unsigned int, Vec2d> ExtruderOffsetsMap; + struct Result + { + std::vector<MoveVertex> moves; + void reset() { moves = std::vector<MoveVertex>(); } + }; + + 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 d5a1fa178..d342c9056 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 7b326472e..ef5548222 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 e5a2f3fae..4cebe98b1 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 548a19f77..126a77ae7 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<PrinterTechnology>("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 c8ece38f0..5b6f09d27 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 b5319a2f1..b96b8b47f 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<std::string>& str_tool_colors) { const Print *print = this->fff_print(); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 9ae127880..0dc2b26dd 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 <float.h> @@ -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<std::string>& str_tool_colors); void load_sla_preview(); void load_preview(const std::vector<std::string>& str_tool_colors, const std::vector<CustomGCode::Item>& color_print_values); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 5afdb3bb4..d0493adfc 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<void()> 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<void()> 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 cc8f15325..f0e7abfec 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -6,6 +6,9 @@ #include <string> #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<void()> 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<void()> 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<void()> 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 317181887..3886d5f35 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 b3c16f4b0..50b338325 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<char>(t)), std::istreambuf_iterator<char>()); 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 3378a8363..3d3b54ef0 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);