mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	Remove self-intersections before supplying polygon data to polyPartition and rename triangulate2() to triangulate_pp()
This commit is contained in:
		
							parent
							
								
									9734a40647
								
							
						
					
					
						commit
						60f640f100
					
				
					 7 changed files with 53 additions and 30 deletions
				
			
		| 
						 | 
					@ -442,14 +442,24 @@ static void traverse_pt(ClipperLib::PolyNodes &nodes, Slic3r::Polygons &retval)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void simplify_polygons(const Slic3r::Polygons &subject, Slic3r::Polygons &retval)
 | 
					void simplify_polygons(const Slic3r::Polygons &subject, Slic3r::Polygons &retval, bool preserve_collinear)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    // convert into Clipper polygons
 | 
					    // convert into Clipper polygons
 | 
				
			||||||
    ClipperLib::Paths* input_subject = new ClipperLib::Paths();
 | 
					    ClipperLib::Paths* input_subject = new ClipperLib::Paths();
 | 
				
			||||||
    Slic3rMultiPoints_to_ClipperPaths(subject, *input_subject);
 | 
					    Slic3rMultiPoints_to_ClipperPaths(subject, *input_subject);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    ClipperLib::Paths* output = new ClipperLib::Paths();
 | 
					    ClipperLib::Paths* output = new ClipperLib::Paths();
 | 
				
			||||||
    ClipperLib::SimplifyPolygons(*input_subject, *output, ClipperLib::pftNonZero);
 | 
					    
 | 
				
			||||||
 | 
					    if (preserve_collinear) {
 | 
				
			||||||
 | 
					        ClipperLib::Clipper c;
 | 
				
			||||||
 | 
					        c.PreserveCollinear(true);
 | 
				
			||||||
 | 
					        c.StrictlySimple(true);
 | 
				
			||||||
 | 
					        c.AddPaths(*input_subject, ClipperLib::ptSubject, true);
 | 
				
			||||||
 | 
					        c.Execute(ClipperLib::ctUnion, *output, ClipperLib::pftNonZero, ClipperLib::pftNonZero);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        ClipperLib::SimplifyPolygons(*input_subject, *output, ClipperLib::pftNonZero);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    delete input_subject;
 | 
					    delete input_subject;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // convert into Slic3r polygons
 | 
					    // convert into Slic3r polygons
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -98,7 +98,7 @@ void union_pt(const Slic3r::Polygons &subject, ClipperLib::PolyTree &retval, boo
 | 
				
			||||||
void union_pt_chained(const Slic3r::Polygons &subject, Slic3r::Polygons &retval, bool safety_offset_ = false);
 | 
					void union_pt_chained(const Slic3r::Polygons &subject, Slic3r::Polygons &retval, bool safety_offset_ = false);
 | 
				
			||||||
static void traverse_pt(ClipperLib::PolyNodes &nodes, Slic3r::Polygons &retval);
 | 
					static void traverse_pt(ClipperLib::PolyNodes &nodes, Slic3r::Polygons &retval);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void simplify_polygons(const Slic3r::Polygons &subject, Slic3r::Polygons &retval);
 | 
					void simplify_polygons(const Slic3r::Polygons &subject, Slic3r::Polygons &retval, bool preserve_collinear = false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void safety_offset(ClipperLib::Paths* &subject);
 | 
					void safety_offset(ClipperLib::Paths* &subject);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -239,6 +239,8 @@ ExPolygon::get_trapezoids2(Polygons* polygons, double angle) const
 | 
				
			||||||
        polygon->rotate(-(PI/2 - angle), Point(0,0));
 | 
					        polygon->rotate(-(PI/2 - angle), Point(0,0));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// While this triangulates successfully, it's NOT a constrained triangulation
 | 
				
			||||||
 | 
					// as it will create more vertices on the boundaries than the ones supplied.
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
ExPolygon::triangulate(Polygons* polygons) const
 | 
					ExPolygon::triangulate(Polygons* polygons) const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -252,33 +254,44 @@ ExPolygon::triangulate(Polygons* polygons) const
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
ExPolygon::triangulate2(Polygons* polygons) const
 | 
					ExPolygon::triangulate_pp(Polygons* polygons) const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    // convert polygons
 | 
					    // convert polygons
 | 
				
			||||||
    std::list<TPPLPoly> input;
 | 
					    std::list<TPPLPoly> input;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // contour
 | 
					    Polygons pp = *this;
 | 
				
			||||||
    {
 | 
					    simplify_polygons(pp, pp, true);
 | 
				
			||||||
        TPPLPoly p;
 | 
					    ExPolygons expp;
 | 
				
			||||||
        p.Init(this->contour.points.size());
 | 
					    union_(pp, expp);
 | 
				
			||||||
        for (Points::const_iterator point = this->contour.points.begin(); point != this->contour.points.end(); ++point) {
 | 
					 | 
				
			||||||
            p[ point-this->contour.points.begin() ].x = point->x;
 | 
					 | 
				
			||||||
            p[ point-this->contour.points.begin() ].y = point->y;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        p.SetHole(false);
 | 
					 | 
				
			||||||
        input.push_back(p);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // holes
 | 
					    for (ExPolygons::const_iterator ex = expp.begin(); ex != expp.end(); ++ex) {
 | 
				
			||||||
    for (Polygons::const_iterator hole = this->holes.begin(); hole != this->holes.end(); ++hole) {
 | 
					        // contour
 | 
				
			||||||
        TPPLPoly p;
 | 
					        {
 | 
				
			||||||
        p.Init(hole->points.size());
 | 
					            TPPLPoly p;
 | 
				
			||||||
        for (Points::const_iterator point = hole->points.begin(); point != hole->points.end(); ++point) {
 | 
					            p.Init(ex->contour.points.size());
 | 
				
			||||||
            p[ point-hole->points.begin() ].x = point->x;
 | 
					            //printf("%zu\n0\n", ex->contour.points.size());
 | 
				
			||||||
            p[ point-hole->points.begin() ].y = point->y;
 | 
					            for (Points::const_iterator point = ex->contour.points.begin(); point != ex->contour.points.end(); ++point) {
 | 
				
			||||||
 | 
					                p[ point-ex->contour.points.begin() ].x = point->x;
 | 
				
			||||||
 | 
					                p[ point-ex->contour.points.begin() ].y = point->y;
 | 
				
			||||||
 | 
					                //printf("%ld %ld\n", point->x, point->y);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            p.SetHole(false);
 | 
				
			||||||
 | 
					            input.push_back(p);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					        // holes
 | 
				
			||||||
 | 
					        for (Polygons::const_iterator hole = ex->holes.begin(); hole != ex->holes.end(); ++hole) {
 | 
				
			||||||
 | 
					            TPPLPoly p;
 | 
				
			||||||
 | 
					            p.Init(hole->points.size());
 | 
				
			||||||
 | 
					            //printf("%zu\n1\n", hole->points.size());
 | 
				
			||||||
 | 
					            for (Points::const_iterator point = hole->points.begin(); point != hole->points.end(); ++point) {
 | 
				
			||||||
 | 
					                p[ point-hole->points.begin() ].x = point->x;
 | 
				
			||||||
 | 
					                p[ point-hole->points.begin() ].y = point->y;
 | 
				
			||||||
 | 
					                //printf("%ld %ld\n", point->x, point->y);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            p.SetHole(true);
 | 
				
			||||||
 | 
					            input.push_back(p);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        p.SetHole(true);
 | 
					 | 
				
			||||||
        input.push_back(p);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // perform triangulation
 | 
					    // perform triangulation
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,7 +32,7 @@ class ExPolygon
 | 
				
			||||||
    void get_trapezoids2(Polygons* polygons) const;
 | 
					    void get_trapezoids2(Polygons* polygons) const;
 | 
				
			||||||
    void get_trapezoids2(Polygons* polygons, double angle) 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 triangulate_pp(Polygons* polygons) const;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    #ifdef SLIC3RXS
 | 
					    #ifdef SLIC3RXS
 | 
				
			||||||
    void from_SV(SV* poly_sv);
 | 
					    void from_SV(SV* poly_sv);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -923,7 +923,7 @@ TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower)
 | 
				
			||||||
        // triangulate section
 | 
					        // triangulate section
 | 
				
			||||||
        Polygons triangles;
 | 
					        Polygons triangles;
 | 
				
			||||||
        for (ExPolygons::const_iterator expolygon = section.begin(); expolygon != section.end(); ++expolygon)
 | 
					        for (ExPolygons::const_iterator expolygon = section.begin(); expolygon != section.end(); ++expolygon)
 | 
				
			||||||
            expolygon->triangulate2(&triangles);
 | 
					            expolygon->triangulate_pp(&triangles);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        // convert triangles to facets and append them to mesh
 | 
					        // convert triangles to facets and append them to mesh
 | 
				
			||||||
        for (Polygons::const_iterator polygon = triangles.begin(); polygon != triangles.end(); ++polygon) {
 | 
					        for (Polygons::const_iterator polygon = triangles.begin(); polygon != triangles.end(); ++polygon) {
 | 
				
			||||||
| 
						 | 
					@ -951,7 +951,7 @@ TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower)
 | 
				
			||||||
        // triangulate section
 | 
					        // triangulate section
 | 
				
			||||||
        Polygons triangles;
 | 
					        Polygons triangles;
 | 
				
			||||||
        for (ExPolygons::const_iterator expolygon = section.begin(); expolygon != section.end(); ++expolygon)
 | 
					        for (ExPolygons::const_iterator expolygon = section.begin(); expolygon != section.end(); ++expolygon)
 | 
				
			||||||
            expolygon->triangulate2(&triangles);
 | 
					            expolygon->triangulate_pp(&triangles);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        // convert triangles to facets and append them to mesh
 | 
					        // convert triangles to facets and append them to mesh
 | 
				
			||||||
        for (Polygons::const_iterator polygon = triangles.begin(); polygon != triangles.end(); ++polygon) {
 | 
					        for (Polygons::const_iterator polygon = triangles.begin(); polygon != triangles.end(); ++polygon) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -134,7 +134,7 @@ is $expolygon->area, 100*100-20*20, 'area';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    my $triangles = $expolygon->triangulate2;
 | 
					    my $triangles = $expolygon->triangulate_pp;
 | 
				
			||||||
    is scalar(@$triangles), 8, 'expected number of triangles';
 | 
					    is scalar(@$triangles), 8, 'expected number of triangles';
 | 
				
			||||||
    is sum(map $_->area, @$triangles), $expolygon->area, 'sum of triangles area equals original expolygon area';
 | 
					    is sum(map $_->area, @$triangles), $expolygon->area, 'sum of triangles area equals original expolygon area';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,8 +36,8 @@
 | 
				
			||||||
        %code{% THIS->get_trapezoids2(&RETVAL, angle); %};
 | 
					        %code{% THIS->get_trapezoids2(&RETVAL, angle); %};
 | 
				
			||||||
    Polygons triangulate()
 | 
					    Polygons triangulate()
 | 
				
			||||||
        %code{% THIS->triangulate(&RETVAL); %};
 | 
					        %code{% THIS->triangulate(&RETVAL); %};
 | 
				
			||||||
    Polygons triangulate2()
 | 
					    Polygons triangulate_pp()
 | 
				
			||||||
        %code{% THIS->triangulate2(&RETVAL); %};
 | 
					        %code{% THIS->triangulate_pp(&RETVAL); %};
 | 
				
			||||||
%{
 | 
					%{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ExPolygon*
 | 
					ExPolygon*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue