mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	Time estimate shown in GUI as formatted string / Write to file made by class GCode's private methods
This commit is contained in:
		
							parent
							
								
									20234c94ee
								
							
						
					
					
						commit
						0fe855cd6d
					
				
					 7 changed files with 146 additions and 141 deletions
				
			
		|  | @ -434,7 +434,7 @@ sub new { | |||
|                 fil_mm3 => "Used Filament (mm^3)", | ||||
|                 fil_g   => "Used Filament (g)", | ||||
|                 cost    => "Cost", | ||||
|                 time    => "Estimated printing time (min)", | ||||
|                 time    => "Estimated printing time", | ||||
|             ); | ||||
|             while (my $field = shift @info) { | ||||
|                 my $label = shift @info; | ||||
|  | @ -1428,7 +1428,7 @@ sub on_export_completed { | |||
|     $self->{"print_info_cost"}->SetLabel(sprintf("%.2f" , $self->{print}->total_cost)); | ||||
|     $self->{"print_info_fil_g"}->SetLabel(sprintf("%.2f" , $self->{print}->total_weight)); | ||||
|     $self->{"print_info_fil_mm3"}->SetLabel(sprintf("%.2f" , $self->{print}->total_extruded_volume)); | ||||
|     $self->{"print_info_time"}->SetLabel(sprintf("%.2f" , $self->{print}->estimated_print_time)); | ||||
|     $self->{"print_info_time"}->SetLabel($self->{print}->estimated_print_time); | ||||
|     $self->{"print_info_fil_m"}->SetLabel(sprintf("%.2f" , $self->{print}->total_used_filament / 1000)); | ||||
|     $self->{"print_info_box_show"}->(1); | ||||
| 
 | ||||
|  |  | |||
|  | @ -267,72 +267,6 @@ std::string WipeTowerIntegration::finalize(GCode &gcodegen) | |||
| 
 | ||||
| #define EXTRUDER_CONFIG(OPT) m_config.OPT.get_at(m_writer.extruder()->id()) | ||||
| 
 | ||||
| // Helper class for writing to file with/without time estimation
 | ||||
| class Write | ||||
| { | ||||
|   static GCodeTimeEstimator* s_time_estimator; | ||||
| 
 | ||||
| public: | ||||
|   static void set_time_estimator(GCodeTimeEstimator* time_estimator) | ||||
|   { | ||||
|     s_time_estimator = time_estimator; | ||||
|   } | ||||
| 
 | ||||
|   static void write(FILE* file, const std::string& what) | ||||
|   { | ||||
|     if (!what.empty()) | ||||
|     { | ||||
|       fwrite(what.data(), 1, what.size(), file); | ||||
| 
 | ||||
|       if (s_time_estimator != nullptr) | ||||
|       { | ||||
|         const char endLine = '\n'; | ||||
|         std::string::size_type beginPos = 0; | ||||
|         std::string::size_type endPos = what.find_first_of(endLine, beginPos); | ||||
|         while (endPos != std::string::npos) | ||||
|         { | ||||
|           s_time_estimator->add_gcode_line(what.substr(beginPos, endPos - beginPos + 1)); | ||||
|            | ||||
|           beginPos = endPos + 1; | ||||
|           endPos = what.find_first_of(endLine, beginPos); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| //std::string Write::s_cache = "";
 | ||||
| GCodeTimeEstimator* Write::s_time_estimator = nullptr; | ||||
| 
 | ||||
| inline void write(FILE *file, const std::string &what) | ||||
| { | ||||
|   Write::write(file, what); | ||||
| } | ||||
| 
 | ||||
| inline void write_format(FILE* file, const char* format, ...) | ||||
| { | ||||
|   char buffer[1024]; | ||||
|   va_list args; | ||||
|   va_start(args, format); | ||||
|   int res = ::vsnprintf(buffer, 1024, format, args); | ||||
|   va_end(args); | ||||
| 
 | ||||
|   if (res >= 0) | ||||
|     write(file, buffer); | ||||
| } | ||||
| 
 | ||||
| // Write a string into a file. Add a newline, if the string does not end with a newline already.
 | ||||
| // Used to export a custom G-code section processed by the PlaceholderParser.
 | ||||
| inline void writeln(FILE *file, const std::string &what) | ||||
| { | ||||
|     if (! what.empty()) { | ||||
|         if (what.back() != '\n') | ||||
|           write_format(file, "%s\n", what.c_str()); | ||||
|         else | ||||
|           write(file, what); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Collect pairs of object_layer + support_layer sorted by print_z.
 | ||||
| // object_layer & support_layer are considered to be on the same print_z, if they are not further than EPSILON.
 | ||||
| std::vector<GCode::LayerToPrint> GCode::collect_layers_to_print(const PrintObject &object) | ||||
|  | @ -456,7 +390,6 @@ void GCode::_do_export(Print &print, FILE *file) | |||
| { | ||||
|     // resets time estimator
 | ||||
|     m_time_estimator.reset(); | ||||
|     Write::set_time_estimator(&m_time_estimator); | ||||
| 
 | ||||
|     // How many times will be change_layer() called?
 | ||||
|     // change_layer() in turn increments the progress bar status.
 | ||||
|  | @ -541,7 +474,7 @@ void GCode::_do_export(Print &print, FILE *file) | |||
|     m_enable_extrusion_role_markers = (bool)m_pressure_equalizer; | ||||
| 
 | ||||
|     // Write information on the generator.
 | ||||
|     fprintf(file, "; %s\n\n", Slic3r::header_slic3r_generated().c_str()); | ||||
|     _write_format(file, "; %s\n\n", Slic3r::header_slic3r_generated().c_str()); | ||||
|     // Write notes (content of the Print Settings tab -> Notes)
 | ||||
|     { | ||||
|         std::list<std::string> lines; | ||||
|  | @ -550,10 +483,10 @@ void GCode::_do_export(Print &print, FILE *file) | |||
|             // Remove the trailing '\r' from the '\r\n' sequence.
 | ||||
|             if (! line.empty() && line.back() == '\r') | ||||
|                 line.pop_back(); | ||||
|             fprintf(file, "; %s\n", line.c_str()); | ||||
|             _write_format(file, "; %s\n", line.c_str()); | ||||
|         } | ||||
|         if (! lines.empty()) | ||||
|           fprintf(file, "\n"); | ||||
|             _write(file, "\n"); | ||||
|     } | ||||
|     // Write some terse information on the slicing parameters.
 | ||||
|     { | ||||
|  | @ -562,16 +495,17 @@ void GCode::_do_export(Print &print, FILE *file) | |||
|         const double       first_layer_height = first_object->config.first_layer_height.get_abs_value(layer_height); | ||||
|         for (size_t region_id = 0; region_id < print.regions.size(); ++ region_id) { | ||||
|             auto region = print.regions[region_id]; | ||||
|             fprintf(file, "; external perimeters extrusion width = %.2fmm\n", region->flow(frExternalPerimeter, layer_height, false, false, -1., *first_object).width); | ||||
|             fprintf(file, "; perimeters extrusion width = %.2fmm\n",          region->flow(frPerimeter,         layer_height, false, false, -1., *first_object).width); | ||||
|             fprintf(file, "; infill extrusion width = %.2fmm\n",              region->flow(frInfill,            layer_height, false, false, -1., *first_object).width); | ||||
|             fprintf(file, "; solid infill extrusion width = %.2fmm\n",        region->flow(frSolidInfill,       layer_height, false, false, -1., *first_object).width); | ||||
|             fprintf(file, "; top infill extrusion width = %.2fmm\n",          region->flow(frTopSolidInfill,    layer_height, false, false, -1., *first_object).width); | ||||
|             _write_format(file, "; external perimeters extrusion width = %.2fmm\n", region->flow(frExternalPerimeter, layer_height, false, false, -1., *first_object).width); | ||||
|             _write_format(file, "; perimeters extrusion width = %.2fmm\n", region->flow(frPerimeter, layer_height, false, false, -1., *first_object).width); | ||||
|             _write_format(file, "; infill extrusion width = %.2fmm\n", region->flow(frInfill, layer_height, false, false, -1., *first_object).width); | ||||
|             _write_format(file, "; solid infill extrusion width = %.2fmm\n", region->flow(frSolidInfill, layer_height, false, false, -1., *first_object).width); | ||||
|             _write_format(file, "; top infill extrusion width = %.2fmm\n", region->flow(frTopSolidInfill, layer_height, false, false, -1., *first_object).width); | ||||
|             if (print.has_support_material()) | ||||
|                 fprintf(file, "; support material extrusion width = %.2fmm\n", support_material_flow(first_object).width); | ||||
|               _write_format(file, "; support material extrusion width = %.2fmm\n", support_material_flow(first_object).width); | ||||
|             if (print.config.first_layer_extrusion_width.value > 0) | ||||
|                 fprintf(file, "; first layer extrusion width = %.2fmm\n",   region->flow(frPerimeter, first_layer_height, false, true, -1., *first_object).width); | ||||
|             fprintf(file, "\n"); | ||||
|               _write_format(file, "; first layer extrusion width = %.2fmm\n", region->flow(frPerimeter, first_layer_height, false, true, -1., *first_object).width); | ||||
| 
 | ||||
|             _write(file, "\n"); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|  | @ -615,7 +549,7 @@ void GCode::_do_export(Print &print, FILE *file) | |||
| 
 | ||||
|     // Disable fan.
 | ||||
|     if (! print.config.cooling.get_at(initial_extruder_id) || print.config.disable_fan_first_layers.get_at(initial_extruder_id)) | ||||
|       write(file, m_writer.set_fan(0, true)); | ||||
|       _write(file, m_writer.set_fan(0, true)); | ||||
| 
 | ||||
|     // Let the start-up script prime the 1st printing tool.
 | ||||
|     m_placeholder_parser.set("initial_tool", initial_extruder_id); | ||||
|  | @ -632,24 +566,24 @@ void GCode::_do_export(Print &print, FILE *file) | |||
|     // Set extruder(s) temperature before and after start G-code.
 | ||||
|     this->_print_first_layer_extruder_temperatures(file, print, start_gcode, initial_extruder_id, false); | ||||
|     // Write the custom start G-code
 | ||||
|     writeln(file, start_gcode); | ||||
|     _writeln(file, start_gcode); | ||||
|     // Process filament-specific gcode in extruder order.
 | ||||
|     if (print.config.single_extruder_multi_material) { | ||||
|         if (has_wipe_tower) { | ||||
|             // Wipe tower will control the extruder switching, it will call the start_filament_gcode.
 | ||||
|         } else { | ||||
|             // Only initialize the initial extruder.
 | ||||
|             writeln(file, this->placeholder_parser_process("start_filament_gcode", print.config.start_filament_gcode.values[initial_extruder_id], initial_extruder_id)); | ||||
|           _writeln(file, this->placeholder_parser_process("start_filament_gcode", print.config.start_filament_gcode.values[initial_extruder_id], initial_extruder_id)); | ||||
|         } | ||||
|     } else { | ||||
|         for (const std::string &start_gcode : print.config.start_filament_gcode.values) | ||||
|             writeln(file, this->placeholder_parser_process("start_gcode", start_gcode, (unsigned int)(&start_gcode - &print.config.start_filament_gcode.values.front()))); | ||||
|           _writeln(file, this->placeholder_parser_process("start_gcode", start_gcode, (unsigned int)(&start_gcode - &print.config.start_filament_gcode.values.front()))); | ||||
|     } | ||||
|     this->_print_first_layer_extruder_temperatures(file, print, start_gcode, initial_extruder_id, true); | ||||
|      | ||||
|     // Set other general things.
 | ||||
|     write(file, this->preamble()); | ||||
|      | ||||
|     _write(file, this->preamble()); | ||||
| 
 | ||||
|     // Initialize a motion planner for object-to-object travel moves.
 | ||||
|     if (print.config.avoid_crossing_perimeters.value) { | ||||
|         // Collect outer contours of all objects over all layers.
 | ||||
|  | @ -697,7 +631,7 @@ void GCode::_do_export(Print &print, FILE *file) | |||
|     } | ||||
|      | ||||
|     // Set initial extruder only after custom start G-code.
 | ||||
|     write(file, this->set_extruder(initial_extruder_id)); | ||||
|     _write(file, this->set_extruder(initial_extruder_id)); | ||||
| 
 | ||||
|     // Do all objects for each layer.
 | ||||
|     if (print.config.complete_objects.value) { | ||||
|  | @ -727,8 +661,8 @@ void GCode::_do_export(Print &print, FILE *file) | |||
|                     // 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 = true; | ||||
|                     write(file, this->retract()); | ||||
|                     write(file, this->travel_to(Point(0, 0), erNone, "move to origin position for next object")); | ||||
|                     _write(file, this->retract()); | ||||
|                     _write(file, 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 = true; | ||||
|  | @ -740,7 +674,7 @@ void GCode::_do_export(Print &print, FILE *file) | |||
|                     // Set first layer bed and extruder temperatures, don't wait for it to reach the temperature.
 | ||||
|                     this->_print_first_layer_bed_temperature(file, print, between_objects_gcode, initial_extruder_id, false); | ||||
|                     this->_print_first_layer_extruder_temperatures(file, print, between_objects_gcode, initial_extruder_id, false); | ||||
|                     writeln(file, between_objects_gcode); | ||||
|                     _writeln(file, between_objects_gcode); | ||||
|                 } | ||||
|                 // Reset the cooling buffer internal state (the current position, feed rate, accelerations).
 | ||||
|                 m_cooling_buffer->reset(); | ||||
|  | @ -753,8 +687,9 @@ void GCode::_do_export(Print &print, FILE *file) | |||
|                     this->process_layer(file, print, lrs, tool_ordering.tools_for_layer(ltp.print_z()), © - object._shifted_copies.data()); | ||||
|                 } | ||||
|                 if (m_pressure_equalizer) | ||||
|                     write(file, m_pressure_equalizer->process("", true)); | ||||
|                 ++ finished_objects; | ||||
|                   _write(file, m_pressure_equalizer->process("", true)); | ||||
| 
 | ||||
|                 ++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; | ||||
|  | @ -773,7 +708,7 @@ void GCode::_do_export(Print &print, FILE *file) | |||
|         // Prusa Multi-Material wipe tower.
 | ||||
|         if (has_wipe_tower && ! layers_to_print.empty()) { | ||||
|             m_wipe_tower.reset(new WipeTowerIntegration(print.config, *print.m_wipe_tower_priming.get(), print.m_wipe_tower_tool_changes, *print.m_wipe_tower_final_purge.get())); | ||||
| 		    write(file, m_wipe_tower->prime(*this)); | ||||
|         _write(file, m_wipe_tower->prime(*this)); | ||||
|             // Verify, whether the print overaps the priming extrusions.
 | ||||
|             BoundingBoxf bbox_print(get_print_extrusions_extents(print)); | ||||
|             coordf_t twolayers_printz = ((layers_to_print.size() == 1) ? layers_to_print.front() : layers_to_print[1]).first + EPSILON; | ||||
|  | @ -783,16 +718,17 @@ void GCode::_do_export(Print &print, FILE *file) | |||
|             BoundingBoxf bbox_prime(get_wipe_tower_priming_extrusions_extents(print)); | ||||
|             bbox_prime.offset(0.5f); | ||||
|             // Beep for 500ms, tone 800Hz. Yet better, play some Morse.
 | ||||
|             write(file, this->retract()); | ||||
|             write(file, "M300 S800 P500\n"); | ||||
|             _write(file, this->retract()); | ||||
|             _write(file, "M300 S800 P500\n"); | ||||
|             if (bbox_prime.overlap(bbox_print)) { | ||||
|                 // Wait for the user to remove the priming extrusions, otherwise they would
 | ||||
|                 // get covered by the print.
 | ||||
|               write(file, "M1 Remove priming towers and click button.\n"); | ||||
|             } else { | ||||
|               _write(file, "M1 Remove priming towers and click button.\n"); | ||||
|             } | ||||
|             else { | ||||
|                 // Just wait for a bit to let the user check, that the priming succeeded.
 | ||||
|                 //TODO Add a message explaining what the printer is waiting for. This needs a firmware fix.
 | ||||
|               write(file, "M1 S10\n"); | ||||
|               _write(file, "M1 S10\n"); | ||||
|             } | ||||
|         } | ||||
|         // Extrude the layers.
 | ||||
|  | @ -803,26 +739,27 @@ void GCode::_do_export(Print &print, FILE *file) | |||
|             this->process_layer(file, print, layer.second, layer_tools, size_t(-1)); | ||||
|         } | ||||
|         if (m_pressure_equalizer) | ||||
|             write(file, m_pressure_equalizer->process("", true)); | ||||
|           _write(file, m_pressure_equalizer->process("", true)); | ||||
|         if (m_wipe_tower) | ||||
|             // Purge the extruder, pull out the active filament.
 | ||||
|             write(file, m_wipe_tower->finalize(*this)); | ||||
|           _write(file, m_wipe_tower->finalize(*this)); | ||||
|     } | ||||
| 
 | ||||
|     // Write end commands to file.
 | ||||
|     write(file, this->retract()); | ||||
|     write(file, m_writer.set_fan(false)); | ||||
|     _write(file, this->retract()); | ||||
|     _write(file, m_writer.set_fan(false)); | ||||
|     // Process filament-specific gcode in extruder order.
 | ||||
|     if (print.config.single_extruder_multi_material) { | ||||
|         // Process the end_filament_gcode for the active filament only.
 | ||||
|         writeln(file, this->placeholder_parser_process("end_filament_gcode", print.config.end_filament_gcode.get_at(m_writer.extruder()->id()), m_writer.extruder()->id())); | ||||
|     } else { | ||||
|         for (const std::string &end_gcode : print.config.end_filament_gcode.values) | ||||
|             writeln(file, this->placeholder_parser_process("end_gcode", end_gcode, (unsigned int)(&end_gcode - &print.config.end_filament_gcode.values.front()))); | ||||
|       _writeln(file, this->placeholder_parser_process("end_filament_gcode", print.config.end_filament_gcode.get_at(m_writer.extruder()->id()), m_writer.extruder()->id())); | ||||
|     } | ||||
|     writeln(file, this->placeholder_parser_process("end_gcode", print.config.end_gcode, m_writer.extruder()->id())); | ||||
|     write(file, m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100%
 | ||||
|     write(file, m_writer.postamble()); | ||||
|     else { | ||||
|         for (const std::string &end_gcode : print.config.end_filament_gcode.values) | ||||
|           _writeln(file, this->placeholder_parser_process("end_gcode", end_gcode, (unsigned int)(&end_gcode - &print.config.end_filament_gcode.values.front()))); | ||||
|     } | ||||
|     _writeln(file, this->placeholder_parser_process("end_gcode", print.config.end_gcode, m_writer.extruder()->id())); | ||||
|     _write(file, m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100%
 | ||||
|     _write(file, m_writer.postamble()); | ||||
| 
 | ||||
|     // calculates estimated printing time
 | ||||
|     m_time_estimator.calculate_time(); | ||||
|  | @ -833,37 +770,37 @@ void GCode::_do_export(Print &print, FILE *file) | |||
|     print.total_extruded_volume  = 0.; | ||||
|     print.total_weight           = 0.; | ||||
|     print.total_cost             = 0.; | ||||
|     print.estimated_print_time   = (double)m_time_estimator.get_time() / 60.0; | ||||
|     print.estimated_print_time   = m_time_estimator.get_time_hms(); | ||||
|     for (const Extruder &extruder : m_writer.extruders()) { | ||||
|         double used_filament   = extruder.used_filament(); | ||||
|         double extruded_volume = extruder.extruded_volume(); | ||||
|         double filament_weight = extruded_volume * extruder.filament_density() * 0.001; | ||||
|         double filament_cost   = filament_weight * extruder.filament_cost()    * 0.001; | ||||
|         print.filament_stats.insert(std::pair<size_t,float>(extruder.id(), used_filament)); | ||||
|         fprintf(file, "; filament used = %.1lfmm (%.1lfcm3)\n", used_filament, extruded_volume * 0.001); | ||||
|         _write_format(file, "; filament used = %.1lfmm (%.1lfcm3)\n", used_filament, extruded_volume * 0.001); | ||||
|         if (filament_weight > 0.) { | ||||
|             print.total_weight = print.total_weight + filament_weight; | ||||
|             fprintf(file, "; filament used = %.1lf\n", filament_weight); | ||||
|             _write_format(file, "; filament used = %.1lf\n", filament_weight); | ||||
|             if (filament_cost > 0.) { | ||||
|                 print.total_cost = print.total_cost + filament_cost; | ||||
|                 fprintf(file, "; filament cost = %.1lf\n", filament_cost); | ||||
|                 _write_format(file, "; filament cost = %.1lf\n", filament_cost); | ||||
|             } | ||||
|         } | ||||
|         print.total_used_filament   = print.total_used_filament + used_filament; | ||||
|         print.total_used_filament = print.total_used_filament + used_filament; | ||||
|         print.total_extruded_volume = print.total_extruded_volume + extruded_volume; | ||||
|     } | ||||
|     fprintf(file, "; total filament cost = %.1lf\n", print.total_cost); | ||||
|     fprintf(file, "; estimated printing time = %s\n", m_time_estimator.get_time_hms()); | ||||
|     _write_format(file, "; total filament cost = %.1lf\n", print.total_cost); | ||||
|     _write_format(file, "; estimated printing time = %s\n", m_time_estimator.get_time_hms()); | ||||
| 
 | ||||
|     // Append full config.
 | ||||
|     fprintf(file, "\n"); | ||||
|     _write(file, "\n"); | ||||
|     { | ||||
|         StaticPrintConfig *configs[] = { &print.config, &print.default_object_config, &print.default_region_config }; | ||||
|         for (size_t i = 0; i < sizeof(configs) / sizeof(configs[0]); ++ i) { | ||||
|             StaticPrintConfig *cfg = configs[i]; | ||||
|         for (const std::string &key : cfg->keys()) | ||||
|             if (key != "compatible_printers") | ||||
|                 fprintf(file, "; %s = %s\n", key.c_str(), cfg->serialize(key).c_str()); | ||||
|               _write_format(file, "; %s = %s\n", key.c_str(), cfg->serialize(key).c_str()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -954,7 +891,7 @@ void GCode::_print_first_layer_bed_temperature(FILE *file, Print &print, const s | |||
|     // the custom start G-code emited these.
 | ||||
|     std::string set_temp_gcode = m_writer.set_bed_temperature(temp, wait); | ||||
|     if (! temp_set_by_gcode) | ||||
|         write(file, set_temp_gcode); | ||||
|       _write(file, set_temp_gcode); | ||||
| } | ||||
| 
 | ||||
| // Write 1st layer extruder temperatures into the G-code.
 | ||||
|  | @ -977,15 +914,16 @@ void GCode::_print_first_layer_extruder_temperatures(FILE *file, Print &print, c | |||
|             // Set temperature of the first printing extruder only.
 | ||||
|             int temp = print.config.first_layer_temperature.get_at(first_printing_extruder_id); | ||||
|             if (temp > 0) | ||||
|                 write(file, m_writer.set_temperature(temp, wait, first_printing_extruder_id)); | ||||
|         } else { | ||||
|               _write(file, m_writer.set_temperature(temp, wait, first_printing_extruder_id)); | ||||
|         } | ||||
|         else { | ||||
|             // Set temperatures of all the printing extruders.
 | ||||
|             for (unsigned int tool_id : print.extruders()) { | ||||
|                 int temp = print.config.first_layer_temperature.get_at(tool_id); | ||||
|                 if (print.config.ooze_prevention.value) | ||||
|                     temp += print.config.standby_temperature_delta.value; | ||||
|                 if (temp > 0) | ||||
|                     write(file, m_writer.set_temperature(temp, wait, tool_id)); | ||||
|                   _write(file, m_writer.set_temperature(temp, wait, tool_id)); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | @ -1419,7 +1357,7 @@ void GCode::process_layer( | |||
|         gcode = m_pressure_equalizer->process(gcode.c_str(), false); | ||||
|     // printf("G-code after filter:\n%s\n", out.c_str());
 | ||||
| 
 | ||||
|     write(file, gcode); | ||||
|     _write(file, gcode); | ||||
| } | ||||
| 
 | ||||
| void GCode::apply_print_config(const PrintConfig &print_config) | ||||
|  | @ -2054,6 +1992,51 @@ std::string GCode::extrude_support(const ExtrusionEntityCollection &support_fill | |||
|     return gcode; | ||||
| } | ||||
| 
 | ||||
| void GCode::_write(FILE* file, const std::string& what) | ||||
| { | ||||
|   if (!what.empty()) | ||||
|   { | ||||
|     // writes string to file
 | ||||
|     fwrite(what.data(), 1, what.size(), file); | ||||
| 
 | ||||
|     // updates time estimator and gcode lines vector
 | ||||
|     const char endLine = '\n'; | ||||
|     std::string::size_type beginPos = 0; | ||||
|     std::string::size_type endPos = what.find_first_of(endLine, beginPos); | ||||
|     while (endPos != std::string::npos) | ||||
|     { | ||||
|       std::string line = what.substr(beginPos, endPos - beginPos + 1); | ||||
|       m_time_estimator.add_gcode_line(line); | ||||
| 
 | ||||
|       beginPos = endPos + 1; | ||||
|       endPos = what.find_first_of(endLine, beginPos); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void GCode::_writeln(FILE* file, const std::string& what) | ||||
| { | ||||
|   if (!what.empty()) | ||||
|   { | ||||
|     if (what.back() != '\n') | ||||
|       _write_format(file, "%s\n", what.c_str()); | ||||
|     else | ||||
|       _write(file, what); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void GCode::_write_format(FILE* file, const char* format, ...) | ||||
| { | ||||
|   char buffer[1024]; | ||||
|   va_list args; | ||||
|   va_start(args, format); | ||||
|   int res = ::vsnprintf(buffer, 1024, format, args); | ||||
|   va_end(args); | ||||
| 
 | ||||
|   if (res >= 0) | ||||
|     _writeln(file, buffer); | ||||
| } | ||||
| 
 | ||||
| std::string GCode::_extrude(const ExtrusionPath &path, std::string description, double speed) | ||||
| { | ||||
|     std::string gcode; | ||||
|  |  | |||
|  | @ -277,6 +277,17 @@ protected: | |||
|     // Time estimator
 | ||||
|     GCodeTimeEstimator m_time_estimator; | ||||
| 
 | ||||
|     // Write a string into a file.
 | ||||
|     void _write(FILE* file, const std::string& what); | ||||
| 
 | ||||
|     // Write a string into a file. 
 | ||||
|     // Add a newline, if the string does not end with a newline already.
 | ||||
|     // Used to export a custom G-code section processed by the PlaceholderParser.
 | ||||
|     void _writeln(FILE* file, const std::string& what); | ||||
| 
 | ||||
|     // Formats and write into a file the given data. 
 | ||||
|     void _write_format(FILE* file, const char* format, ...); | ||||
| 
 | ||||
|     std::string _extrude(const ExtrusionPath &path, std::string description = "", double speed = -1); | ||||
|     void _print_first_layer_bed_temperature(FILE *file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait); | ||||
|     void _print_first_layer_extruder_temperatures(FILE *file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait); | ||||
|  |  | |||
|  | @ -157,6 +157,16 @@ namespace Slic3r { | |||
|     reset(); | ||||
|   } | ||||
| 
 | ||||
|   void GCodeTimeEstimator::calculate_time_from_lines(const std::vector<std::string>& gcode_lines) | ||||
|   { | ||||
|     for (const std::string& line : gcode_lines) | ||||
|     { | ||||
|       _parser.parse_line(line, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2)); | ||||
|     } | ||||
|     _calculate_time(); | ||||
|     reset(); | ||||
|   } | ||||
| 
 | ||||
|   void GCodeTimeEstimator::add_gcode_line(const std::string& gcode_line) | ||||
|   { | ||||
|     _parser.parse_line(gcode_line, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2)); | ||||
|  | @ -354,8 +364,14 @@ namespace Slic3r { | |||
|     int minutes = (int)(timeinsecs / 60.0f); | ||||
|     timeinsecs -= (float)minutes * 60.0f; | ||||
| 
 | ||||
|     char buffer[16]; | ||||
|     ::sprintf(buffer, "%02d:%02d:%02d", hours, minutes, (int)timeinsecs); | ||||
|     char buffer[64]; | ||||
|     if (hours > 0) | ||||
|       ::sprintf(buffer, "%dh %dm %ds", hours, minutes, (int)timeinsecs); | ||||
|     else if (minutes > 0) | ||||
|       ::sprintf(buffer, "%dm %ds", minutes, (int)timeinsecs); | ||||
|     else | ||||
|       ::sprintf(buffer, "%ds", (int)timeinsecs); | ||||
| 
 | ||||
|     return buffer; | ||||
|   } | ||||
| 
 | ||||
|  | @ -393,7 +409,7 @@ namespace Slic3r { | |||
|   { | ||||
|     if (line.cmd.length() > 1) | ||||
|     { | ||||
|       switch (line.cmd[0]) | ||||
|       switch (::toupper(line.cmd[0])) | ||||
|       { | ||||
|       case 'G': | ||||
|         { | ||||
|  |  | |||
|  | @ -184,6 +184,9 @@ namespace Slic3r { | |||
|     // Calculates the time estimate from the gcode contained in the file with the given filename
 | ||||
|     void calculate_time_from_file(const std::string& file); | ||||
| 
 | ||||
|     // Calculates the time estimate from the gcode contained in given list of gcode lines
 | ||||
|     void calculate_time_from_lines(const std::vector<std::string>& gcode_lines); | ||||
| 
 | ||||
|     // Adds the given gcode line
 | ||||
|     void add_gcode_line(const std::string& gcode_line); | ||||
| 
 | ||||
|  | @ -252,7 +255,7 @@ namespace Slic3r { | |||
|     // Calculates the time estimate
 | ||||
|     void _calculate_time(); | ||||
| 
 | ||||
|     // Processes GCode line
 | ||||
|     // Processes the given gcode line
 | ||||
|     void _process_gcode_line(GCodeReader&, const GCodeReader::GCodeLine& line); | ||||
| 
 | ||||
|     // Move
 | ||||
|  |  | |||
|  | @ -233,14 +233,15 @@ public: | |||
|     PrintRegionPtrs regions; | ||||
|     PlaceholderParser placeholder_parser; | ||||
|     // TODO: status_cb
 | ||||
|     double                          total_used_filament, total_extruded_volume, total_cost, total_weight, estimated_print_time; | ||||
|     std::string estimated_print_time; | ||||
|     double                          total_used_filament, total_extruded_volume, total_cost, total_weight; | ||||
|     std::map<size_t, float>          filament_stats; | ||||
|     PrintState<PrintStep, psCount>  state; | ||||
| 
 | ||||
|     // ordered collections of extrusion paths to build skirt loops and brim
 | ||||
|     ExtrusionEntityCollection skirt, brim; | ||||
| 
 | ||||
|     Print() : total_used_filament(0), total_extruded_volume(0), estimated_print_time(0) { restart(); } | ||||
|     Print() : total_used_filament(0), total_extruded_volume(0) { restart(); } | ||||
|     ~Print() { clear_objects(); } | ||||
|      | ||||
|     // methods for handling objects
 | ||||
|  |  | |||
|  | @ -153,6 +153,8 @@ _constant() | |||
|         %code%{ RETVAL = &THIS->skirt; %}; | ||||
|     Ref<ExtrusionEntityCollection> brim() | ||||
|         %code%{ RETVAL = &THIS->brim; %}; | ||||
|     std::string estimated_print_time() | ||||
|         %code%{ RETVAL = THIS->estimated_print_time; %}; | ||||
| 
 | ||||
|     PrintObjectPtrs* objects() | ||||
|         %code%{ RETVAL = &THIS->objects; %}; | ||||
|  | @ -281,17 +283,6 @@ Print::total_cost(...) | |||
|         } | ||||
|         RETVAL = THIS->total_cost; | ||||
|     OUTPUT: | ||||
|         RETVAL | ||||
| 
 | ||||
| double | ||||
| Print::estimated_print_time(...) | ||||
|     CODE: | ||||
|         if (items > 1) { | ||||
|             THIS->estimated_print_time = (double)SvNV(ST(1)); | ||||
|         } | ||||
|         RETVAL = THIS->estimated_print_time; | ||||
|     OUTPUT: | ||||
|         RETVAL | ||||
|          | ||||
|         RETVAL         | ||||
| %} | ||||
| }; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Enrico Turri
						Enrico Turri