mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 12:41:20 -06:00 
			
		
		
		
	Tech ENABLE_SHOW_WIPE_MOVES set as default
This commit is contained in:
		
							parent
							
								
									8a20b09d08
								
							
						
					
					
						commit
						f77475e501
					
				
					 8 changed files with 0 additions and 71 deletions
				
			
		|  | @ -256,10 +256,8 @@ namespace Slic3r { | |||
| 
 | ||||
|             // subdivide the retraction in segments
 | ||||
|             if (!wipe_path.empty()) { | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|                 // add tag for processor
 | ||||
|                 gcode += ";" + GCodeProcessor::Wipe_Start_Tag + "\n"; | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
|                 for (const Line& line : wipe_path.lines()) { | ||||
|                     double segment_length = line.length(); | ||||
|                     /*  Reduce retraction length a bit to avoid effective retraction speed to be greater than the configured one
 | ||||
|  | @ -274,10 +272,8 @@ namespace Slic3r { | |||
|                         "wipe and retract" | ||||
|                     ); | ||||
|                 } | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|                 // add tag for processor
 | ||||
|                 gcode += ";" + GCodeProcessor::Wipe_End_Tag + "\n"; | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
|                 gcodegen.set_last_pos(wipe_path.points.back()); | ||||
|             } | ||||
| 
 | ||||
|  |  | |||
|  | @ -25,10 +25,8 @@ static const float DEFAULT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 | |||
| namespace Slic3r { | ||||
| 
 | ||||
| const std::string GCodeProcessor::Extrusion_Role_Tag = "TYPE:"; | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
| const std::string GCodeProcessor::Wipe_Start_Tag     = "WIPE_START"; | ||||
| const std::string GCodeProcessor::Wipe_End_Tag       = "WIPE_END"; | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
| const std::string GCodeProcessor::Height_Tag         = "HEIGHT:"; | ||||
| const std::string GCodeProcessor::Layer_Change_Tag   = "LAYER_CHANGE"; | ||||
| const std::string GCodeProcessor::Color_Change_Tag   = "COLOR_CHANGE"; | ||||
|  | @ -39,10 +37,8 @@ const std::string GCodeProcessor::First_Line_M73_Placeholder_Tag          = "; _ | |||
| const std::string GCodeProcessor::Last_Line_M73_Placeholder_Tag           = "; _GP_LAST_LINE_M73_PLACEHOLDER"; | ||||
| const std::string GCodeProcessor::Estimated_Printing_Time_Placeholder_Tag = "; _GP_ESTIMATED_PRINTING_TIME_PLACEHOLDER"; | ||||
| 
 | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
| const float GCodeProcessor::Wipe_Width = 0.05f; | ||||
| const float GCodeProcessor::Wipe_Height = 0.05f; | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
| 
 | ||||
| #if ENABLE_GCODE_VIEWER_DATA_CHECKING | ||||
| const std::string GCodeProcessor::Width_Tag      = "WIDTH:"; | ||||
|  | @ -738,9 +734,7 @@ void GCodeProcessor::reset() | |||
|     m_end_position = { 0.0f, 0.0f, 0.0f, 0.0f }; | ||||
|     m_origin = { 0.0f, 0.0f, 0.0f, 0.0f }; | ||||
|     m_cached_position.reset(); | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|     m_wiping = false; | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
| 
 | ||||
|     m_feedrate = 0.0f; | ||||
|     m_width = 0.0f; | ||||
|  | @ -822,7 +816,6 @@ void GCodeProcessor::process_file(const std::string& filename, bool apply_postpr | |||
|         process_gcode_line(line); | ||||
|         }); | ||||
| 
 | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|     // update width/height of wipe moves
 | ||||
|     for (MoveVertex& move : m_result.moves) { | ||||
|         if (move.type == EMoveType::Wipe) { | ||||
|  | @ -830,7 +823,6 @@ void GCodeProcessor::process_file(const std::string& filename, bool apply_postpr | |||
|             move.height = Wipe_Height; | ||||
|         } | ||||
|     } | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
| 
 | ||||
|     // process the time blocks
 | ||||
|     for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) { | ||||
|  | @ -1053,7 +1045,6 @@ void GCodeProcessor::process_tags(const std::string_view comment) | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|     // wipe start tag
 | ||||
|     if (starts_with(comment, Wipe_Start_Tag)) { | ||||
|         m_wiping = true; | ||||
|  | @ -1065,7 +1056,6 @@ void GCodeProcessor::process_tags(const std::string_view comment) | |||
|         m_wiping = false; | ||||
|         return; | ||||
|     } | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
| 
 | ||||
|     if ((!m_producers_enabled || m_producer == EProducer::PrusaSlicer) && | ||||
|         starts_with(comment, Height_Tag)) { | ||||
|  | @ -1606,13 +1596,9 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) | |||
|     auto move_type = [this](const AxisCoords& delta_pos) { | ||||
|         EMoveType type = EMoveType::Noop; | ||||
| 
 | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|         if (m_wiping) | ||||
|             type = EMoveType::Wipe; | ||||
|         else if (delta_pos[E] < 0.0f) | ||||
| #else | ||||
|         if (delta_pos[E] < 0.0f) | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
|             type = (delta_pos[X] != 0.0f || delta_pos[Y] != 0.0f || delta_pos[Z] != 0.0f) ? EMoveType::Travel : EMoveType::Retract; | ||||
|         else if (delta_pos[E] > 0.0f) { | ||||
|             if (delta_pos[X] == 0.0f && delta_pos[Y] == 0.0f) | ||||
|  |  | |||
|  | @ -24,9 +24,7 @@ namespace Slic3r { | |||
|         Pause_Print, | ||||
|         Custom_GCode, | ||||
|         Travel, | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|         Wipe, | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
|         Extrude, | ||||
|         Count | ||||
|     }; | ||||
|  | @ -72,10 +70,8 @@ namespace Slic3r { | |||
|     { | ||||
|     public: | ||||
|         static const std::string Extrusion_Role_Tag; | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|         static const std::string Wipe_Start_Tag; | ||||
|         static const std::string Wipe_End_Tag; | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
|         static const std::string Height_Tag; | ||||
|         static const std::string Layer_Change_Tag; | ||||
|         static const std::string Color_Change_Tag; | ||||
|  | @ -85,10 +81,8 @@ namespace Slic3r { | |||
|         static const std::string Last_Line_M73_Placeholder_Tag; | ||||
|         static const std::string Estimated_Printing_Time_Placeholder_Tag; | ||||
| 
 | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|         static const float Wipe_Width; | ||||
|         static const float Wipe_Height; | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
| 
 | ||||
| #if ENABLE_GCODE_VIEWER_DATA_CHECKING | ||||
|         static const std::string Width_Tag; | ||||
|  | @ -402,9 +396,7 @@ namespace Slic3r { | |||
|         AxisCoords m_end_position; // mm
 | ||||
|         AxisCoords m_origin; // mm
 | ||||
|         CachedPosition m_cached_position; | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|         bool m_wiping; | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
| 
 | ||||
|         float m_feedrate; // mm/s
 | ||||
|         float m_width; // mm
 | ||||
|  |  | |||
|  | @ -77,7 +77,6 @@ | |||
| //===================
 | ||||
| #define ENABLE_2_3_0_BETA1 1 | ||||
| 
 | ||||
| #define ENABLE_SHOW_WIPE_MOVES (1 && ENABLE_2_3_0_BETA1) | ||||
| #define ENABLE_DRAG_AND_DROP_FIX (1 && ENABLE_2_3_0_BETA1) | ||||
| #define ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN (1 && ENABLE_2_3_0_BETA1) | ||||
| 
 | ||||
|  |  | |||
|  | @ -271,9 +271,7 @@ const std::vector<GCodeViewer::Color> GCodeViewer::Travel_Colors {{ | |||
|     { 0.505f, 0.064f, 0.028f }  // Retract
 | ||||
| }}; | ||||
| 
 | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
| const GCodeViewer::Color GCodeViewer::Wipe_Color = { 1.0f, 1.0f, 0.0f }; | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
| 
 | ||||
| const std::vector<GCodeViewer::Color> GCodeViewer::Range_Colors {{ | ||||
|     { 0.043f, 0.173f, 0.478f }, // bluish
 | ||||
|  | @ -463,9 +461,7 @@ void GCodeViewer::render() const | |||
|                 buffer.shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110"; | ||||
|                 break; | ||||
|             } | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|             case EMoveType::Wipe: | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
|             case EMoveType::Extrude: { | ||||
|                 buffer.shader = "gouraud_light"; | ||||
|                 break; | ||||
|  | @ -579,9 +575,7 @@ unsigned int GCodeViewer::get_options_visibility_flags() const | |||
| 
 | ||||
|     unsigned int flags = 0; | ||||
|     flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::Travel), is_toolpath_move_type_visible(EMoveType::Travel)); | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|     flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::Wipe), is_toolpath_move_type_visible(EMoveType::Wipe)); | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
|     flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::Retractions), is_toolpath_move_type_visible(EMoveType::Retract)); | ||||
|     flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::Unretractions), is_toolpath_move_type_visible(EMoveType::Unretract)); | ||||
|     flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::ToolChanges), is_toolpath_move_type_visible(EMoveType::Tool_change)); | ||||
|  | @ -601,9 +595,7 @@ void GCodeViewer::set_options_visibility_from_flags(unsigned int flags) | |||
|     }; | ||||
| 
 | ||||
|     set_toolpath_move_type_visible(EMoveType::Travel, is_flag_set(static_cast<unsigned int>(Preview::OptionType::Travel))); | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|     set_toolpath_move_type_visible(EMoveType::Wipe, is_flag_set(static_cast<unsigned int>(Preview::OptionType::Wipe))); | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
|     set_toolpath_move_type_visible(EMoveType::Retract, is_flag_set(static_cast<unsigned int>(Preview::OptionType::Retractions))); | ||||
|     set_toolpath_move_type_visible(EMoveType::Unretract, is_flag_set(static_cast<unsigned int>(Preview::OptionType::Unretractions))); | ||||
|     set_toolpath_move_type_visible(EMoveType::Tool_change, is_flag_set(static_cast<unsigned int>(Preview::OptionType::ToolChanges))); | ||||
|  | @ -941,9 +933,7 @@ void GCodeViewer::init() | |||
|             buffer.vertices.format = VBuffer::EFormat::Position; | ||||
|             break; | ||||
|         } | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|         case EMoveType::Wipe: | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
|         case EMoveType::Extrude: | ||||
|         { | ||||
|             buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Triangle; | ||||
|  | @ -1407,13 +1397,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) | |||
|         } | ||||
|     } | ||||
| 
 | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|     // move the wipe toolpaths half height up to render them on proper position
 | ||||
|     std::vector<float>& wipe_vertices = vertices[buffer_id(EMoveType::Wipe)]; | ||||
|     for (size_t i = 2; i < wipe_vertices.size(); i += 3) { | ||||
|         wipe_vertices[i] += 0.5f * GCodeProcessor::Wipe_Height; | ||||
|     } | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
| 
 | ||||
|     log_memory_usage("Loaded G-code generated vertex buffers, ", vertices, indices); | ||||
| 
 | ||||
|  | @ -1448,11 +1436,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) | |||
|         buffer.paths.clear(); | ||||
|     } | ||||
|     // variable used to keep track of the current size (in vertices) of the vertex buffer
 | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|     std::vector<size_t> curr_buffer_vertices_size(m_buffers.size(), 0); | ||||
| #else | ||||
|     size_t curr_buffer_vertices_size = 0; | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
|     for (size_t i = 0; i < m_moves_count; ++i) { | ||||
|         // skip first vertex
 | ||||
|         if (i == 0) | ||||
|  | @ -1480,11 +1464,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) | |||
|         // create another index buffer, and move the current path indices into it
 | ||||
|         if (buffer_indices.back().size() >= THRESHOLD - static_cast<size_t>(buffer.indices_per_segment())) { | ||||
|             buffer_indices.push_back(IndexBuffer()); | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|             if (buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Point) { | ||||
| #else | ||||
|             if (curr.type == EMoveType::Extrude || curr.type == EMoveType::Travel) { | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
|                 if (!(prev.type != curr.type || !buffer.paths.back().matches(curr))) { | ||||
|                     Path& last_path = buffer.paths.back(); | ||||
|                     size_t delta_id = last_path.last.i_id - last_path.first.i_id; | ||||
|  | @ -1515,11 +1495,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) | |||
|             break; | ||||
|         } | ||||
|         case TBuffer::ERenderPrimitiveType::Triangle: { | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|             add_indices_as_solid(prev, curr, buffer, curr_buffer_vertices_size[id], static_cast<unsigned int>(buffer_indices.size()) - 1, buffer_indices.back(), i); | ||||
| #else | ||||
|             add_indices_as_solid(prev, curr, buffer, curr_buffer_vertices_size, static_cast<unsigned int>(buffer_indices.size()) - 1, buffer_indices.back(), i); | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
|             break; | ||||
|         } | ||||
|         } | ||||
|  | @ -1564,13 +1540,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) | |||
|     for (size_t i = 0; i < travel_buffer_indices.size(); ++i) { | ||||
|         m_statistics.travel_segments_count = travel_buffer_indices[i].size() / m_buffers[travel_buffer_id].indices_per_segment(); | ||||
|     } | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|     unsigned int wipe_buffer_id = buffer_id(EMoveType::Wipe); | ||||
|     const MultiIndexBuffer& wipe_buffer_indices = indices[wipe_buffer_id]; | ||||
|     for (size_t i = 0; i < wipe_buffer_indices.size(); ++i) { | ||||
|         m_statistics.wipe_segments_count = wipe_buffer_indices[i].size() / m_buffers[wipe_buffer_id].indices_per_segment(); | ||||
|     } | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
|     unsigned int extrude_buffer_id = buffer_id(EMoveType::Extrude); | ||||
|     const MultiIndexBuffer& extrude_buffer_indices = indices[extrude_buffer_id]; | ||||
|     for (size_t i = 0; i < extrude_buffer_indices.size(); ++i) { | ||||
|  | @ -1901,9 +1875,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool | |||
| 
 | ||||
|             break; | ||||
|         } | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|         case EMoveType::Wipe: { color = Wipe_Color; break; } | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
|         default: { color = { 0.0f, 0.0f, 0.0f }; break; } | ||||
|         } | ||||
| 
 | ||||
|  | @ -2636,7 +2608,6 @@ void GCodeViewer::render_legend() const | |||
|         } | ||||
|     } | ||||
| 
 | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|     // wipe paths section
 | ||||
|     if (m_buffers[buffer_id(EMoveType::Wipe)].visible) { | ||||
|         switch (m_view_type) | ||||
|  | @ -2656,7 +2627,6 @@ void GCodeViewer::render_legend() const | |||
|         } | ||||
|         } | ||||
|     } | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
| 
 | ||||
|     auto any_option_available = [this]() { | ||||
|         auto available = [this](EMoveType type) { | ||||
|  | @ -2888,9 +2858,7 @@ void GCodeViewer::render_statistics() const | |||
| 
 | ||||
|     if (ImGui::CollapsingHeader("Other")) { | ||||
|         add_counter(std::string("Travel segments count:"), m_statistics.travel_segments_count); | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|         add_counter(std::string("Wipe segments count:"), m_statistics.wipe_segments_count); | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
|         add_counter(std::string("Extrude segments count:"), m_statistics.extrude_segments_count); | ||||
|         add_counter(std::string("Max vertices in vertex buffer:"), m_statistics.max_vertices_in_vertex_buffer); | ||||
|         add_counter(std::string("Max indices in index buffer:"), m_statistics.max_indices_in_index_buffer); | ||||
|  |  | |||
|  | @ -23,9 +23,7 @@ class GCodeViewer | |||
|     static const std::vector<Color> Extrusion_Role_Colors; | ||||
|     static const std::vector<Color> Options_Colors; | ||||
|     static const std::vector<Color> Travel_Colors; | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|     static const Color              Wipe_Color; | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
|     static const std::vector<Color> Range_Colors; | ||||
| 
 | ||||
|     enum class EOptionsColors : unsigned char | ||||
|  | @ -329,9 +327,7 @@ class GCodeViewer | |||
|         long long render_paths_size{ 0 }; | ||||
|         // other
 | ||||
|         long long travel_segments_count{ 0 }; | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|         long long wipe_segments_count{ 0 }; | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
|         long long extrude_segments_count{ 0 }; | ||||
|         long long max_vertices_in_vertex_buffer{ 0 }; | ||||
|         long long max_indices_in_index_buffer{ 0 }; | ||||
|  | @ -366,9 +362,7 @@ class GCodeViewer | |||
| 
 | ||||
|         void reset_others() { | ||||
|             travel_segments_count = 0; | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|             wipe_segments_count = 0; | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
|             extrude_segments_count =  0; | ||||
|             max_vertices_in_vertex_buffer = 0; | ||||
|             max_indices_in_index_buffer = 0; | ||||
|  |  | |||
|  | @ -248,9 +248,7 @@ bool Preview::init(wxWindow* parent, Model* model) | |||
|     m_combochecklist_options->Create(m_bottom_toolbar_panel, wxID_ANY, _L("Options"), wxDefaultPosition, wxDefaultSize, wxCB_READONLY); | ||||
|     std::string options_items = GUI::into_u8( | ||||
|         get_option_type_string(OptionType::Travel) + "|0|" + | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|         get_option_type_string(OptionType::Wipe) + "|0|" + | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
|         get_option_type_string(OptionType::Retractions) + "|0|" + | ||||
|         get_option_type_string(OptionType::Unretractions) + "|0|" + | ||||
|         get_option_type_string(OptionType::ToolChanges) + "|0|" + | ||||
|  | @ -1019,9 +1017,7 @@ wxString Preview::get_option_type_string(OptionType type) const | |||
|     switch (type) | ||||
|     { | ||||
|     case OptionType::Travel:        { return _L("Travel"); } | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|     case OptionType::Wipe:          { return _L("Wipe"); } | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
|     case OptionType::Retractions:   { return _L("Retractions"); } | ||||
|     case OptionType::Unretractions: { return _L("Deretractions"); } | ||||
|     case OptionType::ToolChanges:   { return _L("Tool changes"); } | ||||
|  |  | |||
|  | @ -117,9 +117,7 @@ public: | |||
|     enum class OptionType : unsigned int | ||||
|     { | ||||
|         Travel, | ||||
| #if ENABLE_SHOW_WIPE_MOVES | ||||
|         Wipe, | ||||
| #endif // ENABLE_SHOW_WIPE_MOVES
 | ||||
|         Retractions, | ||||
|         Unretractions, | ||||
|         ToolChanges, | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 enricoturri1966
						enricoturri1966