mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	GCodeViewer -> Extrusion toolpaths colored by color print (wip) + visualization of tool changes, color changes, pause prints, custom gcodes + refactoring
This commit is contained in:
		
							parent
							
								
									603f128568
								
							
						
					
					
						commit
						7a0df4bcb4
					
				
					 16 changed files with 516 additions and 77 deletions
				
			
		
							
								
								
									
										45
									
								
								resources/shaders/colorchanges.fs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								resources/shaders/colorchanges.fs
									
										
									
									
									
										Normal file
									
								
							|  | @ -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); | ||||||
|  | } | ||||||
							
								
								
									
										17
									
								
								resources/shaders/colorchanges.vs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								resources/shaders/colorchanges.vs
									
										
									
									
									
										Normal file
									
								
							|  | @ -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; | ||||||
|  | } | ||||||
							
								
								
									
										45
									
								
								resources/shaders/customs.fs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								resources/shaders/customs.fs
									
										
									
									
									
										Normal file
									
								
							|  | @ -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); | ||||||
|  | } | ||||||
							
								
								
									
										17
									
								
								resources/shaders/customs.vs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								resources/shaders/customs.vs
									
										
									
									
									
										Normal file
									
								
							|  | @ -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; | ||||||
|  | } | ||||||
							
								
								
									
										45
									
								
								resources/shaders/pauses.fs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								resources/shaders/pauses.fs
									
										
									
									
									
										Normal file
									
								
							|  | @ -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); | ||||||
|  | } | ||||||
							
								
								
									
										17
									
								
								resources/shaders/pauses.vs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								resources/shaders/pauses.vs
									
										
									
									
									
										Normal file
									
								
							|  | @ -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; | ||||||
