Refactored signatures of many C++ methods for more efficient and safer style. Includes a bugfix for Point::nearest_point() which was returning a pointer to freed memory. #1961

This commit is contained in:
Alessandro Ranellucci 2014-04-24 16:40:10 +02:00
parent 6201aacf88
commit ca4d4211c9
30 changed files with 203 additions and 161 deletions

View File

@ -76,10 +76,10 @@ ExPolygon::is_valid() const
} }
bool bool
ExPolygon::contains_line(const Line* line) const ExPolygon::contains_line(const Line &line) const
{ {
Polylines pl; Polylines pl;
pl.push_back(*line); pl.push_back(line);
Polylines pl_out; Polylines pl_out;
diff(pl, *this, pl_out); diff(pl, *this, pl_out);
@ -87,7 +87,7 @@ ExPolygon::contains_line(const Line* line) const
} }
bool bool
ExPolygon::contains_point(const Point* point) const ExPolygon::contains_point(const Point &point) const
{ {
if (!this->contour.contains_point(point)) return false; if (!this->contour.contains_point(point)) return false;
for (Polygons::const_iterator it = this->holes.begin(); it != this->holes.end(); ++it) { for (Polygons::const_iterator it = this->holes.begin(); it != this->holes.end(); ++it) {

View File

@ -21,8 +21,8 @@ class ExPolygon
void rotate(double angle, const Point &center); void rotate(double angle, const Point &center);
double area() const; double area() const;
bool is_valid() const; bool is_valid() const;
bool contains_line(const Line* line) const; bool contains_line(const Line &line) const;
bool contains_point(const Point* point) const; bool contains_point(const Point &point) const;
Polygons simplify_p(double tolerance) const; Polygons simplify_p(double tolerance) const;
ExPolygons simplify(double tolerance) const; ExPolygons simplify(double tolerance) const;
void simplify(double tolerance, ExPolygons &expolygons) const; void simplify(double tolerance, ExPolygons &expolygons) const;

View File

@ -40,7 +40,7 @@ ExPolygonCollection::rotate(double angle, const Point &center)
} }
bool bool
ExPolygonCollection::contains_point(const Point* point) const ExPolygonCollection::contains_point(const Point &point) const
{ {
for (ExPolygons::const_iterator it = this->expolygons.begin(); it != this->expolygons.end(); ++it) { for (ExPolygons::const_iterator it = this->expolygons.begin(); it != this->expolygons.end(); ++it) {
if (it->contains_point(point)) return true; if (it->contains_point(point)) return true;

View File

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

View File

@ -43,16 +43,16 @@ ExtrusionPath::reverse()
this->polyline.reverse(); this->polyline.reverse();
} }
Point* Point
ExtrusionPath::first_point() const ExtrusionPath::first_point() const
{ {
return new Point(this->polyline.points.front()); return this->polyline.points.front();
} }
Point* Point
ExtrusionPath::last_point() const ExtrusionPath::last_point() const
{ {
return new Point(this->polyline.points.back()); return this->polyline.points.back();
} }
void void
@ -200,16 +200,16 @@ ExtrusionLoop::reverse()
// no-op // no-op
} }
Point* Point
ExtrusionLoop::first_point() const ExtrusionLoop::first_point() const
{ {
return new Point(this->polygon.points.front()); return this->polygon.points.front();
} }
Point* Point
ExtrusionLoop::last_point() const ExtrusionLoop::last_point() const
{ {
return new Point(this->polygon.points.front()); // in polygons, first == last return this->polygon.points.front(); // in polygons, first == last
} }
} }

View File

@ -33,8 +33,8 @@ class ExtrusionEntity
ExtrusionRole role; ExtrusionRole role;
double mm3_per_mm; // mm^3 of plastic per mm of linear head motion double mm3_per_mm; // mm^3 of plastic per mm of linear head motion
virtual void reverse() = 0; virtual void reverse() = 0;
virtual Point* first_point() const = 0; virtual Point first_point() const = 0;
virtual Point* last_point() const = 0; virtual Point last_point() const = 0;
bool is_perimeter() const; bool is_perimeter() const;
bool is_fill() const; bool is_fill() const;
bool is_bridge() const; bool is_bridge() const;
@ -48,8 +48,8 @@ class ExtrusionPath : public ExtrusionEntity
ExtrusionPath* clone() const; ExtrusionPath* clone() const;
Polyline polyline; Polyline polyline;
void reverse(); void reverse();
Point* first_point() const; Point first_point() const;
Point* last_point() const; Point last_point() const;
void intersect_expolygons(const ExPolygonCollection &collection, ExtrusionEntityCollection* retval) const; void intersect_expolygons(const ExPolygonCollection &collection, ExtrusionEntityCollection* retval) const;
void subtract_expolygons(const ExPolygonCollection &collection, ExtrusionEntityCollection* retval) const; void subtract_expolygons(const ExPolygonCollection &collection, ExtrusionEntityCollection* retval) const;
void clip_end(double distance); void clip_end(double distance);
@ -75,8 +75,8 @@ class ExtrusionLoop : public ExtrusionEntity
ExtrusionPath* split_at_first_point() const; ExtrusionPath* split_at_first_point() const;
bool make_counter_clockwise(); bool make_counter_clockwise();
void reverse(); void reverse();
Point* first_point() const; Point first_point() const;
Point* last_point() const; Point last_point() const;
}; };
} }

