mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	Wipe tower accounts for extruder offsets
Also, in case of non-single-extruder printer with the wipe tower, first wiping line was printed where the border should have been - fixed
This commit is contained in:
		
							parent
							
								
									2de6d95322
								
							
						
					
					
						commit
						eb29c3e01d
					
				
					 4 changed files with 55 additions and 23 deletions
				
			
		|  | @ -169,6 +169,9 @@ static inline Point wipe_tower_point_to_object_point(GCode &gcodegen, const Vec2 | |||
| 
 | ||||
| std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::ToolChangeResult &tcr, int new_extruder_id) const | ||||
| { | ||||
|     if (new_extruder_id != -1 && new_extruder_id != tcr.new_tool) | ||||
|         throw std::invalid_argument("Error: WipeTowerIntegration::append_tcr was asked to do a toolchange it didn't expect."); | ||||
| 
 | ||||
|     std::string gcode; | ||||
| 
 | ||||
|     // Toolchangeresult.gcode assumes the wipe tower corner is at the origin
 | ||||
|  | @ -182,8 +185,11 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T | |||
|         end_pos = Eigen::Rotation2Df(alpha) * end_pos; | ||||
|         end_pos += m_wipe_tower_pos; | ||||
|     } | ||||
|     std::string tcr_rotated_gcode = tcr.priming ? tcr.gcode : rotate_wipe_tower_moves(tcr.gcode, tcr.start_pos, m_wipe_tower_pos, alpha); | ||||
|      | ||||
| 
 | ||||
|     Vec2f wipe_tower_offset = tcr.priming ? Vec2f::Zero() : m_wipe_tower_pos; | ||||
|     float wipe_tower_rotation = tcr.priming ? 0.f : alpha; | ||||
| 
 | ||||
|     std::string tcr_rotated_gcode = post_process_wipe_tower_moves(tcr, wipe_tower_offset, wipe_tower_rotation); | ||||
| 
 | ||||
|     // Disable linear advance for the wipe tower operations.
 | ||||
|     gcode += (gcodegen.config().gcode_flavor == gcfRepRap ? std::string("M572 D0 S0\n") : std::string("M900 K0\n")); | ||||
|  | @ -285,17 +291,21 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T | |||
| 
 | ||||
| // This function postprocesses gcode_original, rotates and moves all G1 extrusions and returns resulting gcode
 | ||||
| // Starting position has to be supplied explicitely (otherwise it would fail in case first G1 command only contained one coordinate)
 | ||||
