New coverage detection for bridges. Includes implementation of ExPolygon::get_trapezoids()

This commit is contained in:
Alessandro Ranellucci 2014-04-24 13:43:24 +02:00
parent d458a7c4d2
commit 6201aacf88
21 changed files with 358 additions and 27 deletions

View file

@ -47,7 +47,7 @@ ExPolygon::translate(double x, double y)
}
void
ExPolygon::rotate(double angle, Point* center)
ExPolygon::rotate(double angle, const Point &center)
{
contour.rotate(angle, center);
for (Polygons::iterator it = holes.begin(); it != holes.end(); ++it) {
@ -158,6 +158,24 @@ ExPolygon::medial_axis(double max_width, double min_width, Polylines* polylines)
intersection(*polylines, *this, *polylines);
}
void
ExPolygon::get_trapezoids(Polygons* polygons) const
{
ExPolygons expp;
expp.push_back(*this);
boost::polygon::get_trapezoids(*polygons, expp);
}
void
ExPolygon::get_trapezoids(Polygons* polygons, double angle) const
{
ExPolygon clone = *this;
clone.rotate(PI/2 - angle, Point(0,0));
clone.get_trapezoids(polygons);
for (Polygons::iterator polygon = polygons->begin(); polygon != polygons->end(); ++polygon)
polygon->rotate(-(PI/2 - angle), Point(0,0));
}
#ifdef SLIC3RXS
SV*
ExPolygon::to_AV() {

View file

@ -18,7 +18,7 @@ class ExPolygon
operator Polygons() const;
void scale(double factor);
void translate(double x, double y);
void rotate(double angle, Point* center);
void rotate(double angle, const Point &center);
double area() const;
bool is_valid() const;
bool contains_line(const Line* line) const;
@ -27,6 +27,8 @@ class ExPolygon
ExPolygons simplify(double tolerance) const;
void simplify(double tolerance, ExPolygons &expolygons) const;
void medial_axis(double max_width, double min_width, Polylines* polylines) const;
void get_trapezoids(Polygons* polygons) const;
void get_trapezoids(Polygons* polygons, double angle) const;
#ifdef SLIC3RXS
void from_SV(SV* poly_sv);
@ -40,4 +42,108 @@ class ExPolygon
}
// start Boost
#include <boost/polygon/polygon.hpp>
namespace boost { namespace polygon {
template <>
struct polygon_traits<ExPolygon> {
typedef coord_t coordinate_type;
typedef Points::const_iterator iterator_type;
typedef Point point_type;
// Get the begin iterator
static inline iterator_type begin_points(const ExPolygon& t) {
return t.contour.points.begin();
}
// Get the end iterator
static inline iterator_type end_points(const ExPolygon& t) {
return t.contour.points.end();
}
// Get the number of sides of the polygon
static inline std::size_t size(const ExPolygon& t) {
return t.contour.points.size();
}
// Get the winding direction of the polygon
static inline winding_direction winding(const ExPolygon& t) {
return unknown_winding;
}
};
template <>
struct polygon_mutable_traits<ExPolygon> {
//expects stl style iterators
template <typename iT>
static inline ExPolygon& set_points(ExPolygon& expolygon, iT input_begin, iT input_end) {
expolygon.contour.points.assign(input_begin, input_end);
// skip last point since Boost will set last point = first point
expolygon.contour.points.pop_back();
return expolygon;
}
};
template <>
struct geometry_concept<ExPolygon> { typedef polygon_with_holes_concept type; };
template <>
struct polygon_with_holes_traits<ExPolygon> {
typedef Polygons::const_iterator iterator_holes_type;
typedef Polygon hole_type;
static inline iterator_holes_type begin_holes(const ExPolygon& t) {
return t.holes.begin();
}
static inline iterator_holes_type end_holes(const ExPolygon& t) {
return t.holes.end();
}
static inline unsigned int size_holes(const ExPolygon& t) {
return t.holes.size();
}
};
template <>
struct polygon_with_holes_mutable_traits<ExPolygon> {
template <typename iT>
static inline ExPolygon& set_holes(ExPolygon& t, iT inputBegin, iT inputEnd) {
t.holes.assign(inputBegin, inputEnd);
return t;
}
};
//first we register CPolygonSet as a polygon set
template <>
struct geometry_concept<ExPolygons> { typedef polygon_set_concept type; };
//next we map to the concept through traits
template <>
struct polygon_set_traits<ExPolygons> {
typedef coord_t coordinate_type;
typedef ExPolygons::const_iterator iterator_type;
typedef ExPolygons operator_arg_type;
static inline iterator_type begin(const ExPolygons& polygon_set) {
return polygon_set.begin();
}
static inline iterator_type end(const ExPolygons& polygon_set) {
return polygon_set.end();
}
//don't worry about these, just return false from them
static inline bool clean(const ExPolygons& polygon_set) { return false; }
static inline bool sorted(const ExPolygons& polygon_set) { return false; }
};
template <>
struct polygon_set_mutable_traits<ExPolygons> {
template <typename input_iterator_type>
static inline void set(ExPolygons& expolygons, input_iterator_type input_begin, input_iterator_type input_end) {
expolygons.assign(input_begin, input_end);
}
};
} }
// end Boost
#endif

View file

@ -32,7 +32,7 @@ ExPolygonCollection::translate(double x, double y)
}
void
ExPolygonCollection::rotate(double angle, Point* center)
ExPolygonCollection::rotate(double angle, const Point &center)
{
for (ExPolygons::iterator it = expolygons.begin(); it != expolygons.end(); ++it) {
(*it).rotate(angle, center);

View file

@ -13,7 +13,7 @@ class ExPolygonCollection
operator Polygons() const;
void scale(double factor);
void translate(double x, double y);
void rotate(double angle, Point* center);
void rotate(double angle, const Point &center);
bool contains_point(const Point* point) const;
void simplify(double tolerance);
void convex_hull(Polygon* hull) const;

View file

@ -38,7 +38,7 @@ Line::translate(double x, double y)
}
void
Line::rotate(double angle, Point* center)
Line::rotate(double angle, const Point &center)
{
this->a.rotate(angle, center);
this->b.rotate(angle, center);

View file

@ -3,7 +3,6 @@
#include <myinit.h>
#include "Point.hpp"
#include <boost/polygon/polygon.hpp>
namespace Slic3r {
@ -21,7 +20,7 @@ class Line
operator Polyline() const;
void scale(double factor);
void translate(double x, double y);
void rotate(double angle, Point* center);
void rotate(double angle, const Point &center);
void reverse();
double length() const;
Point* midpoint() const;
@ -48,6 +47,7 @@ typedef std::vector<Line> Lines;
}
// start Boost
#include <boost/polygon/polygon.hpp>
namespace boost { namespace polygon {
template <>
struct geometry_concept<Line> { typedef segment_concept type; };

View file

@ -19,7 +19,7 @@ MultiPoint::translate(double x, double y)
}
void
MultiPoint::rotate(double angle, Point* center)
MultiPoint::rotate(double angle, const Point &center)
{
for (Points::iterator it = points.begin(); it != points.end(); ++it) {
(*it).rotate(angle, center);

View file

@ -14,7 +14,7 @@ class MultiPoint
Points points;
void scale(double factor);
void translate(double x, double y);
void rotate(double angle, Point* center);
void rotate(double angle, const Point &center);
void reverse();
Point* first_point() const;
virtual Point* last_point() const = 0;

View file

@ -34,12 +34,12 @@ Point::translate(double x, double y)
}
void
Point::rotate(double angle, Point* center)
Point::rotate(double angle, const Point &center)
{
double cur_x = (double)this->x;
double cur_y = (double)this->y;
this->x = (coord_t)round( (double)center->x + cos(angle) * (cur_x - (double)center->x) - sin(angle) * (cur_y - (double)center->y) );
this->y = (coord_t)round( (double)center->y + cos(angle) * (cur_y - (double)center->y) + sin(angle) * (cur_x - (double)center->x) );
this->x = (coord_t)round( (double)center.x + cos(angle) * (cur_x - (double)center.x) - sin(angle) * (cur_y - (double)center.y) );
this->y = (coord_t)round( (double)center.y + cos(angle) * (cur_y - (double)center.y) + sin(angle) * (cur_x - (double)center.x) );
}
bool

View file

@ -4,7 +4,6 @@
#include <myinit.h>
#include <vector>
#include <math.h>
#include <boost/polygon/polygon.hpp>
#include <string>
namespace Slic3r {
@ -27,7 +26,7 @@ class Point
std::string wkt() const;
void scale(double factor);
void translate(double x, double y);
void rotate(double angle, Point* center);
void rotate(double angle, const Point &center);
bool coincides_with(const Point &point) const;
bool coincides_with(const Point* point) const;
int nearest_point_index(Points &points) const;
@ -83,7 +82,21 @@ class Pointf3 : public Pointf
}
// start Boost
#include <boost/polygon/polygon.hpp>
namespace boost { namespace polygon {
template <>
struct geometry_concept<coord_t> { typedef coordinate_concept type; };
template <>
struct coordinate_traits<coord_t> {
typedef coord_t coordinate_type;
typedef long double area_type;
typedef long long manhattan_area_type;
typedef unsigned long long unsigned_area_type;
typedef long long coordinate_difference;
typedef long double coordinate_distance;
};
template <>
struct geometry_concept<Point> { typedef point_concept type; };
@ -95,6 +108,23 @@ namespace boost { namespace polygon {
return (orient == HORIZONTAL) ? point.x : point.y;
}
};
template <>
struct point_mutable_traits<Point> {
typedef coord_t coordinate_type;
static inline void set(Point& point, orientation_2d orient, coord_t value) {
if (orient == HORIZONTAL)
point.x = value;
else
point.y = value;
}
static inline Point construct(coord_t x_value, coord_t y_value) {
Point retval;
retval.x = x_value;
retval.y = y_value;
return retval;
}
};
} }
// end Boost

View file

@ -41,4 +41,87 @@ class Polygon : public MultiPoint {
}
// start Boost
#include <boost/polygon/polygon.hpp>
namespace boost { namespace polygon {
template <>
struct geometry_concept<Polygon>{ typedef polygon_concept type; };
template <>
struct polygon_traits<Polygon> {
typedef coord_t coordinate_type;
typedef Points::const_iterator iterator_type;
typedef Point point_type;
// Get the begin iterator
static inline iterator_type begin_points(const Polygon& t) {
return t.points.begin();
}
// Get the end iterator
static inline iterator_type end_points(const Polygon& t) {
return t.points.end();
}
// Get the number of sides of the polygon
static inline std::size_t size(const Polygon& t) {
return t.points.size();
}
// Get the winding direction of the polygon
static inline winding_direction winding(const Polygon& t) {
return unknown_winding;
}
};
template <>
struct polygon_mutable_traits<Polygon> {
// expects stl style iterators
template <typename iT>
static inline Polygon& set_points(Polygon& polygon, iT input_begin, iT input_end) {
polygon.points.clear();
while (input_begin != input_end) {
polygon.points.push_back(Point());
boost::polygon::assign(polygon.points.back(), *input_begin);
++input_begin;
}
// skip last point since Boost will set last point = first point
polygon.points.pop_back();
return polygon;
}
};
template <>
struct geometry_concept<Polygons> { typedef polygon_set_concept type; };
//next we map to the concept through traits
template <>
struct polygon_set_traits<Polygons> {
typedef coord_t coordinate_type;
typedef Polygons::const_iterator iterator_type;
typedef Polygons operator_arg_type;
static inline iterator_type begin(const Polygons& polygon_set) {
return polygon_set.begin();
}
static inline iterator_type end(const Polygons& polygon_set) {
return polygon_set.end();
}
//don't worry about these, just return false from them
static inline bool clean(const Polygons& polygon_set) { return false; }
static inline bool sorted(const Polygons& polygon_set) { return false; }
};
template <>
struct polygon_set_mutable_traits<Polygons> {
template <typename input_iterator_type>
static inline void set(Polygons& polygons, input_iterator_type input_begin, input_iterator_type input_end) {
polygons.assign(input_begin, input_end);
}
};
} }
// end Boost
#endif