View File

@ -1,16 +1,36 @@
#include "ExtrusionEntityCollection.hpp" #include "ExtrusionEntityCollection.hpp"
#include <algorithm>
#include <map> #include <map>
namespace Slic3r { namespace Slic3r {
ExtrusionEntityCollection::ExtrusionEntityCollection(const ExtrusionEntityCollection& collection)
: no_sort(collection.no_sort), orig_indices(collection.orig_indices)
{
this->entities.reserve(collection.entities.size());
for (ExtrusionEntitiesPtr::const_iterator it = collection.entities.begin(); it != collection.entities.end(); ++it)
this->entities.push_back((*it)->clone());
}
ExtrusionEntityCollection& ExtrusionEntityCollection::operator= (const ExtrusionEntityCollection &other)
{
ExtrusionEntityCollection tmp(other);
this->swap(tmp);
return *this;
}
void
ExtrusionEntityCollection::swap (ExtrusionEntityCollection &c)
{
std::swap(this->entities, c.entities);
std::swap(this->orig_indices, c.orig_indices);
std::swap(this->no_sort, c.no_sort);
}
ExtrusionEntityCollection* ExtrusionEntityCollection*
ExtrusionEntityCollection::clone() const ExtrusionEntityCollection::clone() const
{ {
ExtrusionEntityCollection* collection = new ExtrusionEntityCollection (*this); return new ExtrusionEntityCollection(*this);
for (ExtrusionEntitiesPtr::iterator it = collection->entities.begin(); it != collection->entities.end(); ++it) {
*it = (*it)->clone();
}
return collection;
} }
void void
@ -22,32 +42,32 @@ ExtrusionEntityCollection::reverse()
std::reverse(this->entities.begin(), this->entities.end()); std::reverse(this->entities.begin(), this->entities.end());
} }
Point* Point
ExtrusionEntityCollection::first_point() const ExtrusionEntityCollection::first_point() const
{ {
return this->entities.front()->first_point(); return this->entities.front()->first_point();
} }
Point* Point
ExtrusionEntityCollection::last_point() const ExtrusionEntityCollection::last_point() const
{ {
return this->entities.back()->last_point(); return this->entities.back()->last_point();
} }
ExtrusionEntityCollection* void
ExtrusionEntityCollection::chained_path(bool no_reverse, std::vector<size_t>* orig_indices) const ExtrusionEntityCollection::chained_path(ExtrusionEntityCollection* retval, bool no_reverse, std::vector<size_t>* orig_indices) const
{ {
if (this->entities.empty()) { if (this->entities.empty()) return;
return new ExtrusionEntityCollection (); this->chained_path_from(this->entities.front()->first_point(), retval, no_reverse, orig_indices);
}
return this->chained_path_from(this->entities.front()->first_point(), no_reverse, orig_indices);
} }
ExtrusionEntityCollection* void
ExtrusionEntityCollection::chained_path_from(Point* start_near, bool no_reverse, std::vector<size_t>* orig_indices) const ExtrusionEntityCollection::chained_path_from(Point start_near, ExtrusionEntityCollection* retval, bool no_reverse, std::vector<size_t>* orig_indices) const
{ {
if (this->no_sort) return this->clone(); if (this->no_sort) {
ExtrusionEntityCollection* retval = new ExtrusionEntityCollection; *retval = *this;
return;
}
retval->entities.reserve(this->entities.size()); retval->entities.reserve(this->entities.size());
retval->orig_indices.reserve(this->entities.size()); retval->orig_indices.reserve(this->entities.size());
@ -63,17 +83,17 @@ ExtrusionEntityCollection::chained_path_from(Point* start_near, bool no_reverse,
Points endpoints; Points endpoints;
for (ExtrusionEntitiesPtr::iterator it = my_paths.begin(); it != my_paths.end(); ++it) { for (ExtrusionEntitiesPtr::iterator it = my_paths.begin(); it != my_paths.end(); ++it) {
endpoints.push_back(*(*it)->first_point()); endpoints.push_back((*it)->first_point());
if (no_reverse) { if (no_reverse) {
endpoints.push_back(*(*it)->first_point()); endpoints.push_back((*it)->first_point());
} else { } else {
endpoints.push_back(*(*it)->last_point()); endpoints.push_back((*it)->last_point());
} }
} }
while (!my_paths.empty()) { while (!my_paths.empty()) {
// find nearest point // find nearest point
int start_index = start_near->nearest_point_index(endpoints); int start_index = start_near.nearest_point_index(endpoints);
int path_index = start_index/2; int path_index = start_index/2;
ExtrusionEntity* entity = my_paths.at(path_index); ExtrusionEntity* entity = my_paths.at(path_index);
if (start_index % 2 && !no_reverse) { if (start_index % 2 && !no_reverse) {
@ -85,8 +105,6 @@ ExtrusionEntityCollection::chained_path_from(Point* start_near, bool no_reverse,
endpoints.erase(endpoints.begin() + 2*path_index, endpoints.begin() + 2*path_index + 2); endpoints.erase(endpoints.begin() + 2*path_index, endpoints.begin() + 2*path_index + 2);
start_near = retval->entities.back()->last_point(); start_near = retval->entities.back()->last_point();
} }
return retval;
} }
} }

View File

@ -14,11 +14,14 @@ class ExtrusionEntityCollection : public ExtrusionEntity
std::vector<size_t> orig_indices; // handy for XS std::vector<size_t> orig_indices; // handy for XS
bool no_sort; bool no_sort;
ExtrusionEntityCollection(): no_sort(false) {}; ExtrusionEntityCollection(): no_sort(false) {};
ExtrusionEntityCollection* chained_path(bool no_reverse, std::vector<size_t>* orig_indices = NULL) const; ExtrusionEntityCollection(const ExtrusionEntityCollection &collection);
ExtrusionEntityCollection* chained_path_from(Point* start_near, bool no_reverse, std::vector<size_t>* orig_indices = NULL) const; ExtrusionEntityCollection& operator= (const ExtrusionEntityCollection &other);
void swap (ExtrusionEntityCollection &c);
void chained_path(ExtrusionEntityCollection* retval, bool no_reverse = false, std::vector<size_t>* orig_indices = NULL) const;
void chained_path_from(Point start_near, ExtrusionEntityCollection* retval, bool no_reverse = false, std::vector<size_t>* orig_indices = NULL) const;
void reverse(); void reverse();
Point* first_point() const; Point first_point() const;
Point* last_point() const; Point last_point() const;
}; };
} }

