Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FormerLurker/ArcWelderLib.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFormerLurker <hochgebe@gmail.com>2021-01-18 01:12:46 +0300
committerFormerLurker <hochgebe@gmail.com>2021-01-18 01:12:46 +0300
commitad9a648077a750a256744aee3d7718eea9d07dcb (patch)
tree33daa0ff558d7fdbcc5c253a5508842b26c4ce4f /ArcWelder
parent1b1dd123064761d07c2182edf75ffab325f217a2 (diff)
Separate code to write arc gcode.
Diffstat (limited to 'ArcWelder')
-rw-r--r--ArcWelder/arc_welder.cpp121
-rw-r--r--ArcWelder/arc_welder.h1
-rw-r--r--ArcWelder/segmented_shape.cpp96
-rw-r--r--ArcWelder/segmented_shape.h2
4 files changed, 73 insertions, 147 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;