| std::string WipeTowerIntegration::rotate_wipe_tower_moves(const std::string& gcode_original, const Vec2f& start_pos, const Vec2f& translation, float angle) const | ||||
| std::string WipeTowerIntegration::post_process_wipe_tower_moves(const WipeTower::ToolChangeResult& tcr, const Vec2f& translation, float angle) const | ||||
| { | ||||
|     std::istringstream gcode_str(gcode_original); | ||||
|     Vec2f extruder_offset = m_extruder_offsets[tcr.initial_tool].cast<float>(); | ||||
| 
 | ||||
|     std::istringstream gcode_str(tcr.gcode); | ||||
|     std::string gcode_out; | ||||
|     std::string line; | ||||
|     Vec2f pos = start_pos; | ||||
|     Vec2f transformed_pos; | ||||
|     Vec2f pos = tcr.start_pos; | ||||
|     Vec2f transformed_pos = pos; | ||||
|     Vec2f old_pos(-1000.1f, -1000.1f); | ||||
| 
 | ||||
|     while (gcode_str) { | ||||
|         std::getline(gcode_str, line);  // we read the gcode line by line
 | ||||
| 
 | ||||
|         // All G1 commands should be translated and rotated
 | ||||
|         if (line.find("G1 ") == 0) { | ||||
|             std::ostringstream line_out; | ||||
|             std::istringstream line_str(line); | ||||
|  | @ -317,17 +327,34 @@ std::string WipeTowerIntegration::rotate_wipe_tower_moves(const std::string& gco | |||
| 
 | ||||
|             if (transformed_pos != old_pos) { | ||||
|                 line = line_out.str(); | ||||
|                 char buf[2048] = "G1"; | ||||
|                 std::ostringstream oss; | ||||
|                 oss << std::fixed << std::setprecision(3) << "G1 "; | ||||
|                 if (transformed_pos.x() != old_pos.x()) | ||||
|                     sprintf(buf + strlen(buf), " X%.3f", transformed_pos.x()); | ||||
|                     oss << " X" << transformed_pos.x() - extruder_offset.x(); | ||||
|                 if (transformed_pos.y() != old_pos.y()) | ||||
|                     sprintf(buf + strlen(buf), " Y%.3f", transformed_pos.y()); | ||||
|                     oss << " Y" << transformed_pos.y() - extruder_offset.y(); | ||||
| 
 | ||||
|                 line.replace(line.find("G1 "), 3, buf); | ||||
|                 line.replace(line.find("G1 "), 3, oss.str()); | ||||
|                 old_pos = transformed_pos; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         gcode_out += line + "\n"; | ||||
| 
 | ||||
|         // If this was a toolchange command, we should change current extruder offset
 | ||||
|         if (line == "[toolchange_gcode]") { | ||||
|             extruder_offset = m_extruder_offsets[tcr.new_tool].cast<float>(); | ||||
| 
 | ||||
|             // If the extruder offset changed, add an extra move so everything is continuous
 | ||||
|             if (extruder_offset != m_extruder_offsets[tcr.initial_tool].cast<float>()) { | ||||
|                 std::ostringstream oss; | ||||
|                 oss << std::fixed << std::setprecision(3) | ||||
|                     << "G1 X" << transformed_pos.x() - extruder_offset.x() | ||||
|                     << " Y"   << transformed_pos.y() - extruder_offset.y() | ||||
|                     << "\n"; | ||||
|                 gcode_out += oss.str(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     return gcode_out; | ||||
| } | ||||
|  |  | |||
|  | @ -90,6 +90,7 @@ public: | |||
|         m_right(float(/*print_config.wipe_tower_x.value +*/ print_config.wipe_tower_width.value)), | ||||
|         m_wipe_tower_pos(float(print_config.wipe_tower_x.value), float(print_config.wipe_tower_y.value)), | ||||
|         m_wipe_tower_rotation(float(print_config.wipe_tower_rotation_angle)), | ||||
|         m_extruder_offsets(print_config.extruder_offset.values), | ||||
|         m_priming(priming), | ||||
|         m_tool_changes(tool_changes), | ||||
|         m_final_purge(final_purge), | ||||
|  | @ -107,14 +108,16 @@ private: | |||
|     WipeTowerIntegration& operator=(const WipeTowerIntegration&); | ||||
|     std::string append_tcr(GCode &gcodegen, const WipeTower::ToolChangeResult &tcr, int new_extruder_id) const; | ||||
| 
 | ||||
|     // Postprocesses gcode: rotates and moves all G1 extrusions and returns result
 | ||||
|     std::string rotate_wipe_tower_moves(const std::string& gcode_original, const Vec2f& start_pos, const Vec2f& translation, float angle) const; | ||||
|     // Postprocesses gcode: rotates and moves G1 extrusions and returns result
 | ||||
|     std::string post_process_wipe_tower_moves(const WipeTower::ToolChangeResult& tcr, const Vec2f& translation, float angle) const; | ||||
| 
 | ||||
|     // Left / right edges of the wipe tower, for the planning of wipe moves.
 | ||||
|     const float                                                  m_left; | ||||
|     const float                                                  m_right; | ||||
|     const Vec2f                                                  m_wipe_tower_pos; | ||||
|     const float                                                  m_wipe_tower_rotation; | ||||
|     const std::vector<Vec2d>                                     m_extruder_offsets; | ||||
| 
 | ||||
|     // Reference to cached values at the Printer class.
 | ||||
|     const std::vector<WipeTower::ToolChangeResult>              &m_priming; | ||||
|     const std::vector<std::vector<WipeTower::ToolChangeResult>> &m_tool_changes; | ||||
|  |  | |||
|  | @ -553,7 +553,7 @@ std::vector<WipeTower::ToolChangeResult> WipeTower::prime( | |||
|         result.elapsed_time = writer.elapsed_time(); | ||||
|         result.extrusions 	= writer.extrusions(); | ||||
|         result.start_pos  	= writer.start_pos_rotated(); | ||||
|         result.end_pos 	  	= writer.pos_rotated(); | ||||
|         result.end_pos 	  	= writer.pos(); | ||||
| 
 | ||||
|         results.push_back(std::move(result)); | ||||
| 
 | ||||
|  | @ -643,7 +643,7 @@ WipeTower::ToolChangeResult WipeTower::tool_change(unsigned int tool, bool last_ | |||
|                           m_is_first_layer ? m_filpar[tool].first_layer_temperature : m_filpar[tool].temperature); | ||||
|         toolchange_Change(writer, tool, m_filpar[tool].material); // Change the tool, set a speed override for soluble and flex materials.
 | ||||
|         toolchange_Load(writer, cleaning_box); | ||||
|         writer.travel(writer.x(),writer.y()-m_perimeter_width); // cooling and loading were done a bit down the road
 | ||||
|         writer.travel(writer.x(), writer.y()-m_perimeter_width); // cooling and loading were done a bit down the road
 | ||||
|         toolchange_Wipe(writer, cleaning_box, wipe_volume);     // Wipe the newly loaded filament until the end of the assigned wipe area.
 | ||||
|         ++ m_num_tool_changes; | ||||
|     } else | ||||
|  |  | |||
|  | @ -139,13 +139,15 @@ public: | |||
| 
 | ||||
|         m_perimeter_width = nozzle_diameter * Width_To_Nozzle_Ratio; // all extruders are now assumed to have the same diameter
 | ||||
| 
 | ||||
|         std::stringstream stream{m_semm ? ramming_parameters : std::string()}; | ||||
|         float speed = 0.f; | ||||
|         stream >> m_filpar[idx].ramming_line_width_multiplicator >> m_filpar[idx].ramming_step_multiplicator; | ||||
|         m_filpar[idx].ramming_line_width_multiplicator /= 100; | ||||
|         m_filpar[idx].ramming_step_multiplicator /= 100; | ||||
|         while (stream >> speed) | ||||
|             m_filpar[idx].ramming_speed.push_back(speed); | ||||
|         if (m_semm) { | ||||
|             std::stringstream stream{ramming_parameters}; | ||||
|             float speed = 0.f; | ||||
|             stream >> m_filpar[idx].ramming_line_width_multiplicator >> m_filpar[idx].ramming_step_multiplicator; | ||||
|             m_filpar[idx].ramming_line_width_multiplicator /= 100; | ||||
|             m_filpar[idx].ramming_step_multiplicator /= 100; | ||||
|             while (stream >> speed) | ||||
|                 m_filpar[idx].ramming_speed.push_back(speed); | ||||
|         } | ||||
| 
 | ||||
|         m_used_filament_length.resize(std::max(m_used_filament_length.size(), idx + 1)); // makes sure that the vector is big enough so we don't have to check later
 | ||||
| 	} | ||||
|  | @ -241,8 +243,8 @@ public: | |||
|         int                 cooling_moves = 0; | ||||
|         float               cooling_initial_speed = 0.f; | ||||
|         float               cooling_final_speed = 0.f; | ||||
|         float               ramming_line_width_multiplicator = 0.f; | ||||
|         float               ramming_step_multiplicator = 0.f; | ||||
|         float               ramming_line_width_multiplicator = 1.f; | ||||
|         float               ramming_step_multiplicator = 1.f; | ||||
|         float               max_e_speed = std::numeric_limits<float>::max(); | ||||
|         std::vector<float>  ramming_speed; | ||||
|         float               nozzle_diameter; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Lukas Matena
						Lukas Matena