Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove icoords in the code #467

Merged
merged 2 commits into from
Jul 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ available_drills_tests_SOURCES = available_drills_tests.cpp available_drills.hpp
gerberimporter_tests_SOURCES = gerberimporter.hpp gerberimporter.cpp gerberimporter_tests.cpp merge_near_points.hpp merge_near_points.cpp eulerian_paths.cpp eulerian_paths.hpp segmentize.cpp segmentize.hpp boost_unit_test.cpp bg_helpers.cpp bg_helpers.hpp bg_operators.hpp bg_operators.cpp
gerberimporter_tests_LDFLAGS = $(glibmm_LIBS) $(gdkmm_LIBS) $(rsvg_LIBS)
options_tests_SOURCES = options_tests.cpp options.hpp options.cpp boost_unit_test.cpp
autoleveller_tests_SOURCES = autoleveller_tests.cpp autoleveller.hpp autoleveller.cpp options.cpp options.hpp boost_unit_test.cpp
autoleveller_tests_SOURCES = autoleveller_tests.cpp autoleveller.hpp autoleveller.cpp options.cpp options.hpp boost_unit_test.cpp bg_operators.hpp bg_operators.cpp bg_helpers.hpp bg_helpers.cpp eulerian_paths.hpp eulerian_paths.cpp segmentize.hpp segmentize.cpp merge_near_points.hpp merge_near_points.cpp
common_tests_SOURCES = common.hpp common.cpp common_tests.cpp boost_unit_test.cpp
backtrack_tests_SOURCES = backtrack.hpp backtrack.cpp backtrack_tests.cpp boost_unit_test.cpp bg_helpers.hpp bg_helpers.cpp eulerian_paths.hpp eulerian_paths.cpp segmentize.hpp segmentize.cpp merge_near_points.hpp merge_near_points.cpp bg_operators.hpp bg_operators.cpp
trim_paths_tests_SOURCES = trim_paths.hpp trim_paths.cpp trim_paths_tests.cpp boost_unit_test.cpp bg_helpers.hpp bg_helpers.cpp eulerian_paths.hpp eulerian_paths.cpp segmentize.hpp segmentize.cpp merge_near_points.hpp merge_near_points.cpp bg_operators.hpp bg_operators.cpp
Expand Down
79 changes: 34 additions & 45 deletions autoleveller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ using std::pair;

#include "units.hpp"

#include "bg_operators.hpp"

const string autoleveller::callSubRepeat[] = {
"o%3$d repeat [%2%]\n%4$s o%1% call\n%4$so%3$d endrepeat\n",
"M98 P%1% L%2%\n",
Expand Down Expand Up @@ -101,20 +103,20 @@ string autoleveller::getVarName( int i, int j )
return '#' + to_string(i * numYPoints + j + 500); //getVarName(10,8) returns (numYPoints=10) #180
}

box_type_fp computeWorkarea(const vector<pair<coordinate_type_fp, vector<shared_ptr<icoords>>>>& toolpaths) {
box_type_fp computeWorkarea(const vector<pair<coordinate_type_fp, multi_linestring_type_fp>>& toolpaths) {
box_type_fp bounding_box = boost::geometry::make_inverse<box_type_fp>();

for (const auto& toolpath : toolpaths) {
for (const auto& linestring : toolpath.second) {
boost::geometry::expand(bounding_box,
boost::geometry::return_envelope<box_type_fp>(*linestring));
boost::geometry::return_envelope<box_type_fp>(linestring));
}
}

return bounding_box;
}

void autoleveller::prepareWorkarea(const vector<pair<coordinate_type_fp, vector<shared_ptr<icoords>>>>& toolpaths) {
void autoleveller::prepareWorkarea(const vector<pair<coordinate_type_fp, multi_linestring_type_fp>>& toolpaths) {
box_type_fp workarea;
double workareaLenX;
double workareaLenY;
Expand Down Expand Up @@ -298,21 +300,21 @@ static inline T clamp(const T& x, const T& min_x, const T& max_x) {
return std::max(min_x, std::min(x, max_x));
}

string autoleveller::interpolatePoint ( icoordpair point )
string autoleveller::interpolatePoint ( point_type_fp point )
{
unsigned int xminindex;
unsigned int yminindex;
double x_minus_x0_rel;
double y_minus_y0_rel;

xminindex = floor((point.first - startPointX) / XProbeDist);
xminindex = floor((point.x() - startPointX) / XProbeDist);
xminindex = clamp(xminindex, 0U, numXPoints - 1);

yminindex = floor((point.second - startPointY) / YProbeDist);
yminindex = floor((point.y() - startPointY) / YProbeDist);
yminindex = clamp(yminindex, 0U, numYPoints - 1);

x_minus_x0_rel = ( point.first - startPointX - xminindex * XProbeDist ) / XProbeDist;
y_minus_y0_rel = ( point.second - startPointY - yminindex * YProbeDist ) / YProbeDist;
x_minus_x0_rel = ( point.x() - startPointX - xminindex * XProbeDist ) / XProbeDist;
y_minus_y0_rel = ( point.y() - startPointY - yminindex * YProbeDist ) / YProbeDist;

return str( format( "#1=[%3$s+[%1$s-%3$s]*%5$.5f]\n#2=[%4$s+[%2$s-%4$s]*%5$.5f]\n#3=[#1+[#2-#1]*%6$.5f]\n" ) %
getVarName( xminindex, yminindex + 1 ) %
Expand All @@ -322,53 +324,39 @@ string autoleveller::interpolatePoint ( icoordpair point )
y_minus_y0_rel % x_minus_x0_rel );
}

static inline icoordpair operator+(const icoordpair& a, const icoordpair& b) {
return icoordpair(a.first + b.first, a.second + b.second);
}

static inline icoordpair operator-(const icoordpair& a, const icoordpair& b) {
return icoordpair(a.first - b.first, a.second - b.second);
static inline point_type_fp operator*(const point_type_fp& a, const point_type_fp& b) {
return point_type_fp(a.x() * b.x(), a.y() * b.y());
}

static inline icoordpair operator*(const icoordpair& a, const icoordpair& b) {
return icoordpair(a.first * b.first, a.second * b.second);
static inline point_type_fp operator/(const point_type_fp& a, const point_type_fp& b) {
return point_type_fp(a.x() / b.x(), a.y() / b.y());
}

static inline icoordpair operator/(const icoordpair& a, const icoordpair& b) {
return icoordpair(a.first / b.first, a.second / b.second);
}

static inline icoordpair operator*(const icoordpair& a, const double& b) {
return icoordpair(a.first * b, a.second * b);
}

static inline icoordpair floor(const icoordpair& a) {
return icoordpair(floor(a.first), floor(a.second));
}

icoords partition_segment(const icoordpair& source, const icoordpair& dest,
const icoordpair& grid_zero, const icoordpair& grid_width) {
linestring_type_fp partition_segment(const point_type_fp& source, const point_type_fp& dest,
const point_type_fp& grid_zero, const point_type_fp& grid_width) {
if (source == dest) {
return {dest};
}
double current_progress = 0;
icoords points;
linestring_type_fp points;
while (current_progress != 1) {
const auto current = source + (dest - source) * current_progress;
points.push_back(current);

const auto current_index = floor((current - grid_zero) / grid_width);
double best_progress = 1;
for (const auto& index_delta : {-1,0,1,2}) {
const auto new_point = (current_index + icoordpair(index_delta, index_delta)) * grid_width + grid_zero;
const auto new_point = (current_index + point_type_fp(index_delta, index_delta)) * grid_width + grid_zero;
const auto new_progress = (new_point - source) / (dest - source);
if (new_progress.first > current_progress && new_progress.first < best_progress) {
if (new_progress.x() > current_progress && new_progress.x() < best_progress) {
// This step gets us closer to the end yet moves the least amount in that direction.
best_progress = new_progress.first;
best_progress = new_progress.x();
}
if (new_progress.second > current_progress && new_progress.second < best_progress) {
if (new_progress.y() > current_progress && new_progress.y() < best_progress) {
// This step gets us closer to the end yet moves the least amount in that direction.
best_progress = new_progress.second;
best_progress = new_progress.y();
}
}
current_progress = best_progress;
Expand All @@ -377,30 +365,31 @@ icoords partition_segment(const icoordpair& source, const icoordpair& dest,
return points;
}

string autoleveller::addChainPoint (icoordpair point, double zwork) {
string autoleveller::addChainPoint (point_type_fp point, double zwork) {
string outputStr;
icoords subsegments;
icoords::const_iterator i;
linestring_type_fp subsegments;
linestring_type_fp::const_iterator i;

subsegments = partition_segment(lastPoint, point, icoordpair(startPointX, startPointY), icoordpair(XProbeDist, YProbeDist));
subsegments = partition_segment(lastPoint, point, point_type_fp(startPointX, startPointY), point_type_fp(XProbeDist, YProbeDist));

if (software == Software::LINUXCNC || software == Software::MACH4 || software == Software::MACH3) {
for( i = subsegments.begin() + 1; i != subsegments.end(); i++ )
outputStr += str( silent_format( callSub2[software] ) % g01InterpolatedNum % i->first % i->second % zwork);
outputStr += str( silent_format( callSub2[software] ) % g01InterpolatedNum % i->x() % i->y() % zwork);
} else {
for(i = subsegments.begin() + 1; i != subsegments.end(); i++) {
outputStr += interpolatePoint( *i );
outputStr += str( format( "X%1$.5f Y%2$.5f Z[#3+%3$.5f]\n" ) % i->first % i->second % zwork);
outputStr += str( format( "X%1$.5f Y%2$.5f Z[#3+%3$.5f]\n" ) % i->x() % i->y() % zwork);
}
}

lastPoint = point;
return outputStr;
}

string autoleveller::g01Corrected (icoordpair point, double zwork) {
if( software == Software::LINUXCNC || software == Software::MACH4 || software == Software::MACH3 )
return str( silent_format( callSub2[software] ) % g01InterpolatedNum % point.first % point.second % zwork);
else
return interpolatePoint( point ) + "G01 Z[" + str(format("%.5f")%zwork) + "+#" + returnVar + "]\n";
string autoleveller::g01Corrected (point_type_fp point, double zwork) {
if( software == Software::LINUXCNC || software == Software::MACH4 || software == Software::MACH3 ) {
return str( silent_format( callSub2[software] ) % g01InterpolatedNum % point.x() % point.y() % zwork);
} else {
return interpolatePoint( point ) + "G01 Z[" + str(format("%.5f")%zwork) + "+#" + returnVar + "]\n";
}
}
16 changes: 8 additions & 8 deletions autoleveller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class autoleveller
// prepareWorkarea computes the area of the milling project and computes the required number of probe
// points; if it exceeds the maximum number of probe point it return false, otherwise it returns true
// All the arguments must be in inches
void prepareWorkarea(const std::vector<std::pair<coordinate_type_fp, std::vector<std::shared_ptr<icoords>>>>& toolpaths);
void prepareWorkarea(const std::vector<std::pair<coordinate_type_fp, multi_linestring_type_fp>>& toolpaths);

// header prints in of the header required for the probing (subroutines and probe calls for LinuxCNC,
// only the probe calls for the other softwares)
Expand All @@ -60,14 +60,14 @@ class autoleveller
// required number of points between the previous and the current point and it interpolates them too.
// This function adds a new chain point. Always call setLastChainPoint before starting a new chain
// (call it also for the 1st chain)
std::string addChainPoint(icoordpair point, double zwork);
std::string addChainPoint(point_type_fp point, double zwork);

// g01Corrected interpolates only one point (without adding it to the chain), and it prints a G01 to that
// position
std::string g01Corrected(icoordpair point, double zwork);
std::string g01Corrected(point_type_fp point, double zwork);

// Set lastPoint as the last chain point. You can use this function when you want to start a new chain
inline void setLastChainPoint ( icoordpair lastPoint )
inline void setLastChainPoint ( point_type_fp lastPoint )
{
this->lastPoint = lastPoint;
}
Expand Down Expand Up @@ -150,7 +150,7 @@ class autoleveller

std::string callSub2[3];

icoordpair lastPoint;
point_type_fp lastPoint;

// footerNoIf prints the footer, regardless of the software
void footerNoIf( std::ofstream &of );
Expand All @@ -161,10 +161,10 @@ class autoleveller

// interpolatePoint finds the correct 4 probed points and computes a bilinear interpolation of point.
// The result of the interpolation is saved in the parameter number RESULT_VAR
std::string interpolatePoint ( icoordpair point );
std::string interpolatePoint ( point_type_fp point );
};

icoords partition_segment(const icoordpair& source, const icoordpair& dest,
const icoordpair& grid_zero, const icoordpair& grid_width);
linestring_type_fp partition_segment(const point_type_fp& source, const point_type_fp& dest,
const point_type_fp& grid_zero, const point_type_fp& grid_width);

#endif // AUTOLEVELLER_H
86 changes: 35 additions & 51 deletions autoleveller_tests.cpp
Original file line number Diff line number Diff line change
@@ -1,37 +1,21 @@
#define BOOST_TEST_MODULE autoleveller tests
#include <boost/test/unit_test.hpp>

#include "geometry.hpp"
#include "bg_operators.hpp"

#include "autoleveller.hpp"

using namespace std;

namespace std {
static inline std::ostream& operator<<(std::ostream& out, const icoordpair& point) {
out << "{" << point.first << ", " << point.second << "}";
return out;
}

static inline std::ostream& operator<<(std::ostream& out, const icoords& points) {
out << "{";
for (auto p = points.cbegin(); p != points.cend(); p++) {
out << *p;
if (p + 1 != points.cend()) {
out << ", ";
}
}
out << "}";
return out;
}
}

BOOST_AUTO_TEST_SUITE(autoleveller_tests)

BOOST_AUTO_TEST_CASE(ten_by_ten) {
const auto actual = partition_segment(icoordpair(0,0),
icoordpair(100,100),
icoordpair(0,0),
icoordpair(10, 10));
const icoords expected {
const auto actual = partition_segment(point_type_fp(0,0),
point_type_fp(100,100),
point_type_fp(0,0),
point_type_fp(10, 10));
const linestring_type_fp expected {
{0, 0},
{10, 10},
{20, 20},
Expand All @@ -48,11 +32,11 @@ BOOST_AUTO_TEST_CASE(ten_by_ten) {
}

BOOST_AUTO_TEST_CASE(horizontal_aligned) {
const auto actual = partition_segment(icoordpair(0,0),
icoordpair(0,100),
icoordpair(0,0),
icoordpair(10, 10));
const icoords expected {
const auto actual = partition_segment(point_type_fp(0,0),
point_type_fp(0,100),
point_type_fp(0,0),
point_type_fp(10, 10));
const linestring_type_fp expected {
{0, 0},
{0, 10},
{0, 20},
Expand All @@ -69,11 +53,11 @@ BOOST_AUTO_TEST_CASE(horizontal_aligned) {
}

BOOST_AUTO_TEST_CASE(horizontal_unaligned) {
const auto actual = partition_segment(icoordpair(0.1,0.1),
icoordpair(0.1,19.9),
icoordpair(0,0),
icoordpair(10, 10));
const icoords expected {
const auto actual = partition_segment(point_type_fp(0.1,0.1),
point_type_fp(0.1,19.9),
point_type_fp(0,0),
point_type_fp(10, 10));
const linestring_type_fp expected {
{0.1, 0.1},
{0.1, 10},
{0.1, 19.9},
Expand All @@ -82,11 +66,11 @@ BOOST_AUTO_TEST_CASE(horizontal_unaligned) {
}

BOOST_AUTO_TEST_CASE(ten_by_ten_offset) {
const auto actual = partition_segment(icoordpair(0,0),
icoordpair(100,100),
icoordpair(1,1),
icoordpair(10, 10));
const icoords expected {
const auto actual = partition_segment(point_type_fp(0,0),
point_type_fp(100,100),
point_type_fp(1,1),
point_type_fp(10, 10));
const linestring_type_fp expected {
{0, 0},
{1, 1},
{11, 11},
Expand All @@ -104,22 +88,22 @@ BOOST_AUTO_TEST_CASE(ten_by_ten_offset) {
}

BOOST_AUTO_TEST_CASE(source_equals_dest) {
const auto actual = partition_segment(icoordpair(0,0),
icoordpair(0,0),
icoordpair(1,2),
icoordpair(3, 4));
const icoords expected {
const auto actual = partition_segment(point_type_fp(0,0),
point_type_fp(0,0),
point_type_fp(1,2),
point_type_fp(3, 4));
const linestring_type_fp expected {
{0, 0}
};
BOOST_CHECK_EQUAL(actual, expected);
}

BOOST_AUTO_TEST_CASE(skewed) {
const auto actual = partition_segment(icoordpair(5,5),
icoordpair(99,12),
icoordpair(0,0),
icoordpair(7, 5));
const icoords expected {
const auto actual = partition_segment(point_type_fp(5,5),
point_type_fp(99,12),
point_type_fp(0,0),
point_type_fp(7, 5));
const linestring_type_fp expected {
{5, 5},
{7, 5.14894},
{14, 5.67021},
Expand All @@ -141,8 +125,8 @@ BOOST_AUTO_TEST_CASE(skewed) {
BOOST_CHECK_EQUAL(actual.size(), expected.size());
for (size_t i = 0; i < actual.size(); i++) {
BOOST_TEST_CONTEXT("actual[" << i << "] == expected[" << i << "]") {
BOOST_CHECK_CLOSE(actual[i].first, expected[i].first, 0.001);
BOOST_CHECK_CLOSE(actual[i].second, expected[i].second, 0.001);
BOOST_CHECK_CLOSE(actual[i].x(), expected[i].x(), 0.001);
BOOST_CHECK_CLOSE(actual[i].y(), expected[i].y(), 0.001);
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions bg_operators.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef BG_OPERATORS_HPP
#define BG_OPERATORS_HPP

#include "geometry.hpp"

#include <boost/functional/hash/hash.hpp>

template <typename polygon_type_t, typename rhs_t>
Expand Down Expand Up @@ -75,6 +77,10 @@ boost::geometry::model::d2::point_xy<T> operator*(
const boost::geometry::model::d2::point_xy<T>& lhs,
const S& rhs);

static inline point_type_fp floor(const point_type_fp& a) {
return point_type_fp(std::floor(a.x()), std::floor(a.y()));
}

template <typename T>
bool operator==(
const boost::geometry::model::d2::point_xy<T>& x,
Expand Down
Loading