View File

@ -53,7 +53,7 @@ Line::reverse()
double double
Line::length() const Line::length() const
{ {
return this->a.distance_to(&(this->b)); return this->a.distance_to(this->b);
} }
Point* Point*
@ -82,15 +82,15 @@ Line::point_at(double distance) const
} }
bool bool
Line::coincides_with(const Line* line) const Line::coincides_with(const Line &line) const
{ {
return this->a.coincides_with(&line->a) && this->b.coincides_with(&line->b); return this->a.coincides_with(line.a) && this->b.coincides_with(line.b);
} }
double double
Line::distance_to(const Point* point) const Line::distance_to(const Point &point) const
{ {
return point->distance_to(this); return point.distance_to(*this);
} }
double double

View File

@ -26,8 +26,8 @@ class Line
Point* midpoint() const; Point* midpoint() const;
void point_at(double distance, Point* point) const; void point_at(double distance, Point* point) const;
Point point_at(double distance) const; Point point_at(double distance) const;
bool coincides_with(const Line* line) const; bool coincides_with(const Line &line) const;
double distance_to(const Point* point) const; double distance_to(const Point &point) const;
double atan2_() const; double atan2_() const;
double direction() const; double direction() const;
Vector vector() const; Vector vector() const;

View File

@ -32,10 +32,10 @@ MultiPoint::reverse()
std::reverse(this->points.begin(), this->points.end()); std::reverse(this->points.begin(), this->points.end());
} }
Point* Point
MultiPoint::first_point() const MultiPoint::first_point() const
{ {
return new Point(this->points.front()); return this->points.front();
} }
double double

View File

@ -16,8 +16,8 @@ class MultiPoint
void translate(double x, double y); void translate(double x, double y);
void rotate(double angle, const Point &center); void rotate(double angle, const Point &center);
void reverse(); void reverse();
Point* first_point() const; Point first_point() const;
virtual Point* last_point() const = 0; virtual Point last_point() const = 0;
virtual Lines lines() const = 0; virtual Lines lines() const = 0;
double length() const; double length() const;
bool is_valid() const; bool is_valid() const;

View File

