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);