mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 12:41:20 -06:00 
			
		
		
		
	New get_trapezoids() implementation. Maybe heavier but it doesn't fail with some versions of GCC like the one provided by Boost.Polygon. #1965
This commit is contained in:
		
							parent
							
								
									d4e97d17d5
								
							
						
					
					
						commit
						2720000a17
					
				
					 7 changed files with 79 additions and 4 deletions
				
			
		|  | @ -170,7 +170,7 @@ sub coverage { | ||||||
|     my $grown = $expolygon->offset_ex(+$self->extrusion_width/2); |     my $grown = $expolygon->offset_ex(+$self->extrusion_width/2); | ||||||
|      |      | ||||||
|     # Compute trapezoids according to a vertical orientation |     # Compute trapezoids according to a vertical orientation | ||||||
|     my $trapezoids = [ map @{$_->get_trapezoids(PI/2)}, @$grown ]; |     my $trapezoids = [ map @{$_->get_trapezoids2(PI/2)}, @$grown ]; | ||||||
|      |      | ||||||
|     # get anchors and rotate them too |     # get anchors and rotate them too | ||||||
|     my $anchors = [ map $_->clone, @{$self->_anchors} ]; |     my $anchors = [ map $_->clone, @{$self->_anchors} ]; | ||||||
|  |  | ||||||
|  | @ -1,3 +1,4 @@ | ||||||
|  | #include "BoundingBox.hpp" | ||||||
| #include "ExPolygon.hpp" | #include "ExPolygon.hpp" | ||||||
| #include "Geometry.hpp" | #include "Geometry.hpp" | ||||||
| #include "Polygon.hpp" | #include "Polygon.hpp" | ||||||
|  | @ -8,6 +9,7 @@ | ||||||
| #include "perlglue.hpp" | #include "perlglue.hpp" | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #include <algorithm> | ||||||
| #include <list> | #include <list> | ||||||
| 
 | 
 | ||||||
| namespace Slic3r { | namespace Slic3r { | ||||||
|  | @ -182,6 +184,61 @@ ExPolygon::get_trapezoids(Polygons* polygons, double angle) const | ||||||
|         polygon->rotate(-(PI/2 - angle), Point(0,0)); |         polygon->rotate(-(PI/2 - angle), Point(0,0)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // This algorithm may return more trapezoids than necessary
 | ||||||
|  | // (i.e. it may break a single trapezoid in several because
 | ||||||
|  | // other parts of the object have x coordinates in the middle)
 | ||||||
|  | void | ||||||
|  | ExPolygon::get_trapezoids2(Polygons* polygons) const | ||||||
|  | { | ||||||
|  |     // get all points of this ExPolygon
 | ||||||
|  |     Points pp = *this; | ||||||
|  |      | ||||||
|  |     // build our bounding box
 | ||||||
|  |     BoundingBox bb(pp); | ||||||
|  |      | ||||||
|  |     // get all x coordinates
 | ||||||
|  |     std::vector<coord_t> xx; | ||||||
|  |     xx.reserve(pp.size()); | ||||||
|  |     for (Points::const_iterator p = pp.begin(); p != pp.end(); ++p) | ||||||
|  |         xx.push_back(p->x); | ||||||
|  |     std::sort(xx.begin(), xx.end()); | ||||||
|  |      | ||||||
|  |     // find trapezoids by looping from first to next-to-last coordinate
 | ||||||
|  |     for (std::vector<coord_t>::const_iterator x = xx.begin(); x != xx.end()-1; ++x) { | ||||||
|  |         coord_t next_x = *(x + 1); | ||||||
|  |         if (*x == next_x) continue; | ||||||
|  |          | ||||||
|  |         // build rectangle
 | ||||||
|  |         Polygon poly; | ||||||
|  |         poly.points.resize(4); | ||||||
|  |         poly[0].x = *x; | ||||||
|  |         poly[0].y = bb.min.y; | ||||||
|  |         poly[1].x = next_x; | ||||||
|  |         poly[1].y = bb.min.y; | ||||||
|  |         poly[2].x = next_x; | ||||||
|  |         poly[2].y = bb.max.y; | ||||||
|  |         poly[3].x = *x; | ||||||
|  |         poly[3].y = bb.max.y; | ||||||
|  |          | ||||||
|  |         // intersect with this expolygon
 | ||||||
|  |         Polygons trapezoids; | ||||||
|  |         intersection(poly, *this, trapezoids); | ||||||
|  |          | ||||||
|  |         // append results to return value
 | ||||||
|  |         polygons->insert(polygons->end(), trapezoids.begin(), trapezoids.end()); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | ExPolygon::get_trapezoids2(Polygons* polygons, double angle) const | ||||||
|  | { | ||||||
|  |     ExPolygon clone = *this; | ||||||
|  |     clone.rotate(PI/2 - angle, Point(0,0)); | ||||||
|  |     clone.get_trapezoids2(polygons); | ||||||
|  |     for (Polygons::iterator polygon = polygons->begin(); polygon != polygons->end(); ++polygon) | ||||||
|  |         polygon->rotate(-(PI/2 - angle), Point(0,0)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void | void | ||||||
| ExPolygon::triangulate(Polygons* polygons) const | ExPolygon::triangulate(Polygons* polygons) const | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -29,6 +29,8 @@ class ExPolygon | ||||||
|     void medial_axis(double max_width, double min_width, Polylines* polylines) const; |     void medial_axis(double max_width, double min_width, Polylines* polylines) const; | ||||||
|     void get_trapezoids(Polygons* polygons) const; |     void get_trapezoids(Polygons* polygons) const; | ||||||
|     void get_trapezoids(Polygons* polygons, double angle) const; |     void get_trapezoids(Polygons* polygons, double angle) const; | ||||||
|  |     void get_trapezoids2(Polygons* polygons) const; | ||||||
|  |     void get_trapezoids2(Polygons* polygons, double angle) const; | ||||||
|     void triangulate(Polygons* polygons) const; |     void triangulate(Polygons* polygons) const; | ||||||
|     void triangulate2(Polygons* polygons) const; |     void triangulate2(Polygons* polygons) const; | ||||||
|      |      | ||||||
|  |  | ||||||
|  | @ -15,6 +15,18 @@ Polygon::operator Polygons() const | ||||||
|     return pp; |     return pp; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | Point& | ||||||
|  | Polygon::operator[](Points::size_type idx) | ||||||
|  | { | ||||||
|  |     return this->points[idx]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const Point& | ||||||
|  | Polygon::operator[](Points::size_type idx) const | ||||||
|  | { | ||||||
|  |     return this->points[idx]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| Point | Point | ||||||
| Polygon::last_point() const | Polygon::last_point() const | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -15,6 +15,8 @@ typedef std::vector<Polygon> Polygons; | ||||||
| class Polygon : public MultiPoint { | class Polygon : public MultiPoint { | ||||||
|     public: |     public: | ||||||
|     operator Polygons() const; |     operator Polygons() const; | ||||||
|  |     Point& operator[](Points::size_type idx); | ||||||
|  |     const Point& operator[](Points::size_type idx) 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; | ||||||
|  |  | ||||||
|  | @ -107,14 +107,14 @@ is $expolygon->area, 100*100-20*20, 'area'; | ||||||
| 
 | 
 | ||||||
| { | { | ||||||
|     my $expolygon = Slic3r::ExPolygon->new($square); |     my $expolygon = Slic3r::ExPolygon->new($square); | ||||||
|     my $polygons = $expolygon->get_trapezoids(PI/2); |     my $polygons = $expolygon->get_trapezoids2(PI/2); | ||||||
|     is scalar(@$polygons), 1, 'correct number of trapezoids returned'; |     is scalar(@$polygons), 1, 'correct number of trapezoids returned'; | ||||||
|     is scalar(@{$polygons->[0]}), 4, 'trapezoid has 4 points'; |     is scalar(@{$polygons->[0]}), 4, 'trapezoid has 4 points'; | ||||||
|     is $polygons->[0]->area, $expolygon->area, 'trapezoid has correct area'; |     is $polygons->[0]->area, $expolygon->area, 'trapezoid has correct area'; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| { | { | ||||||
|     my $polygons = $expolygon->get_trapezoids(PI/2); |     my $polygons = $expolygon->get_trapezoids2(PI/2); | ||||||
|     is scalar(@$polygons), 4, 'correct number of trapezoids returned'; |     is scalar(@$polygons), 4, 'correct number of trapezoids returned'; | ||||||
|      |      | ||||||
|     # trapezoid polygons might have more than 4 points in case of collinear segments |     # trapezoid polygons might have more than 4 points in case of collinear segments | ||||||
|  | @ -127,7 +127,7 @@ is $expolygon->area, 100*100-20*20, 'area'; | ||||||
| 
 | 
 | ||||||
| { | { | ||||||
|     my $expolygon = Slic3r::ExPolygon->new([ [0,100],[100,0],[200,0],[300,100],[200,200],[100,200] ]); |     my $expolygon = Slic3r::ExPolygon->new([ [0,100],[100,0],[200,0],[300,100],[200,200],[100,200] ]); | ||||||
|     my $polygons = $expolygon->get_trapezoids(PI/2); |     my $polygons = $expolygon->get_trapezoids2(PI/2); | ||||||
|     is scalar(@$polygons), 3, 'correct number of trapezoids returned'; |     is scalar(@$polygons), 3, 'correct number of trapezoids returned'; | ||||||
|     is scalar(grep { $_->area == 100*200/2 } @$polygons), 2, 'trapezoids have expected area'; |     is scalar(grep { $_->area == 100*200/2 } @$polygons), 2, 'trapezoids have expected area'; | ||||||
|     is scalar(grep { $_->area == 100*200 } @$polygons), 1, 'trapezoids have expected area'; |     is scalar(grep { $_->area == 100*200 } @$polygons), 1, 'trapezoids have expected area'; | ||||||
|  |  | ||||||
|  | @ -32,6 +32,8 @@ | ||||||
|         %code{% THIS->medial_axis(max_width, min_width, &RETVAL); %}; |         %code{% THIS->medial_axis(max_width, min_width, &RETVAL); %}; | ||||||
|     Polygons get_trapezoids(double angle) |     Polygons get_trapezoids(double angle) | ||||||
|         %code{% THIS->get_trapezoids(&RETVAL, angle); %}; |         %code{% THIS->get_trapezoids(&RETVAL, angle); %}; | ||||||
|  |     Polygons get_trapezoids2(double angle) | ||||||
|  |         %code{% THIS->get_trapezoids2(&RETVAL, angle); %}; | ||||||
|     Polygons triangulate() |     Polygons triangulate() | ||||||
|         %code{% THIS->triangulate(&RETVAL); %}; |         %code{% THIS->triangulate(&RETVAL); %}; | ||||||
|     Polygons triangulate2() |     Polygons triangulate2() | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci