From ca4d4211c9bb84fe63647283d11ad8d22d792053 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Thu, 24 Apr 2014 16:40:10 +0200 Subject: [PATCH] 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 --- xs/src/ExPolygon.cpp | 6 +-- xs/src/ExPolygon.hpp | 4 +- xs/src/ExPolygonCollection.cpp | 2 +- xs/src/ExPolygonCollection.hpp | 2 +- xs/src/ExtrusionEntity.cpp | 16 +++---- xs/src/ExtrusionEntity.hpp | 12 +++--- xs/src/ExtrusionEntityCollection.cpp | 64 ++++++++++++++++++---------- xs/src/ExtrusionEntityCollection.hpp | 11 +++-- xs/src/Line.cpp | 10 ++--- xs/src/Line.hpp | 4 +- xs/src/MultiPoint.cpp | 4 +- xs/src/MultiPoint.hpp | 4 +- xs/src/Point.cpp | 52 ++++++++++------------ xs/src/Point.hpp | 13 +++--- xs/src/Polygon.cpp | 12 +++--- xs/src/Polygon.hpp | 6 +-- xs/src/Polyline.cpp | 22 +++++++--- xs/src/Polyline.hpp | 3 +- xs/src/PolylineCollection.cpp | 37 ++++++++-------- xs/src/PolylineCollection.hpp | 6 +-- xs/xsp/ExPolygon.xsp | 6 ++- xs/xsp/ExPolygonCollection.xsp | 3 +- xs/xsp/ExtrusionEntityCollection.xsp | 20 ++++++--- xs/xsp/ExtrusionLoop.xsp | 4 +- xs/xsp/ExtrusionPath.xsp | 4 +- xs/xsp/Line.xsp | 2 +- xs/xsp/Point.xsp | 10 +++-- xs/xsp/Polygon.xsp | 7 +-- xs/xsp/Polyline.xsp | 4 +- xs/xsp/PolylineCollection.xsp | 14 ++++-- 30 files changed, 203 insertions(+), 161 deletions(-) diff --git a/xs/src/ExPolygon.cpp b/xs/src/ExPolygon.cpp index 0bbaf7c0f..774c023ef 100644 --- a/xs/src/ExPolygon.cpp +++ b/xs/src/ExPolygon.cpp @@ -76,10 +76,10 @@ ExPolygon::is_valid() const } bool -ExPolygon::contains_line(const Line* line) const +ExPolygon::contains_line(const Line &line) const { Polylines pl; - pl.push_back(*line); + pl.push_back(line); Polylines pl_out; diff(pl, *this, pl_out); @@ -87,7 +87,7 @@ ExPolygon::contains_line(const Line* line) const } bool -ExPolygon::contains_point(const Point* point) const +ExPolygon::contains_point(const Point &point) const { if (!this->contour.contains_point(point)) return false; for (Polygons::const_iterator it = this->holes.begin(); it != this->holes.end(); ++it) { diff --git a/xs/src/ExPolygon.hpp b/xs/src/ExPolygon.hpp index 9b1017cf4..2eefc73c5 100644 --- a/xs/src/ExPolygon.hpp +++ b/xs/src/ExPolygon.hpp @@ -21,8 +21,8 @@ class ExPolygon void rotate(double angle, const Point ¢er); double area() const; bool is_valid() const; - bool contains_line(const Line* line) const; - bool contains_point(const Point* point) const; + bool contains_line(const Line &line) const; + bool contains_point(const Point &point) const; Polygons simplify_p(double tolerance) const; ExPolygons simplify(double tolerance) const; void simplify(double tolerance, ExPolygons &expolygons) const; diff --git a/xs/src/ExPolygonCollection.cpp b/xs/src/ExPolygonCollection.cpp index 979e3777e..55cf1e468 100644 --- a/xs/src/ExPolygonCollection.cpp +++ b/xs/src/ExPolygonCollection.cpp @@ -40,7 +40,7 @@ ExPolygonCollection::rotate(double angle, const Point ¢er) } 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) { if (it->contains_point(point)) return true; diff --git a/xs/src/ExPolygonCollection.hpp b/xs/src/ExPolygonCollection.hpp index 0037b26dc..75f2f5052 100644 --- a/xs/src/ExPolygonCollection.hpp +++ b/xs/src/ExPolygonCollection.hpp @@ -14,7 +14,7 @@ class ExPolygonCollection void scale(double factor); void translate(double x, double y); void rotate(double angle, const Point ¢er); - bool contains_point(const Point* point) const; + bool contains_point(const Point &point) const; void simplify(double tolerance); void convex_hull(Polygon* hull) const; }; diff --git a/xs/src/ExtrusionEntity.cpp b/xs/src/ExtrusionEntity.cpp index 7e63a6215..f76bd2c74 100644 --- a/xs/src/ExtrusionEntity.cpp +++ b/xs/src/ExtrusionEntity.cpp @@ -43,16 +43,16 @@ ExtrusionPath::reverse() this->polyline.reverse(); } -Point* +Point ExtrusionPath::first_point() const { - return new Point(this->polyline.points.front()); + return this->polyline.points.front(); } -Point* +Point ExtrusionPath::last_point() const { - return new Point(this->polyline.points.back()); + return this->polyline.points.back(); } void @@ -200,16 +200,16 @@ ExtrusionLoop::reverse() // no-op } -Point* +Point ExtrusionLoop::first_point() const { - return new Point(this->polygon.points.front()); + return this->polygon.points.front(); } -Point* +Point ExtrusionLoop::last_point() const { - return new Point(this->polygon.points.front()); // in polygons, first == last + return this->polygon.points.front(); // in polygons, first == last } } diff --git a/xs/src/ExtrusionEntity.hpp b/xs/src/ExtrusionEntity.hpp index f5c7a19ce..cab5be7d9 100644 --- a/xs/src/ExtrusionEntity.hpp +++ b/xs/src/ExtrusionEntity.hpp @@ -33,8 +33,8 @@ class ExtrusionEntity ExtrusionRole role; double mm3_per_mm; // mm^3 of plastic per mm of linear head motion virtual void reverse() = 0; - virtual Point* first_point() const = 0; - virtual Point* last_point() const = 0; + virtual Point first_point() const = 0; + virtual Point last_point() const = 0; bool is_perimeter() const; bool is_fill() const; bool is_bridge() const; @@ -48,8 +48,8 @@ class ExtrusionPath : public ExtrusionEntity ExtrusionPath* clone() const; Polyline polyline; void reverse(); - Point* first_point() const; - Point* last_point() const; + Point first_point() const; + Point last_point() const; void intersect_expolygons(const ExPolygonCollection &collection, ExtrusionEntityCollection* retval) const; void subtract_expolygons(const ExPolygonCollection &collection, ExtrusionEntityCollection* retval) const; void clip_end(double distance); @@ -75,8 +75,8 @@ class ExtrusionLoop : public ExtrusionEntity ExtrusionPath* split_at_first_point() const; bool make_counter_clockwise(); void reverse(); - Point* first_point() const; - Point* last_point() const; + Point first_point() const; + Point last_point() const; }; } diff --git a/xs/src/ExtrusionEntityCollection.cpp b/xs/src/ExtrusionEntityCollection.cpp index f4d78b404..cc68a5d84 100644 --- a/xs/src/ExtrusionEntityCollection.cpp +++ b/xs/src/ExtrusionEntityCollection.cpp @@ -1,16 +1,36 @@ #include "ExtrusionEntityCollection.hpp" +#include #include 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::clone() const { - ExtrusionEntityCollection* collection = new ExtrusionEntityCollection (*this); - for (ExtrusionEntitiesPtr::iterator it = collection->entities.begin(); it != collection->entities.end(); ++it) { - *it = (*it)->clone(); - } - return collection; + return new ExtrusionEntityCollection(*this); } void @@ -22,32 +42,32 @@ ExtrusionEntityCollection::reverse() std::reverse(this->entities.begin(), this->entities.end()); } -Point* +Point ExtrusionEntityCollection::first_point() const { return this->entities.front()->first_point(); } -Point* +Point ExtrusionEntityCollection::last_point() const { return this->entities.back()->last_point(); } -ExtrusionEntityCollection* -ExtrusionEntityCollection::chained_path(bool no_reverse, std::vector* orig_indices) const +void +ExtrusionEntityCollection::chained_path(ExtrusionEntityCollection* retval, bool no_reverse, std::vector* orig_indices) const { - if (this->entities.empty()) { - return new ExtrusionEntityCollection (); - } - return this->chained_path_from(this->entities.front()->first_point(), no_reverse, orig_indices); + if (this->entities.empty()) return; + this->chained_path_from(this->entities.front()->first_point(), retval, no_reverse, orig_indices); } -ExtrusionEntityCollection* -ExtrusionEntityCollection::chained_path_from(Point* start_near, bool no_reverse, std::vector* orig_indices) const +void +ExtrusionEntityCollection::chained_path_from(Point start_near, ExtrusionEntityCollection* retval, bool no_reverse, std::vector* orig_indices) const { - if (this->no_sort) return this->clone(); - ExtrusionEntityCollection* retval = new ExtrusionEntityCollection; + if (this->no_sort) { + *retval = *this; + return; + } retval->entities.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; 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) { - endpoints.push_back(*(*it)->first_point()); + endpoints.push_back((*it)->first_point()); } else { - endpoints.push_back(*(*it)->last_point()); + endpoints.push_back((*it)->last_point()); } } while (!my_paths.empty()) { // 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; ExtrusionEntity* entity = my_paths.at(path_index); 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); start_near = retval->entities.back()->last_point(); } - - return retval; } } diff --git a/xs/src/ExtrusionEntityCollection.hpp b/xs/src/ExtrusionEntityCollection.hpp index 591546b36..bc660611b 100644 --- a/xs/src/ExtrusionEntityCollection.hpp +++ b/xs/src/ExtrusionEntityCollection.hpp @@ -14,11 +14,14 @@ class ExtrusionEntityCollection : public ExtrusionEntity std::vector orig_indices; // handy for XS bool no_sort; ExtrusionEntityCollection(): no_sort(false) {}; - ExtrusionEntityCollection* chained_path(bool no_reverse, std::vector* orig_indices = NULL) const; - ExtrusionEntityCollection* chained_path_from(Point* start_near, bool no_reverse, std::vector* orig_indices = NULL) const; + ExtrusionEntityCollection(const ExtrusionEntityCollection &collection); + ExtrusionEntityCollection& operator= (const ExtrusionEntityCollection &other); + void swap (ExtrusionEntityCollection &c); + void chained_path(ExtrusionEntityCollection* retval, bool no_reverse = false, std::vector* orig_indices = NULL) const; + void chained_path_from(Point start_near, ExtrusionEntityCollection* retval, bool no_reverse = false, std::vector* orig_indices = NULL) const; void reverse(); - Point* first_point() const; - Point* last_point() const; + Point first_point() const; + Point last_point() const; }; } diff --git a/xs/src/Line.cpp b/xs/src/Line.cpp index c0b2807fc..f8fd7f67e 100644 --- a/xs/src/Line.cpp +++ b/xs/src/Line.cpp @@ -53,7 +53,7 @@ Line::reverse() double Line::length() const { - return this->a.distance_to(&(this->b)); + return this->a.distance_to(this->b); } Point* @@ -82,15 +82,15 @@ Line::point_at(double distance) const } 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 -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 diff --git a/xs/src/Line.hpp b/xs/src/Line.hpp index a08999a5e..9773338b7 100644 --- a/xs/src/Line.hpp +++ b/xs/src/Line.hpp @@ -26,8 +26,8 @@ class Line Point* midpoint() const; void point_at(double distance, Point* point) const; Point point_at(double distance) const; - bool coincides_with(const Line* line) const; - double distance_to(const Point* point) const; + bool coincides_with(const Line &line) const; + double distance_to(const Point &point) const; double atan2_() const; double direction() const; Vector vector() const; diff --git a/xs/src/MultiPoint.cpp b/xs/src/MultiPoint.cpp index a8dca5b56..42ec4f09d 100644 --- a/xs/src/MultiPoint.cpp +++ b/xs/src/MultiPoint.cpp @@ -32,10 +32,10 @@ MultiPoint::reverse() std::reverse(this->points.begin(), this->points.end()); } -Point* +Point MultiPoint::first_point() const { - return new Point(this->points.front()); + return this->points.front(); } double diff --git a/xs/src/MultiPoint.hpp b/xs/src/MultiPoint.hpp index 4f3d366c1..087b3cb47 100644 --- a/xs/src/MultiPoint.hpp +++ b/xs/src/MultiPoint.hpp @@ -16,8 +16,8 @@ class MultiPoint void translate(double x, double y); void rotate(double angle, const Point ¢er); void reverse(); - Point* first_point() const; - virtual Point* last_point() const = 0; + Point first_point() const; + virtual Point last_point() const = 0; virtual Lines lines() const = 0; double length() const; bool is_valid() const; diff --git a/xs/src/Point.cpp b/xs/src/Point.cpp index b1ca9a0df..f9b14429c 100644 --- a/xs/src/Point.cpp +++ b/xs/src/Point.cpp @@ -42,12 +42,6 @@ Point::rotate(double angle, const Point ¢er) 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 Point::coincides_with(const Point &point) const { @@ -55,22 +49,22 @@ Point::coincides_with(const Point &point) const } int -Point::nearest_point_index(Points &points) const +Point::nearest_point_index(const Points &points) const { - PointPtrs p; + PointConstPtrs p; 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); return this->nearest_point_index(p); } int -Point::nearest_point_index(PointPtrs &points) const +Point::nearest_point_index(const PointConstPtrs &points) const { int idx = -1; 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 best previous candidate, we know we don't want it */ double d = pow(this->x - (*it)->x, 2); @@ -90,30 +84,34 @@ Point::nearest_point_index(PointPtrs &points) const return idx; } -Point* -Point::nearest_point(Points points) const +int +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 -Point::distance_to(const Point* point) const +Point::distance_to(const Point &point) const { - double dx = ((double)point->x - this->x); - double dy = ((double)point->y - this->y); + double dx = ((double)point.x - this->x); + double dy = ((double)point.y - this->y); return sqrt(dx*dx + dy*dy); } -double -Point::distance_to(const Line* line) const -{ - return this->distance_to(*line); -} - double 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)(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); } -double -Point::ccw(const Point* p1, const Point* p2) const -{ - return this->ccw(*p1, *p2); -} - double Point::ccw(const Line &line) const { diff --git a/xs/src/Point.hpp b/xs/src/Point.hpp index f970a96ca..508c13bf1 100644 --- a/xs/src/Point.hpp +++ b/xs/src/Point.hpp @@ -14,6 +14,7 @@ class Pointf; typedef Point Vector; typedef std::vector Points; typedef std::vector PointPtrs; +typedef std::vector PointConstPtrs; typedef std::vector Pointfs; class Point @@ -28,15 +29,13 @@ class Point void translate(double x, double y); void rotate(double angle, const Point ¢er); bool coincides_with(const Point &point) const; - bool coincides_with(const Point* point) const; - int nearest_point_index(Points &points) const; - int nearest_point_index(PointPtrs &points) const; - Point* nearest_point(Points points) const; - double distance_to(const Point* point) const; - double distance_to(const Line* line) const; + int nearest_point_index(const Points &points) const; + int nearest_point_index(const PointConstPtrs &points) const; + int nearest_point_index(const PointPtrs &points) const; + void nearest_point(const Points &points, Point* point) const; + double distance_to(const Point &point) 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 Line &line) const; #ifdef SLIC3RXS diff --git a/xs/src/Polygon.cpp b/xs/src/Polygon.cpp index 1d807bf54..5efbd56ec 100644 --- a/xs/src/Polygon.cpp +++ b/xs/src/Polygon.cpp @@ -12,10 +12,10 @@ Polygon::operator Polygons() const return pp; } -Point* +Point 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 @@ -37,7 +37,7 @@ Polygon::lines(Lines* lines) const } Polyline* -Polygon::split_at(const Point* point) const +Polygon::split_at(const Point &point) const { // find index of point for (Points::const_iterator it = this->points.begin(); it != this->points.end(); ++it) { @@ -124,15 +124,15 @@ Polygon::is_valid() const } 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 bool result = false; Points::const_iterator i = this->points.begin(); Points::const_iterator j = this->points.end() - 1; for (; i != this->points.end(); j = i++) { - 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) ) + 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) ) result = !result; } return result; diff --git a/xs/src/Polygon.hpp b/xs/src/Polygon.hpp index fa0433938..4a3f9242e 100644 --- a/xs/src/Polygon.hpp +++ b/xs/src/Polygon.hpp @@ -15,10 +15,10 @@ typedef std::vector Polygons; class Polygon : public MultiPoint { public: operator Polygons() const; - Point* last_point() const; + Point last_point() const; 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_first_point() const; Points equally_spaced_points(double distance) const; @@ -28,7 +28,7 @@ class Polygon : public MultiPoint { bool make_counter_clockwise(); bool make_clockwise(); bool is_valid() const; - bool contains_point(const Point* point) const; + bool contains_point(const Point &point) const; Polygons simplify(double tolerance) const; void simplify(double tolerance, Polygons &polygons) const; diff --git a/xs/src/Polyline.cpp b/xs/src/Polyline.cpp index 29c983c28..6d719de9c 100644 --- a/xs/src/Polyline.cpp +++ b/xs/src/Polyline.cpp @@ -10,10 +10,20 @@ Polyline::operator Polylines() const return polylines; } -Point* +Point 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 @@ -32,7 +42,7 @@ void Polyline::clip_end(double distance) { while (distance > 0) { - Point last_point = *this->last_point(); + Point last_point = this->last_point(); this->points.pop_back(); if (this->points.empty()) break; @@ -42,7 +52,7 @@ Polyline::clip_end(double distance) continue; } - Line segment(last_point, *this->last_point()); + Line segment(last_point, this->last_point()); this->points.push_back(segment.point_at(distance)); distance = 0; } @@ -80,11 +90,11 @@ Points Polyline::equally_spaced_points(double distance) const { Points pts; - pts.push_back(*this->first_point()); + pts.push_back(this->first_point()); double len = 0; 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; if (len < distance) continue; diff --git a/xs/src/Polyline.hpp b/xs/src/Polyline.hpp index 56cadddfc..b2648ba48 100644 --- a/xs/src/Polyline.hpp +++ b/xs/src/Polyline.hpp @@ -12,7 +12,8 @@ typedef std::vector Polylines; class Polyline : public MultiPoint { public: operator Polylines() const; - Point* last_point() const; + Point last_point() const; + Point leftmost_point() const; Lines lines() const; void clip_end(double distance); void clip_start(double distance); diff --git a/xs/src/PolylineCollection.cpp b/xs/src/PolylineCollection.cpp index c08732beb..41644c335 100644 --- a/xs/src/PolylineCollection.cpp +++ b/xs/src/PolylineCollection.cpp @@ -2,32 +2,31 @@ namespace Slic3r { -PolylineCollection* -PolylineCollection::chained_path(bool no_reverse) const +void +PolylineCollection::chained_path(PolylineCollection* retval, bool no_reverse) const { - if (this->polylines.empty()) return new PolylineCollection (); - return this->chained_path_from(this->polylines.front().first_point(), no_reverse); + if (this->polylines.empty()) return; + this->chained_path_from(this->polylines.front().first_point(), retval, no_reverse); } -PolylineCollection* -PolylineCollection::chained_path_from(const Point* start_near, bool no_reverse) const +void +PolylineCollection::chained_path_from(Point start_near, PolylineCollection* retval, bool no_reverse) const { - PolylineCollection* retval = new PolylineCollection; Polylines my_paths = this->polylines; Points endpoints; 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) { - endpoints.push_back(*(*it).first_point()); + endpoints.push_back(it->first_point()); } else { - endpoints.push_back(*(*it).last_point()); + endpoints.push_back(it->last_point()); } } while (!my_paths.empty()) { // 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; if (start_index % 2 && !no_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); start_near = retval->polylines.back().last_point(); } - - return retval; } -Point* +Point PolylineCollection::leftmost_point() const { - const Point* p = NULL; - for (Polylines::const_iterator it = this->polylines.begin(); it != this->polylines.end(); ++it) { - if (p == NULL || it->points.front().x < p->x) - p = &(it->points.front()); + if (this->polylines.empty()) CONFESS("leftmost_point() called on empty PolylineCollection"); + Point p = this->polylines.front().leftmost_point(); + for (Polylines::const_iterator it = this->polylines.begin() + 1; it != this->polylines.end(); ++it) { + Point p2 = it->leftmost_point(); + if (p2.x < p.x) p = p2; } - if (p == NULL) return NULL; - return new Point (*p); + return p; } } diff --git a/xs/src/PolylineCollection.hpp b/xs/src/PolylineCollection.hpp index dd2bed711..ace03ad37 100644 --- a/xs/src/PolylineCollection.hpp +++ b/xs/src/PolylineCollection.hpp @@ -10,9 +10,9 @@ class PolylineCollection { public: Polylines polylines; - PolylineCollection* chained_path(bool no_reverse = false) const; - PolylineCollection* chained_path_from(const Point* start_near, bool no_reverse = false) const; - Point* leftmost_point() const; + void chained_path(PolylineCollection* retval, bool no_reverse = false) const; + void chained_path_from(Point start_near, PolylineCollection* retval, bool no_reverse = false) const; + Point leftmost_point() const; }; } diff --git a/xs/xsp/ExPolygon.xsp b/xs/xsp/ExPolygon.xsp index 19e98c081..78fca61fe 100644 --- a/xs/xsp/ExPolygon.xsp +++ b/xs/xsp/ExPolygon.xsp @@ -21,8 +21,10 @@ void translate(double x, double y); double area(); bool is_valid(); - bool contains_line(Line* line); - bool contains_point(Point* point); + bool contains_line(Line* line) + %code{% RETVAL = THIS->contains_line(*line); %}; + bool contains_point(Point* point) + %code{% RETVAL = THIS->contains_point(*point); %}; ExPolygons simplify(double tolerance); Polygons simplify_p(double tolerance); Polylines medial_axis(double max_width, double min_width) diff --git a/xs/xsp/ExPolygonCollection.xsp b/xs/xsp/ExPolygonCollection.xsp index e8516fe93..536e50372 100644 --- a/xs/xsp/ExPolygonCollection.xsp +++ b/xs/xsp/ExPolygonCollection.xsp @@ -17,7 +17,8 @@ %code{% THIS->rotate(angle, *center); %}; int count() %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); %{ diff --git a/xs/xsp/ExtrusionEntityCollection.xsp b/xs/xsp/ExtrusionEntityCollection.xsp index f2196c760..1021b56f1 100644 --- a/xs/xsp/ExtrusionEntityCollection.xsp +++ b/xs/xsp/ExtrusionEntityCollection.xsp @@ -11,13 +11,21 @@ void clear() %code{% THIS->entities.clear(); %}; 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) - %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() - %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() - %code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->last_point(); %}; + %code{% const char* CLASS = "Slic3r::Point"; RETVAL = new Point(THIS->last_point()); %}; int count() %code{% RETVAL = THIS->entities.size(); %}; std::vector orig_indices() @@ -84,9 +92,9 @@ ExtrusionEntityCollection::chained_path_indices(bool no_reverse) PREINIT: const char* CLASS = "Slic3r::ExtrusionPath::Collection"; CODE: + RETVAL = new ExtrusionEntityCollection(); std::vector indices; - RETVAL = THIS->chained_path(no_reverse, &indices); - RETVAL->orig_indices = indices; + THIS->chained_path(RETVAL, no_reverse, &RETVAL->orig_indices); OUTPUT: RETVAL diff --git a/xs/xsp/ExtrusionLoop.xsp b/xs/xsp/ExtrusionLoop.xsp index fbf4dfca3..02e55c7d3 100644 --- a/xs/xsp/ExtrusionLoop.xsp +++ b/xs/xsp/ExtrusionLoop.xsp @@ -19,9 +19,9 @@ %code{% const char* CLASS = "Slic3r::ExtrusionPath"; RETVAL = THIS->split_at_first_point(); %}; bool make_counter_clockwise(); 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() - %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_fill(); bool is_bridge(); diff --git a/xs/xsp/ExtrusionPath.xsp b/xs/xsp/ExtrusionPath.xsp index 36b5fdae8..15b1a7181 100644 --- a/xs/xsp/ExtrusionPath.xsp +++ b/xs/xsp/ExtrusionPath.xsp @@ -18,9 +18,9 @@ Lines lines() %code{% RETVAL = THIS->polyline.lines(); %}; 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() - %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 simplify(double tolerance); double length(); diff --git a/xs/xsp/Line.xsp b/xs/xsp/Line.xsp index 7f9f332b9..49e2dcf34 100644 --- a/xs/xsp/Line.xsp +++ b/xs/xsp/Line.xsp @@ -56,7 +56,7 @@ Line::coincides_with(line_sv) CODE: Line line; line.from_SV_check(line_sv); - RETVAL = THIS->coincides_with(&line); + RETVAL = THIS->coincides_with(line); OUTPUT: RETVAL diff --git a/xs/xsp/Point.xsp b/xs/xsp/Point.xsp index 5a24edb59..dd408ccf2 100644 --- a/xs/xsp/Point.xsp +++ b/xs/xsp/Point.xsp @@ -22,9 +22,11 @@ %code{% RETVAL = THIS->y; %}; int nearest_point_index(Points points); Point* nearest_point(Points points) - %code{% const char* CLASS = "Slic3r::Point"; RETVAL = new Point(*(THIS->nearest_point(points))); %}; - double distance_to(Point* point); - %name{distance_to_line} double distance_to(Line* line); + %code{% const char* CLASS = "Slic3r::Point"; RETVAL = new Point(); THIS->nearest_point(points, RETVAL); %}; + double distance_to(Point* point) + %code{% RETVAL = THIS->distance_to(*point); %}; + double distance_to_line(Line* line) + %code{% RETVAL = THIS->distance_to(*line); %}; double ccw(Point* p1, Point* p2) %code{% RETVAL = THIS->ccw(*p1, *p2); %}; @@ -45,7 +47,7 @@ Point::coincides_with(point_sv) CODE: Point point; point.from_SV_check(point_sv); - RETVAL = THIS->coincides_with(&point); + RETVAL = THIS->coincides_with(point); OUTPUT: RETVAL diff --git a/xs/xsp/Polygon.xsp b/xs/xsp/Polygon.xsp index 2aafe9ef0..8a32f29e4 100644 --- a/xs/xsp/Polygon.xsp +++ b/xs/xsp/Polygon.xsp @@ -18,7 +18,7 @@ void reverse(); Lines lines(); 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) %code{% const char* CLASS = "Slic3r::Polyline"; RETVAL = THIS->split_at_index(index); %}; Polyline* split_at_first_point() @@ -32,8 +32,9 @@ bool make_clockwise(); bool is_valid(); Point* first_point() - %code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->first_point(); %}; - bool contains_point(Point* point); + %code{% const char* CLASS = "Slic3r::Point"; RETVAL = new Point(THIS->first_point()); %}; + bool contains_point(Point* point) + %code{% RETVAL = THIS->contains_point(*point); %}; Polygons simplify(double tolerance); %{ diff --git a/xs/xsp/Polyline.xsp b/xs/xsp/Polyline.xsp index aadbf06c2..8d10fb734 100644 --- a/xs/xsp/Polyline.xsp +++ b/xs/xsp/Polyline.xsp @@ -21,9 +21,9 @@ void reverse(); Lines lines(); 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() - %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); double length(); bool is_valid(); diff --git a/xs/xsp/PolylineCollection.xsp b/xs/xsp/PolylineCollection.xsp index d93dbc7b1..a9061115c 100644 --- a/xs/xsp/PolylineCollection.xsp +++ b/xs/xsp/PolylineCollection.xsp @@ -12,13 +12,21 @@ void clear() %code{% THIS->polylines.clear(); %}; 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) - %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() %code{% RETVAL = THIS->polylines.size(); %}; 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*