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-12-13 00:49:33 +0300
committerFormerLurker <hochgebe@gmail.com>2020-12-13 00:49:33 +0300
commit893b8eea5e182457e90db9ddbaac8a7fb435a0c7 (patch)
tree421dd5296fcdf57f807c86a2a78ceb5143201fbe
parent8cbd08c6c27bb792d28345d24ffc7a7765c35079 (diff)
Prevent arc generation if I and J are both 0 within the current precision. Add default xyz and e precision settings, and enable/disable dynamic gcode precision.
-rw-r--r--ArcWelder/arc_welder.cpp15
-rw-r--r--ArcWelder/arc_welder.h7
-rw-r--r--ArcWelder/segmented_arc.cpp58
-rw-r--r--ArcWelder/segmented_arc.h4
-rw-r--r--ArcWelder/segmented_shape.cpp50
-rw-r--r--ArcWelder/segmented_shape.h27
-rw-r--r--ArcWelderConsole/ArcWelderConsole.cpp68
-rw-r--r--ArcWelderTest/ArcWelderTest.cpp9
-rw-r--r--ArcWelderTest/ArcWelderTest.h2
-rw-r--r--PyArcWelder/py_arc_welder.h6
-rw-r--r--PyArcWelder/py_arc_welder_extension.cpp76
-rw-r--r--PyArcWelder/py_arc_welder_extension.h11
12 files changed, 280 insertions, 53 deletions
diff --git a/ArcWelder/arc_welder.cpp b/ArcWelder/arc_welder.cpp
index 9fe02d0..d7b6120 100644
--- a/ArcWelder/arc_welder.cpp
+++ b/ArcWelder/arc_welder.cpp
@@ -46,6 +46,9 @@ arc_welder::arc_welder(
double mm_per_arc_segment,
bool g90_g91_influences_extruder,
bool allow_3d_arcs,
+ bool allow_dynamic_precision,
+ unsigned char default_xyz_precision,
+ unsigned char default_e_precision,
int buffer_size,
progress_callback callback) : current_arc_(
DEFAULT_MIN_SEGMENTS,
@@ -55,7 +58,9 @@ arc_welder::arc_welder(
max_radius,
min_arc_segments,
mm_per_arc_segment,
- allow_3d_arcs
+ allow_3d_arcs,
+ default_xyz_precision,
+ default_e_precision
),
segment_statistics_(
segment_statistic_lengths,
@@ -77,6 +82,7 @@ arc_welder::arc_welder(
target_path_ = target_path;
gcode_position_args_ = get_args_(g90_g91_influences_extruder, buffer_size);
allow_3d_arcs_ = allow_3d_arcs;
+ allow_dynamic_precision_ = allow_dynamic_precision;
notification_period_seconds = 1;
lines_processed_ = 0;
gcodes_processed_ = 0;
@@ -195,7 +201,10 @@ arc_welder_results results;
<< ", min_arc_segments:" << std::setprecision(0) <<current_arc_.get_min_arc_segments()
<< ", mm_per_arc_segment:" << std::setprecision(0) << current_arc_.get_mm_per_arc_segment()
<< ", g90_91_influences_extruder: " << (p_source_position_->get_g90_91_influences_extruder() ? "True" : "False")
- << ", allow_3d_arcs: " << (allow_3d_arcs_ ? "True" : "False");
+ << ", allow_3d_arcs: " << (allow_3d_arcs_ ? "True" : "False")
+ << ", allow_dynamic_precision: " << (allow_dynamic_precision_ ? "True" : "False")
+ << ", default_xyz_precision: " << std::setprecision(0) << (current_arc_.get_xyz_precision())
+ << ", default_e_precision: " << std::setprecision(0) << (current_arc_.get_e_precision());
p_logger_->log(logger_type_, INFO, stream.str());
@@ -407,7 +416,7 @@ int arc_welder::process_gcode(parsed_command cmd, bool is_end, bool is_reprocess
// We need to make sure the printer is using absolute xyz, is extruding, and the extruder axis mode is the same as that of the previous position
// TODO: Handle relative XYZ axis. This is possible, but maybe not so important.
bool is_g1_g2 = cmd.command == "G0" || cmd.command == "G1";
- if (is_g1_g2)
+ if (allow_dynamic_precision_ && is_g1_g2)
{
for (std::vector<parsed_command_parameter>::iterator it = cmd.parameters.begin(); it != cmd.parameters.end(); ++it)
{
diff --git a/ArcWelder/arc_welder.h b/ArcWelder/arc_welder.h
index 0e6bb81..9e6d74a 100644
--- a/ArcWelder/arc_welder.h
+++ b/ArcWelder/arc_welder.h
@@ -412,6 +412,7 @@ struct arc_welder_results {
};
#define DEFAULT_GCODE_BUFFER_SIZE 1000
#define DEFAULT_G90_G91_INFLUENCES_EXTRUDER false
+#define DEFAULT_ALLOW_DYNAMIC_PRECISION false
class arc_welder
{
public:
@@ -425,7 +426,10 @@ public:
int min_arc_segments,
double mm_per_arc_segment,
bool g90_g91_influences_extruder = DEFAULT_G90_G91_INFLUENCES_EXTRUDER,
- bool allow_3d_arcs = DEFAULT_allow_3d_arcs,
+ bool allow_3d_arcs = DEFAULT_ALLOW_3D_ARCS,
+ bool allow_dynamic_precision = DEFAULT_ALLOW_DYNAMIC_PRECISION,
+ unsigned char default_xyz_precision = DEFAULT_XYZ_PRECISION,
+ unsigned char default_e_precision = DEFAULT_E_PRECISION,
int buffer_size = DEFAULT_GCODE_BUFFER_SIZE,
progress_callback callback = NULL);
void set_logger_type(int logger_type);
@@ -451,6 +455,7 @@ private:
std::string target_path_;
double resolution_mm_;
gcode_position_args gcode_position_args_;
+ bool allow_dynamic_precision_;
bool allow_3d_arcs_;
long file_size_;
int lines_processed_;
diff --git a/ArcWelder/segmented_arc.cpp b/ArcWelder/segmented_arc.cpp
index c92809f..0618917 100644
--- a/ArcWelder/segmented_arc.cpp
+++ b/ArcWelder/segmented_arc.cpp
@@ -35,7 +35,8 @@ segmented_arc::segmented_arc() : segmented_shape(DEFAULT_MIN_SEGMENTS, DEFAULT_M
{
max_radius_mm_ = DEFAULT_MAX_RADIUS_MM;
min_arc_segments_ = DEFAULT_MIN_ARC_SEGMENTS,
- allow_3d_arcs_ = DEFAULT_allow_3d_arcs;
+ mm_per_arc_segment_ = DEFAULT_MM_PER_ARC_SEGMENT;
+ allow_3d_arcs_ = DEFAULT_ALLOW_3D_ARCS;
num_firmware_compensations_ = 0;
}
@@ -47,8 +48,10 @@ segmented_arc::segmented_arc(
double max_radius_mm,
int min_arc_segments,
double mm_per_arc_segment,
- bool allow_3d_arcs
-) : segmented_shape(min_segments, max_segments, resolution_mm, path_tolerance_percent)
+ bool allow_3d_arcs,
+ unsigned char default_xyz_precision,
+ unsigned char default_e_precision
+) : segmented_shape(min_segments, max_segments, resolution_mm, path_tolerance_percent, default_xyz_precision, default_e_precision)
{
max_radius_mm_ = max_radius_mm;
if (max_radius_mm > DEFAULT_MAX_RADIUS_MM) {
@@ -210,10 +213,10 @@ bool segmented_arc::try_add_point_internal_(point p, double pd)
double previous_shape_length = original_shape_length_;
original_shape_length_ += pd;
arc original_arc = current_arc_;
- if (arc::try_create_arc(points_, current_arc_, original_shape_length_, max_radius_mm_, resolution_mm_, path_tolerance_percent_, min_arc_segments_, mm_per_arc_segment_, xyz_precision_, allow_3d_arcs_))
+ if (arc::try_create_arc(points_, current_arc_, original_shape_length_, max_radius_mm_, resolution_mm_, path_tolerance_percent_, min_arc_segments_, mm_per_arc_segment_, get_xyz_precision(), allow_3d_arcs_))
{
// See how many arcs will be interpolated
- bool firmware_corrected = false;
+ bool abort_arc = false;
if (min_arc_segments_ > 0 && mm_per_arc_segment_ > 0)
{
double circumference = 2.0 * PI_DOUBLE * current_arc_.radius;
@@ -222,14 +225,24 @@ bool segmented_arc::try_add_point_internal_(point p, double pd)
//num_segments = (int)std::ceil(circumference/approximate_length) * (int)std::ceil(approximate_length / mm_per_arc_segment);
num_segments = (int)std::floor(circumference / original_shape_length_);
if (num_segments < min_arc_segments_) {
- firmware_corrected = true;
- current_arc_ = original_arc;
+ abort_arc = true;
num_firmware_compensations_++;
}
}
}
+ // check for I=0 and J=0
+ if (!abort_arc && utilities::is_zero(current_arc_.get_i(), get_xyz_tolerance()) && utilities::is_zero(current_arc_.get_j(), get_xyz_tolerance()))
+ {
+ abort_arc = true;
+ }
- if (!firmware_corrected)
+ if (abort_arc)
+ {
+ // This arc has been cancelled either due to firmware correction,
+ // or because both I and J == 0
+ current_arc_ = original_arc;
+ }
+ else if (!abort_arc)
{
if (!is_shape())
{
@@ -262,8 +275,8 @@ std::string segmented_arc::get_shape_gcode_(bool has_e, double e, double f) cons
std::string gcode;
- double i = current_arc_.center.x - current_arc_.start_point.x;
- double j = current_arc_.center.y - current_arc_.start_point.y;
+ double i = current_arc_.get_i();
+ double j = current_arc_.get_j();
// 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
@@ -279,35 +292,40 @@ std::string segmented_arc::get_shape_gcode_(bool has_e, double e, double f) cons
}
// Add X, Y, I and J
gcode += " X";
- gcode += utilities::to_string(current_arc_.end_point.x, xyz_precision_, buf, false);
+ gcode += utilities::to_string(current_arc_.end_point.x, get_xyz_precision(), buf, false);
gcode += " Y";
- gcode += utilities::to_string(current_arc_.end_point.y, xyz_precision_, buf, false);
+ gcode += utilities::to_string(current_arc_.end_point.y, get_xyz_precision(), buf, false);
if (allow_3d_arcs_)
{
// We may need to add a z coordinate
double z_initial = current_arc_.start_point.z;
double z_final = current_arc_.end_point.z;
- if (!utilities::is_equal(z_initial, z_final, std::pow(10.0, -1.0 * xyz_precision_)))
+ if (!utilities::is_equal(z_initial, z_final, get_xyz_tolerance()))
{
// The z axis has changed within the precision of the gcode coordinates
gcode += " Z";
- gcode += utilities::to_string(current_arc_.end_point.z, xyz_precision_, buf, false);
+ gcode += utilities::to_string(current_arc_.end_point.z, get_xyz_precision(), buf, false);
}
}
- gcode += " I";
- gcode += utilities::to_string(i, xyz_precision_, buf, false);
-
- gcode += " J";
- gcode += utilities::to_string(j, xyz_precision_, buf, false);
+ if (!utilities::is_zero(i, get_xyz_tolerance()))
+ {
+ gcode += " I";
+ gcode += utilities::to_string(i, get_xyz_precision(), buf, false);
+ }
+ if (!utilities::is_zero(j, get_xyz_tolerance()))
+ {
+ gcode += " J";
+ gcode += utilities::to_string(j, get_xyz_precision(), buf, false);
+ }
// Add E if it appears
if (has_e)
{
gcode += " E";
- gcode += utilities::to_string(e, e_precision_, buf, false);
+ gcode += utilities::to_string(e, get_e_precision(), buf, false);
}
// Add F if it appears
diff --git a/ArcWelder/segmented_arc.h b/ArcWelder/segmented_arc.h
index a51cbbd..36d20da 100644
--- a/ArcWelder/segmented_arc.h
+++ b/ArcWelder/segmented_arc.h
@@ -43,7 +43,9 @@ public:
double max_radius_mm = DEFAULT_MAX_RADIUS_MM,
int min_arc_segments = DEFAULT_MIN_ARC_SEGMENTS,
double mm_per_arc_segment = DEFAULT_MM_PER_ARC_SEGMENT,
- bool allow_3d_arcs = DEFAULT_allow_3d_arcs
+ bool allow_3d_arcs = DEFAULT_ALLOW_3D_ARCS,
+ unsigned char default_xyz_precision = DEFAULT_XYZ_PRECISION,
+ unsigned char default_e_precision = DEFAULT_E_PRECISION
);
virtual ~segmented_arc();
virtual bool try_add_point(point p, double e_relative);
diff --git a/ArcWelder/segmented_shape.cpp b/ArcWelder/segmented_shape.cpp
index 65995b4..f505d59 100644
--- a/ArcWelder/segmented_shape.cpp
+++ b/ArcWelder/segmented_shape.cpp
@@ -323,6 +323,16 @@ bool circle::is_over_deviation(const array_list<point>& points, const double res
#pragma region Arc Functions
+double arc::get_i() const
+{
+ return center.x - start_point.x;
+}
+
+double arc::get_j() const
+{
+ return center.y - start_point.y;
+}
+
bool arc::try_create_arc(
const circle& c,
const point& start_point,
@@ -477,11 +487,11 @@ bool arc::try_create_arc(
#pragma endregion
-segmented_shape::segmented_shape(int min_segments, int max_segments, double resolution_mm, double path_tolerance_percnet) : points_(max_segments)
+segmented_shape::segmented_shape(int min_segments, int max_segments, double resolution_mm, double path_tolerance_percnet, unsigned char default_xyz_precision, unsigned char default_e_precision) : points_(max_segments)
{
- xyz_precision_ = DEFAULT_XYZ_PRECISION;
- e_precision_ = DEFAULT_E_PRECISION;
+ set_xyz_precision(default_xyz_precision);
+ e_precision_ = default_e_precision;
max_segments_ = max_segments;
path_tolerance_percent_ = path_tolerance_percnet;
resolution_mm_ = resolution_mm / 2.0; // divide by 2 because it is + or - 1/2 of the desired resolution.
@@ -500,21 +510,47 @@ segmented_shape::~segmented_shape()
}
+unsigned char segmented_shape::get_xyz_precision() const
+{
+ return xyz_precision_;
+}
+
+double segmented_shape::get_xyz_tolerance() const
+{
+ return xyz_tolerance_;
+}
+
+unsigned char segmented_shape::get_e_precision() const
+{
+ return e_precision_;
+}
+
+void segmented_shape::set_xyz_precision(unsigned char precision)
+{
+ xyz_precision_ = precision;
+ set_xyz_tolerance_from_precision();
+}
+
+void segmented_shape::set_xyz_tolerance_from_precision()
+{
+ xyz_tolerance_ = std::pow(10.0, -1.0 * static_cast<double>(xyz_precision_));
+}
+
void segmented_shape::reset_precision()
{
- xyz_precision_ = DEFAULT_XYZ_PRECISION;
+ set_xyz_precision(DEFAULT_XYZ_PRECISION);
e_precision_ = DEFAULT_E_PRECISION;
}
-void segmented_shape::update_xyz_precision(int precision)
+void segmented_shape::update_xyz_precision(unsigned char precision)
{
if (xyz_precision_ < precision)
{
- xyz_precision_ = precision;
+ set_xyz_precision(precision);
}
}
-void segmented_shape::update_e_precision(int precision)
+void segmented_shape::update_e_precision(unsigned char precision)
{
if (e_precision_ < precision)
{
diff --git a/ArcWelder/segmented_shape.h b/ArcWelder/segmented_shape.h
index eda6a7c..3b8e807 100644
--- a/ArcWelder/segmented_shape.h
+++ b/ArcWelder/segmented_shape.h
@@ -121,7 +121,7 @@ struct circle {
};
#define DEFAULT_RESOLUTION_MM 0.05
-#define DEFAULT_allow_3d_arcs false
+#define DEFAULT_ALLOW_3D_ARCS false
#define DEFAULT_MIN_ARC_SEGMENTS 0
#define DEFAULT_MM_PER_ARC_SEGMENT 0
struct arc : circle
@@ -153,6 +153,9 @@ struct arc : circle
double max_deviation;
point start_point;
point end_point;
+
+ double get_i() const;
+ double get_j() const;
// Statis functions
static bool try_create_arc(
const circle& c,
@@ -163,7 +166,7 @@ struct arc : circle
double approximate_length,
double resolution = DEFAULT_RESOLUTION_MM,
double path_tolerance_percent = ARC_LENGTH_PERCENT_TOLERANCE_DEFAULT,
- bool allow_3d_arcs = DEFAULT_allow_3d_arcs);
+ bool allow_3d_arcs = DEFAULT_ALLOW_3D_ARCS);
static bool try_create_arc(
const array_list<point>& points,
@@ -175,7 +178,7 @@ struct arc : circle
int min_arc_segments = DEFAULT_MIN_ARC_SEGMENTS,
double mm_per_arc_segment = DEFAULT_MM_PER_ARC_SEGMENT,
int xyz_precision = DEFAULT_XYZ_PRECISION,
- bool allow_3d_arcs = DEFAULT_allow_3d_arcs);
+ bool allow_3d_arcs = DEFAULT_ALLOW_3D_ARCS);
};
double distance_from_segment(segment s, point p);
@@ -189,7 +192,9 @@ public:
segmented_shape(int min_segments = DEFAULT_MIN_SEGMENTS,
int max_segments = DEFAULT_MAX_SEGMENTS,
double resolution_mm = DEFAULT_RESOLUTION_MM,
- double path_tolerance_percent = ARC_LENGTH_PERCENT_TOLERANCE_DEFAULT
+ double path_tolerance_percent = ARC_LENGTH_PERCENT_TOLERANCE_DEFAULT,
+ unsigned char default_xyz_precision = DEFAULT_XYZ_PRECISION,
+ unsigned char default_e_precision = DEFAULT_E_PRECISION
);
segmented_shape& operator=(const segmented_shape& pos);
virtual ~segmented_shape();
@@ -202,8 +207,8 @@ public:
double get_shape_e_relative();
void set_resolution_mm(double resolution_mm);
void reset_precision();
- void update_xyz_precision(int precision);
- void update_e_precision(int precision);
+ void update_xyz_precision(unsigned char precision);
+ void update_e_precision(unsigned char precision);
virtual bool is_shape() const;
// public virtual functions
virtual void clear();
@@ -213,11 +218,12 @@ public:
virtual std::string get_shape_gcode_absolute(double e_abs_start);
virtual std::string get_shape_gcode_relative();
bool is_extruding();
+ unsigned char get_xyz_precision() const;
+ unsigned char get_e_precision() const;
+ double get_xyz_tolerance() const;
protected:
array_list<point> points_;
void set_is_shape(bool value);
- unsigned char xyz_precision_;
- unsigned char e_precision_;
double original_shape_length_;
double e_relative_;
bool is_extruding_;
@@ -227,5 +233,10 @@ protected:
private:
int min_segments_;
int max_segments_;
+ unsigned char xyz_precision_;
+ double xyz_tolerance_;
+ unsigned char e_precision_;
+ void set_xyz_tolerance_from_precision();
+ void set_xyz_precision(unsigned char precision);
};
diff --git a/ArcWelderConsole/ArcWelderConsole.cpp b/ArcWelderConsole/ArcWelderConsole.cpp
index bf7c63f..b301237 100644
--- a/ArcWelderConsole/ArcWelderConsole.cpp
+++ b/ArcWelderConsole/ArcWelderConsole.cpp
@@ -47,6 +47,9 @@ int main(int argc, char* argv[])
bool hide_progress;
bool overwrite_source_file = false;
bool allow_3d_arcs = false;
+ bool allow_dynamic_precision = DEFAULT_ALLOW_DYNAMIC_PRECISION;
+ unsigned char default_xyz_precision = DEFAULT_XYZ_PRECISION;
+ unsigned char default_e_precision = DEFAULT_E_PRECISION;
std::string log_level_string;
std::string log_level_string_default = "INFO";
int log_level_value;
@@ -114,8 +117,26 @@ int main(int argc, char* argv[])
// -z --allow-3d-arcs
arg_description_stream.clear();
arg_description_stream.str("");
- arg_description_stream << "(experimental) - If supplied, 3D arcs will be allowed (supports spiral vase mode). Not all firmware supports this. Default Value: " << DEFAULT_allow_3d_arcs;
- TCLAP::SwitchArg allow_3d_arcs_arg("z", "allow-3d-arcs", arg_description_stream.str(), DEFAULT_allow_3d_arcs);
+ arg_description_stream << "(experimental) - If supplied, 3D arcs will be allowed (supports spiral vase mode). Not all firmware supports this. Default Value: " << DEFAULT_ALLOW_3D_ARCS;
+ TCLAP::SwitchArg allow_3d_arcs_arg("z", "allow-3d-arcs", arg_description_stream.str(), DEFAULT_ALLOW_3D_ARCS);
+
+ // -d --allow-dynamic-precision
+ arg_description_stream.clear();
+ arg_description_stream.str("");
+ arg_description_stream << "If supplied, arcwelder will adjust the precision of the outputted gcode based on the precision of the input gcode. Default Value: " << DEFAULT_ALLOW_DYNAMIC_PRECISION;
+ TCLAP::SwitchArg allow_dynamic_precision_arg("d", "allow-dynamic-precision", arg_description_stream.str(), DEFAULT_ALLOW_DYNAMIC_PRECISION);
+
+ // -x --default-xyz-precision
+ arg_description_stream.clear();
+ arg_description_stream.str("");
+ arg_description_stream << "The default precision of X, Y, Z, I and J output gcode parameters. The precision may be larger than this value if allow-dynamic-precision is set to true. Default Value: " << DEFAULT_XYZ_PRECISION;
+ TCLAP::ValueArg<unsigned char> default_xyz_precision_arg("x", "default-xyz-precision", arg_description_stream.str(), false, DEFAULT_XYZ_PRECISION, "unsigned char");
+
+ // -e --default-e-precision
+ arg_description_stream.clear();
+ arg_description_stream.str("");
+ arg_description_stream << "The default precision of E output gcode parameters. The precision may be larger than this value if allow-dynamic-precision is set to true. Default Value: " << DEFAULT_E_PRECISION;
+ TCLAP::ValueArg<unsigned char> default_e_precision_arg("e", "default-e-precision", arg_description_stream.str(), false, DEFAULT_E_PRECISION, "unsigned char");
// -g --hide-progress
TCLAP::SwitchArg hide_progress_arg("p", "hide-progress", "If supplied, prevents progress updates from being displayed.", false);
@@ -145,6 +166,9 @@ int main(int argc, char* argv[])
cmd.add(min_arc_segments_arg);
cmd.add(mm_per_arc_segment_arg);
cmd.add(allow_3d_arcs_arg);
+ cmd.add(allow_dynamic_precision_arg);
+ cmd.add(default_xyz_precision_arg);
+ cmd.add(default_e_precision_arg);
cmd.add(g90_arg);
cmd.add(hide_progress_arg);
cmd.add(log_level_arg);
@@ -168,6 +192,9 @@ int main(int argc, char* argv[])
path_tolerance_percent = path_tolerance_percent_arg.getValue();
allow_3d_arcs = allow_3d_arcs_arg.getValue();
g90_g91_influences_extruder = g90_arg.getValue();
+ allow_dynamic_precision = allow_dynamic_precision_arg.getValue();
+ default_xyz_precision = default_xyz_precision_arg.getValue();
+ default_e_precision = default_e_precision_arg.getValue();
hide_progress = hide_progress_arg.getValue();
log_level_string = log_level_arg.getValue();
@@ -218,6 +245,34 @@ int main(int argc, char* argv[])
std::cout << "warning: The provided path tolerance percent of " << path_tolerance_percent << " is less than greater than 0.001 (0.1%), which is not recommended." << std::endl;
}
+ if (default_xyz_precision < 3)
+ {
+ // warning
+ std::cout << "warning: The provided default_xyz_precision " << default_xyz_precision << "mm is less than 3, with will cause issues printing arcs. A value of 3 will be used instead." << std::endl;
+ default_xyz_precision = 3;
+ }
+
+ if (default_e_precision < DEFAULT_E_PRECISION)
+ {
+ // warning
+ std::cout << "warning: The provided default_e_precision " << default_e_precision << "mm is less than 3, with will cause extrusion issues. A value of 3 will be used instead." << std::endl;
+ default_e_precision = 3;
+ }
+
+ if (default_xyz_precision > 6)
+ {
+ // warning
+ std::cout << "warning: The provided default_xyz_precision " << default_xyz_precision << "mm is greater than 6, which may cause gcode checksum errors while printing depending on your firmeware, so a value of 6 will be used instead." << std::endl;
+ default_xyz_precision = 6;
+ }
+
+ if (default_e_precision > 6)
+ {
+ // warning
+ std::cout << "warning: The provided default_e_precision " << default_e_precision << "mm is greater than 6, which may cause gcode checksum errors while printing depending on your firmeware, so value of 6 will be used instead." << std::endl;
+ default_e_precision = 6;
+ }
+
if (has_error)
{
return 1;
@@ -292,7 +347,10 @@ int main(int argc, char* argv[])
log_messages << "\tMaximum Arc Radius : " << std::setprecision(0) << max_radius_mm << "mm\n";
log_messages << "\tMin Arc Segments : " << std::setprecision(0) << min_arc_segments << "\n";
log_messages << "\tMM Per Arc Segment : " << std::setprecision(3) << mm_per_arc_segment << "\n";
- log_messages << "\tAllow Z-Axis Changes : " << (allow_3d_arcs ? "True" : "False") << "\n";
+ log_messages << "\tAllow 3D Arcs : " << (allow_3d_arcs ? "True" : "False") << "\n";
+ log_messages << "\tAllow Dynamic Precision : " << (allow_dynamic_precision ? "True" : "False") << "\n";
+ log_messages << "\tDefault XYZ Precision : " << std::setprecision(0) << static_cast<int>(default_xyz_precision) << "\n";
+ log_messages << "\tDefault E Precision : " << std::setprecision(0) << static_cast<int>(default_e_precision) << "\n";
log_messages << "\tG90/G91 Influences Extruder : " << (g90_g91_influences_extruder ? "True" : "False") << "\n";
log_messages << "\tLog Level : " << log_level_string << "\n";
log_messages << "\tHide Progress Updates : " << (hide_progress ? "True" : "False");
@@ -304,9 +362,9 @@ int main(int argc, char* argv[])
target_file_path = temp_file_path;
}
if (!hide_progress)
- p_arc_welder = new arc_welder(source_file_path, target_file_path, p_logger, resolution_mm, path_tolerance_percent, max_radius_mm, min_arc_segments, mm_per_arc_segment, g90_g91_influences_extruder, allow_3d_arcs, DEFAULT_GCODE_BUFFER_SIZE, on_progress);
+ p_arc_welder = new arc_welder(source_file_path, target_file_path, p_logger, resolution_mm, path_tolerance_percent, max_radius_mm, min_arc_segments, mm_per_arc_segment, g90_g91_influences_extruder, allow_3d_arcs, allow_dynamic_precision, default_xyz_precision, default_e_precision, DEFAULT_GCODE_BUFFER_SIZE, on_progress);
else
- p_arc_welder = new arc_welder(source_file_path, target_file_path, p_logger, resolution_mm, path_tolerance_percent, max_radius_mm, min_arc_segments, mm_per_arc_segment, g90_g91_influences_extruder, allow_3d_arcs, DEFAULT_GCODE_BUFFER_SIZE, suppress_progress);
+ p_arc_welder = new arc_welder(source_file_path, target_file_path, p_logger, resolution_mm, path_tolerance_percent, max_radius_mm, min_arc_segments, mm_per_arc_segment, g90_g91_influences_extruder, allow_3d_arcs, allow_dynamic_precision, default_xyz_precision, default_e_precision, DEFAULT_GCODE_BUFFER_SIZE, suppress_progress);
arc_welder_results results = p_arc_welder->process();
if (results.success)
diff --git a/ArcWelderTest/ArcWelderTest.cpp b/ArcWelderTest/ArcWelderTest.cpp
index ab33d83..0a11498 100644
--- a/ArcWelderTest/ArcWelderTest.cpp
+++ b/ArcWelderTest/ArcWelderTest.cpp
@@ -237,11 +237,11 @@ static void TestAntiStutter(std::string filePath)
double max_resolution = 0.05;
double max_radius_mm = 100000;
//int min_arc_segments = DEFAULT_MIN_ARC_SEGMENTS;
- int min_arc_segments = 12;
+ int min_arc_segments = 0;
double mm_per_arc_segment = 1;
//double path_tolerance_percent = ARC_LENGTH_PERCENT_TOLERANCE_DEFAULT; // 1 percent
- double path_tolerance_percent = 0.05;
+ double path_tolerance_percent = 0.05;
//double path_tolerance_percent = 0.05;
std::vector<std::string> logger_names;
logger_names.push_back("arc_welder.gcode_conversion");
@@ -259,7 +259,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(
- ISSUE_85,
+ ISSUE_93,
"C:\\Users\\Brad\\Documents\\3DPrinter\\AntiStutter\\test_output.gcode",
p_logger,
max_resolution,
@@ -269,6 +269,9 @@ static void TestAntiStutter(std::string filePath)
mm_per_arc_segment,
false,
true,
+ DEFAULT_ALLOW_DYNAMIC_PRECISION,
+ DEFAULT_XYZ_PRECISION,
+ DEFAULT_E_PRECISION,
DEFAULT_GCODE_BUFFER_SIZE,
on_progress);
//FIRMWARE_COMPENSATION_TEST_1
diff --git a/ArcWelderTest/ArcWelderTest.h b/ArcWelderTest/ArcWelderTest.h
index e6d843a..65a3604 100644
--- a/ArcWelderTest/ArcWelderTest.h
+++ b/ArcWelderTest/ArcWelderTest.h
@@ -88,7 +88,7 @@ static std::string SPIRAL_VASE_TEST_PI_BOWL = "C:\\Users\\Brad\\Documents\\3DPri
static std::string FIRMWARE_COMPENSATION_TEST_1 = "C:\\Users\\Brad\\Documents\\3DPrinter\\AntiStutter\\cylinder_tests\\cylinder_test_0.1_5.0_0.1.gcode";
static std::string BENCHY_MIN_RADIUS_TEST = "C:\\Users\\Brad\\Documents\\3DPrinter\\AntiStutter\\BenchyMinRadiusTest.gcode";
-static std::string ISSUE_85 = "C:\\Users\\Brad\\Documents\\3DPrinter\\AntiStutter\\Issue85.gcode";
+static std::string ISSUE_93 = "C:\\Users\\Brad\\Documents\\3DPrinter\\AntiStutter\\Issues\\93\\FailingGCode.gcode";
diff --git a/PyArcWelder/py_arc_welder.h b/PyArcWelder/py_arc_welder.h
index 14d5760..ed4e8cc 100644
--- a/PyArcWelder/py_arc_welder.h
+++ b/PyArcWelder/py_arc_welder.h
@@ -46,6 +46,9 @@ public:
double mm_per_arc_segment,
bool g90_g91_influences_extruder,
bool allow_3d_arcs,
+ bool allow_dynamic_precision,
+ unsigned char default_xyz_precision,
+ unsigned char default_e_precision,
int buffer_size,
PyObject* py_progress_callback
): arc_welder(
@@ -59,6 +62,9 @@ public:
mm_per_arc_segment,
g90_g91_influences_extruder,
allow_3d_arcs,
+ allow_dynamic_precision,
+ default_xyz_precision,
+ default_e_precision,
buffer_size
){
guid_ = guid;
diff --git a/PyArcWelder/py_arc_welder_extension.cpp b/PyArcWelder/py_arc_welder_extension.cpp
index 25eb9d9..1e0728b 100644
--- a/PyArcWelder/py_arc_welder_extension.cpp
+++ b/PyArcWelder/py_arc_welder_extension.cpp
@@ -195,7 +195,24 @@ extern "C"
std::string message = "py_gcode_arc_converter.ConvertFile - Beginning Arc Conversion.";
p_py_logger->log(GCODE_CONVERSION, INFO, message);
- py_arc_welder arc_welder_obj(args.guid, args.source_path, args.target_path, p_py_logger, args.resolution_mm, args.path_tolerance_percent, args.max_radius_mm, args.min_arc_segments, args.mm_per_arc_segment, args.g90_g91_influences_extruder, args.allow_3d_arcs, DEFAULT_GCODE_BUFFER_SIZE, py_progress_callback);
+ py_arc_welder arc_welder_obj(
+ args.guid,
+ args.source_path,
+ args.target_path,
+ p_py_logger,
+ args.resolution_mm,
+ args.path_tolerance_percent,
+ args.max_radius_mm,
+ args.min_arc_segments,
+ args.mm_per_arc_segment,
+ args.g90_g91_influences_extruder,
+ args.allow_3d_arcs,
+ args.allow_dynamic_precision,
+ args.default_xyz_precision,
+ args.default_e_precision,
+ DEFAULT_GCODE_BUFFER_SIZE,
+ py_progress_callback
+ );
arc_welder_results results = arc_welder_obj.process();
message = "py_gcode_arc_converter.ConvertFile - Arc Conversion Complete.";
p_py_logger->log(GCODE_CONVERSION, INFO, message);
@@ -271,6 +288,60 @@ static bool ParseArgs(PyObject* py_args, py_gcode_arc_args& args, PyObject** py_
args.resolution_mm = 0.05; // Set to the default if no resolution is provided, or if it is less than 0.
}
+ // extract allow_dynamic_precision
+ PyObject* py_allow_dynamic_precision = PyDict_GetItemString(py_args, "allow_dynamic_precision");
+ if (py_allow_dynamic_precision == NULL)
+ {
+ std::string message = "ParseArgs - Unable to retrieve allow_dynamic_precision from the args.";
+ p_py_logger->log_exception(GCODE_CONVERSION, message);
+ return false;
+ }
+ args.allow_dynamic_precision = PyLong_AsLong(py_allow_dynamic_precision) > 0;
+
+ // extract default_xyz_precision
+ PyObject* py_default_xyz_precision = PyDict_GetItemString(py_args, "default_xyz_precision");
+ if (py_default_xyz_precision == NULL)
+ {
+ std::string message = "ParseArgs - Unable to retrieve the default_xyz_precision parameter from the args.";
+ p_py_logger->log_exception(GCODE_CONVERSION, message);
+ return false;
+ }
+ args.default_xyz_precision = gcode_arc_converter::PyFloatOrInt_AsDouble(py_default_xyz_precision);
+ if (args.default_xyz_precision < 3)
+ {
+ std::string message = "ParseArgs - The default XYZ precision received was less than 3, which could cause problems printing arcs. Setting to 3.";
+ p_py_logger->log(WARNING, GCODE_CONVERSION, message);
+ args.default_xyz_precision = 3;
+ }
+ else if (args.default_xyz_precision > 6)
+ {
+ std::string message = "ParseArgs - The default XYZ precision received was greater than 6, which could can cause checksum errors depending on your firmware. Setting to 6.";
+ p_py_logger->log(WARNING, GCODE_CONVERSION, message);
+ args.default_xyz_precision = 6;
+ }
+
+ // extract default_e_precision
+ PyObject* py_default_e_precision = PyDict_GetItemString(py_args, "default_e_precision");
+ if (py_default_e_precision == NULL)
+ {
+ std::string message = "ParseArgs - Unable to retrieve the default_e_precision parameter from the args.";
+ p_py_logger->log_exception(GCODE_CONVERSION, message);
+ return false;
+ }
+ args.default_e_precision = gcode_arc_converter::PyFloatOrInt_AsDouble(py_default_e_precision);
+ if (args.default_e_precision < 3)
+ {
+ std::string message = "ParseArgs - The default E precision received was less than 3, which could cause extrusion problems. Setting to 3.";
+ p_py_logger->log(WARNING, GCODE_CONVERSION, message);
+ args.default_e_precision = 3;
+ }
+ else if (args.default_e_precision > 6)
+ {
+ std::string message = "ParseArgs - The default E precision received was greater than 6, which could can cause checksum errors depending on your firmware. Setting to 6.";
+ p_py_logger->log(WARNING, GCODE_CONVERSION, message);
+ args.default_e_precision = 6;
+ }
+
// Extract the path tolerance_percent
PyObject* py_path_tolerance_percent = PyDict_GetItemString(py_args, "path_tolerance_percent");
if (py_path_tolerance_percent == NULL)
@@ -327,8 +398,7 @@ static bool ParseArgs(PyObject* py_args, py_gcode_arc_args& args, PyObject** py_
args.min_arc_segments = 0; // Set to the default if no resolution is provided, or if it is less than 0.
}
- // Extract Allow Z Axis Changes
- // allow_3d_arcs
+ // extract allow_3d_arcs
PyObject* py_allow_3d_arcs = PyDict_GetItemString(py_args, "allow_3d_arcs");
if (py_allow_3d_arcs == NULL)
{
diff --git a/PyArcWelder/py_arc_welder_extension.h b/PyArcWelder/py_arc_welder_extension.h
index 46944a1..2c2ecec 100644
--- a/PyArcWelder/py_arc_welder_extension.h
+++ b/PyArcWelder/py_arc_welder_extension.h
@@ -52,7 +52,7 @@ struct py_gcode_arc_args {
min_arc_segments = DEFAULT_MIN_ARC_SEGMENTS;
mm_per_arc_segment = DEFAULT_MM_PER_ARC_SEGMENT;
g90_g91_influences_extruder = DEFAULT_G90_G91_INFLUENCES_EXTREUDER;
- allow_3d_arcs = DEFAULT_allow_3d_arcs;
+ allow_3d_arcs = DEFAULT_ALLOW_3D_ARCS;
log_level = 0;
}
py_gcode_arc_args(
@@ -66,6 +66,9 @@ struct py_gcode_arc_args {
double mm_per_arc_segment_,
bool g90_g91_influences_extruder_,
bool allow_3d_arcs_,
+ bool allow_dynamic_precision_,
+ unsigned char default_xyz_precision_,
+ unsigned char default_e_precision_,
int log_level_
) {
guid = guid_;
@@ -77,6 +80,9 @@ struct py_gcode_arc_args {
min_arc_segments = min_arc_segments_;
mm_per_arc_segment = mm_per_arc_segment_;
allow_3d_arcs = allow_3d_arcs_;
+ allow_dynamic_precision = allow_dynamic_precision_;
+ default_xyz_precision = default_xyz_precision_;
+ default_e_precision = default_e_precision_;
g90_g91_influences_extruder = g90_g91_influences_extruder_;
log_level = log_level_;
}
@@ -86,6 +92,9 @@ struct py_gcode_arc_args {
double resolution_mm;
double path_tolerance_percent;
bool allow_3d_arcs;
+ bool allow_dynamic_precision;
+ unsigned char default_xyz_precision;
+ unsigned char default_e_precision;
bool g90_g91_influences_extruder;
double max_radius_mm;
int min_arc_segments;