|  | } | ||||||
|  | @ -2329,11 +2329,13 @@ void GCode::process_layer( | ||||||
|         gcode += "\n; " + GCodeAnalyzer::End_Pause_Print_Or_Custom_Code_Tag + "\n"; |         gcode += "\n; " + GCodeAnalyzer::End_Pause_Print_Or_Custom_Code_Tag + "\n"; | ||||||
| 
 | 
 | ||||||
| #if ENABLE_GCODE_VIEWER | #if ENABLE_GCODE_VIEWER | ||||||
|  | #if !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT | ||||||
|     // add tag for processor
 |     // add tag for processor
 | ||||||
|     if (gcode.find(GCodeProcessor::Pause_Print_Tag) != gcode.npos) |     if (gcode.find(GCodeProcessor::Pause_Print_Tag) != gcode.npos) | ||||||
|         gcode += "\n; " + GCodeProcessor::End_Pause_Print_Or_Custom_Code_Tag + "\n"; |         gcode += "\n; " + GCodeProcessor::End_Pause_Print_Or_Custom_Code_Tag + "\n"; | ||||||
|     else if (gcode.find(GCodeProcessor::Custom_Code_Tag) != gcode.npos) |     else if (gcode.find(GCodeProcessor::Custom_Code_Tag) != gcode.npos) | ||||||
|         gcode += "\n; " + GCodeProcessor::End_Pause_Print_Or_Custom_Code_Tag + "\n"; |         gcode += "\n; " + GCodeProcessor::End_Pause_Print_Or_Custom_Code_Tag + "\n"; | ||||||
|  | #endif // !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT
 | ||||||
| #endif // ENABLE_GCODE_VIEWER
 | #endif // ENABLE_GCODE_VIEWER
 | ||||||
| 
 | 
 | ||||||
| #ifdef HAS_PRESSURE_EQUALIZER | #ifdef HAS_PRESSURE_EQUALIZER | ||||||
|  |  | ||||||
|  | @ -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::Color_Change_Tag   = "_PROCESSOR_COLOR_CHANGE"; | ||||||
| const std::string GCodeProcessor::Pause_Print_Tag    = "_PROCESSOR_PAUSE_PRINT"; | const std::string GCodeProcessor::Pause_Print_Tag    = "_PROCESSOR_PAUSE_PRINT"; | ||||||
| const std::string GCodeProcessor::Custom_Code_Tag    = "_PROCESSOR_CUSTOM_CODE"; | 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"; | 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() | void GCodeProcessor::CachedPosition::reset() | ||||||
| { | { | ||||||
|  | @ -236,13 +238,20 @@ void GCodeProcessor::process_tags(const std::string& comment) | ||||||
|         pos = comment.find_last_of(",T"); |         pos = comment.find_last_of(",T"); | ||||||
|         try |         try | ||||||
|         { |         { | ||||||
|             unsigned char extruder_id = (pos == comment.npos) ? 0 : static_cast<unsigned char>(std::stoi(comment.substr(pos + 1, comment.npos))); |             unsigned char extruder_id = (pos == comment.npos) ? 0 : static_cast<unsigned char>(std::stoi(comment.substr(pos + 1))); | ||||||
| 
 | 
 | ||||||
|             m_extruders_color[extruder_id] = static_cast<unsigned char>(m_extruder_offsets.size()) + m_cp_color.counter; // color_change position in list of color for preview
 |             m_extruders_color[extruder_id] = static_cast<unsigned char>(m_extruder_offsets.size()) + m_cp_color.counter; // color_change position in list of color for preview
 | ||||||
|             ++m_cp_color.counter; |             ++m_cp_color.counter; | ||||||
|  |             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]; |                 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 (...) |         catch (...) | ||||||
|         { |         { | ||||||
|  | @ -256,7 +265,11 @@ void GCodeProcessor::process_tags(const std::string& comment) | ||||||
|     pos = comment.find(Pause_Print_Tag); |     pos = comment.find(Pause_Print_Tag); | ||||||
|     if (pos != comment.npos) |     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; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -264,19 +277,25 @@ void GCodeProcessor::process_tags(const std::string& comment) | ||||||
|     pos = comment.find(Custom_Code_Tag); |     pos = comment.find(Custom_Code_Tag); | ||||||
|     if (pos != comment.npos) |     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; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | #if !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT | ||||||
|     // end pause print or custom code tag
 |     // end pause print or custom code tag
 | ||||||
|     pos = comment.find(End_Pause_Print_Or_Custom_Code_Tag); |     pos = comment.find(End_Pause_Print_Or_Custom_Code_Tag); | ||||||
|     if (pos != comment.npos) |     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]; |             m_cp_color.current = m_extruders_color[m_extruder_id]; | ||||||
| 
 | 
 | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  | #endif // !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) | void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) | ||||||
|  | @ -569,7 +588,9 @@ void GCodeProcessor::process_T(const std::string& command) | ||||||
|                 else |                 else | ||||||
|                 { |                 { | ||||||
|                     m_extruder_id = id; |                     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]; |                         m_cp_color.current = m_extruders_color[id]; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -21,7 +21,9 @@ namespace Slic3r { | ||||||
|         static const std::string Color_Change_Tag; |         static const std::string Color_Change_Tag; | ||||||
|         static const std::string Pause_Print_Tag; |         static const std::string Pause_Print_Tag; | ||||||
|         static const std::string Custom_Code_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; |         static const std::string End_Pause_Print_Or_Custom_Code_Tag; | ||||||
|  | #endif // !ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT
 | ||||||
| 
 | 
 | ||||||
|     private: |     private: | ||||||
|         using AxisCoords = std::array<float, 4>; |         using AxisCoords = std::array<float, 4>; | ||||||
|  | @ -62,6 +64,11 @@ namespace Slic3r { | ||||||
|             Retract, |             Retract, | ||||||
|             Unretract, |             Unretract, | ||||||
|             Tool_change, |             Tool_change, | ||||||
|  | #if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT | ||||||
|  |             Color_change, | ||||||
|  |             Pause_Print, | ||||||
|  |             Custom_GCode, | ||||||
|  | #endif // ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT
 | ||||||
|             Travel, |             Travel, | ||||||
|             Extrude, |             Extrude, | ||||||
|             Count |             Count | ||||||
|  |  | ||||||
|  | @ -59,6 +59,7 @@ | ||||||
| // Enable G-Code viewer
 | // Enable G-Code viewer
 | ||||||
| #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) | #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) | ||||||
| #define ENABLE_GCODE_VIEWER_DEBUG_OUTPUT (0 && ENABLE_GCODE_VIEWER) | #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_
 | #endif // _prusaslicer_technologies_h_
 | ||||||
|  |  | ||||||
|  | @ -7,9 +7,10 @@ | ||||||
| #include "PresetBundle.hpp" | #include "PresetBundle.hpp" | ||||||
| #include "Camera.hpp" | #include "Camera.hpp" | ||||||
| #include "I18N.hpp" | #include "I18N.hpp" | ||||||
| #include "libslic3r/I18N.hpp" |  | ||||||
| #if ENABLE_GCODE_VIEWER | #if ENABLE_GCODE_VIEWER | ||||||
| #include "GUI_Utils.hpp" | #include "GUI_Utils.hpp" | ||||||
|  | #include "DoubleSlider.hpp" | ||||||
|  | #include "libslic3r/Model.hpp" | ||||||
| #endif // ENABLE_GCODE_VIEWER
 | #endif // ENABLE_GCODE_VIEWER
 | ||||||
| 
 | 
 | ||||||
| #include <GL/glew.h> | #include <GL/glew.h> | ||||||
|  | @ -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) | void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move) | ||||||
| { | { | ||||||
|     unsigned int id = static_cast<unsigned int>(data.size()); |     unsigned int id = static_cast<unsigned int>(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<float, 3> GCodeViewer::Extrusions::Range::get_color_at(float value) const | std::array<float, 3> GCodeViewer::Extrusions::Range::get_color_at(float value) const | ||||||
|  | @ -123,8 +124,8 @@ std::array<float, 3> GCodeViewer::Extrusions::Range::get_color_at(float value) c | ||||||
|     return ret; |     return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const std::array<std::array<float, 3>, erCount> GCodeViewer::Extrusion_Role_Colors {{ | const std::vector<std::array<float, 3>> GCodeViewer::Extrusion_Role_Colors {{ | ||||||
|     { 1.00f, 1.00f, 1.00f },   // erNone
 |     { 0.50f, 0.50f, 0.50f },   // erNone
 | ||||||
|     { 1.00f, 1.00f, 0.40f },   // erPerimeter
 |     { 1.00f, 1.00f, 0.40f },   // erPerimeter
 | ||||||
|     { 1.00f, 0.65f, 0.00f },   // erExternalPerimeter
 |     { 1.00f, 0.65f, 0.00f },   // erExternalPerimeter
 | ||||||
|     { 0.00f, 0.00f, 1.00f },   // erOverhangPerimeter
 |     { 0.00f, 0.00f, 1.00f },   // erOverhangPerimeter
 | ||||||
|  | @ -141,7 +142,7 @@ const std::array<std::array<float, 3>, erCount> GCodeViewer::Extrusion_Role_Colo | ||||||
|     { 0.00f, 0.00f, 0.00f }    // erMixed
 |     { 0.00f, 0.00f, 0.00f }    // erMixed
 | ||||||
| }}; | }}; | ||||||
| 
 | 
 | ||||||
| const std::array<std::array<float, 3>, GCodeViewer::Range_Colors_Count> GCodeViewer::Range_Colors {{ | const std::vector<std::array<float, 3>> GCodeViewer::Range_Colors {{ | ||||||
|     { 0.043f, 0.173f, 0.478f }, // bluish
 |     { 0.043f, 0.173f, 0.478f }, // bluish
 | ||||||
|     { 0.075f, 0.349f, 0.522f }, |     { 0.075f, 0.349f, 0.522f }, | ||||||
|     { 0.110f, 0.533f, 0.569f }, |     { 0.110f, 0.533f, 0.569f }, | ||||||
|  | @ -154,7 +155,7 @@ const std::array<std::array<float, 3>, GCodeViewer::Range_Colors_Count> GCodeVie | ||||||
|     { 0.761f, 0.322f, 0.235f }  // reddish
 |     { 0.761f, 0.322f, 0.235f }  // reddish
 | ||||||
| }}; | }}; | ||||||
| 
 | 
 | ||||||
| void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const std::vector<std::string>& 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
 |     // avoid processing if called with the same gcode_result
 | ||||||
|     if (m_last_result_id == gcode_result.id) |     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
 |     // release gpu memory, if used
 | ||||||
|     reset(); |     reset(); | ||||||
| 
 | 
 | ||||||
|     m_tool_colors = decode_colors(str_tool_colors); |  | ||||||
| 
 |  | ||||||
|     load_toolpaths(gcode_result); |     load_toolpaths(gcode_result); | ||||||
|     load_shells(print, initialized); |     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<std::string>& str_tool_colors) | ||||||
| { | { | ||||||
|     if (m_vertices.vertices_count == 0) |     if (m_vertices.vertices_count == 0) | ||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|  |     m_tool_colors = decode_colors(str_tool_colors); | ||||||
|  | 
 | ||||||
|     m_extrusions.reset_ranges(); |     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) | ||||||
|  | @ -217,6 +218,8 @@ void GCodeViewer::reset() | ||||||
| 
 | 
 | ||||||
|     m_bounding_box = BoundingBoxf3(); |     m_bounding_box = BoundingBoxf3(); | ||||||
|     m_tool_colors = std::vector<std::array<float, 3>>(); |     m_tool_colors = std::vector<std::array<float, 3>>(); | ||||||
|  |     m_extruder_ids = std::vector<unsigned char>(); | ||||||
|  | //    m_cp_color_ids = std::vector<unsigned char>();
 | ||||||
|     m_extrusions.reset_role_visibility_flags(); |     m_extrusions.reset_role_visibility_flags(); | ||||||
|     m_extrusions.reset_ranges(); |     m_extrusions.reset_ranges(); | ||||||
|     m_shells.volumes.clear(); |     m_shells.volumes.clear(); | ||||||
|  | @ -257,11 +260,16 @@ bool GCodeViewer::init_shaders() | ||||||
| 
 | 
 | ||||||
|         switch (buffer_type(i)) |         switch (buffer_type(i)) | ||||||
|         { |         { | ||||||
|         case GCodeProcessor::EMoveType::Tool_change: { vertex_shader = "toolchanges.vs"; fragment_shader = "toolchanges.fs"; break; } |         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; } | #if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT | ||||||
|         case GCodeProcessor::EMoveType::Unretract:   { vertex_shader = "unretractions.vs"; fragment_shader = "unretractions.fs"; break; } |         case GCodeProcessor::EMoveType::Color_change: { vertex_shader = "colorchanges.vs"; fragment_shader = "colorchanges.fs"; break; } | ||||||
|         case GCodeProcessor::EMoveType::Extrude:     { vertex_shader = "extrusions.vs"; fragment_shader = "extrusions.fs"; break; } |         case GCodeProcessor::EMoveType::Pause_Print:  { vertex_shader = "pauses.vs"; fragment_shader = "pauses.fs"; break; } | ||||||
|         case GCodeProcessor::EMoveType::Travel:      { vertex_shader = "travels.vs"; fragment_shader = "travels.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; } |         default: { break; } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -322,6 +330,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) | ||||||
|         switch (curr.type) |         switch (curr.type) | ||||||
|         { |         { | ||||||
|         case GCodeProcessor::EMoveType::Tool_change: |         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::Retract: | ||||||
|         case GCodeProcessor::EMoveType::Unretract: |         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) |     for (const GCodeProcessor::MoveVertex& move : gcode_result.moves) | ||||||
|     { |     { | ||||||
|         if (move.type == GCodeProcessor::EMoveType::Extrude) |         if (move.type == GCodeProcessor::EMoveType::Extrude) | ||||||
|             m_layers_zs.emplace_back(move.position[2]); |             m_layers_zs.emplace_back(move.position[2]); | ||||||
| 
 | 
 | ||||||
|         m_roles.emplace_back(move.extrusion_role); |         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.
 |     // 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()); |     std::sort(m_roles.begin(), m_roles.end()); | ||||||
|     m_roles.erase(std::unique(m_roles.begin(), m_roles.end()), 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(); |     auto end_time = std::chrono::high_resolution_clock::now(); | ||||||
|     std::cout << "toolpaths generation time: " << std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count() << "ms \n"; |     std::cout << "toolpaths generation time: " << std::chrono::duration_cast<std::chrono::milliseconds>(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::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::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::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; } |         default:                        { color = { 1.0f, 1.0f, 1.0f }; break; } | ||||||
|         } |         } | ||||||
|         return color; |         return color; | ||||||
|  | @ -482,7 +505,7 @@ void GCodeViewer::render_toolpaths() const | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     glsafe(::glCullFace(GL_BACK)); |     glsafe(::glCullFace(GL_BACK)); | ||||||
|     glsafe(::glLineWidth(1.0f)); |     glsafe(::glLineWidth(3.0f)); | ||||||
| 
 | 
 | ||||||
|     unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); |     unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); | ||||||
|     unsigned char end_id = buffer_id(GCodeProcessor::EMoveType::Count); |     unsigned char end_id = buffer_id(GCodeProcessor::EMoveType::Count); | ||||||
|  | @ -522,6 +545,35 @@ void GCodeViewer::render_toolpaths() const | ||||||
|                 glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); |                 glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|  | #if ENABLE_GCODE_VIEWER_SEPARATE_PAUSE_PRINT | ||||||
|  |             case GCodeProcessor::EMoveType::Color_change: | ||||||
|  |             { | ||||||
|  |                 std::array<float, 3> 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<float, 3> 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<float, 3> 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: |             case GCodeProcessor::EMoveType::Retract: | ||||||
|             { |             { | ||||||
|                 std::array<float, 3> color = { 1.0f, 0.0f, 1.0f }; |                 std::array<float, 3> color = { 1.0f, 0.0f, 1.0f }; | ||||||
|  | @ -533,7 +585,7 @@ void GCodeViewer::render_toolpaths() const | ||||||
|             } |             } | ||||||
|             case GCodeProcessor::EMoveType::Unretract: |             case GCodeProcessor::EMoveType::Unretract: | ||||||
|             { |             { | ||||||
|                 std::array<float, 3> color = { 0.0f, 1.0f, 0.0f }; |                 std::array<float, 3> color = { 0.0f, 1.0f, 1.0f }; | ||||||
|                 set_color(current_program_id, color); |                 set_color(current_program_id, color); | ||||||
|                 glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); |                 glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); | ||||||
|                 glsafe(::glDrawElements(GL_POINTS, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); |                 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(); |     ImDrawList* draw_list = ImGui::GetWindowDrawList(); | ||||||
| 
 | 
 | ||||||
|     auto add_range = [this, draw_list, &imgui](const Extrusions::Range& range, unsigned int decimals) { |     auto add_item = [draw_list, &imgui](const std::array<float, 3>& color, const std::string& label) { | ||||||
|         auto add_item = [this, draw_list, &imgui](int i, float value, unsigned int decimals) { |         ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f); | ||||||
|             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); | ||||||
|             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)); | ||||||
|             const std::array<float, 3>& color = Range_Colors[i]; |         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); | ||||||
|             ImU32 fill_color = ImGui::GetColorU32(ImVec4(color[0], color[1], color[2], 1.0f)); |         ImGui::SetCursorPosX(pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT); | ||||||
|             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::AlignTextToFramePadding(); | ||||||
|             ImGui::SetCursorPosX(pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT); |         imgui.text(label); | ||||||
|             ImGui::AlignTextToFramePadding(); |     }; | ||||||
|  | 
 | ||||||
|  |     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]; |             char buf[1024]; | ||||||
|             ::sprintf(buf, "%.*f", decimals, value); |             ::sprintf(buf, "%.*f", decimals, value); | ||||||
|             imgui.text(buf); |             add_item(Range_Colors[i], buf); | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         float step_size = range.step_size(); |         float step_size = range.step_size(); | ||||||
|         if (step_size == 0.0f) |         if (step_size == 0.0f) | ||||||
|             add_item(0, range.min, decimals); |             // single item use case
 | ||||||
|  |             add_range_item(0, range.min, decimals); | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
|             for (int i = Range_Colors_Count - 1; i >= 0; --i) |             for (int i = static_cast<int>(Range_Colors.size()) - 1; i >= 0; --i) | ||||||
|             { |             { | ||||||
|                 add_item(i, range.min + static_cast<float>(i) * step_size, decimals); |                 add_range_item(i, range.min + static_cast<float>(i) * step_size, decimals); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|  | @ -634,14 +690,15 @@ void GCodeViewer::render_overlay() const | ||||||
|     ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); |     ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); | ||||||
|     switch (m_view_type) |     switch (m_view_type) | ||||||
|     { |     { | ||||||
|     case EViewType::FeatureType:    { imgui.text(Slic3r::I18N::translate(L("Feature type"))); break; } |     case EViewType::FeatureType:    { imgui.text(I18N::translate_utf8(L("Feature type"))); break; } | ||||||
|     case EViewType::Height:         { imgui.text(Slic3r::I18N::translate(L("Height (mm)"))); break; } |     case EViewType::Height:         { imgui.text(I18N::translate_utf8(L("Height (mm)"))); break; } | ||||||
|     case EViewType::Width:          { imgui.text(Slic3r::I18N::translate(L("Width (mm)"))); break; } |     case EViewType::Width:          { imgui.text(I18N::translate_utf8(L("Width (mm)"))); break; } | ||||||
|     case EViewType::Feedrate:       { imgui.text(Slic3r::I18N::translate(L("Speed (mm/s)"))); break; } |     case EViewType::Feedrate:       { imgui.text(I18N::translate_utf8(L("Speed (mm/s)"))); break; } | ||||||
|     case EViewType::FanSpeed:       { imgui.text(Slic3r::I18N::translate(L("Fan Speed (%)"))); break; } |     case EViewType::FanSpeed:       { imgui.text(I18N::translate_utf8(L("Fan Speed (%)"))); break; } | ||||||
|     case EViewType::VolumetricRate: { imgui.text(Slic3r::I18N::translate(L("Volumetric flow rate (mm³/s)"))); break; } |     case EViewType::VolumetricRate: { imgui.text(I18N::translate_utf8(L("Volumetric flow rate (mm³/s)"))); break; } | ||||||
|     case EViewType::Tool:           { imgui.text(Slic3r::I18N::translate(L("Tool"))); break; } |     case EViewType::Tool:           { imgui.text(I18N::translate_utf8(L("Tool"))); break; } | ||||||
|     case EViewType::ColorPrint:     { imgui.text(Slic3r::I18N::translate(L("Color Print"))); break; } |     case EViewType::ColorPrint:     { imgui.text(I18N::translate_utf8(L("Color Print"))); break; } | ||||||
|  |     default:                        { break; } | ||||||
|     } |     } | ||||||
|     ImGui::PopStyleColor(); |     ImGui::PopStyleColor(); | ||||||
| 
 | 
 | ||||||
|  | @ -653,14 +710,7 @@ void GCodeViewer::render_overlay() const | ||||||
|     { |     { | ||||||
|         for (ExtrusionRole role : m_roles) |         for (ExtrusionRole role : m_roles) | ||||||
|         { |         { | ||||||
|             ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f); |             add_item(Extrusion_Role_Colors[static_cast<unsigned int>(role)], I18N::translate_utf8(ExtrusionEntity::role_to_string(role))); | ||||||
|             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<float, 3>& color = Extrusion_Role_Colors[static_cast<unsigned int>(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))); |  | ||||||
|         } |         } | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|  | @ -674,18 +724,82 @@ void GCodeViewer::render_overlay() const | ||||||
|         size_t tools_count = m_tool_colors.size(); |         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) | ||||||
|         { |         { | ||||||
|             ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f); |             auto it = std::find(m_extruder_ids.begin(), m_extruder_ids.end(), static_cast<unsigned char>(i)); | ||||||
|             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); |             if (it == m_extruder_ids.end()) | ||||||
|             const std::array<float, 3>& color = m_tool_colors[i]; |                 continue; | ||||||
|             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); |             add_item(m_tool_colors[i], (boost::format(I18N::translate_utf8(L("Extruder %d"))) % (i + 1)).str()); | ||||||
|             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; |         break; | ||||||
|     } |     } | ||||||
|     case EViewType::ColorPrint: { break; } |     case EViewType::ColorPrint: | ||||||
|  |     { | ||||||
|  |         const std::vector<CustomGCode::Item>& 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<std::pair<double, double>> 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<int>(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(); |     imgui.end(); | ||||||
|  |  | ||||||
|  | @ -15,9 +15,8 @@ namespace GUI { | ||||||
| 
 | 
 | ||||||
| class GCodeViewer | class GCodeViewer | ||||||
| { | { | ||||||
|     static const std::array<std::array<float, 3>, erCount> Extrusion_Role_Colors; |     static const std::vector<std::array<float, 3>> Extrusion_Role_Colors; | ||||||
|     static const size_t Range_Colors_Count = 10; |     static const std::vector<std::array<float, 3>> Range_Colors; | ||||||
|     static const std::array<std::array<float, 3>, Range_Colors_Count> Range_Colors; |  | ||||||
| 
 | 
 | ||||||
|     // buffer containing vertices data
 |     // buffer containing vertices data
 | ||||||
|     struct VBuffer |     struct VBuffer | ||||||
|  | @ -46,11 +45,12 @@ class GCodeViewer | ||||||
|         float fan_speed{ 0.0f }; |         float fan_speed{ 0.0f }; | ||||||
|         float volumetric_rate{ 0.0f }; |         float volumetric_rate{ 0.0f }; | ||||||
|         unsigned char extruder_id{ 0 }; |         unsigned char extruder_id{ 0 }; | ||||||
|  |         unsigned char cp_color_id{ 0 }; | ||||||
| 
 | 
 | ||||||
|         bool matches(const GCodeProcessor::MoveVertex& move) const { |         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 && 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; |                 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 update_from(const float value) { min = std::min(min, value); max = std::max(max, value); } | ||||||
|             void reset() { min = FLT_MAX; max = -FLT_MAX; } |             void reset() { min = FLT_MAX; max = -FLT_MAX; } | ||||||
| 
 | 
 | ||||||
|             float step_size() const { return (max - min) / (static_cast<float>(Range_Colors_Count) - 1.0f); } |             float step_size() const { return (max - min) / (static_cast<float>(Range_Colors.size()) - 1.0f); } | ||||||
|             std::array<float, 3> get_color_at(float value) const; |             std::array<float, 3> get_color_at(float value) const; | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|  | @ -155,6 +155,8 @@ private: | ||||||
|     std::vector<std::array<float, 3>> m_tool_colors; |     std::vector<std::array<float, 3>> m_tool_colors; | ||||||
|     std::vector<double> m_layers_zs; |     std::vector<double> m_layers_zs; | ||||||
|     std::vector<ExtrusionRole> m_roles; |     std::vector<ExtrusionRole> m_roles; | ||||||
|  |     std::vector<unsigned char> m_extruder_ids; | ||||||
|  | //    std::vector<unsigned char> m_cp_color_ids;
 | ||||||
|     Extrusions m_extrusions; |     Extrusions m_extrusions; | ||||||
|     Shells m_shells; |     Shells m_shells; | ||||||
|     EViewType m_view_type{ EViewType::FeatureType }; |     EViewType m_view_type{ EViewType::FeatureType }; | ||||||
|  | @ -170,9 +172,9 @@ public: | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // extract rendering data from the given parameters
 |     // extract rendering data from the given parameters
 | ||||||
|     void load(const GCodeProcessor::Result& gcode_result, const std::vector<std::string>& str_tool_colors, const Print& print, bool initialized); |     void load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized); | ||||||
|     // recalculate ranges in dependence of what is visible
 |     // recalculate ranges in dependence of what is visible and sets tool/print colors
 | ||||||
|     void refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result); |     void refresh(const GCodeProcessor::Result& gcode_result, const std::vector<std::string>& str_tool_colors); | ||||||
| 
 | 
 | ||||||
|     void reset(); |     void reset(); | ||||||
|     void render() const; |     void render() const; | ||||||
|  |  | ||||||
|  | @ -2835,7 +2835,7 @@ static void load_gcode_retractions(const GCodePreviewData::Retraction& retractio | ||||||
| #endif // !ENABLE_GCODE_VIEWER
 | #endif // !ENABLE_GCODE_VIEWER
 | ||||||
| 
 | 
 | ||||||
| #if ENABLE_GCODE_VIEWER | #if ENABLE_GCODE_VIEWER | ||||||
| void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector<std::string>& str_tool_colors) | void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result) | ||||||
| { | { | ||||||
| #if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT | #if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT | ||||||
|     static unsigned int last_result_id = 0; |     static unsigned int last_result_id = 0; | ||||||
|  | @ -2852,12 +2852,12 @@ void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result, | ||||||
|         out.close(); |         out.close(); | ||||||
|     } |     } | ||||||
| #endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT
 | #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<std::string>& str_tool_colors) | ||||||
| { | { | ||||||
|     m_gcode_viewer.refresh_toolpaths_ranges(gcode_result); |     m_gcode_viewer.refresh(gcode_result, str_tool_colors); | ||||||
| } | } | ||||||
| #endif // ENABLE_GCODE_VIEWER
 | #endif // ENABLE_GCODE_VIEWER
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -664,8 +664,10 @@ public: | ||||||
|     void reload_scene(bool refresh_immediately, bool force_full_scene_refresh = false); |     void reload_scene(bool refresh_immediately, bool force_full_scene_refresh = false); | ||||||
| 
 | 
 | ||||||
| #if ENABLE_GCODE_VIEWER | #if ENABLE_GCODE_VIEWER | ||||||
|     void load_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector<std::string>& str_tool_colors); |     void load_gcode_preview(const GCodeProcessor::Result& gcode_result); | ||||||
|     void refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result); |     void refresh_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector<std::string>& 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 | #else | ||||||
|     void load_gcode_preview(const GCodePreviewData& preview_data, const std::vector<std::string>& str_tool_colors); |     void load_gcode_preview(const GCodePreviewData& preview_data, const std::vector<std::string>& str_tool_colors); | ||||||
| #endif // ENABLE_GCODE_VIEWER
 | #endif // ENABLE_GCODE_VIEWER
 | ||||||
|  |  | ||||||
|  | @ -229,6 +229,12 @@ Preview::Preview( | ||||||
|     , m_checkbox_travel(nullptr) |     , m_checkbox_travel(nullptr) | ||||||
|     , m_checkbox_retractions(nullptr) |     , m_checkbox_retractions(nullptr) | ||||||
|     , m_checkbox_unretractions(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_shells(nullptr) | ||||||
|     , m_checkbox_legend(nullptr) |     , m_checkbox_legend(nullptr) | ||||||
|     , m_config(config) |     , 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_travel = new wxCheckBox(this, wxID_ANY, _(L("Travel"))); | ||||||
|     m_checkbox_retractions = new wxCheckBox(this, wxID_ANY, _(L("Retractions"))); |     m_checkbox_retractions = new wxCheckBox(this, wxID_ANY, _(L("Retractions"))); | ||||||
|     m_checkbox_unretractions = new wxCheckBox(this, wxID_ANY, _(L("Unretractions"))); |     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_shells = new wxCheckBox(this, wxID_ANY, _(L("Shells"))); | ||||||
|     m_checkbox_legend = new wxCheckBox(this, wxID_ANY, _(L("Legend"))); |     m_checkbox_legend = new wxCheckBox(this, wxID_ANY, _(L("Legend"))); | ||||||
|     m_checkbox_legend->SetValue(true); |     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->AddSpacer(10); | ||||||
|     bottom_sizer->Add(m_checkbox_unretractions, 0, wxEXPAND | wxALL, 5); |     bottom_sizer->Add(m_checkbox_unretractions, 0, wxEXPAND | wxALL, 5); | ||||||
|     bottom_sizer->AddSpacer(10); |     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->Add(m_checkbox_shells, 0, wxEXPAND | wxALL, 5); | ||||||
|     bottom_sizer->AddSpacer(20); |     bottom_sizer->AddSpacer(20); | ||||||
|     bottom_sizer->Add(m_checkbox_legend, 0, wxEXPAND | wxALL, 5); |     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_travel->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_travel, this); | ||||||
|     m_checkbox_retractions->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_retractions, this); |     m_checkbox_retractions->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_retractions, this); | ||||||
|     m_checkbox_unretractions->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_unretractions, 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_shells->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_shells, this); | ||||||
|     m_checkbox_legend->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_legend, 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_travel->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_travel, this); | ||||||
|     m_checkbox_retractions->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_retractions, this); |     m_checkbox_retractions->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_retractions, this); | ||||||
|     m_checkbox_unretractions->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_unretractions, 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_shells->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_shells, this); | ||||||
|     m_checkbox_legend->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_legend, 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_travel->Enable(enable);  | ||||||
|     m_checkbox_retractions->Enable(enable); |     m_checkbox_retractions->Enable(enable); | ||||||
|     m_checkbox_unretractions->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_shells->Enable(enable); | ||||||
|     m_checkbox_legend->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_travel->Show(visible); | ||||||
|     m_checkbox_retractions->Show(visible); |     m_checkbox_retractions->Show(visible); | ||||||
|     m_checkbox_unretractions->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_shells->Show(visible); | ||||||
|     m_checkbox_legend->Show(visible); |     m_checkbox_legend->Show(visible); | ||||||
|     m_label_view_type->Show(visible); |     m_label_view_type->Show(visible); | ||||||
|  | @ -663,6 +709,32 @@ void Preview::on_checkbox_unretractions(wxCommandEvent& evt) | ||||||
|     refresh_print(); |     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) | void Preview::on_checkbox_shells(wxCommandEvent& evt) | ||||||
| { | { | ||||||
| #if ENABLE_GCODE_VIEWER | #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 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
 |         int type = (number_extruders > 1) ? tool_idx /* color by a tool number */ : 0; // color by a feature type
 | ||||||
|         m_choice_view_type->SetSelection(type); |         m_choice_view_type->SetSelection(type); | ||||||
|  | #if ENABLE_GCODE_VIEWER | ||||||
|  |         if (0 <= type && type < static_cast<int>(GCodeViewer::EViewType::Count)) | ||||||
|  |             m_canvas->set_gcode_view_preview_type(static_cast<GCodeViewer::EViewType>(type)); | ||||||
|  | #else | ||||||
|         if ((0 <= type) && (type < (int)GCodePreviewData::Extrusion::Num_View_Types)) |         if ((0 <= type) && (type < (int)GCodePreviewData::Extrusion::Num_View_Types)) | ||||||
|             m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)type; |             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".
 |         // If the->SetSelection changed the following line, revert it to "decide yourself".
 | ||||||
|         m_preferred_color_mode = "tool_or_feature"; |         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(); |     bool gcode_preview_data_valid = print->is_step_done(psGCodeExport) && ! m_gcode_preview_data->empty(); | ||||||
|  | #endif // ENABLE_GCODE_VIEWER
 | ||||||
|     // Collect colors per extruder.
 |     // Collect colors per extruder.
 | ||||||
|     std::vector<std::string> colors; |     std::vector<std::string> colors; | ||||||
|     std::vector<CustomGCode::Item> color_print_values = {}; |     std::vector<CustomGCode::Item> color_print_values = {}; | ||||||
|     // set color print values, if it si selected "ColorPrint" view type
 |     // 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) |     if (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint) | ||||||
|  | #endif // ENABLE_GCODE_VIEWER
 | ||||||
|     { |     { | ||||||
|         colors = wxGetApp().plater()->get_colors_for_color_print(); |         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 
 |         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) |         if (!gcode_preview_data_valid) | ||||||
|             color_print_values = wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes; |             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) ) |     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(); |         colors = wxGetApp().plater()->get_extruder_colors_from_plater_config(); | ||||||
|         color_print_values.clear(); |         color_print_values.clear(); | ||||||
|  | @ -984,8 +1076,8 @@ void Preview::load_print_as_fff(bool keep_z_range) | ||||||
|         if (gcode_preview_data_valid) { |         if (gcode_preview_data_valid) { | ||||||
|             // Load the real G-code preview.
 |             // Load the real G-code preview.
 | ||||||
| #if ENABLE_GCODE_VIEWER | #if ENABLE_GCODE_VIEWER | ||||||
|             m_canvas->load_gcode_preview(*m_gcode_result, colors); |             m_canvas->load_gcode_preview(*m_gcode_result); | ||||||
|             m_canvas->refresh_toolpaths_ranges(*m_gcode_result); |             m_canvas->refresh_gcode_preview(*m_gcode_result, colors); | ||||||
| #else | #else | ||||||
|             m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); |             m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); | ||||||
| #endif // ENABLE_GCODE_VIEWER
 | #endif // ENABLE_GCODE_VIEWER
 | ||||||
|  |  | ||||||
|  | @ -98,6 +98,12 @@ class Preview : public wxPanel | ||||||
|     wxCheckBox* m_checkbox_travel; |     wxCheckBox* m_checkbox_travel; | ||||||
|     wxCheckBox* m_checkbox_retractions; |     wxCheckBox* m_checkbox_retractions; | ||||||
|     wxCheckBox* m_checkbox_unretractions; |     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_shells; | ||||||
|     wxCheckBox* m_checkbox_legend; |     wxCheckBox* m_checkbox_legend; | ||||||
| 
 | 
 | ||||||
|  | @ -189,6 +195,12 @@ private: | ||||||
|     void on_checkbox_travel(wxCommandEvent& evt); |     void on_checkbox_travel(wxCommandEvent& evt); | ||||||
|     void on_checkbox_retractions(wxCommandEvent& evt); |     void on_checkbox_retractions(wxCommandEvent& evt); | ||||||
|     void on_checkbox_unretractions(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_shells(wxCommandEvent& evt); | ||||||
|     void on_checkbox_legend(wxCommandEvent& evt); |     void on_checkbox_legend(wxCommandEvent& evt); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 enricoturri1966
						enricoturri1966