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>2020-10-17 02:34:25 +0300
committerFormerLurker <hochgebe@gmail.com>2020-10-17 02:34:25 +0300
commit4fd38897fd66c245991a4066c7bb3db373087e70 (patch)
tree30a91cd0ded86278929869ec265c939fc839e18a /ArcWelder/arc_welder.h
parent04958af691abfebc8314b300b4d8676f074439a7 (diff)
Add additional statistics. Fix windows c++ build for python 2.7 compilers.
Diffstat (limited to 'ArcWelder/arc_welder.h')
-rw-r--r--ArcWelder/arc_welder.h298
1 files changed, 288 insertions, 10 deletions
diff --git a/ArcWelder/arc_welder.h b/ArcWelder/arc_welder.h
index 3e501af..d21c2c8 100644
--- a/ArcWelder/arc_welder.h
+++ b/ArcWelder/arc_welder.h
@@ -36,11 +36,284 @@
#include "array_list.h"
#include "unwritten_command.h"
#include "logger.h"
+#include <cmath>
+
+#ifdef _MSC_VER
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
#define DEFAULT_G90_G91_INFLUENCES_EXTREUDER false
+static const int segment_statistic_lengths_count = 12;
+const double segment_statistic_lengths[] = { 0.002f, 0.005f, 0.01f, 0.05f, 0.1f, 0.5f, 1.0f, 5.0f, 10.0f, 20.0f, 50.0f, 100.0f };
+
+struct segment_statistic {
+ segment_statistic(double min_length_mm, double max_length_mm)
+ {
+ count = 0;
+ min_mm = min_length_mm;
+ max_mm = max_length_mm;
+ }
+
+ double min_mm;
+ double max_mm;
+ int count;
+};
+
+struct source_target_segment_statistics {
+
+
+ source_target_segment_statistics(const double segment_tracking_lengths[], const int num_lengths, logger* p_logger = NULL) {
+ total_length_source = 0;
+ total_length_target = 0;
+ total_count_source = 0;
+ total_count_target = 0;
+ max_width = 0;
+ max_precision = 3;
+ num_segment_tracking_lengths = num_lengths;
+ double current_min = 0;
+ for (int index = 0; index < num_lengths; index++)
+ {
+ double current_max = segment_tracking_lengths[index];
+ source_segments.push_back(segment_statistic(current_min, segment_tracking_lengths[index]));
+ target_segments.push_back(segment_statistic(current_min, segment_tracking_lengths[index]));
+ current_min = current_max;
+ }
+ source_segments.push_back(segment_statistic(current_min, -1.0f));
+ target_segments.push_back(segment_statistic(current_min, -1.0f));
+ max_width = utilities::get_num_digits(current_min);
+ p_logger_ = p_logger_;
+ logger_type_ = 0;
+ }
+
+ std::vector<segment_statistic> source_segments;
+ std::vector<segment_statistic> target_segments;
+ double total_length_source;
+ double total_length_target;
+ int max_width;
+ int max_precision;
+ int total_count_source;
+ int total_count_target;
+ int num_segment_tracking_lengths;
+
+ void update(double length, bool is_source)
+ {
+ if (length <= 0)
+ return;
+
+ std::vector<segment_statistic>* stats;
+ if (is_source)
+ {
+ total_count_source++;
+ total_length_source += length;
+ stats = &source_segments;
+ }
+ else
+ {
+ total_count_target++;
+ total_length_target += length;
+ stats = &target_segments;
+ }
+ for (int index = 0; index < (*stats).size(); index++)
+ {
+ segment_statistic& stat = (*stats)[index];
+ if (stat.min_mm <= length && stat.max_mm > length || (index + 1) == (*stats).size())
+ {
+ stat.count++;
+ break;
+ }
+ }
+ }
+
+ std::string str() const {
+
+ //if (p_logger_ != NULL) p_logger_->log(logger_type_, VERBOSE, "Building Segment Statistics.");
+
+ std::stringstream output_stream;
+ std::stringstream format_stream;
+ const int min_column_size = 8;
+ int mm_col_size = max_width + max_precision + 2; // Adding 2 for the mm
+ int min_max_label_col_size = 4;
+ int percent_col_size = 9;
+ int totals_row_label_size = 22;
+ int count_col_size;
+
+ // Calculate the count column size
+ int max_count = 0;
+ //if (p_logger_ != NULL) p_logger_->log(logger_type_, VERBOSE, "Calculating Column Size.");
+
+ for (int index = 0; index < source_segments.size(); index++)
+ {
+ int source_count = source_segments[index].count;
+ int target_count = target_segments[index].count;
+ if (max_count < source_count)
+ {
+ max_count = source_count;
+ }
+ if (max_count < target_count)
+ {
+ max_count = target_count;
+ }
+ }
+ // Get the number of digits in the max count
+ count_col_size = utilities::get_num_digits(max_count);
+ // enforce the minimum of 6
+ if (count_col_size < min_column_size)
+ {
+ count_col_size = min_column_size;
+ }
+
+ if (max_precision > 0)
+ {
+ // We need an extra space in our column for the decimal.
+ mm_col_size++;
+ }
+
+ // enforce the min column size
+ if (mm_col_size < min_column_size)
+ {
+ mm_col_size = min_column_size;
+ }
+ // Get the table width
+ int table_width = mm_col_size + min_max_label_col_size + mm_col_size + count_col_size + count_col_size + percent_col_size;
+ // Add a separator for the statistics
+ //output_stream << std::setw(table_width) << std::setfill('-') << "-" << "\n" << std::setfill(' ') ;
+ // Output the column headers
+ // Center the min and max column.
+ output_stream << utilities::center("Min", mm_col_size);
+ output_stream << std::setw(min_max_label_col_size) << "";
+ output_stream << utilities::center("Max", mm_col_size);
+ // right align the source, target and change columns
+ output_stream << std::setw(count_col_size) << std::right << "Source";
+ output_stream << std::setw(count_col_size) << std::right << "Target";
+ output_stream << std::setw(percent_col_size) << std::right << "Change";
+ output_stream << "\n";
+ output_stream << std::setw(table_width) << std::setfill('-') << "" << std::setfill(' ') << "\n";
+ output_stream << std::fixed << std::setprecision(max_precision);
+ for (int index = 0; index < source_segments.size(); index++) {
+ //extract the necessary variables from the source and target segments
+ double min_mm = source_segments[index].min_mm;
+ double max_mm = source_segments[index].max_mm;
+ int source_count = source_segments[index].count;
+ int target_count = target_segments[index].count;
+ // Calculate the percent change and create the string
+ // Construct the percent_change_string
+ std::string percent_change_string = utilities::get_percent_change_string(source_count, target_count, 1);
+
+ // Create the strings to hold the column values
+ std::string min_mm_string;
+ std::string max_mm_string;
+ std::string source_count_string;
+ std::string target_count_string;
+
+ // Clear the format stream and construct the min_mm_string
+ format_stream.str(std::string());
+ format_stream << std::fixed << std::setprecision(max_precision) << min_mm << "mm";
+ min_mm_string = format_stream.str();
+ // Clear the format stream and construct the max_mm_string
+ format_stream.str(std::string());
+ format_stream << std::fixed << std::setprecision(max_precision) << max_mm << "mm";
+ max_mm_string = format_stream.str();
+ // Clear the format stream and construct the source_count_string
+ format_stream.str(std::string());
+ format_stream << std::fixed << std::setprecision(0) << source_count;
+ source_count_string = format_stream.str();
+ // Clear the format stream and construct the target_count_string
+ format_stream.str(std::string());
+ format_stream << std::fixed << std::setprecision(0) << target_count;
+ target_count_string = format_stream.str();
+ // The min and max columns and the label need to be handled differently if this is the last item
+ if (index == source_segments.size() - 1)
+ {
+ // If we are on the last setment item, the 'min' value is the max, and there is no end
+ // The is because the last item contains the count of all items above the max length provided
+ // in the constructor
+
+ // The 'min' column is empty here
+ output_stream << std::setw(mm_col_size) << std::internal << "";
+ // Add the min/max label
+ output_stream << std::setw(min_max_label_col_size) << " >= ";
+ // Add the min mm string
+ output_stream << std::setw(mm_col_size) << std::internal << min_mm_string;
+ }
+ else
+ {
+ //if (p_logger_ != NULL) p_logger_->log(logger_type_, VERBOSE, "Adding row text.");
+
+ // add the 'min' column
+ output_stream << std::setw(mm_col_size) << std::internal << min_mm_string;
+ // Add the min/max label
+ output_stream << std::setw(min_max_label_col_size) << " to ";
+ // Add the 'max' column
+ output_stream << std::setw(mm_col_size) << std::internal << max_mm_string;
+ }
+ // Add the source count
+ output_stream << std::setw(count_col_size) << source_count_string;
+ // Add the target count
+ output_stream << std::setw(count_col_size) << target_count_string;
+ // Add the percent change string
+ output_stream << std::setw(percent_col_size) << percent_change_string;
+ // End the line
+ output_stream << "\n";
+ }
+ // Add the total rows separator
+ output_stream << std::setw(table_width) << std::setfill('-') << "" << std::setfill(' ') << "\n";
+ // Add the total rows;
+ if (utilities::is_equal(total_length_source, total_length_target, 0.001))
+ {
+ std::string total_distance_string;
+ format_stream.str(std::string());
+ format_stream << std::fixed << std::setprecision(max_precision) << total_length_source << "mm";
+ total_distance_string = format_stream.str();
+ output_stream << std::setw(totals_row_label_size) << std::right << "Total distance:";
+ output_stream << std::setw(table_width - totals_row_label_size) << std::setfill('.') << std::right << total_distance_string << "\n" << std::setfill(' ');
+ }
+ else
+ {
+ // We need to output two different distances (this probably should never happen)
+ // Format the total source distance string
+ std::string total_source_distance_string;
+ format_stream.str(std::string());
+ format_stream << std::fixed << std::setprecision(max_precision) << total_length_source << "mm";
+ total_source_distance_string = format_stream.str();
+ // Add the total source distance row
+ output_stream << std::setw(totals_row_label_size) << std::right << "Total distance source:";
+ output_stream << std::setw(table_width - totals_row_label_size) << std::setfill('.') << std::right << total_source_distance_string << "\n" << std::setfill(' ');
+
+ // Format the total target distance string
+ std::string total_target_distance_string;
+ format_stream.str(std::string());
+ format_stream << std::fixed << std::setprecision(max_precision) << total_length_target << "mm";
+ total_target_distance_string = format_stream.str();
+ // Add the total target distance row
+ output_stream << std::setw(totals_row_label_size) << std::right << "Total distance target:";
+ output_stream << std::setw(table_width - totals_row_label_size) << std::setfill('.') << std::right << total_target_distance_string << "\n" << std::setfill(' ');
+ }
+
+ // Add the total count rows
+ // Add the source count
+ output_stream << std::setprecision(0) << std::setw(totals_row_label_size) << std::right << "Total count source:";
+ output_stream << std::setw(table_width - totals_row_label_size) << std::setfill('.') << std::right << total_count_source << "\n" << std::setfill(' ');
+ // Add the target count
+ output_stream << std::setw(totals_row_label_size) << std::right << "Total count target:";
+ output_stream << std::setw(table_width - totals_row_label_size) << std::setfill('.') << std::right << total_count_target << "\n" << std::setfill(' ');
+ // Add the total percent change row
+ std::string total_percent_change_string = utilities::get_percent_change_string(total_count_source, total_count_target, 1);
+ output_stream << std::setw(totals_row_label_size) << std::right << "Total percent change:";
+ output_stream << std::setw(table_width - totals_row_label_size) << std::setfill('.') << std::right << total_percent_change_string << "\n" << std::setfill(' ');
+ std::string output_string = output_stream.str();
+ return output_string;
+ }
+
+private:
+ logger* p_logger_;
+ int logger_type_;
+};
+
+// Struct to hold the progress, statistics, and return values
struct arc_welder_progress {
- arc_welder_progress() {
+ arc_welder_progress() : segment_statistics(segment_statistic_lengths, segment_statistic_lengths_count, NULL) {
percent_complete = 0.0;
seconds_elapsed = 0.0;
seconds_remaining = 0.0;
@@ -53,6 +326,7 @@ struct arc_welder_progress {
target_file_size = 0;
compression_ratio = 0;
compression_percent = 0;
+
}
double percent_complete;
double seconds_elapsed;
@@ -66,11 +340,12 @@ struct arc_welder_progress {
long source_file_position;
long source_file_size;
long target_file_size;
+ source_target_segment_statistics segment_statistics;
std::string str() const {
std::stringstream stream;
stream << std::fixed << std::setprecision(2);
-
+
stream << percent_complete << "% complete in " << seconds_elapsed << " seconds with " << seconds_remaining << " seconds remaining.";
stream << " Gcodes Processed: " << gcodes_processed;
stream << ", Current Line: " << lines_processed;
@@ -80,8 +355,12 @@ struct arc_welder_progress {
stream << ", Size Reduction: " << compression_percent << "% ";
return stream.str();
}
+ std::string detail_str() const {
+ std::stringstream stream;
+ stream << "\n" << "Extrusion/Retraction Counts" << "\n" << segment_statistics.str() << "\n";
+ return stream.str();
+ }
};
-
// define the progress callback type
typedef bool(*progress_callback)(arc_welder_progress);
@@ -101,9 +380,7 @@ struct arc_welder_results {
class arc_welder
{
public:
- arc_welder(std::string source_path, std::string target_path, logger * log, double resolution_mm, double max_radius_mm, gcode_position_args args);
- arc_welder(std::string source_path, std::string target_path, logger * log, double resolution_mm, double max_radius_mm, bool g90_g91_influences_extruder, int buffer_size);
- arc_welder(std::string source_path, std::string target_path, logger * log, double resolution_mm, double max_radius_mm, bool g90_g91_influences_extruder, int buffer_size, progress_callback callback);
+ arc_welder(std::string source_path, std::string target_path, logger* log, double resolution_mm, double max_radius, bool g90_g91_influences_extruder, int buffer_size, progress_callback callback = NULL);
void set_logger_type(int logger_type);
virtual ~arc_welder();
arc_welder_results process();
@@ -111,12 +388,12 @@ public:
protected:
virtual bool on_progress_(const arc_welder_progress& progress);
private:
- arc_welder_progress get_progress_(long source_file_position, double start_clock);
+ arc_welder_progress get_progress_(long source_file_position, double start_clock);
void add_arcwelder_comment_to_target();
void reset();
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);
+ int process_gcode(parsed_command cmd, bool is_end, bool is_reprocess);
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);
@@ -134,6 +411,7 @@ private:
int last_gcode_line_written_;
int points_compressed_;
int arcs_created_;
+ source_target_segment_statistics segment_statistics_;
long get_file_size(const std::string& file_path);
double get_time_elapsed(double start_clock, double end_clock);
double get_next_update_time() const;
@@ -141,9 +419,9 @@ private:
array_list<unwritten_command> unwritten_commands_;
segmented_arc current_arc_;
std::ofstream output_file_;
-
+
// We don't care about the printer settings, except for g91 influences extruder.
- gcode_position * p_source_position_;
+ gcode_position* p_source_position_;
double previous_feedrate_;
bool previous_is_extruder_relative_;
gcode_parser parser_;