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-11-20 20:17:12 +0300
committerFormerLurker <hochgebe@gmail.com>2020-11-20 20:17:12 +0300
commit995ec6d5b35cf8ae23dabb74065fdafdcc843740 (patch)
tree83b947814b49f057625fd11ff23c9d6c82654977 /ArcWelder
parent0f57a03f82a555a9b6d3afdfb133457c72455d54 (diff)
Add test spiral vase support.
Diffstat (limited to 'ArcWelder')
-rw-r--r--ArcWelder/arc_welder.cpp24
-rw-r--r--ArcWelder/arc_welder.h2
-rw-r--r--ArcWelder/segmented_arc.cpp46
-rw-r--r--ArcWelder/segmented_arc.h5
-rw-r--r--ArcWelder/segmented_shape.cpp57
-rw-r--r--ArcWelder/segmented_shape.h35
6 files changed, 133 insertions, 36 deletions
diff --git a/ArcWelder/arc_welder.cpp b/ArcWelder/arc_welder.cpp
index 374196d..7f78c3c 100644
--- a/ArcWelder/arc_welder.cpp
+++ b/ArcWelder/arc_welder.cpp
@@ -43,13 +43,15 @@ arc_welder::arc_welder(
double path_tolerance_percent,
double max_radius,
bool g90_g91_influences_extruder,
+ bool allow_z_axis_changes,
int buffer_size,
progress_callback callback) : current_arc_(
DEFAULT_MIN_SEGMENTS,
buffer_size - 5,
resolution_mm,
path_tolerance_percent,
- max_radius
+ max_radius,
+ allow_z_axis_changes
),
segment_statistics_(
segment_statistic_lengths,
@@ -70,6 +72,7 @@ arc_welder::arc_welder(
source_path_ = source_path;
target_path_ = target_path;
gcode_position_args_ = get_args_(g90_g91_influences_extruder, buffer_size);
+ allow_z_axis_changes_ = allow_z_axis_changes;
notification_period_seconds = 1;
lines_processed_ = 0;
gcodes_processed_ = 0;
@@ -296,7 +299,7 @@ arc_welder_results results;
{
// Sending final progress update message
p_logger_->log(logger_type_, VERBOSE, "Sending final progress update message.");
- on_progress_(final_progress);
+ on_progress_(arc_welder_progress(final_progress));
}
p_logger_->log(logger_type_, DEBUG, "Processing complete, closing source and target file.");
output_file_.close();
@@ -377,7 +380,15 @@ int arc_welder::process_gcode(parsed_command cmd, bool is_end, bool is_reprocess
// Update the source file statistics
if (p_cur_pos->has_xy_position_changed && (extruder_current.is_extruding || extruder_current.is_retracting) && !is_reprocess)
{
- double movement_length_mm = utilities::get_cartesian_distance(p_pre_pos->x, p_pre_pos->y, p_cur_pos->x, p_cur_pos->y);
+ double movement_length_mm;
+
+ if (allow_z_axis_changes_) {
+ movement_length_mm = utilities::get_cartesian_distance(p_pre_pos->x, p_pre_pos->y, p_pre_pos->z, p_cur_pos->x, p_cur_pos->y, p_cur_pos->z);
+ }
+ else {
+ movement_length_mm = utilities::get_cartesian_distance(p_pre_pos->x, p_pre_pos->y, p_cur_pos->x, p_cur_pos->y);
+ }
+
if (movement_length_mm > 0)
{
segment_statistics_.update(movement_length_mm, true);
@@ -408,7 +419,10 @@ int arc_welder::process_gcode(parsed_command cmd, bool is_end, bool is_reprocess
if (
!is_end && cmd.is_known_command && !cmd.is_empty && (
is_g1_g2 &&
- utilities::is_equal(p_cur_pos->z, p_pre_pos->z) &&
+ (
+ allow_z_axis_changes_ ||
+ utilities::is_equal(p_cur_pos->z, p_pre_pos->z)
+ ) &&
utilities::is_equal(p_cur_pos->x_offset, p_pre_pos->x_offset) &&
utilities::is_equal(p_cur_pos->y_offset, p_pre_pos->y_offset) &&
utilities::is_equal(p_cur_pos->z_offset, p_pre_pos->z_offset) &&
@@ -482,7 +496,7 @@ int arc_welder::process_gcode(parsed_command cmd, bool is_end, bool is_reprocess
{
p_logger_->log(logger_type_, DEBUG, "Command '"+ cmd.command + "' is not G0/G1, skipping. Gcode:" + cmd.gcode);
}
- else if (!utilities::is_equal(p_cur_pos->z, p_pre_pos->z))
+ else if (!allow_z_axis_changes_ && !utilities::is_equal(p_cur_pos->z, p_pre_pos->z))
{
p_logger_->log(logger_type_, DEBUG, "Z axis position changed, cannot convert:" + cmd.gcode);
}
diff --git a/ArcWelder/arc_welder.h b/ArcWelder/arc_welder.h
index 5a8d9b4..0c2b3ea 100644
--- a/ArcWelder/arc_welder.h
+++ b/ArcWelder/arc_welder.h
@@ -420,6 +420,7 @@ public:
double path_tolerance_percent,
double max_radius,
bool g90_g91_influences_extruder = DEFAULT_G90_G91_INFLUENCES_EXTRUDER,
+ bool allow_z_axis_changes = DEFAULT_ALLOW_Z_AXIS_CHANGES,
int buffer_size = DEFAULT_GCODE_BUFFER_SIZE,
progress_callback callback = NULL);
void set_logger_type(int logger_type);
@@ -445,6 +446,7 @@ private:
std::string target_path_;
double resolution_mm_;
gcode_position_args gcode_position_args_;
+ bool allow_z_axis_changes_;
long file_size_;
int lines_processed_;
int gcodes_processed_;
diff --git a/ArcWelder/segmented_arc.cpp b/ArcWelder/segmented_arc.cpp
index f438761..f1cc66d 100644
--- a/ArcWelder/segmented_arc.cpp
+++ b/ArcWelder/segmented_arc.cpp
@@ -33,7 +33,8 @@
segmented_arc::segmented_arc() : segmented_shape(DEFAULT_MIN_SEGMENTS, DEFAULT_MAX_SEGMENTS, DEFAULT_RESOLUTION_MM, ARC_LENGTH_PERCENT_TOLERANCE_DEFAULT)
{
-
+ max_radius_mm_ = DEFAULT_MAX_RADIUS_MM;
+ allow_z_axis_changes_ = DEFAULT_ALLOW_Z_AXIS_CHANGES;
}
segmented_arc::segmented_arc(
@@ -41,12 +42,13 @@ segmented_arc::segmented_arc(
int max_segments,
double resolution_mm,
double path_tolerance_percent,
- double max_radius_mm
+ double max_radius_mm,
+ bool allow_z_axis_changes
) : segmented_shape(min_segments, max_segments, resolution_mm, path_tolerance_percent)
{
if (max_radius_mm > DEFAULT_MAX_RADIUS_MM) max_radius_mm_ = DEFAULT_MAX_RADIUS_MM;
else max_radius_mm_ = max_radius_mm;
-
+ allow_z_axis_changes_ = allow_z_axis_changes;
}
segmented_arc::~segmented_arc()
@@ -97,20 +99,23 @@ bool segmented_arc::try_add_point(point p, double e_relative)
if (points_.count() > 0)
{
point p1 = points_[points_.count() - 1];
- distance = utilities::get_cartesian_distance(p1.x, p1.y, p.x, p.y);
- if (!utilities::is_equal(p1.z, p.z))
- {
- // Arcs require that z is equal for all points
- //std::cout << " failed - z change.\n";
-
- return false;
+ if (allow_z_axis_changes_){
+ // If we can draw arcs in 3 space, add in the distance of the z axis changes
+ distance = utilities::get_cartesian_distance(p1.x, p1.y, p1.z, p.x, p.y, p.z);
}
-
+ else {
+ distance = utilities::get_cartesian_distance(p1.x, p1.y, p.x, p.y);
+ if (!utilities::is_equal(p1.z, p.z))
+ {
+ // Z axis changes aren't allowed
+ return false;
+ }
+ }
+
if (utilities::is_zero(distance))
{
// there must be some distance between the points
// to make an arc.
- //std::cout << " failed - no distance change.\n";
return false;
}
@@ -177,7 +182,7 @@ bool segmented_arc::try_add_point_internal_(point p, double pd)
double previous_shape_length = original_shape_length_;
original_shape_length_ += pd;
- if (arc::try_create_arc(points_, current_arc_, original_shape_length_, max_radius_mm_, resolution_mm_, path_tolerance_percent_))
+ if (arc::try_create_arc(points_, current_arc_, original_shape_length_, max_radius_mm_, resolution_mm_, path_tolerance_percent_, xyz_precision_, allow_z_axis_changes_))
{
if (!is_shape())
{
@@ -208,7 +213,7 @@ std::string segmented_arc::get_shape_gcode_(bool has_e, double e, double f) cons
char buf[20];
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;
// Here is where the performance part kicks in (these are expensive calls) that makes things a bit ugly.
@@ -231,6 +236,19 @@ std::string segmented_arc::get_shape_gcode_(bool has_e, double e, double f) cons
gcode += " Y";
gcode += utilities::to_string(current_arc_.end_point.y, xyz_precision_, buf, false);
+ if (allow_z_axis_changes_)
+ {
+ // 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, -1 * xyz_precision_)))
+ {
+ // 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 += " I";
gcode += utilities::to_string(i, xyz_precision_, buf, false);
diff --git a/ArcWelder/segmented_arc.h b/ArcWelder/segmented_arc.h
index 59e92d0..5bbdf34 100644
--- a/ArcWelder/segmented_arc.h
+++ b/ArcWelder/segmented_arc.h
@@ -29,6 +29,7 @@
#include <sstream>
#define GCODE_CHAR_BUFFER_SIZE 100
+
class segmented_arc :
public segmented_shape
{
@@ -39,7 +40,8 @@ public:
int max_segments = DEFAULT_MAX_SEGMENTS,
double resolution_mm = DEFAULT_RESOLUTION_MM,
double path_tolerance_percnet = ARC_LENGTH_PERCENT_TOLERANCE_DEFAULT,
- double max_radius_mm = DEFAULT_MAX_RADIUS_MM
+ double max_radius_mm = DEFAULT_MAX_RADIUS_MM ,
+ bool allow_z_axis_changes = DEFAULT_ALLOW_Z_AXIS_CHANGES
);
virtual ~segmented_arc();
virtual bool try_add_point(point p, double e_relative);
@@ -57,5 +59,6 @@ private:
//circle arc_circle_;
arc current_arc_;
double max_radius_mm_;
+ bool allow_z_axis_changes_;
};
diff --git a/ArcWelder/segmented_shape.cpp b/ArcWelder/segmented_shape.cpp
index 4a489da..170b1df 100644
--- a/ArcWelder/segmented_shape.cpp
+++ b/ArcWelder/segmented_shape.cpp
@@ -197,7 +197,7 @@ bool circle::try_create_circle(const point& p1, const point& p2, const point& p3
return true;
}
-bool circle::try_create_circle(const array_list<point>& points, const double max_radius, const double resolution_mm, circle& new_circle, bool check_middle_only)
+bool circle::try_create_circle(const array_list<point>& points, const double max_radius, const double resolution_mm, const int xyz_precision, bool allow_z_axis_changes, bool check_middle_only, circle& new_circle)
{
int middle_index = points.count() / 2;
int check_index;
@@ -209,7 +209,7 @@ bool circle::try_create_circle(const array_list<point>& points, const double max
// 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))
+ if (!new_circle.is_over_deviation(points, resolution_mm, xyz_precision, allow_z_axis_changes))
{
return true;
}
@@ -268,20 +268,40 @@ point circle::get_closest_point(const point& p) const
return point(px, py, pz, 0);
}
-bool circle::is_over_deviation(const array_list<point>& points, const double resolution_mm)
+bool circle::is_over_deviation(const array_list<point>& points, const double resolution_mm, const int xyz_precision, const bool allow_z_axis_changes)
{
+ // We need to ensure that the Z steps are constand per linear travel unit
+ double z_step_per_distance = 0;
// Skip the first and last points since they will fit perfectly.
+ // UNLESS allow z changes is set to true, then we need to do some different stuff
+ int final_index = points.count() - 1 + (allow_z_axis_changes ? 1 : 0);
for (int index = 1; index < points.count() - 1; index++)
{
// Make sure the length from the center of our circle to the test point is
// at or below our max distance.
- double distance = utilities::get_cartesian_distance(points[index].x, points[index].y, center.x, center.y);
+ double distance = distance = utilities::get_cartesian_distance(points[index].x, points[index].y, center.x, center.y);
+ if (allow_z_axis_changes) {
+ double z1 = points[index - 1].z;
+ double z2 = points[index].z;
+
+ double current_z_stepper_distance = (z2 - z1)/distance;
+ if (z_step_per_distance == 0){
+ z_step_per_distance = current_z_stepper_distance;
+ }
+ if (!utilities::is_equal(z_step_per_distance, current_z_stepper_distance, std::pow(10, -1.0 * xyz_precision)))
+ {
+ // The z step is uneven, can't create arc
+ return true;
+ }
+
+ }
+
if (std::abs(distance - radius) > resolution_mm)
{
return true;
}
}
-
+
// Check the point perpendicular from the segment to the circle's center, if any such point exists
for (int index = 0; index < points.count() - 1; index++)
{
@@ -310,7 +330,8 @@ bool arc::try_create_arc(
arc& target_arc,
double approximate_length,
double resolution,
- double path_tolerance_percent)
+ double path_tolerance_percent,
+ bool allow_z_axis_changes)
{
double polar_start_theta = c.get_polar_radians(start_point);
double polar_mid_theta = c.get_polar_radians(mid_point);
@@ -383,6 +404,17 @@ bool arc::try_create_arc(
arc_length = test_arc_length;
direction = direction == 1 ? 2 : 1;
}
+
+ if (allow_z_axis_changes)
+ {
+ // Ensure the perimeter of the arc is less than that of a full circle
+ double perimeter = c.radius * 2.0 * PI_DOUBLE;
+ if (perimeter <= approximate_length) {
+ return false;
+ }
+
+ }
+
if(direction == 2)
angle_radians *= -1.0;
@@ -407,10 +439,11 @@ bool arc::try_create_arc(
arc& target_arc,
double approximate_length,
double resolution,
- double path_tolerance_percent)
+ double path_tolerance_percent,
+ bool allow_z_axis_changes)
{
int mid_point_index = ((points.count() - 2) / 2) + 1;
- return arc::try_create_arc(c, points[0], points[mid_point_index], points[points.count() - 1], target_arc, approximate_length, resolution, path_tolerance_percent);
+ return arc::try_create_arc(c, points[0], points[mid_point_index], points[points.count() - 1], target_arc, approximate_length, resolution, path_tolerance_percent, allow_z_axis_changes);
}
bool arc::try_create_arc(
const array_list<point>& points,
@@ -418,13 +451,15 @@ bool arc::try_create_arc(
double approximate_length,
double max_radius_mm,
double resolution_mm,
- double path_tolerance_percent)
+ double path_tolerance_percent,
+ int xyz_precision,
+ bool allow_z_axis_changes)
{
circle test_circle;
- if (circle::try_create_circle(points, max_radius_mm, resolution_mm, test_circle, false))
+ if (circle::try_create_circle(points, max_radius_mm, resolution_mm, xyz_precision, allow_z_axis_changes, false, test_circle))
{
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);
+ 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_z_axis_changes);
}
return false;
}
diff --git a/ArcWelder/segmented_shape.h b/ArcWelder/segmented_shape.h
index b5b3cfb..ac9b1db 100644
--- a/ArcWelder/segmented_shape.h
+++ b/ArcWelder/segmented_shape.h
@@ -109,7 +109,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<point>& points, const double max_radius, const double resolutino_mm, circle& new_circle, bool check_middle_only=false);
+ static bool try_create_circle(const array_list<point>& points, const double max_radius, const double resolutino_mm, const int xyz_precision, bool allow_z_axis_changes, bool check_middle_only, circle& new_circle);
double get_radians(const point& p1, const point& p2) const;
@@ -117,10 +117,11 @@ struct circle {
point get_closest_point(const point& p) const;
- bool is_over_deviation(const array_list<point>& points, const double resolution_mm);
+ bool is_over_deviation(const array_list<point>& points, const double resolution_mm, const int xyz_precision, const bool allow_z_axis_changes);
};
#define DEFAULT_RESOLUTION_MM 0.05
+#define DEFAULT_ALLOW_Z_AXIS_CHANGES true
struct arc : circle
{
arc() {
@@ -151,9 +152,33 @@ struct arc : circle
point start_point;
point end_point;
// Statis functions
- static bool try_create_arc(const circle& c, const point& start_point, const point& mid_point, const point& end_point, arc& target_arc, double approximate_length, double resolution = DEFAULT_RESOLUTION_MM, double path_tolerance_percent = ARC_LENGTH_PERCENT_TOLERANCE_DEFAULT);
- static bool try_create_arc(const circle& c, const array_list<point>& points, arc& target_arc, double approximate_length, double resolution = DEFAULT_RESOLUTION_MM, double path_tolerance_percent = ARC_LENGTH_PERCENT_TOLERANCE_DEFAULT);
- static bool try_create_arc(const array_list<point>& points, arc& target_arc, double approximate_length, double max_radius = DEFAULT_MAX_RADIUS_MM, double resolution = DEFAULT_RESOLUTION_MM, double path_tolerance_percent = ARC_LENGTH_PERCENT_TOLERANCE_DEFAULT);
+ static bool try_create_arc(
+ const circle& c,
+ const point& start_point,
+ const point& mid_point,
+ const point& end_point,
+ arc& target_arc,
+ double approximate_length,
+ double resolution = DEFAULT_RESOLUTION_MM,
+ double path_tolerance_percent = ARC_LENGTH_PERCENT_TOLERANCE_DEFAULT,
+ bool allow_z_axis_changes = DEFAULT_ALLOW_Z_AXIS_CHANGES);
+ static bool try_create_arc(
+ const circle& c,
+ const array_list<point>& points,
+ arc& target_arc,
+ double approximate_length,
+ double resolution = DEFAULT_RESOLUTION_MM,
+ double path_tolerance_percent = ARC_LENGTH_PERCENT_TOLERANCE_DEFAULT,
+ bool allow_z_axis_changes = DEFAULT_ALLOW_Z_AXIS_CHANGES);
+ static bool try_create_arc(
+ const array_list<point>& points,
+ arc& target_arc,
+ double approximate_length,
+ double max_radius = DEFAULT_MAX_RADIUS_MM,
+ double resolution = DEFAULT_RESOLUTION_MM,
+ double path_tolerance_percent = ARC_LENGTH_PERCENT_TOLERANCE_DEFAULT,
+ int xyz_precision = DEFAULT_XYZ_PRECISION,
+ bool allow_z_axis_changes = DEFAULT_ALLOW_Z_AXIS_CHANGES);
};
double distance_from_segment(segment s, point p);