mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	ENH: fix the floating layer issue
Fix for floating layer under multi-color printing while z_hop is zero. Signed-off-by: salt.wei <salt.wei@bambulab.com> Change-Id: I8cc96bd18020cac8424fe4c3e62fb87da118b826
This commit is contained in:
		
							parent
							
								
									679ccb658b
								
							
						
					
					
						commit
						0b126dbed6
					
				
					 5 changed files with 108 additions and 17 deletions
				
			
		|  | @ -520,9 +520,20 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print) | |||
| 
 | ||||
|             // retract before toolchange
 | ||||
|             toolchange_gcode_str = toolchange_retract_str + toolchange_gcode_str; | ||||
|             //BBS: current position and fan_speed is unclear after interting change_filament_gcode
 | ||||
|             toolchange_gcode_str += ";_FORCE_RESUME_FAN_SPEED\n"; | ||||
|             gcodegen.writer().set_current_position_clear(false); | ||||
|             //BBS
 | ||||
|             { | ||||
|                 //BBS: current position and fan_speed is unclear after interting change_filament_gcode
 | ||||
|                 check_add_eol(toolchange_gcode_str); | ||||
|                 toolchange_gcode_str += ";_FORCE_RESUME_FAN_SPEED\n"; | ||||
|                 gcodegen.writer().set_current_position_clear(false); | ||||
|                 //BBS: check whether custom gcode changes the z position. Update if changed
 | ||||
|                 double temp_z_after_tool_change; | ||||
|                 if (GCodeProcessor::get_last_z_from_gcode(toolchange_gcode_str, temp_z_after_tool_change)) { | ||||
|                     Vec3d pos = gcodegen.writer().get_position(); | ||||
|                     pos(2) = temp_z_after_tool_change; | ||||
|                     gcodegen.writer().set_position(pos); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             // move to start_pos for wiping after toolchange
 | ||||
|             std::string start_pos_str; | ||||
|  | @ -4239,12 +4250,23 @@ std::string GCode::set_extruder(unsigned int extruder_id, double print_z) | |||
|     std::string toolchange_gcode_parsed; | ||||
|     if (!change_filament_gcode.empty()) { | ||||
|         toolchange_gcode_parsed = placeholder_parser_process("change_filament_gcode", change_filament_gcode, extruder_id, &dyn_config); | ||||
|         check_add_eol(toolchange_gcode_parsed); | ||||
|         gcode += toolchange_gcode_parsed; | ||||
|         check_add_eol(gcode); | ||||
|         //BBS: gcode writer doesn't know where the extruder is and whether fan speed is changed after inserting tool change gcode
 | ||||
|         //Set this flag so that normal lift will be used the first time after tool change.
 | ||||
|         gcode += ";_FORCE_RESUME_FAN_SPEED\n"; | ||||
|         m_writer.set_current_position_clear(false); | ||||
| 
 | ||||
|         //BBS
 | ||||
|         { | ||||
|             //BBS: gcode writer doesn't know where the extruder is and whether fan speed is changed after inserting tool change gcode
 | ||||
|             //Set this flag so that normal lift will be used the first time after tool change.
 | ||||
|             gcode += ";_FORCE_RESUME_FAN_SPEED\n"; | ||||
|             m_writer.set_current_position_clear(false); | ||||
|             //BBS: check whether custom gcode changes the z position. Update if changed
 | ||||
|             double temp_z_after_tool_change; | ||||
|             if (GCodeProcessor::get_last_z_from_gcode(toolchange_gcode_parsed, temp_z_after_tool_change)) { | ||||
|                 Vec3d pos = m_writer.get_position(); | ||||
|                 pos(2) = temp_z_after_tool_change; | ||||
|                 m_writer.set_position(pos); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // BBS. Reset old extruder E-value.
 | ||||
|  |  | |||
|  | @ -12,6 +12,8 @@ | |||
| #include <boost/nowide/cstdio.hpp> | ||||
| #include <boost/filesystem/path.hpp> | ||||
| 
 | ||||
| #include <fast_float/fast_float.h> | ||||
| 
 | ||||
| #include <float.h> | ||||
| #include <assert.h> | ||||
| 
 | ||||
|  | @ -1921,6 +1923,61 @@ int GCodeProcessor::get_gcode_last_filament(const std::string& gcode_str) | |||
|     return out_filament; | ||||
| } | ||||
| 
 | ||||
| //BBS: get last z position from gcode
 | ||||
| bool GCodeProcessor::get_last_z_from_gcode(const std::string& gcode_str, double& z) | ||||
| { | ||||
|     int str_size = gcode_str.size(); | ||||
|     int start_index = 0; | ||||
|     int end_index = 0; | ||||
|     bool is_z_changed = false; | ||||
|     while (end_index < str_size) { | ||||
|         //find a full line
 | ||||
|         if (gcode_str[end_index] != '\n') { | ||||
|             end_index++; | ||||
|             continue; | ||||
|         } | ||||
|         //parse the line
 | ||||
|         if (end_index > start_index) { | ||||
|             std::string line_str = gcode_str.substr(start_index, end_index - start_index); | ||||
|             line_str.erase(0, line_str.find_first_not_of(" ")); | ||||
|             line_str.erase(line_str.find_last_not_of(";") + 1); | ||||
|             line_str.erase(line_str.find_last_not_of(" ") + 1); | ||||
| 
 | ||||
|             //command which may have z movement
 | ||||
|             if (line_str.size() > 5 && (line_str.find("G0 ") == 0 | ||||
|                                        || line_str.find("G1 ") == 0 | ||||
|                                        || line_str.find("G2 ") == 0 | ||||
|                                        || line_str.find("G3 ") == 0)) | ||||
|             { | ||||
|                 auto z_pos = line_str.find(" Z"); | ||||
|                 double temp_z = 0; | ||||
|                 if (z_pos != line_str.npos | ||||
|                     && z_pos + 2 < line_str.size()) { | ||||
|                     // Try to parse the numeric value.
 | ||||
|                     std::string z_sub = line_str.substr(z_pos + 2); | ||||
|                     char* c = &z_sub[0]; | ||||
|                     char* end = c + sizeof(z_sub.c_str()); | ||||
| 
 | ||||
|                     auto is_end_of_word = [](char c) { | ||||
|                         return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == 0 || c == ';'; | ||||
|                     }; | ||||
| 
 | ||||
|                     auto [pend, ec] = fast_float::from_chars(c, end, temp_z); | ||||
|                     if (pend != c && is_end_of_word(*pend)) { | ||||
|                         // The axis value has been parsed correctly.
 | ||||
|                         z = temp_z; | ||||
|                         is_z_changed = true; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         //loop to handle next line
 | ||||
|         start_index = end_index + 1; | ||||
|         end_index = start_index; | ||||
|     } | ||||
|     return is_z_changed; | ||||
| } | ||||
| 
 | ||||
| void GCodeProcessor::process_tags(const std::string_view comment, bool producers_enabled) | ||||
| { | ||||
|     // producers tags
 | ||||
|  |  | |||
|  | @ -238,6 +238,7 @@ namespace Slic3r { | |||
|         static bool contains_reserved_tags(const std::string& gcode, unsigned int max_count, std::vector<std::string>& found_tag); | ||||
| 
 | ||||
|         static int get_gcode_last_filament(const std::string &gcode_str); | ||||
|         static bool get_last_z_from_gcode(const std::string& gcode_str, double& z); | ||||
| 
 | ||||
|         static const float Wipe_Width; | ||||
|         static const float Wipe_Height; | ||||
|  |  | |||
|  | @ -374,20 +374,30 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co | |||
|         /*  In all the other cases, we perform an actual XYZ move and cancel
 | ||||
|             the lift. */ | ||||
|         m_lifted = 0; | ||||
|         m_pos = point; | ||||
|     } | ||||
|      | ||||
|     //BBS: take plate offset into consider
 | ||||
|     this->set_current_position_clear(true); | ||||
|     Vec3d point_on_plate = { dest_point(0) - m_x_offset, dest_point(1) - m_y_offset, dest_point(2) }; | ||||
|     m_pos = dest_point; | ||||
| 
 | ||||
|     std::string out_string; | ||||
|     GCodeG1Formatter w; | ||||
|     w.emit_xyz(point_on_plate); | ||||
|     w.emit_f(this->config.travel_speed.value * 60.0); | ||||
|     //BBS
 | ||||
|     w.emit_comment(GCodeWriter::full_gcode_comment, comment); | ||||
|     return w.string(); | ||||
|     if (!this->is_current_position_clear()) | ||||
|     { | ||||
|         //force to move xy first then z after filament change
 | ||||
|         w.emit_xy(Vec2d(point_on_plate.x(), point_on_plate.y())); | ||||
|         w.emit_f(this->config.travel_speed.value * 60.0); | ||||
|         w.emit_comment(GCodeWriter::full_gcode_comment, comment); | ||||
|         out_string = w.string() + _travel_to_z(point_on_plate.z(), comment); | ||||
|     } else { | ||||
|         GCodeG1Formatter w; | ||||
|         w.emit_xyz(point_on_plate); | ||||
|         w.emit_f(this->config.travel_speed.value * 60.0); | ||||
|         w.emit_comment(GCodeWriter::full_gcode_comment, comment); | ||||
|         out_string = w.string(); | ||||
|     } | ||||
| 
 | ||||
|     m_pos = dest_point; | ||||
|     this->set_current_position_clear(true); | ||||
|     return out_string; | ||||
| } | ||||
| 
 | ||||
| std::string GCodeWriter::travel_to_z(double z, const std::string &comment) | ||||
|  |  | |||
|  | @ -76,6 +76,7 @@ public: | |||
|     std::string lift(LiftType lift_type = LiftType::NormalLift); | ||||
|     std::string unlift(); | ||||
|     Vec3d       get_position() const { return m_pos; } | ||||
|     void       set_position(Vec3d& in) { m_pos = in; } | ||||
| 
 | ||||
|     //BBS: set offset for gcode writer
 | ||||
|     void set_xy_offset(double x, double y) { m_x_offset = x; m_y_offset = y; } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 salt.wei
						salt.wei