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); | ||||
|      | ||||
|     # 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 | ||||
|     my $anchors = [ map $_->clone, @{$self->_anchors} ]; | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| #include "BoundingBox.hpp" | ||||
| #include "ExPolygon.hpp" | ||||
| #include "Geometry.hpp" | ||||
| #include "Polygon.hpp" | ||||
|  | @ -8,6 +9,7 @@ | |||
| #include "perlglue.hpp" | ||||
| #endif | ||||
| 
 | ||||
| #include <algorithm> | ||||
| #include <list> | ||||
| 
 | ||||
| namespace Slic3r { | ||||
|  | @ -182,6 +184,61 @@ ExPolygon::get_trapezoids(Polygons* polygons, double angle) const | |||
|         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 | ||||
| ExPolygon::triangulate(Polygons* polygons) const | ||||
| { | ||||
|  |  | |||
|  | @ -29,6 +29,8 @@ class ExPolygon | |||
|     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; | ||||
|     void get_trapezoids2(Polygons* polygons) const; | ||||
|     void get_trapezoids2(Polygons* polygons, double angle) const; | ||||
|     void triangulate(Polygons* polygons) const; | ||||
|     void triangulate2(Polygons* polygons) const; | ||||
|      | ||||
|  |  | |||
|  | @ -15,6 +15,18 @@ Polygon::operator Polygons() const | |||
|     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 | ||||
| Polygon::last_point() const | ||||
| { | ||||
|  |  | |||
|  | @ -15,6 +15,8 @@ typedef std::vector<Polygon> Polygons; | |||
| class Polygon : public MultiPoint { | ||||
|     public: | ||||
|     operator Polygons() const; | ||||
|     Point& operator[](Points::size_type idx); | ||||
|     const Point& operator[](Points::size_type idx) const; | ||||
|     Point last_point() const; | ||||
|     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 $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->[0]}), 4, 'trapezoid has 4 points'; | ||||
|     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'; | ||||
|      | ||||
|     # 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 $polygons = $expolygon->get_trapezoids(PI/2); | ||||
|     my $polygons = $expolygon->get_trapezoids2(PI/2); | ||||
|     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 } @$polygons), 1, 'trapezoids have expected area'; | ||||
|  |  | |||
|  | @ -32,6 +32,8 @@ | |||
|         %code{% THIS->medial_axis(max_width, min_width, &RETVAL); %}; | ||||
|     Polygons get_trapezoids(double angle) | ||||
|         %code{% THIS->get_trapezoids(&RETVAL, angle); %}; | ||||
|     Polygons get_trapezoids2(double angle) | ||||
|         %code{% THIS->get_trapezoids2(&RETVAL, angle); %}; | ||||
|     Polygons triangulate() | ||||
|         %code{% THIS->triangulate(&RETVAL); %}; | ||||
|     Polygons triangulate2() | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci