Skip to content

Commit

Permalink
Split helpers into helpers and operators
Browse files Browse the repository at this point in the history
  • Loading branch information
eyal0 committed Jul 1, 2020
1 parent 6346b09 commit 9f0c3ba
Show file tree
Hide file tree
Showing 19 changed files with 411 additions and 389 deletions.
14 changes: 8 additions & 6 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ pcb2gcode_SOURCES = \
board.cpp \
bg_helpers.hpp \
bg_helpers.cpp \
bg_operators.hpp \
bg_operators.cpp \
common.hpp \
common.cpp \
drill.hpp \
Expand Down Expand Up @@ -77,19 +79,19 @@ check_PROGRAMS = voronoi_tests eulerian_paths_tests segmentize_tests tsp_solver_
available_drills_tests gerberimporter_tests options_tests path_finding_tests \
autoleveller_tests common_tests backtrack_tests trim_paths_tests
voronoi_tests_SOURCES = voronoi.hpp voronoi.cpp voronoi_tests.cpp boost_unit_test.cpp
eulerian_paths_tests_SOURCES = eulerian_paths_tests.cpp eulerian_paths.hpp geometry_int.hpp boost_unit_test.cpp bg_helpers.hpp bg_helpers.cpp eulerian_paths.cpp segmentize.cpp merge_near_points.cpp
segmentize_tests_SOURCES = segmentize_tests.cpp segmentize.cpp segmentize.hpp merge_near_points.cpp merge_near_points.hpp boost_unit_test.cpp bg_helpers.hpp bg_helpers.cpp eulerian_paths.cpp
path_finding_tests_SOURCES = path_finding_tests.cpp path_finding.cpp path_finding.hpp boost_unit_test.cpp bg_helpers.cpp bg_helpers.hpp eulerian_paths.cpp eulerian_paths.hpp segmentize.hpp segmentize.cpp merge_near_points.cpp merge_near_points.hpp
eulerian_paths_tests_SOURCES = eulerian_paths_tests.cpp eulerian_paths.hpp geometry_int.hpp boost_unit_test.cpp bg_operators.hpp bg_operators.cpp bg_helpers.hpp bg_helpers.cpp eulerian_paths.cpp segmentize.cpp merge_near_points.cpp
segmentize_tests_SOURCES = segmentize_tests.cpp segmentize.cpp segmentize.hpp merge_near_points.cpp merge_near_points.hpp boost_unit_test.cpp bg_helpers.hpp bg_helpers.cpp eulerian_paths.cpp bg_operators.hpp bg_operators.cpp
path_finding_tests_SOURCES = path_finding_tests.cpp path_finding.cpp path_finding.hpp boost_unit_test.cpp bg_helpers.cpp bg_helpers.hpp eulerian_paths.cpp eulerian_paths.hpp segmentize.hpp segmentize.cpp merge_near_points.cpp merge_near_points.hpp bg_operators.hpp bg_operators.cpp
tsp_solver_tests_SOURCES = tsp_solver_tests.cpp tsp_solver.hpp boost_unit_test.cpp
units_tests_SOURCES = units_tests.cpp units.hpp boost_unit_test.cpp
available_drills_tests_SOURCES = available_drills_tests.cpp available_drills.hpp boost_unit_test.cpp
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
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
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
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
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

TESTS = $(check_PROGRAMS)

Expand Down
2 changes: 1 addition & 1 deletion backtrack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <algorithm>

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

#include "backtrack.hpp"

Expand Down
1 change: 1 addition & 0 deletions backtrack_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <vector>

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

#include "backtrack.hpp"
Expand Down
269 changes: 16 additions & 253 deletions bg_helpers.cpp
Original file line number Diff line number Diff line change
@@ -1,159 +1,13 @@
#ifndef BG_HELPERS_H
#define BG_HELPERS_H

#include "eulerian_paths.hpp"
#ifdef GEOS_VERSION
#include <geos/io/WKTReader.h>
#include <geos/io/WKTWriter.h>
#include <geos/operation/buffer/BufferOp.h>
#endif // GEOS_VERSION

#include "geometry.hpp"
#include "geometry_int.hpp"
#include "eulerian_paths.hpp"

#include "bg_operators.hpp"
#include "bg_helpers.hpp"

template <typename polygon_type_t, typename rhs_t>
bg::model::multi_polygon<polygon_type_t> operator-(
const bg::model::multi_polygon<polygon_type_t>& lhs,
const rhs_t& rhs) {
if (bg::area(rhs) <= 0) {
return lhs;
}
bg::model::multi_polygon<polygon_type_t> ret;
bg::difference(lhs, rhs, ret);
return ret;
}

template multi_polygon_type_fp operator-(const multi_polygon_type_fp&, const multi_polygon_type_fp&);
template multi_polygon_type_fp operator-(const multi_polygon_type_fp&, const ring_type_fp&);

template <typename rhs_t>
multi_polygon_type_fp operator-(const polygon_type_fp& lhs, const rhs_t& rhs) {
if (bg::area(rhs) <= 0) {
auto ret = multi_polygon_type_fp();
ret.push_back(lhs);
return ret;
}
multi_polygon_type_fp ret;
bg::difference(lhs, rhs, ret);
return ret;
}

template multi_polygon_type_fp operator-(const polygon_type_fp&, const ring_type_fp&);

template <typename rhs_t>
multi_polygon_type_fp operator-(const box_type_fp& lhs, const rhs_t& rhs) {
auto box_mp = multi_polygon_type_fp();
bg::convert(lhs, box_mp);
return box_mp - rhs;
}

template multi_polygon_type_fp operator-(const box_type_fp&, const multi_polygon_type_fp&);

template <typename linestring_type_t, typename rhs_t>
bg::model::multi_linestring<linestring_type_t> operator-(
const bg::model::multi_linestring<linestring_type_t>& lhs,
const rhs_t& rhs) {
if (bg::area(rhs) <= 0) {
return lhs;
}
bg::model::multi_linestring<linestring_type_t> ret;
bg::difference(lhs, rhs, ret);
return ret;
}

template multi_linestring_type_fp operator-(const multi_linestring_type_fp&, const multi_polygon_type_fp&);

template <typename linestring_type_t, typename rhs_t>
bg::model::multi_linestring<linestring_type_t> operator&(
const bg::model::multi_linestring<linestring_type_t>& lhs,
const rhs_t& rhs) {
bg::model::multi_linestring<linestring_type_t> ret;
if (bg::area(rhs) <= 0) {
return ret;
}
if (bg::length(lhs) <= 0) {
return ret;
}
bg::intersection(lhs, rhs, ret);
return ret;
}

template multi_linestring_type_fp operator&(const multi_linestring_type_fp&, const multi_polygon_type_fp&);
template multi_linestring_type_fp operator&(const multi_linestring_type_fp&, const box_type_fp&);

template <typename rhs_t>
multi_linestring_type_fp operator&(const linestring_type_fp& lhs,
const rhs_t& rhs) {
multi_linestring_type_fp ret;
if (bg::area(rhs) <= 0) {
return ret;
}
if (bg::length(lhs) <= 0) {
return ret;
}
bg::intersection(lhs, rhs, ret);
return ret;
}

template multi_linestring_type_fp operator&(const linestring_type_fp&, const box_type_fp&);

template <typename polygon_type_t, typename rhs_t>
bg::model::multi_polygon<polygon_type_t> operator^(
const bg::model::multi_polygon<polygon_type_t>& lhs,
const rhs_t& rhs) {
if (bg::area(rhs) <= 0) {
return lhs;
}
if (bg::area(lhs) <= 0) {
return rhs;
}
bg::model::multi_polygon<polygon_type_t> ret;
bg::sym_difference(lhs, rhs, ret);
return ret;
}

template multi_polygon_type_fp operator^(const multi_polygon_type_fp&, const multi_polygon_type_fp&);

template <typename polygon_type_t, typename rhs_t>
bg::model::multi_polygon<polygon_type_t> operator&(const bg::model::multi_polygon<polygon_type_t>& lhs,
const rhs_t& rhs) {
bg::model::multi_polygon<polygon_type_t> ret;
if (bg::area(rhs) <= 0) {
return ret;
}
if (bg::area(lhs) <= 0) {
return ret;
}
bg::intersection(lhs, rhs, ret);
return ret;
}

template multi_polygon_type_fp operator&(const multi_polygon_type_fp&, const multi_polygon_type_fp&);
template multi_polygon_type_fp operator&(multi_polygon_type_fp const&, polygon_type_fp const&);
template multi_polygon_type_fp operator&(multi_polygon_type_fp const&, box_type_fp const&);

template <typename point_type_t, typename rhs_t>
multi_polygon_type_fp operator&(const bg::model::polygon<point_type_t>& lhs,
const rhs_t& rhs) {
multi_polygon_type_fp ret;
if (bg::area(rhs) <= 0) {
return ret;
}
if (bg::area(lhs) <= 0) {
return ret;
}
bg::intersection(lhs, rhs, ret);
return ret;
}

template multi_polygon_type_fp operator&(polygon_type_fp const&, multi_polygon_type_fp const&);

template <typename polygon_type_t, typename rhs_t>
bg::model::multi_polygon<polygon_type_t> operator+(const bg::model::multi_polygon<polygon_type_t>& lhs,
const rhs_t& rhs);
namespace bg_helpers {

// The below implementations of buffer are similar to bg::buffer but
Expand Down Expand Up @@ -231,6 +85,21 @@ multi_polygon_type_fp buffer(polygon_type_fp const & geometry_in, CoordinateType

template multi_polygon_type_fp buffer(polygon_type_fp const&, double);

template<typename CoordinateType>
multi_polygon_type_fp buffer(linestring_type_fp const & geometry_in, CoordinateType expand_by) {
if (expand_by == 0) {
return {};
}
multi_polygon_type_fp geometry_out;
bg::buffer(geometry_in, geometry_out,
bg::strategy::buffer::distance_symmetric<coordinate_type_fp>(expand_by),
bg::strategy::buffer::side_straight(),
bg::strategy::buffer::join_round(points_per_circle),
bg::strategy::buffer::end_round(points_per_circle),
bg::strategy::buffer::point_circle(points_per_circle));
return geometry_out;
}

template<typename CoordinateType>
void buffer(multi_linestring_type_fp const & geometry_in, multi_polygon_type_fp & geometry_out, CoordinateType expand_by) {
if (expand_by == 0) {
Expand Down Expand Up @@ -300,109 +169,3 @@ void buffer(ring_type_fp const & geometry_in, multi_polygon_type_fp & geometry_o
template void buffer(ring_type_fp const&, multi_polygon_type_fp&, double);

} // namespace bg_helpers

template <typename polygon_type_t, typename rhs_t>
bg::model::multi_polygon<polygon_type_t> operator+(const bg::model::multi_polygon<polygon_type_t>& lhs,
const rhs_t& rhs) {
if (bg::area(rhs) <= 0) {
return lhs;
}
if (bg::area(lhs) <= 0) {
bg::model::multi_polygon<polygon_type_t> ret;
bg::convert(rhs, ret);
return ret;
}
// This optimization fixes a bug in boost geometry when shapes are bordering
// somwhat but not overlapping. This is exposed by EasyEDA that makes lots of
// shapes like that.
const auto lhs_box = bg::return_envelope<box_type_fp>(lhs);
const auto rhs_box = bg::return_envelope<box_type_fp>(rhs);
if (lhs_box.max_corner().x() == rhs_box.min_corner().x() ||
rhs_box.max_corner().x() == lhs_box.min_corner().x() ||
lhs_box.max_corner().y() == rhs_box.min_corner().y() ||
rhs_box.max_corner().y() == lhs_box.min_corner().y()) {
multi_polygon_type_fp new_rhs;
bg::convert(rhs, new_rhs);
return bg_helpers::buffer(lhs, 0.00001) + bg_helpers::buffer(new_rhs, 0.00001);
}
bg::model::multi_polygon<polygon_type_t> ret;
bg::union_(lhs, rhs, ret);
return ret;
}

template multi_polygon_type_fp operator+(const multi_polygon_type_fp&, const multi_polygon_type_fp&);
template multi_polygon_type_fp operator+(const multi_polygon_type_fp&, const ring_type_fp&);

// It's not great to insert definitions into the bg namespace but they
// are useful for sorting and maps.

namespace boost { namespace geometry { namespace model { namespace d2 {

template <typename T>
bool operator<(
const boost::geometry::model::d2::point_xy<T>& x,
const boost::geometry::model::d2::point_xy<T>& y) {
return std::tie(x.x(), x.y()) < std::tie(y.x(), y.y());
}

template bool operator<(const point_type_fp&, const point_type_fp&);
template bool operator<(const ::point_type&, const ::point_type&);

template <typename T>
boost::geometry::model::d2::point_xy<T> operator-(
const boost::geometry::model::d2::point_xy<T>& lhs,
const boost::geometry::model::d2::point_xy<T>& rhs) {
return {lhs.x()-rhs.x(), lhs.y()-rhs.y()};
}

template point_type_fp operator-(const point_type_fp&, const point_type_fp&);

template <typename T>
boost::geometry::model::d2::point_xy<T> operator+(
const boost::geometry::model::d2::point_xy<T>& lhs,
const boost::geometry::model::d2::point_xy<T>& rhs) {
return {lhs.x()+rhs.x(), lhs.y()+rhs.y()};
}

template point_type_fp operator+(const point_type_fp&, const point_type_fp&);

template <typename T, typename S>
boost::geometry::model::d2::point_xy<T> operator/(
const boost::geometry::model::d2::point_xy<T>& lhs,
const S& rhs) {
return {lhs.x()/static_cast<T>(rhs), lhs.y()/static_cast<T>(rhs)};
}

template point_type_fp operator/(const point_type_fp&, const double&);
template point_type_fp operator/(const point_type_fp&, const int&);

template <typename T, typename S>
boost::geometry::model::d2::point_xy<T> operator*(
const boost::geometry::model::d2::point_xy<T>& lhs,
const S& rhs) {
return {lhs.x()*static_cast<T>(rhs), lhs.y()*static_cast<T>(rhs)};
}

template point_type_fp operator*(const point_type_fp&, const double&);

template <typename T>
bool operator==(
const boost::geometry::model::d2::point_xy<T>& x,
const boost::geometry::model::d2::point_xy<T>& y) {
return std::tie(x.x(), x.y()) == std::tie(y.x(), y.y());
}

template bool operator==<double>(const point_type_fp&, const point_type_fp&);

template <typename T>
bool operator!=(
const boost::geometry::model::d2::point_xy<T>& x,
const boost::geometry::model::d2::point_xy<T>& y) {
return std::tie(x.x(), x.y()) != std::tie(y.x(), y.y());
}

template bool operator!=<double>(const point_type_fp&, const point_type_fp&);

}}}} // namespace boost::geometry::model::d2

#endif //BG_HELPERS_H
Loading

0 comments on commit 9f0c3ba

Please sign in to comment.