diff options
author | FormerLurker <hochgebe@gmail.com> | 2021-01-18 01:12:46 +0300 |
---|---|---|
committer | FormerLurker <hochgebe@gmail.com> | 2021-01-18 01:12:46 +0300 |
commit | ad9a648077a750a256744aee3d7718eea9d07dcb (patch) | |
tree | 33daa0ff558d7fdbcc5c253a5508842b26c4ce4f | |
parent | 1b1dd123064761d07c2182edf75ffab325f217a2 (diff) |
Separate code to write arc gcode.
-rw-r--r-- | ArcWelder/arc_welder.cpp | 121 | ||||
-rw-r--r-- | ArcWelder/arc_welder.h | 1 | ||||
-rw-r--r-- | ArcWelder/segmented_shape.cpp | 96 | ||||
-rw-r--r-- | ArcWelder/segmented_shape.h | 2 | ||||
-rw-r--r-- | ArcWelderTest/ArcWelderTest.cpp | 2 | ||||
-rw-r--r-- | GcodeProcessorLib/parsed_command_parameter.cpp | 1 |
6 files changed, 75 insertions, 148 deletions
diff --git a/ArcWelder/arc_welder.cpp b/ArcWelder/arc_welder.cpp index ecfcf38..74f98ce 100644 --- a/ArcWelder/arc_welder.cpp +++ b/ArcWelder/arc_welder.cpp @@ -237,6 +237,7 @@ arc_welder_results results; p_logger_->log(logger_type_, DEBUG, "Source file opened successfully."); p_logger_->log(logger_type_, DEBUG, "Opening the target file for writing."); + output_file_.open(target_path_.c_str(), std::ifstream::out); if (!output_file_.is_open()) { @@ -246,6 +247,7 @@ arc_welder_results results; gcodeFile.close(); return results; } + p_logger_->log(logger_type_, DEBUG, "Target file opened successfully."); std::string line; int lines_with_no_commands = 0; @@ -601,69 +603,9 @@ int arc_welder::process_gcode(parsed_command cmd, bool is_end, bool is_reprocess // update our statistics points_compressed_ += current_arc_.get_num_segments()-1; arcs_created_++; // increment the number of generated arcs - - //std::cout << "Arc shape found.\n"; - // Get the comment now, before we remove the previous comments - std::string comment = get_comment_for_arc(); - // remove the same number of unwritten gcodes as there are arc segments, minus 1 for the start point - // Which isn't a movement - // note, skip the first point, it is the starting point - for (int index = 0; index < current_arc_.get_num_segments() - 1; index++) - { - unwritten_commands_.pop_back(); - } - // get the feedrate for the previous position (the last command that was turned into an arc) - double current_f = p_pre_pos->f; - - // Undo the current command, since it isn't included in the arc - p_source_position_->undo_update(); - // IMPORTANT NOTE: p_cur_pos and p_pre_pos will NOT be usable beyond this point. + write_arc_gcodes(p_pre_pos->is_extruder_relative, p_pre_pos->f); + p_cur_pos = NULL; p_pre_pos = NULL; - p_cur_pos = p_source_position_->get_current_position_ptr(); - extruder_current = p_cur_pos->get_current_extruder(); - - // Set the current feedrate if it is different, else set to 0 to indicate that no feedrate should be included - if(previous_feedrate_ > 0 && previous_feedrate_ == current_f){ - current_f = 0; - } - - // Craete the arc gcode - std::string gcode; - if (previous_is_extruder_relative_){ - gcode = get_arc_gcode_relative(current_f, comment); - } - - else { - gcode = get_arc_gcode_absolute(extruder_current.get_offset_e(), current_f, comment); - } - - - if (debug_logging_enabled_) - { - char buffer[20]; - std::string message = "Arc created with "; - sprintf(buffer, "%d", current_arc_.get_num_segments()); - message += buffer; - message += " segments: "; - message += gcode; - p_logger_->log(logger_type_, DEBUG, message); - } - - // Get and alter the current position so we can add it to the unwritten commands list - parsed_command arc_command = parser_.parse_gcode(gcode.c_str()); - double arc_extrusion_length = current_arc_.get_shape_length(); - - unwritten_commands_.push_back( - unwritten_command(arc_command, p_cur_pos->is_extruder_relative, arc_extrusion_length) - ); - - // write all unwritten commands (if we don't do this we'll mess up absolute e by adding an offset to the arc) - // including the most recent arc command BEFORE updating the absolute e offset - write_unwritten_gcodes_to_file(); - - // Now clear the arc and flag the processor as not waiting for an arc - waiting_for_arc_ = false; - current_arc_.clear(); // Reprocess this line @@ -711,6 +653,61 @@ int arc_welder::process_gcode(parsed_command cmd, bool is_end, bool is_reprocess return lines_written; } +void arc_welder::write_arc_gcodes(bool is_extruder_relative, double current_feedrate) +{ + + std::string comment = get_comment_for_arc(); + // remove the same number of unwritten gcodes as there are arc segments, minus 1 for the start point + // Which isn't a movement + // note, skip the first point, it is the starting point + for (int index = 0; index < current_arc_.get_num_segments() - 1; index++) + { + unwritten_commands_.pop_back(); + } + + // Undo the current command, since it isn't included in the arc + p_source_position_->undo_update(); + + // Set the current feedrate if it is different, else set to 0 to indicate that no feedrate should be included + if (previous_feedrate_ > 0 && previous_feedrate_ == current_feedrate) { + current_feedrate = 0; + } + + // Craete the arc gcode + std::string gcode; + if (previous_is_extruder_relative_) { + gcode = get_arc_gcode_relative(current_feedrate, comment); + } + + else { + gcode = get_arc_gcode_absolute(p_source_position_->get_current_position_ptr()->get_current_extruder().get_offset_e(), current_feedrate, comment); + } + + + if (debug_logging_enabled_) + { + char buffer[20]; + std::string message = "Arc created with "; + sprintf(buffer, "%d", current_arc_.get_num_segments()); + message += buffer; + message += " segments: "; + message += gcode; + p_logger_->log(logger_type_, DEBUG, message); + } + + // Write everything that hasn't yet been written + write_unwritten_gcodes_to_file(); + + // Update the current extrusion statistics for the current arc gcode + segment_statistics_.update(current_arc_.get_shape_length() , false); + // now write the current arc to the file + write_gcode_to_file(gcode); + + // Now clear the arc and flag the processor as not waiting for an arc + waiting_for_arc_ = false; + current_arc_.clear(); +} + std::string arc_welder::get_comment_for_arc() { // build a comment string from the commands making up the arc diff --git a/ArcWelder/arc_welder.h b/ArcWelder/arc_welder.h index 4e86426..66b6428 100644 --- a/ArcWelder/arc_welder.h +++ b/ArcWelder/arc_welder.h @@ -447,6 +447,7 @@ private: static gcode_position_args get_args_(bool g90_g91_influences_extruder, int buffer_size); progress_callback progress_callback_; int process_gcode(parsed_command cmd, bool is_end, bool is_reprocess); + void write_arc_gcodes(bool is_extruder_relative, double current_feedrate); int write_gcode_to_file(std::string gcode); std::string get_arc_gcode_relative(double f, const std::string comment); std::string get_arc_gcode_absolute(double e, double f, const std::string comment); diff --git a/ArcWelder/segmented_shape.cpp b/ArcWelder/segmented_shape.cpp index dc07470..0ec050b 100644 --- a/ArcWelder/segmented_shape.cpp +++ b/ArcWelder/segmented_shape.cpp @@ -196,70 +196,19 @@ bool circle::try_create_circle(const point& p1, const point& p2, const point& p3 return true; } -/* -bool circle::try_create_circle(const array_list<printer_point>& points, const double max_radius, const double resolution_mm, const double xyz_tolerance, bool allow_3d_arcs, bool check_middle_only, circle& new_circle) -{ - int middle_index = points.count() / 2; - int check_index; - int step = 0; - bool is_right = true; - while (true) { - - check_index = middle_index + (is_right ? step : -1 * step); - // Check the index - if (circle::try_create_circle(points[0], points[check_index], points[points.count() - 1], max_radius, new_circle)) - { - if (!new_circle.is_over_deviation(points, resolution_mm, xyz_tolerance, allow_3d_arcs)) - { - return true; - } - } - if (is_right) - { - if (check_index == points.count() - 1) - { - return false; - } - if (check_index == middle_index) - { - if (check_middle_only) - { - return false; - } - step++; - continue; - } - } - else - { - if (check_index == 0) - { - return false; - } - step++; - } - is_right = !is_right; - } - return false; -} -*/ -bool circle::try_create_circle(const array_list<printer_point>& points, const double max_radius, const double resolution_mm, const double xyz_tolerance, bool allow_3d_arcs, bool check_middle_only, circle& new_circle) + +bool circle::try_create_circle(const array_list<printer_point>& points, const double max_radius, const double resolution_mm, const double xyz_tolerance, bool allow_3d_arcs, circle& new_circle) { int count = points.count(); - + int middle_index = count / 2; + // The middle point will almost always produce the best arcs. if (circle::try_create_circle(points[0], points[middle_index], points[count - 1], max_radius, new_circle) && !new_circle.is_over_deviation(points, resolution_mm, xyz_tolerance, allow_3d_arcs)) { return true; } - - if (check_middle_only || count == 3) - { - // If we are only checking the middle, or if we only have 3 points return - return false; - } - + // Find the circle with the least deviation, if one exists. // Note, this could possibly take a LONG time in the worst case, but it's a pretty unlikely. // However, if the midpoint check doesn't pass, it's worth it to spend a bit more time @@ -535,30 +484,7 @@ bool arc::try_create_arc( return true; } -/* -bool arc::try_create_arc( - const array_list<printer_point>& points, - arc& target_arc, - double approximate_length, - double max_radius_mm, - double resolution_mm, - double path_tolerance_percent, - int min_arc_segments, - double mm_per_arc_segment, - double xyz_tolerance, - bool allow_3d_arcs) -{ - circle test_circle; - if (circle::try_create_circle(points, max_radius_mm, resolution_mm, xyz_tolerance, allow_3d_arcs, false, test_circle)) - { - // We could save a bit of processing power and do our firmware compensation here, but we won't be able to track statistics for this easily. - // moved check to segmented_arc.cpp - int mid_point_index = ((points.count() - 2) / 2) + 1; - return arc::try_create_arc(test_circle, points[0], points[mid_point_index], points[points.count() - 1], target_arc, approximate_length, resolution_mm, path_tolerance_percent, allow_3d_arcs); - } - return false; -} -*/ + bool arc::try_create_arc( const array_list<printer_point>& points, arc& target_arc, @@ -571,12 +497,14 @@ bool arc::try_create_arc( double xyz_tolerance, bool allow_3d_arcs) { - circle test_circle; - if (!circle::try_create_circle(points, max_radius_mm, resolution_mm, xyz_tolerance, allow_3d_arcs, false, test_circle)) + circle test_circle = (circle)target_arc; + + + if (!circle::try_create_circle(points, max_radius_mm, resolution_mm, xyz_tolerance, allow_3d_arcs, test_circle)) { return false; } - + // We could save a bit of processing power and do our firmware compensation here, but we won't be able to track statistics for this easily. // moved check to segmented_arc.cpp int mid_point_index = ((points.count() - 2) / 2) + 1; @@ -617,7 +545,7 @@ bool arc::are_points_within_slice(const arc& test_arc, const array_list<printer_ } // Need to see if point 1 to point 2 cross zero - for (int index = 1; index < point_count; index++) + for (int index = point_count - 2; index < point_count; index++) { double polar_test; if (index < point_count - 1) diff --git a/ArcWelder/segmented_shape.h b/ArcWelder/segmented_shape.h index 6489707..0b617ea 100644 --- a/ArcWelder/segmented_shape.h +++ b/ArcWelder/segmented_shape.h @@ -118,7 +118,7 @@ struct circle { static bool try_create_circle(const point &p1, const point &p2, const point &p3, const double max_radius, circle& new_circle); - static bool try_create_circle(const array_list<printer_point>& points, const double max_radius, const double resolutino_mm, const double xyz_tolerance, bool allow_3d_arcs, bool check_middle_only, circle& new_circle); + static bool try_create_circle(const array_list<printer_point>& points, const double max_radius, const double resolutino_mm, const double xyz_tolerance, bool allow_3d_arcs, circle& new_circle); double get_polar_radians(const point& p1) const; diff --git a/ArcWelderTest/ArcWelderTest.cpp b/ArcWelderTest/ArcWelderTest.cpp index c5426ab..dee0fed 100644 --- a/ArcWelderTest/ArcWelderTest.cpp +++ b/ArcWelderTest/ArcWelderTest.cpp @@ -292,7 +292,7 @@ static void TestAntiStutter(std::string filePath) //arc_welder arc_welder_obj(BENCHY_0_5_MM_NO_WIPE, "C:\\Users\\Brad\\Documents\\3DPrinter\\AntiStutter\\test_output.gcode", p_logger, max_resolution, false, 50, static_cast<progress_callback>(on_progress)); //arc_welder arc_welder_obj(SIX_SPEED_TEST, "C:\\Users\\Brad\\Documents\\3DPrinter\\AntiStutter\\test_output.gcode", p_logger, max_resolution, false, 50, on_progress); arc_welder arc_welder_obj( - WIPER_TEST, + BARBARIAN, "C:\\Users\\Brad\\Documents\\3DPrinter\\AntiStutter\\test_output.gcode", p_logger, max_resolution, diff --git a/GcodeProcessorLib/parsed_command_parameter.cpp b/GcodeProcessorLib/parsed_command_parameter.cpp index 29bf599..6d4fde5 100644 --- a/GcodeProcessorLib/parsed_command_parameter.cpp +++ b/GcodeProcessorLib/parsed_command_parameter.cpp @@ -30,6 +30,7 @@ parsed_command_parameter::parsed_command_parameter() unsigned_long_value = 0; double_value = 0; double_precision = 0; + string_value; string_value = ""; } |