@ -42,12 +42,6 @@ Point::rotate(double angle, const Point &center)
this->y = (coord_t)round( (double)center.y + cos(angle) * (cur_y - (double)center.y) + sin(angle) * (cur_x - (double)center.x) ); this->y = (coord_t)round( (double)center.y + cos(angle) * (cur_y - (double)center.y) + sin(angle) * (cur_x - (double)center.x) );
} }
bool
Point::coincides_with(const Point* point) const
{
return this->coincides_with(*point);
}
bool bool
Point::coincides_with(const Point &point) const Point::coincides_with(const Point &point) const
{ {
@ -55,22 +49,22 @@ Point::coincides_with(const Point &point) const
} }
int int
Point::nearest_point_index(Points &points) const Point::nearest_point_index(const Points &points) const
{ {
PointPtrs p; PointConstPtrs p;
p.reserve(points.size()); p.reserve(points.size());
for (Points::iterator it = points.begin(); it != points.end(); ++it) for (Points::const_iterator it = points.begin(); it != points.end(); ++it)
p.push_back(&*it); p.push_back(&*it);
return this->nearest_point_index(p); return this->nearest_point_index(p);
} }
int int
Point::nearest_point_index(PointPtrs &points) const Point::nearest_point_index(const PointConstPtrs &points) const
{ {
int idx = -1; int idx = -1;
double distance = -1; // double because long is limited to 2147483647 on some platforms and it's not enough double distance = -1; // double because long is limited to 2147483647 on some platforms and it's not enough
for (PointPtrs::const_iterator it = points.begin(); it != points.end(); ++it) { for (PointConstPtrs::const_iterator it = points.begin(); it != points.end(); ++it) {
/* If the X distance of the candidate is > than the total distance of the /* If the X distance of the candidate is > than the total distance of the
best previous candidate, we know we don't want it */ best previous candidate, we know we don't want it */
double d = pow(this->x - (*it)->x, 2); double d = pow(this->x - (*it)->x, 2);
@ -90,30 +84,34 @@ Point::nearest_point_index(PointPtrs &points) const
return idx; return idx;
} }
Point* int
Point::nearest_point(Points points) const Point::nearest_point_index(const PointPtrs &points) const
{ {
return &(points.at(this->nearest_point_index(points))); PointConstPtrs p;
p.reserve(points.size());
for (PointPtrs::const_iterator it = points.begin(); it != points.end(); ++it)
p.push_back(*it);
return this->nearest_point_index(p);
}
void
Point::nearest_point(const Points &points, Point* point) const
{
*point = points.at(this->nearest_point_index(points));
} }
double double
Point::distance_to(const Point* point) const Point::distance_to(const Point &point) const
{ {
double dx = ((double)point->x - this->x); double dx = ((double)point.x - this->x);
double dy = ((double)point->y - this->y); double dy = ((double)point.y - this->y);
return sqrt(dx*dx + dy*dy); return sqrt(dx*dx + dy*dy);
} }
double
Point::distance_to(const Line* line) const
{
return this->distance_to(*line);
}
double double
Point::distance_to(const Line &line) const Point::distance_to(const Line &line) const
{ {
if (line.a.coincides_with(&line.b)) return this->distance_to(&line.a); if (line.a.coincides_with(line.b)) return this->distance_to(line.a);
double n = (double)(line.b.x - line.a.x) * (double)(line.a.y - this->y) double n = (double)(line.b.x - line.a.x) * (double)(line.a.y - this->y)
- (double)(line.a.x - this->x) * (double)(line.b.y - line.a.y); - (double)(line.a.x - this->x) * (double)(line.b.y - line.a.y);
@ -134,12 +132,6 @@ Point::ccw(const Point &p1, const Point &p2) const
return (double)(p2.x - p1.x)*(double)(this->y - p1.y) - (double)(p2.y - p1.y)*(double)(this->x - p1.x); return (double)(p2.x - p1.x)*(double)(this->y - p1.y) - (double)(p2.y - p1.y)*(double)(this->x - p1.x);
} }
double
Point::ccw(const Point* p1, const Point* p2) const
{
return this->ccw(*p1, *p2);
}
double double
Point::ccw(const Line &line) const Point::ccw(const Line &line) const
{ {

View File

@ -14,6 +14,7 @@ class Pointf;
typedef Point Vector; typedef Point Vector;
typedef std::vector<Point> Points; typedef std::vector<Point> Points;
typedef std::vector<Point*> PointPtrs; typedef std::vector<Point*> PointPtrs;
typedef std::vector<const Point*> PointConstPtrs;
typedef std::vector<Pointf> Pointfs; typedef std::vector<Pointf> Pointfs;
class Point class Point
@ -28,15 +29,13 @@ class Point
void translate(double x, double y); void translate(double x, double y);
void rotate(double angle, const Point &center); void rotate(double angle, const Point &center);
bool coincides_with(const Point &point) const; bool coincides_with(const Point &point) const;
bool coincides_with(const Point* point) const; int nearest_point_index(const Points &points) const;
int nearest_point_index(Points &points) const; int nearest_point_index(const PointConstPtrs &points) const;
int nearest_point_index(PointPtrs &points) const; int nearest_point_index(const PointPtrs &points) const;
Point* nearest_point(Points points) const; void nearest_point(const Points &points, Point* point) const;
double distance_to(const Point* point) const; double distance_to(const Point &point) const;
double distance_to(const Line* line) const;
double distance_to(const Line &line) const; double distance_to(const Line &line) const;
double ccw(const Point &p1, const Point &p2) const; double ccw(const Point &p1, const Point &p2) const;
double ccw(const Point* p1, const Point* p2) const;
double ccw(const Line &line) const; double ccw(const Line &line) const;
#ifdef SLIC3RXS #ifdef SLIC3RXS

View File

@ -12,10 +12,10 @@ Polygon::operator Polygons() const
return pp; return pp;
} }
Point* Point
Polygon::last_point() const Polygon::last_point() const
{ {
return new Point(this->points.front()); // last point == first point for polygons return this->points.front(); // last point == first point for polygons
} }
Lines Lines
@ -37,7 +37,7 @@ Polygon::lines(Lines* lines) const
} }
Polyline* Polyline*
Polygon::split_at(const Point* point) const Polygon::split_at(const Point &point) const
{ {
// find index of point // find index of point
for (Points::const_iterator it = this->points.begin(); it != this->points.end(); ++it) { for (Points::const_iterator it = this->points.begin(); it != this->points.end(); ++it) {
@ -124,15 +124,15 @@ Polygon::is_valid() const
} }
bool bool
Polygon::contains_point(const Point* point) const Polygon::contains_point(const Point &point) const
{ {
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
bool result = false; bool result = false;
Points::const_iterator i = this->points.begin(); Points::const_iterator i = this->points.begin();
Points::const_iterator j = this->points.end() - 1; Points::const_iterator j = this->points.end() - 1;
for (; i != this->points.end(); j = i++) { for (; i != this->points.end(); j = i++) {
if ( ((i->y > point->y) != (j->y > point->y)) if ( ((i->y > point.y) != (j->y > point.y))
&& (point->x < (j->x - i->x) * (point->y - i->y) / (j->y - i->y) + i->x) ) && (point.x < (j->x - i->x) * (point.y - i->y) / (j->y - i->y) + i->x) )
result = !result; result = !result;
} }
return result; return result;

View File

@ -15,10 +15,10 @@ typedef std::vector<Polygon> Polygons;
class Polygon : public MultiPoint { class Polygon : public MultiPoint {
public: public:
operator Polygons() const; operator Polygons() const;
Point* last_point() const; Point last_point() const;
Lines lines() const; Lines lines() const;
void lines(Lines* lines) const; void lines(Lines* lines) const;
Polyline* split_at(const Point* point) const; Polyline* split_at(const Point &point) const;
Polyline* split_at_index(int index) const; Polyline* split_at_index(int index) const;
Polyline* split_at_first_point() const; Polyline* split_at_first_point() const;
Points equally_spaced_points(double distance) const; Points equally_spaced_points(double distance) const;
@ -28,7 +28,7 @@ class Polygon : public MultiPoint {
bool make_counter_clockwise(); bool make_counter_clockwise();
bool make_clockwise(); bool make_clockwise();
bool is_valid() const; bool is_valid() const;
bool contains_point(const Point* point) const; bool contains_point(const Point &point) const;
Polygons simplify(double tolerance) const; Polygons simplify(double tolerance) const;
void simplify(double tolerance, Polygons &polygons) const; void simplify(double tolerance, Polygons &polygons) const;

View File

@ -10,10 +10,20 @@ Polyline::operator Polylines() const
return polylines; return polylines;
} }
Point* Point
Polyline::last_point() const Polyline::last_point() const
{ {
return new Point(this->points.back()); return this->points.back();
}
Point
Polyline::leftmost_point() const
{
Point p = this->points.front();
for (Points::const_iterator it = this->points.begin() + 1; it != this->points.end(); ++it) {
if (it->x < p.x) p = *it;
}
return p;
} }
Lines Lines
@ -32,7 +42,7 @@ void
Polyline::clip_end(double distance) Polyline::clip_end(double distance)
{ {
while (distance > 0) { while (distance > 0) {
Point last_point = *this->last_point(); Point last_point = this->last_point();
this->points.pop_back(); this->points.pop_back();
if (this->points.empty()) break; if (this->points.empty()) break;
@ -42,7 +52,7 @@ Polyline::clip_end(double distance)
continue; continue;
} }
Line segment(last_point, *this->last_point()); Line segment(last_point, this->last_point());
this->points.push_back(segment.point_at(distance)); this->points.push_back(segment.point_at(distance));
distance = 0; distance = 0;
} }
@ -80,11 +90,11 @@ Points
Polyline::equally_spaced_points(double distance) const Polyline::equally_spaced_points(double distance) const
{ {
Points pts; Points pts;
pts.push_back(*this->first_point()); pts.push_back(this->first_point());
double len = 0; double len = 0;
for (Points::const_iterator it = this->points.begin() + 1; it != this->points.end(); ++it) { for (Points::const_iterator it = this->points.begin() + 1; it != this->points.end(); ++it) {
double segment_length = it->distance_to(&*(it-1)); double segment_length = it->distance_to(*(it-1));
len += segment_length; len += segment_length;
if (len < distance) continue; if (len < distance) continue;

View File

@ -12,7 +12,8 @@ typedef std::vector<Polyline> Polylines;
class Polyline : public MultiPoint { class Polyline : public MultiPoint {
public: public:
operator Polylines() const; operator Polylines() const;
Point* last_point() const; Point last_point() const;
Point leftmost_point() const;
Lines lines() const; Lines lines() const;
void clip_end(double distance); void clip_end(double distance);
void clip_start(double distance); void clip_start(double distance);

View File

@ -2,32 +2,31 @@
namespace Slic3r { namespace Slic3r {
PolylineCollection* void
PolylineCollection::chained_path(bool no_reverse) const PolylineCollection::chained_path(PolylineCollection* retval, bool no_reverse) const
{ {
if (this->polylines.empty()) return new PolylineCollection (); if (this->polylines.empty()) return;
return this->chained_path_from(this->polylines.front().first_point(), no_reverse); this->chained_path_from(this->polylines.front().first_point(), retval, no_reverse);
} }
PolylineCollection* void
PolylineCollection::chained_path_from(const Point* start_near, bool no_reverse) const PolylineCollection::chained_path_from(Point start_near, PolylineCollection* retval, bool no_reverse) const
{ {
PolylineCollection* retval = new PolylineCollection;
Polylines my_paths = this->polylines; Polylines my_paths = this->polylines;
Points endpoints; Points endpoints;
for (Polylines::const_iterator it = my_paths.begin(); it != my_paths.end(); ++it) { for (Polylines::const_iterator it = my_paths.begin(); it != my_paths.end(); ++it) {
endpoints.push_back(*(*it).first_point()); endpoints.push_back(it->first_point());
if (no_reverse) { if (no_reverse) {
endpoints.push_back(*(*it).first_point()); endpoints.push_back(it->first_point());
} else { } else {
endpoints.push_back(*(*it).last_point()); endpoints.push_back(it->last_point());
} }
} }
while (!my_paths.empty()) { while (!my_paths.empty()) {
// find nearest point // find nearest point
int start_index = start_near->nearest_point_index(endpoints); int start_index = start_near.nearest_point_index(endpoints);
int path_index = start_index/2; int path_index = start_index/2;
if (start_index % 2 && !no_reverse) { if (start_index % 2 && !no_reverse) {
my_paths.at(path_index).reverse(); my_paths.at(path_index).reverse();
@ -37,20 +36,18 @@ PolylineCollection::chained_path_from(const Point* start_near, bool no_reverse)
endpoints.erase(endpoints.begin() + 2*path_index, endpoints.begin() + 2*path_index + 2); endpoints.erase(endpoints.begin() + 2*path_index, endpoints.begin() + 2*path_index + 2);
start_near = retval->polylines.back().last_point(); start_near = retval->polylines.back().last_point();
} }
return retval;
} }
Point* Point
PolylineCollection::leftmost_point() const PolylineCollection::leftmost_point() const
{ {
const Point* p = NULL; if (this->polylines.empty()) CONFESS("leftmost_point() called on empty PolylineCollection");
for (Polylines::const_iterator it = this->polylines.begin(); it != this->polylines.end(); ++it) { Point p = this->polylines.front().leftmost_point();
if (p == NULL || it->points.front().x < p->x) for (Polylines::const_iterator it = this->polylines.begin() + 1; it != this->polylines.end(); ++it) {
p = &(it->points.front()); Point p2 = it->leftmost_point();
if (p2.x < p.x) p = p2;
} }
if (p == NULL) return NULL; return p;
return new Point (*p);
} }
} }

View File

@ -10,9 +10,9 @@ class PolylineCollection
{ {
public: public:
Polylines polylines; Polylines polylines;
PolylineCollection* chained_path(bool no_reverse = false) const; void chained_path(PolylineCollection* retval, bool no_reverse = false) const;
PolylineCollection* chained_path_from(const Point* start_near, bool no_reverse = false) const; void chained_path_from(Point start_near, PolylineCollection* retval, bool no_reverse = false) const;
Point* leftmost_point() const; Point leftmost_point() const;
}; };
} }

View File

@ -21,8 +21,10 @@
void translate(double x, double y); void translate(double x, double y);
double area(); double area();
bool is_valid(); bool is_valid();
bool contains_line(Line* line); bool contains_line(Line* line)
bool contains_point(Point* point); %code{% RETVAL = THIS->contains_line(*line); %};
bool contains_point(Point* point)
%code{% RETVAL = THIS->contains_point(*point); %};
ExPolygons simplify(double tolerance); ExPolygons simplify(double tolerance);
Polygons simplify_p(double tolerance); Polygons simplify_p(double tolerance);
Polylines medial_axis(double max_width, double min_width) Polylines medial_axis(double max_width, double min_width)

View File

@ -17,7 +17,8 @@
%code{% THIS->rotate(angle, *center); %}; %code{% THIS->rotate(angle, *center); %};
int count() int count()
%code{% RETVAL = THIS->expolygons.size(); %}; %code{% RETVAL = THIS->expolygons.size(); %};
bool contains_point(Point* point); bool contains_point(Point* point)
%code{% RETVAL = THIS->contains_point(*point); %};
void simplify(double tolerance); void simplify(double tolerance);
%{ %{

View File

@ -11,13 +11,21 @@
void clear() void clear()
%code{% THIS->entities.clear(); %}; %code{% THIS->entities.clear(); %};
ExtrusionEntityCollection* chained_path(bool no_reverse) ExtrusionEntityCollection* chained_path(bool no_reverse)
%code{% const char* CLASS = "Slic3r::ExtrusionPath::Collection"; RETVAL = THIS->chained_path(no_reverse); %}; %code{%
const char* CLASS = "Slic3r::ExtrusionPath::Collection";
RETVAL = new ExtrusionEntityCollection();
THIS->chained_path(RETVAL, no_reverse);
%};
ExtrusionEntityCollection* chained_path_from(Point* start_near, bool no_reverse) ExtrusionEntityCollection* chained_path_from(Point* start_near, bool no_reverse)
%code{% const char* CLASS = "Slic3r::ExtrusionPath::Collection"; RETVAL = THIS->chained_path_from(start_near, no_reverse); %}; %code{%
const char* CLASS = "Slic3r::ExtrusionPath::Collection";
RETVAL = new ExtrusionEntityCollection();
THIS->chained_path_from(*start_near, RETVAL, no_reverse);
%};
Point* first_point() Point* first_point()
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->first_point(); %}; %code{% const char* CLASS = "Slic3r::Point"; RETVAL = new Point(THIS->first_point()); %};
Point* last_point() Point* last_point()
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->last_point(); %}; %code{% const char* CLASS = "Slic3r::Point"; RETVAL = new Point(THIS->last_point()); %};
int count() int count()
%code{% RETVAL = THIS->entities.size(); %}; %code{% RETVAL = THIS->entities.size(); %};
std::vector<size_t> orig_indices() std::vector<size_t> orig_indices()
@ -84,9 +92,9 @@ ExtrusionEntityCollection::chained_path_indices(bool no_reverse)
PREINIT: PREINIT:
const char* CLASS = "Slic3r::ExtrusionPath::Collection"; const char* CLASS = "Slic3r::ExtrusionPath::Collection";
CODE: CODE:
RETVAL = new ExtrusionEntityCollection();
std::vector<size_t> indices; std::vector<size_t> indices;
RETVAL = THIS->chained_path(no_reverse, &indices); THIS->chained_path(RETVAL, no_reverse, &RETVAL->orig_indices);
RETVAL->orig_indices = indices;
OUTPUT: OUTPUT:
RETVAL RETVAL

View File

@ -19,9 +19,9 @@
%code{% const char* CLASS = "Slic3r::ExtrusionPath"; RETVAL = THIS->split_at_first_point(); %}; %code{% const char* CLASS = "Slic3r::ExtrusionPath"; RETVAL = THIS->split_at_first_point(); %};
bool make_counter_clockwise(); bool make_counter_clockwise();
Point* first_point() Point* first_point()
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->first_point(); %}; %code{% const char* CLASS = "Slic3r::Point"; RETVAL = new Point(THIS->first_point()); %};
Point* last_point() Point* last_point()
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->last_point(); %}; %code{% const char* CLASS = "Slic3r::Point"; RETVAL = new Point(THIS->last_point()); %};
bool is_perimeter(); bool is_perimeter();
bool is_fill(); bool is_fill();
bool is_bridge(); bool is_bridge();

View File

@ -18,9 +18,9 @@
Lines lines() Lines lines()
%code{% RETVAL = THIS->polyline.lines(); %}; %code{% RETVAL = THIS->polyline.lines(); %};
Point* first_point() Point* first_point()
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->first_point(); %}; %code{% const char* CLASS = "Slic3r::Point"; RETVAL = new Point(THIS->first_point()); %};
Point* last_point() Point* last_point()
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->last_point(); %}; %code{% const char* CLASS = "Slic3r::Point"; RETVAL = new Point(THIS->last_point()); %};
void clip_end(double distance); void clip_end(double distance);
void simplify(double tolerance); void simplify(double tolerance);
double length(); double length();

View File

@ -56,7 +56,7 @@ Line::coincides_with(line_sv)
CODE: CODE:
Line line; Line line;
line.from_SV_check(line_sv); line.from_SV_check(line_sv);
RETVAL = THIS->coincides_with(&line); RETVAL = THIS->coincides_with(line);
OUTPUT: OUTPUT:
RETVAL RETVAL

View File

@ -22,9 +22,11 @@
%code{% RETVAL = THIS->y; %}; %code{% RETVAL = THIS->y; %};
int nearest_point_index(Points points); int nearest_point_index(Points points);
Point* nearest_point(Points points) Point* nearest_point(Points points)
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = new Point(*(THIS->nearest_point(points))); %}; %code{% const char* CLASS = "Slic3r::Point"; RETVAL = new Point(); THIS->nearest_point(points, RETVAL); %};
double distance_to(Point* point); double distance_to(Point* point)
%name{distance_to_line} double distance_to(Line* line); %code{% RETVAL = THIS->distance_to(*point); %};
double distance_to_line(Line* line)
%code{% RETVAL = THIS->distance_to(*line); %};
double ccw(Point* p1, Point* p2) double ccw(Point* p1, Point* p2)
%code{% RETVAL = THIS->ccw(*p1, *p2); %}; %code{% RETVAL = THIS->ccw(*p1, *p2); %};
@ -45,7 +47,7 @@ Point::coincides_with(point_sv)
CODE: CODE:
Point point; Point point;
point.from_SV_check(point_sv); point.from_SV_check(point_sv);
RETVAL = THIS->coincides_with(&point); RETVAL = THIS->coincides_with(point);
OUTPUT: OUTPUT:
RETVAL RETVAL

View File

@ -18,7 +18,7 @@
void reverse(); void reverse();
Lines lines(); Lines lines();
Polyline* split_at(Point* point) Polyline* split_at(Point* point)
%code{% const char* CLASS = "Slic3r::Polyline"; RETVAL = THIS->split_at(point); %}; %code{% const char* CLASS = "Slic3r::Polyline"; RETVAL = THIS->split_at(*point); %};
Polyline* split_at_index(int index) Polyline* split_at_index(int index)
%code{% const char* CLASS = "Slic3r::Polyline"; RETVAL = THIS->split_at_index(index); %}; %code{% const char* CLASS = "Slic3r::Polyline"; RETVAL = THIS->split_at_index(index); %};
Polyline* split_at_first_point() Polyline* split_at_first_point()
@ -32,8 +32,9 @@
bool make_clockwise(); bool make_clockwise();
bool is_valid(); bool is_valid();
Point* first_point() Point* first_point()
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->first_point(); %}; %code{% const char* CLASS = "Slic3r::Point"; RETVAL = new Point(THIS->first_point()); %};
bool contains_point(Point* point); bool contains_point(Point* point)
%code{% RETVAL = THIS->contains_point(*point); %};
Polygons simplify(double tolerance); Polygons simplify(double tolerance);
%{ %{

View File

@ -21,9 +21,9 @@
void reverse(); void reverse();
Lines lines(); Lines lines();
Point* first_point() Point* first_point()
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->first_point(); %}; %code{% const char* CLASS = "Slic3r::Point"; RETVAL = new Point(THIS->first_point()); %};
Point* last_point() Point* last_point()
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->last_point(); %}; %code{% const char* CLASS = "Slic3r::Point"; RETVAL = new Point(THIS->last_point()); %};
Points equally_spaced_points(double distance); Points equally_spaced_points(double distance);
double length(); double length();
bool is_valid(); bool is_valid();

View File

@ -12,13 +12,21 @@
void clear() void clear()
%code{% THIS->polylines.clear(); %}; %code{% THIS->polylines.clear(); %};
PolylineCollection* chained_path(bool no_reverse) PolylineCollection* chained_path(bool no_reverse)
%code{% const char* CLASS = "Slic3r::Polyline::Collection"; RETVAL = THIS->chained_path(no_reverse); %}; %code{%
const char* CLASS = "Slic3r::Polyline::Collection";
RETVAL = new PolylineCollection();
THIS->chained_path(RETVAL, no_reverse);
%};
PolylineCollection* chained_path_from(Point* start_near, bool no_reverse) PolylineCollection* chained_path_from(Point* start_near, bool no_reverse)
%code{% const char* CLASS = "Slic3r::Polyline::Collection"; RETVAL = THIS->chained_path_from(start_near, no_reverse); %}; %code{%
const char* CLASS = "Slic3r::Polyline::Collection";
RETVAL = new PolylineCollection();
THIS->chained_path_from(*start_near, RETVAL, no_reverse);
%};
int count() int count()
%code{% RETVAL = THIS->polylines.size(); %}; %code{% RETVAL = THIS->polylines.size(); %};
Point* leftmost_point() Point* leftmost_point()
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->leftmost_point(); %}; %code{% const char* CLASS = "Slic3r::Point"; RETVAL = new Point(THIS->leftmost_point()); %};
%{ %{
PolylineCollection* PolylineCollection*