From 04958af691abfebc8314b300b4d8676f074439a7 Mon Sep 17 00:00:00 2001 From: FormerLurker Date: Sun, 17 May 2020 17:36:56 -0500 Subject: Rewrite arc generation routine, add custom float to string function. --- ArcWelder/ArcWelder.vcxproj | 150 ++++++++++++++++++++++++++++++++++++++++++ ArcWelder/arc_welder.cpp | 14 ++-- ArcWelder/segmented_arc.cpp | 149 +++++++++++++++++++---------------------- ArcWelder/segmented_arc.h | 8 +-- ArcWelder/segmented_shape.cpp | 10 +-- ArcWelder/segmented_shape.h | 3 +- 6 files changed, 233 insertions(+), 101 deletions(-) (limited to 'ArcWelder') diff --git a/ArcWelder/ArcWelder.vcxproj b/ArcWelder/ArcWelder.vcxproj index a9afaa8..adaddf8 100644 --- a/ArcWelder/ArcWelder.vcxproj +++ b/ArcWelder/ArcWelder.vcxproj @@ -1,10 +1,18 @@ + + Debug + ARM + Debug Win32 + + Release + ARM + Release Win32 @@ -17,6 +25,18 @@ Release x64 + + Remote_Pi + ARM + + + Remote_Pi + Win32 + + + Remote_Pi + x64 + 16.0 @@ -31,6 +51,24 @@ v142 Unicode + + StaticLibrary + true + v142 + Unicode + + + StaticLibrary + true + v142 + Unicode + + + StaticLibrary + true + v142 + Unicode + StaticLibrary false @@ -38,12 +76,25 @@ true Unicode + + StaticLibrary + false + v142 + true + Unicode + StaticLibrary true v142 Unicode + + StaticLibrary + true + v142 + Unicode + StaticLibrary false @@ -59,12 +110,27 @@ + + + + + + + + + + + + + + + @@ -73,14 +139,34 @@ true $(SolutionDir)\GcodeProcessorLib\;$(VC_IncludePath);$(WindowsSDK_IncludePath); + + true + $(SolutionDir)\GcodeProcessorLib\;$(VC_IncludePath);$(WindowsSDK_IncludePath); + + + true + $(SolutionDir)\GcodeProcessorLib\;$(VC_IncludePath);$(WindowsSDK_IncludePath); + + + true + $(SolutionDir)\GcodeProcessorLib\;$(VC_IncludePath);$(WindowsSDK_IncludePath); + true $(SolutionDir)\GcodeProcessorLib\;$(VC_IncludePath);$(WindowsSDK_IncludePath); + + true + $(SolutionDir)\GcodeProcessorLib\;$(VC_IncludePath);$(WindowsSDK_IncludePath); + false $(SolutionDir)\GcodeProcessorLib\;$(VC_IncludePath);$(WindowsSDK_IncludePath); + + false + $(SolutionDir)\GcodeProcessorLib\;$(VC_IncludePath);$(WindowsSDK_IncludePath); + false $(SolutionDir)\GcodeProcessorLib\;$(VC_IncludePath);$(WindowsSDK_IncludePath); @@ -97,6 +183,42 @@ true + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + Level3 @@ -109,6 +231,18 @@ true + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + Level3 @@ -125,6 +259,22 @@ true + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + Level3 diff --git a/ArcWelder/arc_welder.cpp b/ArcWelder/arc_welder.cpp index 81cc467..2d3eac5 100644 --- a/ArcWelder/arc_welder.cpp +++ b/ArcWelder/arc_welder.cpp @@ -24,7 +24,6 @@ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include "arc_welder.h" -#include #include #include #include "utilities.h" @@ -160,20 +159,27 @@ double arc_welder::get_time_elapsed(double start_clock, double end_clock) arc_welder_results arc_welder::process() { - arc_welder_results results; +arc_welder_results results; p_logger_->log(logger_type_, DEBUG, "Configuring logging settings."); verbose_logging_enabled_ = p_logger_->is_log_level_enabled(logger_type_, VERBOSE); debug_logging_enabled_ = p_logger_->is_log_level_enabled(logger_type_, DEBUG); info_logging_enabled_ = p_logger_->is_log_level_enabled(logger_type_, INFO); error_logging_enabled_ = p_logger_->is_log_level_enabled(logger_type_, ERROR); + std::stringstream stream; + stream << std::fixed << std::setprecision(5); + stream << "py_gcode_arc_converter.ConvertFile - Parameters received: source_file_path: '" << + source_path_ << "', target_file_path:'" << target_path_ << "', resolution_mm:" << + resolution_mm_ << "mm (+-" << current_arc_.get_resolution_mm() << "mm), max_radius_mm:" << current_arc_.get_max_radius() + << "mm, g90_91_influences_extruder: " << (p_source_position_->get_g90_91_influences_extruder() ? "True" : "False") << "\n"; + p_logger_->log(logger_type_, INFO, stream.str()); + + // reset tracking variables reset(); // local variable to hold the progress update return. If it's false, we will exit. bool continue_processing = true; - // Create a stringstream we can use for messaging. - std::stringstream stream; p_logger_->log(logger_type_, DEBUG, "Configuring progress updates."); int read_lines_before_clock_check = 5000; double next_update_time = get_next_update_time(); diff --git a/ArcWelder/segmented_arc.cpp b/ArcWelder/segmented_arc.cpp index 28145fd..220e740 100644 --- a/ArcWelder/segmented_arc.cpp +++ b/ArcWelder/segmented_arc.cpp @@ -28,7 +28,6 @@ #include "segmented_shape.h" #include #include -#include #include #include @@ -38,8 +37,6 @@ segmented_arc::segmented_arc() : segmented_arc(DEFAULT_MIN_SEGMENTS, DEFAULT_MAX segmented_arc::segmented_arc(int min_segments, int max_segments, double resolution_mm, double max_radius_mm) : segmented_shape(min_segments, max_segments, resolution_mm) { - gcode_buffer_[0] = '\0'; - if (max_radius_mm > DEFAULT_MAX_RADIUS_MM) max_radius_mm_ = DEFAULT_MAX_RADIUS_MM; else max_radius_mm_ = max_radius_mm; } @@ -66,15 +63,18 @@ point segmented_arc::pop_back(double e_relative) set_is_shape(false); } } - -bool segmented_arc::is_shape() +double segmented_arc::get_max_radius() const +{ + return max_radius_mm_; +} +bool segmented_arc::is_shape() const { +/* if (is_shape_) { arc a; - bool is_arc = try_get_arc(a); - return is_arc; - } + return arc::try_create_arc(arc_circle_, points_, original_shape_length_, resolution_mm_, a);; + } */ return is_shape_; } @@ -108,18 +108,26 @@ bool segmented_arc::try_add_point(point p, double e_relative) //std::cout << " failed - no distance change.\n"; return false; } - /*else if (utilities::greater_than(distance, max_segment_length_)) - { - // we can't make an arc if the distance between points - // is greater than the resolution. - return false; - }*/ // Test - see what happens without a max segment length. + } + if (points_.count() < get_min_segments() - 1) { point_added = true; points_.push_back(p); original_shape_length_ += distance; + if (points_.count() == get_min_segments()) + { + arc a; + if (!arc::try_create_arc(arc_circle_, points_, original_shape_length_, resolution_mm_, a)) + { + point_added = false; + points_.pop_back(); + original_shape_length_ -= distance; + } + } + + } else { @@ -200,7 +208,7 @@ bool segmented_arc::try_add_point_internal_(point p, double pd) } -bool segmented_arc::does_circle_fit_points_(const circle& c) +bool segmented_arc::does_circle_fit_points_(circle& c) const { // We know point 1 must fit (we used it to create the circle). Check the other points // Note: We have not added the current point, but that's fine since it is guaranteed to fit too. @@ -215,7 +223,7 @@ bool segmented_arc::does_circle_fit_points_(const circle& c) // Make sure the length from the center of our circle to the test point is // at or below our max distance. distance_from_center = utilities::get_cartesian_distance(points_[index].x, points_[index].y, c.center.x, c.center.y); - double difference_from_radius = abs(distance_from_center - c.radius); + double difference_from_radius = std::abs(distance_from_center - c.radius); if (utilities::greater_than(difference_from_radius, resolution_mm_)) { //std::cout << " failed - end points do not lie on circle.\n"; @@ -230,7 +238,7 @@ bool segmented_arc::does_circle_fit_points_(const circle& c) if (segment::get_closest_perpendicular_point(points_[index], points_[index + 1], c.center, point_to_test)) { distance_from_center = utilities::get_cartesian_distance(point_to_test.x, point_to_test.y, c.center.x, c.center.y); - difference_from_radius = abs(distance_from_center - c.radius); + difference_from_radius = std::abs(distance_from_center - c.radius); // Test allowing more play for the midpoints. if (utilities::greater_than(difference_from_radius, resolution_mm_)) { @@ -242,11 +250,11 @@ bool segmented_arc::does_circle_fit_points_(const circle& c) // get the current arc and compare the total length to the original length arc a; - return try_get_arc_(c, a); + return arc::try_create_arc(c, points_, original_shape_length_, resolution_mm_, a); } -bool segmented_arc::try_get_arc(arc & target_arc) +bool segmented_arc::try_get_arc(arc & target_arc) { //int mid_point_index = ((points_.count() - 2) / 2) + 1; //return arc::try_create_arc(arc_circle_, points_[0], points_[mid_point_index], points_[points_.count() - 1], original_shape_length_, resolution_mm_, target_arc); @@ -271,82 +279,57 @@ std::string segmented_arc::get_shape_gcode_relative(double f) return get_shape_gcode_(has_e, e_relative_, f); } -std::string segmented_arc::get_shape_gcode_(bool has_e, double e, double f) +std::string segmented_arc::get_shape_gcode_(bool has_e, double e, double f) const { + + char buf[20]; + std::string gcode; arc c; - try_get_arc(c); - + arc::try_create_arc(arc_circle_, points_, original_shape_length_, resolution_mm_, c); + double i = c.center.x - c.start_point.x; double j = c.center.y - c.start_point.y; // Here is where the performance part kicks in (these are expensive calls) that makes things a bit ugly. // there are a few cases we need to take into consideration before choosing our sprintf string + // create the XYZ portion + if (utilities::less_than(c.angle_radians, 0)) { - // G2 - if (has_e != 0) - { - // Add E param - if (utilities::greater_than_or_equal(f, 1)) - { - // Add F param - snprintf(gcode_buffer_, GCODE_CHAR_BUFFER_SIZE, "G2 X%.3f Y%.3f I%.3f J%.3f E%.5f F%.0f", c.end_point.x, c.end_point.y, i, j, e, f); - } - else - { - // No F param - snprintf(gcode_buffer_, GCODE_CHAR_BUFFER_SIZE, "G2 X%.3f Y%.3f I%.3f J%.3f E%.5f", c.end_point.x, c.end_point.y, i, j, e); - } - } - else - { - // No E param - // Add E param - if (utilities::greater_than_or_equal(f, 1)) - { - // Add F param - snprintf(gcode_buffer_, GCODE_CHAR_BUFFER_SIZE, "G2 X%.3f Y%.3f I%.3f J%.3f F%.0f", c.end_point.x, c.end_point.y, i, j, f); - } - else - { - // No F param - snprintf(gcode_buffer_, GCODE_CHAR_BUFFER_SIZE, "G2 X%.3f Y%.3f I%.3f J%.3f", c.end_point.x, c.end_point.y, i, j); - } - } + gcode = "G2"; } else { - // G3 - if (has_e != 0) - { - // Add E param - if (utilities::greater_than_or_equal(f, 1)) - { - // Add F param - snprintf(gcode_buffer_, GCODE_CHAR_BUFFER_SIZE, "G3 X%.3f Y%.3f I%.3f J%.3f E%.5f F%.0f", c.end_point.x, c.end_point.y, i, j, e, f); - } - else - { - // No F param - snprintf(gcode_buffer_, GCODE_CHAR_BUFFER_SIZE, "G3 X%.3f Y%.3f I%.3f J%.3f E%.5f", c.end_point.x, c.end_point.y, i, j, e); - } - } - else - { - // No E param - // Add E param - if (utilities::greater_than_or_equal(f, 1)) - { - // Add F param - snprintf(gcode_buffer_, GCODE_CHAR_BUFFER_SIZE, "G3 X%.3f Y%.3f I%.3f J%.3f F%.0f", c.end_point.x, c.end_point.y, i, j, f); - } - else - { - // No F param - snprintf(gcode_buffer_, GCODE_CHAR_BUFFER_SIZE, "G3 X%.3f Y%.3f I%.3f J%.3f", c.end_point.x, c.end_point.y, i, j); - } - } + gcode = "G3"; + + } + // Add X, Y, I and J + gcode += " X"; + gcode += utilities::to_string(c.end_point.x, 3, buf); + + gcode += " Y"; + gcode += utilities::to_string(c.end_point.y, 3, buf); + + gcode += " I"; + gcode += utilities::to_string(i, 3, buf); + + gcode += " J"; + gcode += utilities::to_string(j, 3, buf); + + // Add E if it appears + if (has_e) + { + gcode += " E"; + gcode += utilities::to_string(e, 5, buf); } - return std::string(gcode_buffer_); + + // Add F if it appears + if (utilities::greater_than_or_equal(f, 1)) + { + gcode += " F"; + gcode += utilities::to_string(f, 0, buf); + } + + return gcode; } diff --git a/ArcWelder/segmented_arc.h b/ArcWelder/segmented_arc.h index 4a19b5c..9a412ad 100644 --- a/ArcWelder/segmented_arc.h +++ b/ArcWelder/segmented_arc.h @@ -41,18 +41,18 @@ public: std::string get_shape_gcode_absolute(double e, double f); std::string get_shape_gcode_relative(double f); - virtual bool is_shape(); + virtual bool is_shape() const; point pop_front(double e_relative); point pop_back(double e_relative); bool try_get_arc(arc & target_arc); + double get_max_radius() const; // static gcode buffer private: - char gcode_buffer_[GCODE_CHAR_BUFFER_SIZE + 1]; bool try_add_point_internal_(point p, double pd); - bool does_circle_fit_points_(const circle& c); + bool does_circle_fit_points_(circle& c) const; bool try_get_arc_(const circle& c, arc& target_arc); - std::string get_shape_gcode_(bool has_e, double e, double f); + std::string get_shape_gcode_(bool has_e, double e, double f) const; circle arc_circle_; int test_count_ = 0; double max_radius_mm_; diff --git a/ArcWelder/segmented_shape.cpp b/ArcWelder/segmented_shape.cpp index 9cf0830..312a7dc 100644 --- a/ArcWelder/segmented_shape.cpp +++ b/ArcWelder/segmented_shape.cpp @@ -175,12 +175,6 @@ bool circle::try_create_circle(point p1, point p2, point p3, double max_radius, if (utilities::is_zero(a, CIRCLE_GENERATION_A_ZERO_TOLERANCE)) { -#if _DEBUG - if (!utilities::is_zero(a, 0.000001)) - { - std::cout << "This is an interesting point. Colinear"; - } -#endif return false; } @@ -381,9 +375,9 @@ void segmented_shape::clear() e_relative_ = 0; original_shape_length_ = 0; } -bool segmented_shape::is_shape() +bool segmented_shape::is_shape() const { - // return the pre-calculated value. This should be updated by the plugin; + // return the pre-calculated value. This should be updated by the plugin return is_shape_; } void segmented_shape::set_is_shape(bool value) diff --git a/ArcWelder/segmented_shape.h b/ArcWelder/segmented_shape.h index 53a30ee..9ca480b 100644 --- a/ArcWelder/segmented_shape.h +++ b/ArcWelder/segmented_shape.h @@ -163,7 +163,6 @@ struct arc : circle double polar_end_theta; point start_point; point end_point; - bool is_point_in_arc_slice(const point& p); static bool try_create_arc(const circle& c, const point& start_point, const point& mid_point, const point& end_point, double approximate_length, double resolution, arc& target_arc); static bool try_create_arc(const circle& c, const array_list& points, double approximate_length, double resolution, arc& target_arc); }; @@ -186,7 +185,7 @@ public: double get_shape_length(); double get_shape_e_relative(); void set_resolution_mm(double resolution_mm); - virtual bool is_shape(); + virtual bool is_shape() const; // public virtual functions virtual void clear(); virtual point pop_front(); -- cgit v1.2.3