mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	Finished --cut implementation
This commit is contained in:
		
							parent
							
								
									fe1691c151
								
							
						
					
					
						commit
						4f5d9ca795
					
				
					 8 changed files with 2009 additions and 10 deletions
				
			
		| 
						 | 
					@ -132,9 +132,9 @@ if (@ARGV) {  # slicing from command line
 | 
				
			||||||
            $mesh->cut($opt{cut}, $upper, $lower);
 | 
					            $mesh->cut($opt{cut}, $upper, $lower);
 | 
				
			||||||
            $upper->repair;
 | 
					            $upper->repair;
 | 
				
			||||||
            $lower->repair;
 | 
					            $lower->repair;
 | 
				
			||||||
            Slic3r::Format::STL->write_file("${file}_upper.stl", $upper, binary => 0)
 | 
					            $upper->write_ascii("${file}_upper.stl")
 | 
				
			||||||
                if $upper->facets_count > 0;
 | 
					                if $upper->facets_count > 0;
 | 
				
			||||||
            Slic3r::Format::STL->write_file("${file}_lower.stl", $lower, binary => 0)
 | 
					            $lower->write_ascii("${file}_lower.stl")
 | 
				
			||||||
                if $lower->facets_count > 0;
 | 
					                if $lower->facets_count > 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        exit;
 | 
					        exit;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,6 +3,9 @@
 | 
				
			||||||
#include "Polygon.hpp"
 | 
					#include "Polygon.hpp"
 | 
				
			||||||
#include "Line.hpp"
 | 
					#include "Line.hpp"
 | 
				
			||||||
#include "ClipperUtils.hpp"
 | 
					#include "ClipperUtils.hpp"
 | 
				
			||||||
 | 
					#include "polypartition.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <list>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Slic3r {
 | 
					namespace Slic3r {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -188,6 +191,54 @@ ExPolygon::triangulate(Polygons* polygons) const
 | 
				
			||||||
        polygon->triangulate_convex(polygons);
 | 
					        polygon->triangulate_convex(polygons);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					ExPolygon::triangulate2(Polygons* polygons) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // convert polygons
 | 
				
			||||||
 | 
					    std::list<TPPLPoly> input;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // contour
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        TPPLPoly p;
 | 
				
			||||||
 | 
					        p.Init(this->contour.points.size());
 | 
				
			||||||
 | 
					        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 (Polygons::const_iterator hole = this->holes.begin(); hole != this->holes.end(); ++hole) {
 | 
				
			||||||
 | 
					        TPPLPoly p;
 | 
				
			||||||
 | 
					        p.Init(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;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        p.SetHole(true);
 | 
				
			||||||
 | 
					        input.push_back(p);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // perform triangulation
 | 
				
			||||||
 | 
					    std::list<TPPLPoly> output;
 | 
				
			||||||
 | 
					    int res = TPPLPartition().Triangulate_MONO(&input, &output);
 | 
				
			||||||
 | 
					    if (res != 1) CONFESS("Triangulation failed");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // convert output polygons
 | 
				
			||||||
 | 
					    for (std::list<TPPLPoly>::iterator poly = output.begin(); poly != output.end(); ++poly) {
 | 
				
			||||||
 | 
					        long num_points = poly->GetNumPoints();
 | 
				
			||||||
 | 
					        Polygon p;
 | 
				
			||||||
 | 
					        p.points.resize(num_points);
 | 
				
			||||||
 | 
					        for (long i = 0; i < num_points; ++i) {
 | 
				
			||||||
 | 
					            p.points[i].x = (*poly)[i].x;
 | 
				
			||||||
 | 
					            p.points[i].y = (*poly)[i].y;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        polygons->push_back(p);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef SLIC3RXS
 | 
					#ifdef SLIC3RXS
 | 
				
			||||||
SV*
 | 
					SV*
 | 
				
			||||||
ExPolygon::to_AV() {
 | 
					ExPolygon::to_AV() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,6 +30,7 @@ class ExPolygon
 | 
				
			||||||
    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 triangulate(Polygons* polygons) const;
 | 
					    void triangulate(Polygons* polygons) const;
 | 
				
			||||||
 | 
					    void triangulate2(Polygons* polygons) const;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    #ifdef SLIC3RXS
 | 
					    #ifdef SLIC3RXS
 | 
				
			||||||
    void from_SV(SV* poly_sv);
 | 
					    void from_SV(SV* poly_sv);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -680,6 +680,40 @@ class _area_comp {
 | 
				
			||||||
    std::vector<double>* abs_area;
 | 
					    std::vector<double>* abs_area;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					TriangleMeshSlicer::make_expolygons_simple(std::vector<IntersectionLine> &lines, ExPolygons* slices)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    Polygons loops;
 | 
				
			||||||
 | 
					    this->make_loops(lines, &loops);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    Polygons cw;
 | 
				
			||||||
 | 
					    for (Polygons::const_iterator loop = loops.begin(); loop != loops.end(); ++loop) {
 | 
				
			||||||
 | 
					        if (loop->area() >= 0) {
 | 
				
			||||||
 | 
					            ExPolygon ex;
 | 
				
			||||||
 | 
					            ex.contour = *loop;
 | 
				
			||||||
 | 
					            slices->push_back(ex);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            cw.push_back(*loop);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // assign holes to contours
 | 
				
			||||||
 | 
					    for (Polygons::const_iterator loop = cw.begin(); loop != cw.end(); ++loop) {
 | 
				
			||||||
 | 
					        int slice_idx = -1;
 | 
				
			||||||
 | 
					        double current_contour_area = -1;
 | 
				
			||||||
 | 
					        for (ExPolygons::iterator slice = slices->begin(); slice != slices->end(); ++slice) {
 | 
				
			||||||
 | 
					            if (slice->contour.contains_point(loop->points.front())) {
 | 
				
			||||||
 | 
					                double area = slice->contour.area();
 | 
				
			||||||
 | 
					                if (area < current_contour_area || current_contour_area == -1) {
 | 
				
			||||||
 | 
					                    slice_idx = slice - slices->begin();
 | 
				
			||||||
 | 
					                    current_contour_area = area;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        (*slices)[slice_idx].holes.push_back(*loop);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
TriangleMeshSlicer::make_expolygons(const Polygons &loops, ExPolygons* slices)
 | 
					TriangleMeshSlicer::make_expolygons(const Polygons &loops, ExPolygons* slices)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -852,24 +886,27 @@ TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower)
 | 
				
			||||||
    if (upper != NULL) {
 | 
					    if (upper != NULL) {
 | 
				
			||||||
        // compute shape of section
 | 
					        // compute shape of section
 | 
				
			||||||
        ExPolygons section;
 | 
					        ExPolygons section;
 | 
				
			||||||
        this->make_expolygons(upper_lines, §ion);
 | 
					        this->make_expolygons_simple(upper_lines, §ion);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        // 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->triangulate(&triangles);
 | 
					            expolygon->triangulate2(&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) {
 | 
				
			||||||
            Polygon p = *polygon;
 | 
					            Polygon p = *polygon;
 | 
				
			||||||
            p.reverse();
 | 
					            p.reverse();
 | 
				
			||||||
            stl_facet facet;
 | 
					            stl_facet facet;
 | 
				
			||||||
 | 
					            facet.normal.x = 0;
 | 
				
			||||||
 | 
					            facet.normal.y = 0;
 | 
				
			||||||
 | 
					            facet.normal.z = -1;
 | 
				
			||||||
            for (size_t i = 0; i <= 2; ++i) {
 | 
					            for (size_t i = 0; i <= 2; ++i) {
 | 
				
			||||||
                facet.vertex[i].x = unscale(p.points[i].x);
 | 
					                facet.vertex[i].x = unscale(p.points[i].x);
 | 
				
			||||||
                facet.vertex[i].y = unscale(p.points[i].y);
 | 
					                facet.vertex[i].y = unscale(p.points[i].y);
 | 
				
			||||||
                facet.vertex[i].z = z;
 | 
					                facet.vertex[i].z = z;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            //stl_add_facet(&upper->stl, &facet);
 | 
					            stl_add_facet(&upper->stl, &facet);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
| 
						 | 
					@ -877,29 +914,32 @@ TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower)
 | 
				
			||||||
    if (lower != NULL) {
 | 
					    if (lower != NULL) {
 | 
				
			||||||
        // compute shape of section
 | 
					        // compute shape of section
 | 
				
			||||||
        ExPolygons section;
 | 
					        ExPolygons section;
 | 
				
			||||||
        this->make_expolygons(lower_lines, §ion);
 | 
					        this->make_expolygons_simple(lower_lines, §ion);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        // 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->triangulate(&triangles);
 | 
					            expolygon->triangulate2(&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) {
 | 
				
			||||||
            stl_facet facet;
 | 
					            stl_facet facet;
 | 
				
			||||||
 | 
					            facet.normal.x = 0;
 | 
				
			||||||
 | 
					            facet.normal.y = 0;
 | 
				
			||||||
 | 
					            facet.normal.z = 1;
 | 
				
			||||||
            for (size_t i = 0; i <= 2; ++i) {
 | 
					            for (size_t i = 0; i <= 2; ++i) {
 | 
				
			||||||
                facet.vertex[i].x = unscale(polygon->points[i].x);
 | 
					                facet.vertex[i].x = unscale(polygon->points[i].x);
 | 
				
			||||||
                facet.vertex[i].y = unscale(polygon->points[i].y);
 | 
					                facet.vertex[i].y = unscale(polygon->points[i].y);
 | 
				
			||||||
                facet.vertex[i].z = z;
 | 
					                facet.vertex[i].z = z;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            //stl_add_facet(&lower->stl, &facet);
 | 
					            stl_add_facet(&lower->stl, &facet);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    /*
 | 
					    
 | 
				
			||||||
    stl_get_size(&(upper->stl));
 | 
					    stl_get_size(&(upper->stl));
 | 
				
			||||||
    stl_get_size(&(lower->stl));
 | 
					    stl_get_size(&(lower->stl));
 | 
				
			||||||
    */
 | 
					    
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TriangleMeshSlicer::TriangleMeshSlicer(TriangleMesh* _mesh) : mesh(_mesh), v_scaled_shared(NULL)
 | 
					TriangleMeshSlicer::TriangleMeshSlicer(TriangleMesh* _mesh) : mesh(_mesh), v_scaled_shared(NULL)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -92,6 +92,7 @@ class TriangleMeshSlicer
 | 
				
			||||||
    stl_vertex* v_scaled_shared;
 | 
					    stl_vertex* v_scaled_shared;
 | 
				
			||||||
    void make_loops(std::vector<IntersectionLine> &lines, Polygons* loops);
 | 
					    void make_loops(std::vector<IntersectionLine> &lines, Polygons* loops);
 | 
				
			||||||
    void make_expolygons(const Polygons &loops, ExPolygons* slices);
 | 
					    void make_expolygons(const Polygons &loops, ExPolygons* slices);
 | 
				
			||||||
 | 
					    void make_expolygons_simple(std::vector<IntersectionLine> &lines, ExPolygons* slices);
 | 
				
			||||||
    void make_expolygons(std::vector<IntersectionLine> &lines, ExPolygons* slices);
 | 
					    void make_expolygons(std::vector<IntersectionLine> &lines, ExPolygons* slices);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1561
									
								
								xs/src/polypartition.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1561
									
								
								xs/src/polypartition.cpp
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										343
									
								
								xs/src/polypartition.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										343
									
								
								xs/src/polypartition.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,343 @@
 | 
				
			||||||
 | 
					//Copyright (C) 2011 by Ivan Fratric
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					//of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					//in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					//copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					//furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//The above copyright notice and this permission notice shall be included in
 | 
				
			||||||
 | 
					//all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
				
			||||||
 | 
					//THE SOFTWARE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <list>
 | 
				
			||||||
 | 
					using namespace std;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef double tppl_float;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TPPL_CCW 1
 | 
				
			||||||
 | 
					#define TPPL_CW -1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//2D point structure
 | 
				
			||||||
 | 
					struct TPPLPoint {
 | 
				
			||||||
 | 
						tppl_float x;
 | 
				
			||||||
 | 
						tppl_float y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TPPLPoint operator + (const TPPLPoint& p) const {
 | 
				
			||||||
 | 
							TPPLPoint r;
 | 
				
			||||||
 | 
							r.x = x + p.x;
 | 
				
			||||||
 | 
							r.y = y + p.y;
 | 
				
			||||||
 | 
							return r;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TPPLPoint operator - (const TPPLPoint& p) const {
 | 
				
			||||||
 | 
							TPPLPoint r;
 | 
				
			||||||
 | 
							r.x = x - p.x;
 | 
				
			||||||
 | 
							r.y = y - p.y;
 | 
				
			||||||
 | 
							return r;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TPPLPoint operator * (const tppl_float f ) const {
 | 
				
			||||||
 | 
							TPPLPoint r;
 | 
				
			||||||
 | 
							r.x = x*f;
 | 
				
			||||||
 | 
							r.y = y*f;
 | 
				
			||||||
 | 
							return r;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TPPLPoint operator / (const tppl_float f ) const {
 | 
				
			||||||
 | 
							TPPLPoint r;
 | 
				
			||||||
 | 
							r.x = x/f;
 | 
				
			||||||
 | 
							r.y = y/f;
 | 
				
			||||||
 | 
							return r;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool operator==(const TPPLPoint& p) const {
 | 
				
			||||||
 | 
							if((x == p.x)&&(y==p.y)) return true;
 | 
				
			||||||
 | 
							else return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool operator!=(const TPPLPoint& p) const {
 | 
				
			||||||
 | 
							if((x == p.x)&&(y==p.y)) return false;
 | 
				
			||||||
 | 
							else return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//Polygon implemented as an array of points with a 'hole' flag
 | 
				
			||||||
 | 
					class TPPLPoly {
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TPPLPoint *points;
 | 
				
			||||||
 | 
						long numpoints;
 | 
				
			||||||
 | 
						bool hole;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//constructors/destructors
 | 
				
			||||||
 | 
						TPPLPoly();
 | 
				
			||||||
 | 
						~TPPLPoly();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TPPLPoly(const TPPLPoly &src);
 | 
				
			||||||
 | 
						TPPLPoly& operator=(const TPPLPoly &src);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//getters and setters
 | 
				
			||||||
 | 
						long GetNumPoints() {
 | 
				
			||||||
 | 
							return numpoints;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool IsHole() {
 | 
				
			||||||
 | 
							return hole;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void SetHole(bool hole) {
 | 
				
			||||||
 | 
							this->hole = hole;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TPPLPoint &GetPoint(long i) {
 | 
				
			||||||
 | 
							return points[i];
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TPPLPoint *GetPoints() {
 | 
				
			||||||
 | 
							return points;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TPPLPoint& operator[] (int i) {
 | 
				
			||||||
 | 
							return points[i];	
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//clears the polygon points
 | 
				
			||||||
 | 
						void Clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//inits the polygon with numpoints vertices
 | 
				
			||||||
 | 
						void Init(long numpoints);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//creates a triangle with points p1,p2,p3
 | 
				
			||||||
 | 
						void Triangle(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//inverts the orfer of vertices
 | 
				
			||||||
 | 
						void Invert();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//returns the orientation of the polygon
 | 
				
			||||||
 | 
						//possible values:
 | 
				
			||||||
 | 
						//   TPPL_CCW : polygon vertices are in counter-clockwise order
 | 
				
			||||||
 | 
						//   TPPL_CW : polygon vertices are in clockwise order
 | 
				
			||||||
 | 
						//	 0 : the polygon has no (measurable) area
 | 
				
			||||||
 | 
						int GetOrientation();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//sets the polygon orientation
 | 
				
			||||||
 | 
						//orientation can be
 | 
				
			||||||
 | 
						//   TPPL_CCW : sets vertices in counter-clockwise order
 | 
				
			||||||
 | 
						//   TPPL_CW : sets vertices in clockwise order
 | 
				
			||||||
 | 
						void SetOrientation(int orientation);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TPPLPartition {
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
						struct PartitionVertex {
 | 
				
			||||||
 | 
							bool isActive;
 | 
				
			||||||
 | 
							bool isConvex;
 | 
				
			||||||
 | 
							bool isEar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							TPPLPoint p;
 | 
				
			||||||
 | 
							tppl_float angle;
 | 
				
			||||||
 | 
							PartitionVertex *previous;
 | 
				
			||||||
 | 
							PartitionVertex *next;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct MonotoneVertex {
 | 
				
			||||||
 | 
							TPPLPoint p;
 | 
				
			||||||
 | 
							long previous;
 | 
				
			||||||
 | 
							long next;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						class VertexSorter{
 | 
				
			||||||
 | 
							MonotoneVertex *vertices;
 | 
				
			||||||
 | 
						public:
 | 
				
			||||||
 | 
							VertexSorter(MonotoneVertex *v) : vertices(v) {}
 | 
				
			||||||
 | 
							bool operator() (long index1, long index2);
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct Diagonal {
 | 
				
			||||||
 | 
							long index1;
 | 
				
			||||||
 | 
							long index2;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//dynamic programming state for minimum-weight triangulation
 | 
				
			||||||
 | 
						struct DPState {
 | 
				
			||||||
 | 
							bool visible;
 | 
				
			||||||
 | 
							tppl_float weight;
 | 
				
			||||||
 | 
							long bestvertex;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//dynamic programming state for convex partitioning
 | 
				
			||||||
 | 
						struct DPState2 {
 | 
				
			||||||
 | 
							bool visible;
 | 
				
			||||||
 | 
							long weight;
 | 
				
			||||||
 | 
							list<Diagonal> pairs;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//edge that intersects the scanline
 | 
				
			||||||
 | 
						struct ScanLineEdge {
 | 
				
			||||||
 | 
							long index;
 | 
				
			||||||
 | 
							TPPLPoint p1;
 | 
				
			||||||
 | 
							TPPLPoint p2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							//determines if the edge is to the left of another edge
 | 
				
			||||||
 | 
							bool operator< (const ScanLineEdge & other) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							bool IsConvex(const TPPLPoint& p1, const TPPLPoint& p2, const TPPLPoint& p3) const;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//standard helper functions
 | 
				
			||||||
 | 
						bool IsConvex(TPPLPoint& p1, TPPLPoint& p2, TPPLPoint& p3);
 | 
				
			||||||
 | 
						bool IsReflex(TPPLPoint& p1, TPPLPoint& p2, TPPLPoint& p3);
 | 
				
			||||||
 | 
						bool IsInside(TPPLPoint& p1, TPPLPoint& p2, TPPLPoint& p3, TPPLPoint &p);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						bool InCone(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3, TPPLPoint &p);
 | 
				
			||||||
 | 
						bool InCone(PartitionVertex *v, TPPLPoint &p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int Intersects(TPPLPoint &p11, TPPLPoint &p12, TPPLPoint &p21, TPPLPoint &p22);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TPPLPoint Normalize(const TPPLPoint &p);
 | 
				
			||||||
 | 
						tppl_float Distance(const TPPLPoint &p1, const TPPLPoint &p2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//helper functions for Triangulate_EC
 | 
				
			||||||
 | 
						void UpdateVertexReflexity(PartitionVertex *v);
 | 
				
			||||||
 | 
						void UpdateVertex(PartitionVertex *v,PartitionVertex *vertices, long numvertices);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//helper functions for ConvexPartition_OPT
 | 
				
			||||||
 | 
						void UpdateState(long a, long b, long w, long i, long j, DPState2 **dpstates);
 | 
				
			||||||
 | 
						void TypeA(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates);
 | 
				
			||||||
 | 
						void TypeB(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//helper functions for MonotonePartition
 | 
				
			||||||
 | 
						bool Below(TPPLPoint &p1, TPPLPoint &p2);
 | 
				
			||||||
 | 
						void AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//triangulates a monotone polygon, used in Triangulate_MONO
 | 
				
			||||||
 | 
						int TriangulateMonotone(TPPLPoly *inPoly, list<TPPLPoly> *triangles);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//simple heuristic procedure for removing holes from a list of polygons
 | 
				
			||||||
 | 
						//works by creating a diagonal from the rightmost hole vertex to some visible vertex
 | 
				
			||||||
 | 
						//time complexity: O(h*(n^2)), h is the number of holes, n is the number of vertices
 | 
				
			||||||
 | 
						//space complexity: O(n)
 | 
				
			||||||
 | 
						//params:
 | 
				
			||||||
 | 
						//   inpolys : a list of polygons that can contain holes
 | 
				
			||||||
 | 
						//             vertices of all non-hole polys have to be in counter-clockwise order
 | 
				
			||||||
 | 
						//             vertices of all hole polys have to be in clockwise order
 | 
				
			||||||
 | 
						//   outpolys : a list of polygons without holes
 | 
				
			||||||
 | 
						//returns 1 on success, 0 on failure
 | 
				
			||||||
 | 
						int RemoveHoles(list<TPPLPoly> *inpolys, list<TPPLPoly> *outpolys);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//triangulates a polygon by ear clipping
 | 
				
			||||||
 | 
						//time complexity O(n^2), n is the number of vertices
 | 
				
			||||||
 | 
						//space complexity: O(n)
 | 
				
			||||||
 | 
						//params:
 | 
				
			||||||
 | 
						//   poly : an input polygon to be triangulated
 | 
				
			||||||
 | 
						//          vertices have to be in counter-clockwise order
 | 
				
			||||||
 | 
						//   triangles : a list of triangles (result)
 | 
				
			||||||
 | 
						//returns 1 on success, 0 on failure
 | 
				
			||||||
 | 
						int Triangulate_EC(TPPLPoly *poly, list<TPPLPoly> *triangles);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//triangulates a list of polygons that may contain holes by ear clipping algorithm
 | 
				
			||||||
 | 
						//first calls RemoveHoles to get rid of the holes, and then Triangulate_EC for each resulting polygon
 | 
				
			||||||
 | 
						//time complexity: O(h*(n^2)), h is the number of holes, n is the number of vertices
 | 
				
			||||||
 | 
						//space complexity: O(n)
 | 
				
			||||||
 | 
						//params:
 | 
				
			||||||
 | 
						//   inpolys : a list of polygons to be triangulated (can contain holes)
 | 
				
			||||||
 | 
						//             vertices of all non-hole polys have to be in counter-clockwise order
 | 
				
			||||||
 | 
						//             vertices of all hole polys have to be in clockwise order
 | 
				
			||||||
 | 
						//   triangles : a list of triangles (result)
 | 
				
			||||||
 | 
						//returns 1 on success, 0 on failure
 | 
				
			||||||
 | 
						int Triangulate_EC(list<TPPLPoly> *inpolys, list<TPPLPoly> *triangles);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//creates an optimal polygon triangulation in terms of minimal edge length
 | 
				
			||||||
 | 
						//time complexity: O(n^3), n is the number of vertices
 | 
				
			||||||
 | 
						//space complexity: O(n^2)
 | 
				
			||||||
 | 
						//params:
 | 
				
			||||||
 | 
						//   poly : an input polygon to be triangulated
 | 
				
			||||||
 | 
						//          vertices have to be in counter-clockwise order
 | 
				
			||||||
 | 
						//   triangles : a list of triangles (result)
 | 
				
			||||||
 | 
						//returns 1 on success, 0 on failure
 | 
				
			||||||
 | 
						int Triangulate_OPT(TPPLPoly *poly, list<TPPLPoly> *triangles);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//triangulates a polygons by firstly partitioning it into monotone polygons
 | 
				
			||||||
 | 
						//time complexity: O(n*log(n)), n is the number of vertices
 | 
				
			||||||
 | 
						//space complexity: O(n)
 | 
				
			||||||
 | 
						//params:
 | 
				
			||||||
 | 
						//   poly : an input polygon to be triangulated
 | 
				
			||||||
 | 
						//          vertices have to be in counter-clockwise order
 | 
				
			||||||
 | 
						//   triangles : a list of triangles (result)
 | 
				
			||||||
 | 
						//returns 1 on success, 0 on failure
 | 
				
			||||||
 | 
						int Triangulate_MONO(TPPLPoly *poly, list<TPPLPoly> *triangles);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//triangulates a list of polygons by firstly partitioning them into monotone polygons
 | 
				
			||||||
 | 
						//time complexity: O(n*log(n)), n is the number of vertices
 | 
				
			||||||
 | 
						//space complexity: O(n)
 | 
				
			||||||
 | 
						//params:
 | 
				
			||||||
 | 
						//   inpolys : a list of polygons to be triangulated (can contain holes)
 | 
				
			||||||
 | 
						//             vertices of all non-hole polys have to be in counter-clockwise order
 | 
				
			||||||
 | 
						//             vertices of all hole polys have to be in clockwise order
 | 
				
			||||||
 | 
						//   triangles : a list of triangles (result)
 | 
				
			||||||
 | 
						//returns 1 on success, 0 on failure
 | 
				
			||||||
 | 
						int Triangulate_MONO(list<TPPLPoly> *inpolys, list<TPPLPoly> *triangles);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//creates a monotone partition of a list of polygons that can contain holes
 | 
				
			||||||
 | 
						//time complexity: O(n*log(n)), n is the number of vertices
 | 
				
			||||||
 | 
						//space complexity: O(n)
 | 
				
			||||||
 | 
						//params:
 | 
				
			||||||
 | 
						//   inpolys : a list of polygons to be triangulated (can contain holes)
 | 
				
			||||||
 | 
						//             vertices of all non-hole polys have to be in counter-clockwise order
 | 
				
			||||||
 | 
						//             vertices of all hole polys have to be in clockwise order
 | 
				
			||||||
 | 
						//   monotonePolys : a list of monotone polygons (result)
 | 
				
			||||||
 | 
						//returns 1 on success, 0 on failure
 | 
				
			||||||
 | 
						int MonotonePartition(list<TPPLPoly> *inpolys, list<TPPLPoly> *monotonePolys);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//partitions a polygon into convex polygons by using Hertel-Mehlhorn algorithm
 | 
				
			||||||
 | 
						//the algorithm gives at most four times the number of parts as the optimal algorithm
 | 
				
			||||||
 | 
						//however, in practice it works much better than that and often gives optimal partition
 | 
				
			||||||
 | 
						//uses triangulation obtained by ear clipping as intermediate result
 | 
				
			||||||
 | 
						//time complexity O(n^2), n is the number of vertices
 | 
				
			||||||
 | 
						//space complexity: O(n)
 | 
				
			||||||
 | 
						//params:
 | 
				
			||||||
 | 
						//   poly : an input polygon to be partitioned
 | 
				
			||||||
 | 
						//          vertices have to be in counter-clockwise order
 | 
				
			||||||
 | 
						//   parts : resulting list of convex polygons
 | 
				
			||||||
 | 
						//returns 1 on success, 0 on failure
 | 
				
			||||||
 | 
						int ConvexPartition_HM(TPPLPoly *poly, list<TPPLPoly> *parts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//partitions a list of polygons into convex parts by using Hertel-Mehlhorn algorithm
 | 
				
			||||||
 | 
						//the algorithm gives at most four times the number of parts as the optimal algorithm
 | 
				
			||||||
 | 
						//however, in practice it works much better than that and often gives optimal partition
 | 
				
			||||||
 | 
						//uses triangulation obtained by ear clipping as intermediate result
 | 
				
			||||||
 | 
						//time complexity O(n^2), n is the number of vertices
 | 
				
			||||||
 | 
						//space complexity: O(n)
 | 
				
			||||||
 | 
						//params:
 | 
				
			||||||
 | 
						//   inpolys : an input list of polygons to be partitioned
 | 
				
			||||||
 | 
						//             vertices of all non-hole polys have to be in counter-clockwise order
 | 
				
			||||||
 | 
						//             vertices of all hole polys have to be in clockwise order
 | 
				
			||||||
 | 
						//   parts : resulting list of convex polygons
 | 
				
			||||||
 | 
						//returns 1 on success, 0 on failure
 | 
				
			||||||
 | 
						int ConvexPartition_HM(list<TPPLPoly> *inpolys, list<TPPLPoly> *parts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//optimal convex partitioning (in terms of number of resulting convex polygons)
 | 
				
			||||||
 | 
						//using the Keil-Snoeyink algorithm
 | 
				
			||||||
 | 
						//M. Keil, J. Snoeyink, "On the time bound for convex decomposition of simple polygons", 1998
 | 
				
			||||||
 | 
						//time complexity O(n^3), n is the number of vertices
 | 
				
			||||||
 | 
						//space complexity: O(n^3)
 | 
				
			||||||
 | 
						//   poly : an input polygon to be partitioned
 | 
				
			||||||
 | 
						//          vertices have to be in counter-clockwise order
 | 
				
			||||||
 | 
						//   parts : resulting list of convex polygons
 | 
				
			||||||
 | 
						//returns 1 on success, 0 on failure
 | 
				
			||||||
 | 
						int ConvexPartition_OPT(TPPLPoly *poly, list<TPPLPoly> *parts);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -33,6 +33,8 @@
 | 
				
			||||||
        %code{% THIS->get_trapezoids(&RETVAL, angle); %};
 | 
					        %code{% THIS->get_trapezoids(&RETVAL, angle); %};
 | 
				
			||||||
    Polygons triangulate()
 | 
					    Polygons triangulate()
 | 
				
			||||||
        %code{% THIS->triangulate(&RETVAL); %};
 | 
					        %code{% THIS->triangulate(&RETVAL); %};
 | 
				
			||||||
 | 
					    Polygons triangulate2()
 | 
				
			||||||
 | 
					        %code{% THIS->triangulate2(&RETVAL); %};
 | 
				
			||||||
%{
 | 
					%{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ExPolygon*
 | 
					ExPolygon*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue