mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	ENH: add new calibration
pa calibration for 3rd party printer and retraction calibration Change-Id: Ifeb12807cdce366c9d265a0490b320224dfb23fe (cherry picked from commit 732adceeef43c9c957468ab490f0e3ee20f3173b)
This commit is contained in:
		
							parent
							
								
									2910014887
								
							
						
					
					
						commit
						11fb7fb89f
					
				
					 15 changed files with 515 additions and 120 deletions
				
			
		
							
								
								
									
										
											BIN
										
									
								
								resources/calib/pressure_advance/pressure_advance_test.stl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								resources/calib/pressure_advance/pressure_advance_test.stl
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								resources/calib/pressure_advance/tower.stl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								resources/calib/pressure_advance/tower.stl
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								resources/calib/pressure_advance/tower_with_seam.stl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								resources/calib/pressure_advance/tower_with_seam.stl
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								resources/calib/retraction/retraction_tower.stl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								resources/calib/retraction/retraction_tower.stl
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							|  | @ -37,6 +37,7 @@ set(lisbslic3r_sources | |||
|     Brim.hpp | ||||
|     BuildVolume.cpp | ||||
|     BuildVolume.hpp | ||||
| 	Calib.cpp | ||||
|     Calib.hpp | ||||
|     Circle.cpp | ||||
|     Circle.hpp | ||||
|  |  | |||
							
								
								
									
										221
									
								
								src/libslic3r/Calib.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										221
									
								
								src/libslic3r/Calib.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,221 @@ | |||
| #include "Calib.hpp" | ||||
| #include "Point.hpp" | ||||
| #include "PrintConfig.hpp" | ||||
| #include "GCodeWriter.hpp" | ||||
| #include "GCode.hpp" | ||||
| #include <map> | ||||
| 
 | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| 
 | ||||
|     calib_pressure_advance::calib_pressure_advance(GCode* gcodegen) :mp_gcodegen(gcodegen), m_length_short(20.0), m_length_long(40.0), m_space_y(3.5), m_line_width(0.6), m_draw_numbers(true) {} | ||||
| 
 | ||||
|     std::string calib_pressure_advance::generate_test(double start_pa, double step_pa, int count ) { | ||||
|       BoundingBoxf bed_ext = get_extents(mp_gcodegen->config().printable_area.values); | ||||
|       bool is_delta = false; | ||||
|       if (mp_gcodegen->config().printable_area.values.size() > 4) { | ||||
|         is_delta = true; | ||||
|         bed_ext.scale(1.0f / 1.41421f); | ||||
|       } | ||||
| 
 | ||||
|       auto bed_sizes = mp_gcodegen->config().printable_area.values; | ||||
|       const auto &w = bed_ext.size().x(); | ||||
|       const auto &h = bed_ext.size().y(); | ||||
|       count = std::min(count, int((h - 10) / m_space_y)); | ||||
| 
 | ||||
|       m_length_long = 40 + std::min(w - 120.0, 0.0); | ||||
| 
 | ||||
|       auto startx = (w - m_length_short * 2 - m_length_long - 20) / 2; | ||||
|       auto starty = (h - count * m_space_y) / 2; | ||||
|       if (is_delta) { | ||||
|         startx = -startx; | ||||
|         starty = -(count * m_space_y) / 2; | ||||
|       } | ||||
| 
 | ||||
|       return print_pa_lines(startx, starty, start_pa, step_pa, count); | ||||
|     } | ||||
| 
 | ||||
|     std::string calib_pressure_advance::move_to(Vec2d pt) { | ||||
|         std::stringstream gcode; | ||||
|         gcode << mp_gcodegen->retract(); | ||||
|         gcode << mp_gcodegen->writer().travel_to_xyz(Vec3d(pt.x(), pt.y(), 0.2)); | ||||
|         gcode << mp_gcodegen->unretract(); | ||||
|         return gcode.str(); | ||||
|     } | ||||
| 
 | ||||
|     std::string calib_pressure_advance::print_pa_lines(double start_x, double start_y, double start_pa, double step_pa, int num) { | ||||
| 
 | ||||
|         auto& writer = mp_gcodegen->writer(); | ||||
|         Flow line_flow = Flow(m_line_width, 0.2, mp_gcodegen->config().nozzle_diameter.get_at(0)); | ||||
|         Flow thin_line_flow = Flow(0.44, 0.2, mp_gcodegen->config().nozzle_diameter.get_at(0)); | ||||
|         const double e_calib = line_flow.mm3_per_mm() / 2.40528; // filament_mm/extrusion_mm
 | ||||
|         const double e = thin_line_flow.mm3_per_mm() / 2.40528; // filament_mm/extrusion_mm
 | ||||
| 
 | ||||
| 
 | ||||
|         const double fast = m_fast_speed * 60.0; | ||||
|         const double slow = m_slow_speed * 60.0; | ||||
|         std::stringstream gcode; | ||||
|         gcode << mp_gcodegen->writer().travel_to_z(0.2); | ||||
|         double y_pos = start_y; | ||||
| 
 | ||||
|         // prime line
 | ||||
|         auto prime_x = start_x - 2; | ||||
|         gcode << move_to(Vec2d(prime_x, y_pos + (num - 4) * m_space_y)); | ||||
|         gcode << writer.set_speed(slow); | ||||
|         gcode << writer.extrude_to_xy(Vec2d(prime_x, y_pos + 3 * m_space_y), e_calib * m_space_y * num * 1.1); | ||||
| 
 | ||||
|         for (int i = 0; i < num; ++i) { | ||||
| 
 | ||||
|             gcode << writer.set_pressure_advance(start_pa + i * step_pa); | ||||
|             gcode << move_to(Vec2d(start_x, y_pos + i * m_space_y)); | ||||
|             gcode << writer.set_speed(slow); | ||||
|             gcode << writer.extrude_to_xy(Vec2d(start_x + m_length_short, y_pos + i * m_space_y), e_calib * m_length_short); | ||||
|             gcode << writer.set_speed(fast); | ||||
|             gcode << writer.extrude_to_xy(Vec2d(start_x + m_length_short + m_length_long, y_pos + i * m_space_y), e_calib * m_length_long); | ||||
|             gcode << writer.set_speed(slow); | ||||
|             gcode << writer.extrude_to_xy(Vec2d(start_x + m_length_short + m_length_long + m_length_short, y_pos + i * m_space_y), e_calib * m_length_short); | ||||
| 
 | ||||
|         } | ||||
|         gcode << writer.set_pressure_advance(0.0); | ||||
| 
 | ||||
|         if (m_draw_numbers) { | ||||
|             // draw indicator lines
 | ||||
|             gcode << writer.set_speed(fast); | ||||
|             gcode << move_to(Vec2d(start_x + m_length_short, y_pos + (num - 1) * m_space_y + 2)); | ||||
|             gcode << writer.extrude_to_xy(Vec2d(start_x + m_length_short, y_pos + (num - 1) * m_space_y + 7), e * 7); | ||||
|             gcode << move_to(Vec2d(start_x + m_length_short + m_length_long, y_pos + (num - 1) * m_space_y + 7)); | ||||
|             gcode << writer.extrude_to_xy(Vec2d(start_x + m_length_short + m_length_long, y_pos + (num - 1) * m_space_y + 2), e * 7); | ||||
| 
 | ||||
|             for (int i = 0; i < num; i += 2) { | ||||
|                 gcode << draw_number(start_x + m_length_short + m_length_long + m_length_short + 3, y_pos + i * m_space_y + m_space_y / 2, start_pa + i * step_pa); | ||||
|             } | ||||
|         } | ||||
|         return gcode.str(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     std::string calib_pressure_advance::draw_digit(double startx, double starty, char c) { | ||||
|         auto& writer = mp_gcodegen->writer(); | ||||
|         std::stringstream gcode; | ||||
|         const double lw = 0.48; | ||||
|         Flow line_flow = Flow(lw, 0.2, mp_gcodegen->config().nozzle_diameter.get_at(0)); | ||||
|         const double len = 2; | ||||
|         const double gap = lw / 2.0; | ||||
|         const double e = line_flow.mm3_per_mm() / 2.40528; // filament_mm/extrusion_mm
 | ||||
| 
 | ||||
|         //  0-------1 
 | ||||
|         //  |       |
 | ||||
|         //  3-------2
 | ||||
|         //  |       |
 | ||||
|         //  4-------5
 | ||||
|         const Vec2d p0(startx, starty); | ||||
|         const Vec2d p1(startx + len, starty); | ||||
|         const Vec2d p2(startx + len, starty - len); | ||||
|         const Vec2d p3(startx, starty - len); | ||||
|         const Vec2d p4(startx, starty - len * 2); | ||||
|         const Vec2d p5(startx + len, starty - len * 2); | ||||
| 
 | ||||
|         switch (c) | ||||
|         { | ||||
|         case '0': | ||||
|             gcode << move_to(p0); | ||||
|             gcode << writer.extrude_to_xy(p1, e * len); | ||||
|             gcode << writer.extrude_to_xy(p5, e * len * 2); | ||||
|             gcode << writer.extrude_to_xy(p4, e * len); | ||||
|             gcode << writer.extrude_to_xy(p0 - Vec2d(0, gap), e * len * 2); | ||||
|             break; | ||||
|         case '1': | ||||
|             gcode << move_to(p0 + Vec2d(len / 2, 0)); | ||||
|             gcode << writer.extrude_to_xy(p4 + Vec2d(len / 2, 0), e * len * 2); | ||||
|             break; | ||||
|         case '2': | ||||
|             gcode << move_to(p0); | ||||
|             gcode << writer.extrude_to_xy(p1, e * len); | ||||
|             gcode << writer.extrude_to_xy(p2, e * len); | ||||
|             gcode << writer.extrude_to_xy(p3, e * len); | ||||
|             gcode << writer.extrude_to_xy(p4, e * len); | ||||
|             gcode << writer.extrude_to_xy(p5, e * len); | ||||
|             break; | ||||
|         case '3': | ||||
|             gcode << move_to(p0); | ||||
|             gcode << writer.extrude_to_xy(p1, e * len); | ||||
|             gcode << writer.extrude_to_xy(p5, e * len * 2); | ||||
|             gcode << writer.extrude_to_xy(p4, e * len); | ||||
|             gcode << move_to(p2 - Vec2d(gap, 0)); | ||||
|             gcode << writer.extrude_to_xy(p3, e * len); | ||||
|             break; | ||||
|         case '4': | ||||
|             gcode << move_to(p0); | ||||
|             gcode << writer.extrude_to_xy(p3, e * len); | ||||
|             gcode << writer.extrude_to_xy(p2, e * len); | ||||
|             gcode << move_to(p1); | ||||
|             gcode << writer.extrude_to_xy(p5, e * len * 2); | ||||
|             break; | ||||
|         case '5': | ||||
|             gcode << move_to(p1); | ||||
|             gcode << writer.extrude_to_xy(p0, e * len); | ||||
|             gcode << writer.extrude_to_xy(p3, e * len); | ||||
|             gcode << writer.extrude_to_xy(p2, e * len); | ||||
|             gcode << writer.extrude_to_xy(p5, e * len); | ||||
|             gcode << writer.extrude_to_xy(p4, e * len); | ||||
|             break; | ||||
|         case '6': | ||||
|             gcode << move_to(p1); | ||||
|             gcode << writer.extrude_to_xy(p0, e * len); | ||||
|             gcode << writer.extrude_to_xy(p4, e * len * 2); | ||||
|             gcode << writer.extrude_to_xy(p5, e * len); | ||||
|             gcode << writer.extrude_to_xy(p2, e * len); | ||||
|             gcode << writer.extrude_to_xy(p3, e * len); | ||||
|             break; | ||||
|         case '7': | ||||
|             gcode << move_to(p0); | ||||
|             gcode << writer.extrude_to_xy(p1, e * len); | ||||
|             gcode << writer.extrude_to_xy(p5, e * len * 2); | ||||
|             break; | ||||
|         case '8': | ||||
|             gcode << move_to(p2); | ||||
|             gcode << writer.extrude_to_xy(p3, e * len); | ||||
|             gcode << writer.extrude_to_xy(p4, e * len); | ||||
|             gcode << writer.extrude_to_xy(p5, e * len); | ||||
|             gcode << writer.extrude_to_xy(p1, e * len * 2); | ||||
|             gcode << writer.extrude_to_xy(p0, e * len); | ||||
|             gcode << writer.extrude_to_xy(p3, e * len); | ||||
|             break; | ||||
|         case '9': | ||||
|             gcode << move_to(p5); | ||||
|             gcode << writer.extrude_to_xy(p1, e * len * 2); | ||||
|             gcode << writer.extrude_to_xy(p0, e * len); | ||||
|             gcode << writer.extrude_to_xy(p3, e * len); | ||||
|             gcode << writer.extrude_to_xy(p2, e * len); | ||||
|             break; | ||||
|         case '.': | ||||
|             gcode << move_to(p4 + Vec2d(len / 2, 0)); | ||||
|             gcode << writer.extrude_to_xy(p4 + Vec2d(len / 2, len / 2), e * len); | ||||
|             break; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         return gcode.str(); | ||||
|     } | ||||
|     // draw number
 | ||||
|     std::string calib_pressure_advance::draw_number(double startx, double starty, double value) { | ||||
|         double spacing = 3.0; | ||||
|         auto sNumber = std::to_string(value); | ||||
|         sNumber.erase(sNumber.find_last_not_of('0') + 1, std::string::npos); | ||||
|         sNumber.erase(sNumber.find_last_not_of('.') + 1, std::string::npos); | ||||
|         std::stringstream gcode; | ||||
|         gcode << mp_gcodegen->writer().set_speed(3600); | ||||
| 
 | ||||
| 
 | ||||
|         for (int i = 0; i < sNumber.length(); ++i) { | ||||
|             if (i > 5) | ||||
|                 break; | ||||
|             gcode << draw_digit(startx + i * spacing, starty, sNumber[i]); | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         return gcode.str(); | ||||
|     } | ||||
| } // namespace Slic3r
 | ||||
| 
 | ||||
|  | @ -13,9 +13,11 @@ enum class CalibMode : int { | |||
|     Calib_Flow_Rate, | ||||
|     Calib_Temp_Tower, | ||||
|     Calib_Vol_speed_Tower, | ||||
|     Calib_VFA_Tower | ||||
|     Calib_VFA_Tower, | ||||
|     Calib_Retraction_tower | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
| struct Calib_Params | ||||
| { | ||||
|     Calib_Params() : mode(CalibMode::Calib_None){} | ||||
|  | @ -23,4 +25,35 @@ struct Calib_Params | |||
|     bool print_numbers; | ||||
|     CalibMode mode; | ||||
| }; | ||||
| 
 | ||||
| class calib_pressure_advance | ||||
| { | ||||
| public: | ||||
|     calib_pressure_advance(GCode *gcodegen); | ||||
|     ~calib_pressure_advance() {} | ||||
| 
 | ||||
|     std::string generate_test(double start_pa = 0, double step_pa = 0.002, int count = 50); | ||||
|     void        set_speed(double fast = 100.0, double slow = 20.0) | ||||
|     { | ||||
|         m_slow_speed = slow; | ||||
|         m_fast_speed = fast; | ||||
|     } | ||||
|     double &line_width() { return m_line_width; }; | ||||
|     bool &  draw_numbers() { return m_draw_numbers; } | ||||
| 
 | ||||
| private: | ||||
|     std::string move_to(Vec2d pt); | ||||
|     std::string print_pa_lines(double start_x, double start_y, double start_pa, double step_pa, int num); | ||||
|     std::string draw_digit(double startx, double starty, char c); | ||||
|     std::string draw_number(double startx, double starty, double value); | ||||
| 
 | ||||
| private: | ||||
|     GCode *mp_gcodegen; | ||||
|     double m_length_short, m_length_long; | ||||
|     double m_space_y; | ||||
|     double m_slow_speed, m_fast_speed; | ||||
|     double m_line_width; | ||||
|     bool   m_draw_numbers; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Slic3r
 | ||||
|  |  | |||
|  | @ -1849,98 +1849,124 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato | |||
|     } | ||||
|     if (this->m_objsWithBrim.empty() && this->m_objSupportsWithBrim.empty()) m_brim_done = true; | ||||
| 
 | ||||
|     //BBS: open spaghetti detector
 | ||||
|     // if (print.config().spaghetti_detector.value)
 | ||||
|     if (print.is_BBL_Printer()) | ||||
|         file.write("M981 S1 P20000 ;open spaghetti detector\n"); | ||||
| 
 | ||||
|     // Do all objects for each layer.
 | ||||
|     if (print.config().print_sequence == PrintSequence::ByObject && !has_wipe_tower) { | ||||
|         size_t finished_objects = 0; | ||||
|         const PrintObject *prev_object = (*print_object_instance_sequential_active)->print_object; | ||||
|         for (; print_object_instance_sequential_active != print_object_instances_ordering.end(); ++ print_object_instance_sequential_active) { | ||||
|             const PrintObject &object = *(*print_object_instance_sequential_active)->print_object; | ||||
|             if (&object != prev_object || tool_ordering.first_extruder() != final_extruder_id) { | ||||
|                 tool_ordering = ToolOrdering(object, final_extruder_id); | ||||
|                 unsigned int new_extruder_id = tool_ordering.first_extruder(); | ||||
|                 if (new_extruder_id == (unsigned int)-1) | ||||
|                     // Skip this object.
 | ||||
|                     continue; | ||||
|                 initial_extruder_id = new_extruder_id; | ||||
|                 final_extruder_id   = tool_ordering.last_extruder(); | ||||
|                 assert(final_extruder_id != (unsigned int)-1); | ||||
|             } | ||||
|             print.throw_if_canceled(); | ||||
|             this->set_origin(unscale((*print_object_instance_sequential_active)->shift)); | ||||
| 
 | ||||
|             // BBS: prime extruder if extruder change happens before this object instance
 | ||||
|             bool prime_extruder = false; | ||||
|             if (finished_objects > 0) { | ||||
|                 // Move to the origin position for the copy we're going to print.
 | ||||
|                 // This happens before Z goes down to layer 0 again, so that no collision happens hopefully.
 | ||||
|                 m_enable_cooling_markers = false; // we're not filtering these moves through CoolingBuffer
 | ||||
|                 m_avoid_crossing_perimeters.use_external_mp_once(); | ||||
|                 // BBS. change tool before moving to origin point.
 | ||||
|                 if (m_writer.need_toolchange(initial_extruder_id)) { | ||||
|                     const PrintObjectConfig& object_config = object.config(); | ||||
|                     coordf_t initial_layer_print_height = print.config().initial_layer_print_height.value; | ||||
|                     file.write(this->set_extruder(initial_extruder_id, initial_layer_print_height)); | ||||
|                     prime_extruder = true; | ||||
|                 } | ||||
|                 else { | ||||
|                     file.write(this->retract()); | ||||
|                 } | ||||
|                 file.write(m_writer.travel_to_z(m_max_layer_z)); | ||||
|                 file.write(this->travel_to(Point(0, 0), erNone, "move to origin position for next object")); | ||||
|                 m_enable_cooling_markers = true; | ||||
|                 // Disable motion planner when traveling to first object point.
 | ||||
|                 m_avoid_crossing_perimeters.disable_once(); | ||||
|                 // Ff we are printing the bottom layer of an object, and we have already finished
 | ||||
|                 // another one, set first layer temperatures. This happens before the Z move
 | ||||
|                 // is triggered, so machine has more time to reach such temperatures.
 | ||||
|                 m_placeholder_parser.set("current_object_idx", int(finished_objects)); | ||||
|                 //BBS: remove printing_by_object_gcode
 | ||||
|                 //std::string printing_by_object_gcode = this->placeholder_parser_process("printing_by_object_gcode", print.config().printing_by_object_gcode.value, initial_extruder_id);
 | ||||
|                 std::string printing_by_object_gcode; | ||||
|                 // Set first layer bed and extruder temperatures, don't wait for it to reach the temperature.
 | ||||
|                 this->_print_first_layer_bed_temperature(file, print, printing_by_object_gcode, initial_extruder_id, false); | ||||
|                 this->_print_first_layer_extruder_temperatures(file, print, printing_by_object_gcode, initial_extruder_id, false); | ||||
|                 file.writeln(printing_by_object_gcode); | ||||
|             } | ||||
|             // Reset the cooling buffer internal state (the current position, feed rate, accelerations).
 | ||||
|             m_cooling_buffer->reset(this->writer().get_position()); | ||||
|             m_cooling_buffer->set_current_extruder(initial_extruder_id); | ||||
|             // Process all layers of a single object instance (sequential mode) with a parallel pipeline:
 | ||||
|             // Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser
 | ||||
|             // and export G-code into file.
 | ||||
|             this->process_layers(print, tool_ordering, collect_layers_to_print(object), *print_object_instance_sequential_active - object.instances().data(), file, prime_extruder); | ||||
|             //BBS: close powerlost recovery
 | ||||
|             { | ||||
|                 if (m_second_layer_things_done && print.is_BBL_Printer()) { | ||||
|                     file.write("; close powerlost recovery\n"); | ||||
|                     file.write("M1003 S0\n"); | ||||
|                 } | ||||
|             } | ||||
| #ifdef HAS_PRESSURE_EQUALIZER | ||||
|             if (m_pressure_equalizer) | ||||
|                 file.write(m_pressure_equalizer->process("", true)); | ||||
| #endif /* HAS_PRESSURE_EQUALIZER */ | ||||
|             ++ finished_objects; | ||||
|             // Flag indicating whether the nozzle temperature changes from 1st to 2nd layer were performed.
 | ||||
|             // Reset it when starting another object from 1st layer.
 | ||||
|             m_second_layer_things_done = false; | ||||
|             prev_object = &object; | ||||
|     // SoftFever: calib
 | ||||
|     if (print.calib_params().mode == CalibMode::Calib_PA_Line) { | ||||
|         std::string gcode; | ||||
|         if ((m_config.default_acceleration.value > 0 && m_config.outer_wall_acceleration.value > 0)) { | ||||
|             gcode += m_writer.set_acceleration((unsigned int) floor(m_config.outer_wall_acceleration.value + 0.5)); | ||||
|         } | ||||
|     } else { | ||||
|         // Sort layers by Z.
 | ||||
|         // All extrusion moves with the same top layer height are extruded uninterrupted.
 | ||||
|         std::vector<std::pair<coordf_t, std::vector<LayerToPrint>>> layers_to_print = collect_layers_to_print(print); | ||||
|         // Prusa Multi-Material wipe tower.
 | ||||
|         if (has_wipe_tower && ! layers_to_print.empty()) { | ||||
|             m_wipe_tower.reset(new WipeTowerIntegration(print.config(), print.get_plate_index(), print.get_plate_origin(), * print.wipe_tower_data().priming.get(), print.wipe_tower_data().tool_changes, *print.wipe_tower_data().final_purge.get())); | ||||
|             //BBS
 | ||||
|             //file.write(m_writer.travel_to_z(initial_layer_print_height + m_config.z_offset.value, "Move to the first layer height"));
 | ||||
|             file.write(m_writer.travel_to_z(initial_layer_print_height, "Move to the first layer height")); | ||||
| 
 | ||||
|         // todo: 3rd party printer need
 | ||||
|         //if (m_config.default_jerk.value > 0) {
 | ||||
|         //    double jerk = m_config.outer_wall_jerk.value;
 | ||||
|         //    gcode += m_writer.set_jerk_xy(jerk);
 | ||||
|         //}
 | ||||
| 
 | ||||
|         calib_pressure_advance pa_test(this); | ||||
|         double                 filament_max_volumetric_speed = m_config.option<ConfigOptionFloats>("filament_max_volumetric_speed")->get_at(initial_extruder_id); | ||||
|         Flow                   pattern_line                  = Flow(pa_test.line_width(), 0.2, m_config.nozzle_diameter.get_at(0)); | ||||
|         auto                   fast_speed = std::min(print.default_region_config().outer_wall_speed.value, filament_max_volumetric_speed / pattern_line.mm3_per_mm()); | ||||
|         auto                   slow_speed = std::max(20.0, fast_speed / 10.0); | ||||
|         pa_test.set_speed(fast_speed, slow_speed); | ||||
|         pa_test.draw_numbers() = print.calib_params().print_numbers; | ||||
|         auto params            = print.calib_params(); | ||||
|         gcode += pa_test.generate_test(params.start, params.step, std::llround(std::ceil((params.end - params.start) / params.step))); | ||||
| 
 | ||||
|         file.write(gcode); | ||||
|     } | ||||
|     else { | ||||
|         // BBS: open spaghetti detector
 | ||||
|         // if (print.config().spaghetti_detector.value)
 | ||||
|         if (print.is_BBL_Printer()) file.write("M981 S1 P20000 ;open spaghetti detector\n"); | ||||
| 
 | ||||
|         // Do all objects for each layer.
 | ||||
|         if (print.config().print_sequence == PrintSequence::ByObject && !has_wipe_tower) { | ||||
|             size_t             finished_objects = 0; | ||||
|             const PrintObject *prev_object      = (*print_object_instance_sequential_active)->print_object; | ||||
|             for (; print_object_instance_sequential_active != print_object_instances_ordering.end(); ++print_object_instance_sequential_active) { | ||||
|                 const PrintObject &object = *(*print_object_instance_sequential_active)->print_object; | ||||
|                 if (&object != prev_object || tool_ordering.first_extruder() != final_extruder_id) { | ||||
|                     tool_ordering                = ToolOrdering(object, final_extruder_id); | ||||
|                     unsigned int new_extruder_id = tool_ordering.first_extruder(); | ||||
|                     if (new_extruder_id == (unsigned int) -1) | ||||
|                         // Skip this object.
 | ||||
|                         continue; | ||||
|                     initial_extruder_id = new_extruder_id; | ||||
|                     final_extruder_id   = tool_ordering.last_extruder(); | ||||
|                     assert(final_extruder_id != (unsigned int) -1); | ||||
|                 } | ||||
|                 print.throw_if_canceled(); | ||||
|                 this->set_origin(unscale((*print_object_instance_sequential_active)->shift)); | ||||
| 
 | ||||
|                 // BBS: prime extruder if extruder change happens before this object instance
 | ||||
|                 bool prime_extruder = false; | ||||
|                 if (finished_objects > 0) { | ||||
|                     // Move to the origin position for the copy we're going to print.
 | ||||
|                     // This happens before Z goes down to layer 0 again, so that no collision happens hopefully.
 | ||||
|                     m_enable_cooling_markers = false; // we're not filtering these moves through CoolingBuffer
 | ||||
|                     m_avoid_crossing_perimeters.use_external_mp_once(); | ||||
|                     // BBS. change tool before moving to origin point.
 | ||||
|                     if (m_writer.need_toolchange(initial_extruder_id)) { | ||||
|                         const PrintObjectConfig &object_config              = object.config(); | ||||
|                         coordf_t                 initial_layer_print_height = print.config().initial_layer_print_height.value; | ||||
|                         file.write(this->set_extruder(initial_extruder_id, initial_layer_print_height)); | ||||
|                         prime_extruder = true; | ||||
|                     } else { | ||||
|                         file.write(this->retract()); | ||||
|                     } | ||||
|                     file.write(m_writer.travel_to_z(m_max_layer_z)); | ||||
|                     file.write(this->travel_to(Point(0, 0), erNone, "move to origin position for next object")); | ||||
|                     m_enable_cooling_markers = true; | ||||
|                     // Disable motion planner when traveling to first object point.
 | ||||
|                     m_avoid_crossing_perimeters.disable_once(); | ||||
|                     // Ff we are printing the bottom layer of an object, and we have already finished
 | ||||
|                     // another one, set first layer temperatures. This happens before the Z move
 | ||||
|                     // is triggered, so machine has more time to reach such temperatures.
 | ||||
|                     m_placeholder_parser.set("current_object_idx", int(finished_objects)); | ||||
|                     // BBS: remove printing_by_object_gcode
 | ||||
|                     // std::string printing_by_object_gcode = this->placeholder_parser_process("printing_by_object_gcode", print.config().printing_by_object_gcode.value,
 | ||||
|                     // initial_extruder_id);
 | ||||
|                     std::string printing_by_object_gcode; | ||||
|                     // Set first layer bed and extruder temperatures, don't wait for it to reach the temperature.
 | ||||
|                     this->_print_first_layer_bed_temperature(file, print, printing_by_object_gcode, initial_extruder_id, false); | ||||
|                     this->_print_first_layer_extruder_temperatures(file, print, printing_by_object_gcode, initial_extruder_id, false); | ||||
|                     file.writeln(printing_by_object_gcode); | ||||
|                 } | ||||
|                 // Reset the cooling buffer internal state (the current position, feed rate, accelerations).
 | ||||
|                 m_cooling_buffer->reset(this->writer().get_position()); | ||||
|                 m_cooling_buffer->set_current_extruder(initial_extruder_id); | ||||
|                 // Process all layers of a single object instance (sequential mode) with a parallel pipeline:
 | ||||
|                 // Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser
 | ||||
|                 // and export G-code into file.
 | ||||
|                 this->process_layers(print, tool_ordering, collect_layers_to_print(object), *print_object_instance_sequential_active - object.instances().data(), file, | ||||
|                                      prime_extruder); | ||||
|                 // BBS: close powerlost recovery
 | ||||
|                 { | ||||
|                     if (m_second_layer_things_done && print.is_BBL_Printer()) { | ||||
|                         file.write("; close powerlost recovery\n"); | ||||
|                         file.write("M1003 S0\n"); | ||||
|                     } | ||||
|                 } | ||||
| #ifdef HAS_PRESSURE_EQUALIZER | ||||
|                 if (m_pressure_equalizer) file.write(m_pressure_equalizer->process("", true)); | ||||
| #endif /* HAS_PRESSURE_EQUALIZER */ | ||||
|                 ++finished_objects; | ||||
|                 // Flag indicating whether the nozzle temperature changes from 1st to 2nd layer were performed.
 | ||||
|                 // Reset it when starting another object from 1st layer.
 | ||||
|                 m_second_layer_things_done = false; | ||||
|                 prev_object                = &object; | ||||
|             } | ||||
|         } else { | ||||
|             // Sort layers by Z.
 | ||||
|             // All extrusion moves with the same top layer height are extruded uninterrupted.
 | ||||
|             std::vector<std::pair<coordf_t, std::vector<LayerToPrint>>> layers_to_print = collect_layers_to_print(print); | ||||
|             // Prusa Multi-Material wipe tower.
 | ||||
|             if (has_wipe_tower && !layers_to_print.empty()) { | ||||
|                 m_wipe_tower.reset(new WipeTowerIntegration(print.config(), print.get_plate_index(), print.get_plate_origin(), *print.wipe_tower_data().priming.get(), | ||||
|                                                             print.wipe_tower_data().tool_changes, *print.wipe_tower_data().final_purge.get())); | ||||
|                 // BBS
 | ||||
|                 // file.write(m_writer.travel_to_z(initial_layer_print_height + m_config.z_offset.value, "Move to the first layer height"));
 | ||||
|                 file.write(m_writer.travel_to_z(initial_layer_print_height, "Move to the first layer height")); | ||||
| #if 0 | ||||
|             if (print.config().single_extruder_multi_material_priming) { | ||||
|                 file.write(m_wipe_tower->prime(*this)); | ||||
|  | @ -1979,26 +2005,26 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato | |||
|                 //}
 | ||||
|             } | ||||
| #endif | ||||
|             print.throw_if_canceled(); | ||||
|         } | ||||
|         // Process all layers of all objects (non-sequential mode) with a parallel pipeline:
 | ||||
|         // Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser
 | ||||
|         // and export G-code into file.
 | ||||
|         this->process_layers(print, tool_ordering, print_object_instances_ordering, layers_to_print, file); | ||||
|         //BBS: close powerlost recovery
 | ||||
|         { | ||||
|             if (m_second_layer_things_done && print.is_BBL_Printer()) { | ||||
|                 file.write("; close powerlost recovery\n"); | ||||
|                 file.write("M1003 S0\n"); | ||||
|                 print.throw_if_canceled(); | ||||
|             } | ||||
|             // Process all layers of all objects (non-sequential mode) with a parallel pipeline:
 | ||||
|             // Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser
 | ||||
|             // and export G-code into file.
 | ||||
|             this->process_layers(print, tool_ordering, print_object_instances_ordering, layers_to_print, file); | ||||
|             // BBS: close powerlost recovery
 | ||||
|             { | ||||
|                 if (m_second_layer_things_done && print.is_BBL_Printer()) { | ||||
|                     file.write("; close powerlost recovery\n"); | ||||
|                     file.write("M1003 S0\n"); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| #ifdef HAS_PRESSURE_EQUALIZER | ||||
|         if (m_pressure_equalizer) | ||||
|             file.write(m_pressure_equalizer->process("", true)); | ||||
|             if (m_pressure_equalizer) file.write(m_pressure_equalizer->process("", true)); | ||||
| #endif /* HAS_PRESSURE_EQUALIZER */ | ||||
|         if (m_wipe_tower) | ||||
|             // Purge the extruder, pull out the active filament.
 | ||||
|             file.write(m_wipe_tower->finalize(*this)); | ||||
|             if (m_wipe_tower) | ||||
|                 // Purge the extruder, pull out the active filament.
 | ||||
|                 file.write(m_wipe_tower->finalize(*this)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     //BBS: the last retraction
 | ||||
|  | @ -2748,6 +2774,14 @@ GCode::LayerResult GCode::process_layer( | |||
|         auto _speed = print.calib_params().start + std::floor(print_z / 5.0) * print.calib_params().step; | ||||
|         m_calib_config.set_key_value("outer_wall_speed", new ConfigOptionFloat(std::round(_speed))); | ||||
|     } | ||||
|     else if (print.calib_mode() == CalibMode::Calib_Retraction_tower) { | ||||
|         auto _length = print.calib_params().start + std::floor(std::max(0.0, print_z - 0.4)) * print.calib_params().step; | ||||
|         DynamicConfig _cfg; | ||||
|         _cfg.set_key_value("retraction_length", new ConfigOptionFloats{_length}); | ||||
|         writer().config.apply(_cfg); | ||||
|         sprintf(buf, "; Calib_Retraction_tower: Z_HEIGHT: %g, length:%g\n", print_z, _length); | ||||
|         gcode += buf; | ||||
|     } | ||||
| 
 | ||||
|     //BBS
 | ||||
|     if (first_layer) { | ||||
|  |  | |||
|  | @ -198,6 +198,11 @@ public: | |||
|     // append full config to the given string
 | ||||
|     static void append_full_config(const Print& print, std::string& str); | ||||
| 
 | ||||
|     // BBS: detect lift type in needs_retraction
 | ||||
|     bool        needs_retraction(const Polyline &travel, ExtrusionRole role, LiftType &lift_type); | ||||
|     std::string retract(bool toolchange = false, bool is_last_retraction = false, LiftType lift_type = LiftType::SpiralLift); | ||||
|     std::string unretract() { return m_writer.unlift() + m_writer.unretract(); } | ||||
| 
 | ||||
|     // Object and support extrusions of the same PrintObject at the same print_z.
 | ||||
|     // public, so that it could be accessed by free helper functions from GCode.cpp
 | ||||
|     struct LayerToPrint | ||||
|  | @ -400,10 +405,7 @@ private: | |||
|     std::string     travel_to(const Point &point, ExtrusionRole role, std::string comment); | ||||
|     // BBS
 | ||||
|     LiftType to_lift_type(ZHopType z_hop_types); | ||||
|     // BBS: detect lift type in needs_retraction
 | ||||
|     bool            needs_retraction(const Polyline& travel, ExtrusionRole role, LiftType& lift_type); | ||||
|     std::string     retract(bool toolchange = false, bool is_last_retraction = false, LiftType lift_type = LiftType::SpiralLift); | ||||
|     std::string     unretract() { return m_writer.unlift() + m_writer.unretract(); } | ||||
| 
 | ||||
|     std::string     set_extruder(unsigned int extruder_id, double print_z); | ||||
|     std::set<ObjectID>              m_objsWithBrim; // indicates the objs with brim
 | ||||
|     std::set<ObjectID>              m_objSupportsWithBrim; // indicates the objs' supports with brim
 | ||||
|  |  | |||
|  | @ -182,6 +182,24 @@ std::string GCodeWriter::set_acceleration(unsigned int acceleration) | |||
|     return gcode.str(); | ||||
| } | ||||
| 
 | ||||
| std::string GCodeWriter::set_pressure_advance(double pa) const | ||||
| { | ||||
|     std::ostringstream gcode; | ||||
|     if (pa < 0) return gcode.str(); | ||||
|     if (false) { // todo: bbl printer
 | ||||
|         // SoftFever: set L1000 to use linear model
 | ||||
|         gcode << "M900 K" << std::setprecision(4) << pa << " L1000 M10 ; Override pressure advance value\n"; | ||||
|     } else { | ||||
|         if (this->config.gcode_flavor == gcfKlipper) | ||||
|             gcode << "SET_PRESSURE_ADVANCE ADVANCE=" << std::setprecision(4) << pa << "; Override pressure advance value\n"; | ||||
|         else if (this->config.gcode_flavor == gcfRepRapFirmware) | ||||
|             gcode << ("M572 D0 S") << std::setprecision(4) << pa << "; Override pressure advance value\n"; | ||||
|         else | ||||
|             gcode << "M900 K" << std::setprecision(4) << pa << "; Override pressure advance value\n"; | ||||
|     } | ||||
|     return gcode.str(); | ||||
| } | ||||
| 
 | ||||
| std::string GCodeWriter::reset_e(bool force) | ||||
| { | ||||
|     if (FLAVOR_IS(gcfMach3) | ||||
|  |  | |||
|  | @ -50,6 +50,7 @@ public: | |||
|     std::string set_temperature(unsigned int temperature, bool wait = false, int tool = -1) const; | ||||
|     std::string set_bed_temperature(int temperature, bool wait = false); | ||||
|     std::string set_acceleration(unsigned int acceleration); | ||||
|     std::string set_pressure_advance(double pa) const; | ||||
|     std::string reset_e(bool force = false); | ||||
|     std::string update_progress(unsigned int num, unsigned int tot, bool allow_100 = false) const; | ||||
|     // return false if this extruder was already selected
 | ||||
|  |  | |||
|  | @ -33,7 +33,7 @@ namespace Slic3r { | |||
| 
 | ||||
| enum GCodeFlavor : unsigned char { | ||||
|     gcfMarlinLegacy, gcfRepRapSprinter, gcfRepRapFirmware, gcfRepetier, gcfTeacup, gcfMakerWare, gcfMarlinFirmware, gcfSailfish, gcfMach3, gcfMachinekit, | ||||
|     gcfSmoothie, gcfNoExtrusion, | ||||
|     gcfSmoothie, gcfNoExtrusion, gcfKlipper | ||||
| }; | ||||
| 
 | ||||
| enum class FuzzySkinType { | ||||
|  |  | |||
|  | @ -2782,7 +2782,7 @@ bool MaxVolumetricSpeedWizard::start_calibration(std::vector<int> tray_ids) | |||
|     std::string error_message; | ||||
|     CalibUtils::calib_max_vol_speed(calib_info, error_message); | ||||
|     if (!error_message.empty()) { | ||||
|         MessageDialog msg_dlg(nullptr, error_message, wxEmptyString, wxICON_WARNING | wxOK); | ||||
|         MessageDialog msg_dlg(nullptr, _L(error_message), wxEmptyString, wxICON_WARNING | wxOK); | ||||
|         msg_dlg.ShowModal(); | ||||
|         return false; | ||||
|     } | ||||
|  | @ -2960,7 +2960,7 @@ bool TemperatureWizard::start_calibration(std::vector<int> tray_ids) | |||
|     std::string error_message; | ||||
|     CalibUtils::calib_temptue(calib_info, error_message); | ||||
|     if (!error_message.empty()) { | ||||
|         MessageDialog msg_dlg(nullptr, error_message, wxEmptyString, wxICON_WARNING | wxOK); | ||||
|         MessageDialog msg_dlg(nullptr, _L(error_message), wxEmptyString, wxICON_WARNING | wxOK); | ||||
|         msg_dlg.ShowModal(); | ||||
|         return false; | ||||
|     } | ||||
|  |  | |||
|  | @ -7,9 +7,6 @@ | |||
| 
 | ||||
| #include "libslic3r/Model.hpp" | ||||
| 
 | ||||
| // todo test
 | ||||
| #include "../GUI/BBLStatusBar.hpp" | ||||
| 
 | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| namespace GUI { | ||||
|  | @ -66,6 +63,16 @@ static void read_model_from_file(const std::string& input_file, Model& model) | |||
|         object->ensure_on_bed(); | ||||
| } | ||||
| 
 | ||||
| std::array<Vec3d, 4> get_cut_plane(const BoundingBoxf3 &bbox, const double &cut_height) | ||||
| { | ||||
|     std::array<Vec3d, 4> plane_pts; | ||||
|     plane_pts[0] = Vec3d(bbox.min(0), bbox.min(1), cut_height); | ||||
|     plane_pts[1] = Vec3d(bbox.max(0), bbox.min(1), cut_height); | ||||
|     plane_pts[2] = Vec3d(bbox.max(0), bbox.max(1), cut_height); | ||||
|     plane_pts[3] = Vec3d(bbox.min(0), bbox.max(1), cut_height); | ||||
|     return plane_pts; | ||||
| } | ||||
| 
 | ||||
| void CalibUtils::calib_PA(const X1CCalibInfos& calib_infos, std::string& error_message) | ||||
| { | ||||
|     DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager(); | ||||
|  | @ -306,6 +313,33 @@ void CalibUtils::calib_flowrate(int pass, const CalibInfo& calib_info, std::stri | |||
|     send_to_print(calib_info.dev_id, calib_info.select_ams, calib_info.process_bar, calib_info.bed_type, error_message); | ||||
| } | ||||
| 
 | ||||
| void CalibUtils::calib_generic_PA(const CalibInfo &calib_info, std::string &error_message) | ||||
| { | ||||
|     const Calib_Params ¶ms = calib_info.params; | ||||
|     if (params.mode != CalibMode::Calib_PA_Line) | ||||
|         return; | ||||
| 
 | ||||
|     Model model; | ||||
|     std::string input_file = Slic3r::resources_dir() + "/calib/pressure_advance/pressure_advance_test.stl"; | ||||
|     read_model_from_file(input_file, model); | ||||
| 
 | ||||
|     DynamicPrintConfig print_config    = calib_info.print_prest->config; | ||||
|     DynamicPrintConfig filament_config = calib_info.filament_prest->config; | ||||
|     DynamicPrintConfig printer_config  = calib_info.printer_prest->config; | ||||
| 
 | ||||
|     DynamicPrintConfig full_config; | ||||
|     full_config.apply(FullPrintConfig::defaults()); | ||||
|     full_config.apply(print_config); | ||||
|     full_config.apply(filament_config); | ||||
|     full_config.apply(printer_config); | ||||
| 
 | ||||
|     process_and_store_3mf(&model, full_config, params, error_message); | ||||
|     if (!error_message.empty()) | ||||
|         return; | ||||
| 
 | ||||
|     send_to_print(calib_info.dev_id, calib_info.select_ams, calib_info.process_bar, calib_info.bed_type, error_message); | ||||
| } | ||||
| 
 | ||||
| void CalibUtils::calib_temptue(const CalibInfo& calib_info, std::string& error_message) | ||||
| { | ||||
|     const Calib_Params ¶ms = calib_info.params; | ||||
|  | @ -509,6 +543,55 @@ void CalibUtils::calib_VFA(const CalibInfo& calib_info, std::string& error_messa | |||
|     send_to_print(calib_info.dev_id, calib_info.select_ams, calib_info.process_bar, calib_info.bed_type, error_message); | ||||
| } | ||||
| 
 | ||||
| void CalibUtils::calib_retraction(const CalibInfo &calib_info, std::string &error_message) | ||||
| { | ||||
|     const Calib_Params ¶ms = calib_info.params; | ||||
|     if (params.mode != CalibMode::Calib_Retraction_tower) | ||||
|         return; | ||||
| 
 | ||||
|     Model model; | ||||
|     std::string input_file = Slic3r::resources_dir() + "/calib/retraction/retraction_tower.stl"; | ||||
|     read_model_from_file(input_file, model); | ||||
| 
 | ||||
|     DynamicPrintConfig print_config    = calib_info.print_prest->config; | ||||
|     DynamicPrintConfig filament_config = calib_info.filament_prest->config; | ||||
|     DynamicPrintConfig printer_config  = calib_info.printer_prest->config; | ||||
| 
 | ||||
|     auto obj = model.objects[0]; | ||||
| 
 | ||||
|     double layer_height = 0.2; | ||||
| 
 | ||||
|     auto max_lh = printer_config.option<ConfigOptionFloats>("max_layer_height"); | ||||
|     if (max_lh->values[0] < layer_height) max_lh->values[0] = {layer_height}; | ||||
| 
 | ||||
|     obj->config.set_key_value("wall_loops", new ConfigOptionInt(2)); | ||||
|     obj->config.set_key_value("top_shell_layers", new ConfigOptionInt(0)); | ||||
|     obj->config.set_key_value("bottom_shell_layers", new ConfigOptionInt(3)); | ||||
|     obj->config.set_key_value("sparse_infill_density", new ConfigOptionPercent(0)); | ||||
|     obj->config.set_key_value("initial_layer_print_height", new ConfigOptionFloat(layer_height)); | ||||
|     obj->config.set_key_value("layer_height", new ConfigOptionFloat(layer_height)); | ||||
| 
 | ||||
|     //  cut upper
 | ||||
|     auto obj_bb = obj->bounding_box(); | ||||
|     auto height = 1.0 + 0.4 + ((params.end - params.start)) / params.step; | ||||
|     if (height < obj_bb.size().z()) { | ||||
|         std::array<Vec3d, 4> plane_pts = get_cut_plane(obj_bb, height); | ||||
|         cut_model(model, plane_pts, ModelObjectCutAttribute::KeepLower); | ||||
|     } | ||||
| 
 | ||||
|     DynamicPrintConfig full_config; | ||||
|     full_config.apply(FullPrintConfig::defaults()); | ||||
|     full_config.apply(print_config); | ||||
|     full_config.apply(filament_config); | ||||
|     full_config.apply(printer_config); | ||||
| 
 | ||||
|     process_and_store_3mf(&model, full_config, params, error_message); | ||||
|     if (!error_message.empty()) | ||||
|         return; | ||||
| 
 | ||||
|     send_to_print(calib_info.dev_id, calib_info.select_ams, calib_info.process_bar, calib_info.bed_type, error_message); | ||||
| } | ||||
| 
 | ||||
| void CalibUtils::process_and_store_3mf(Model* model, const DynamicPrintConfig& full_config, const Calib_Params& params, std::string& error_message) | ||||
| { | ||||
|     Pointfs bedfs         = full_config.opt<ConfigOptionPoints>("printable_area")->values; | ||||
|  | @ -544,7 +627,7 @@ void CalibUtils::process_and_store_3mf(Model* model, const DynamicPrintConfig& f | |||
|     BuildVolume build_volume(bedfs, print_height); | ||||
|     unsigned int count = model->update_print_volume_state(build_volume); | ||||
|     if (count == 0) { | ||||
|         error_message = "Nothing to be sliced, either the print is empty or no object is fully inside the print volume before apply."; | ||||
|         error_message = "Unable to calibrate: maybe because the set calibration value range is too large, or the step is too small"; | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -42,9 +42,11 @@ public: | |||
|     static bool get_flow_ratio_calib_results(std::vector<FlowRatioCalibResult> &flow_ratio_calib_results); | ||||
|     static void calib_flowrate(int pass, const CalibInfo& calib_info, std::string& error_message); | ||||
| 
 | ||||
|     static void calib_generic_PA(const CalibInfo& calib_info, std::string &error_message); | ||||
|     static void calib_temptue(const CalibInfo& calib_info, std::string& error_message); | ||||
|     static void calib_max_vol_speed(const CalibInfo& calib_info, std::string& error_message); | ||||
|     static void calib_VFA(const CalibInfo& calib_info, std::string& error_message); | ||||
|     static void calib_retraction(const CalibInfo &calib_info, std::string &error_message); | ||||
| 
 | ||||
| private: | ||||
|     static void process_and_store_3mf(Model* model, const DynamicPrintConfig& full_config, const Calib_Params& params, std::string& error_message); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 zhimin.zeng
						zhimin.zeng