mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	Almost finished porting slice()
This commit is contained in:
		
							parent
							
								
									46bd407da4
								
							
						
					
					
						commit
						dbf739318a
					
				
					 2 changed files with 43 additions and 25 deletions
				
			
		| 
						 | 
				
			
			@ -170,14 +170,14 @@ TriangleMesh::slice(const std::vector<double> &z)
 | 
			
		|||
    typedef std::vector<t_edge>             t_edges;  // edge_idx => a_id,b_id
 | 
			
		||||
    typedef std::map<t_edge,int>            t_edges_map;  // a_id,b_id => edge_idx
 | 
			
		||||
    typedef std::vector< std::vector<int> > t_facets_edges;
 | 
			
		||||
    t_edges        edges;
 | 
			
		||||
    t_facets_edges facets_edges;
 | 
			
		||||
    
 | 
			
		||||
    // reserve() instad of resize() because otherwise we couldn't read .size() below to assign edge_idx
 | 
			
		||||
    edges.reserve(this->stl.stats.number_of_facets * 3);  // number of edges = number of facets * 3
 | 
			
		||||
    facets_edges.resize(this->stl.stats.number_of_facets);
 | 
			
		||||
    
 | 
			
		||||
    {
 | 
			
		||||
        t_edges edges;
 | 
			
		||||
        // reserve() instad of resize() because otherwise we couldn't read .size() below to assign edge_idx
 | 
			
		||||
        edges.reserve(this->stl.stats.number_of_facets * 3);  // number of edges = number of facets * 3
 | 
			
		||||
        t_edges_map edges_map;
 | 
			
		||||
        for (int facet_idx = 0; facet_idx < this->stl.stats.number_of_facets; facet_idx++) {
 | 
			
		||||
            facets_edges[facet_idx].resize(3);
 | 
			
		||||
| 
						 | 
				
			
			@ -238,6 +238,7 @@ TriangleMesh::slice(const std::vector<double> &z)
 | 
			
		|||
            double slice_z = *it;
 | 
			
		||||
            std::vector<IntersectionPoint> points;
 | 
			
		||||
            std::vector< std::vector<IntersectionPoint>::size_type > points_on_layer, intersection_points;
 | 
			
		||||
            bool found_horizontal_edge = false;
 | 
			
		||||
            
 | 
			
		||||
            /* reorder vertices so that the first one is the one with lowest Z
 | 
			
		||||
               this is needed to get all intersection lines in a consistent order
 | 
			
		||||
| 
						 | 
				
			
			@ -252,10 +253,10 @@ TriangleMesh::slice(const std::vector<double> &z)
 | 
			
		|||
            }
 | 
			
		||||
            for (int j = i; (j-i) < 3; j++) {  // loop through facet edges
 | 
			
		||||
                int edge_id = facets_edges[facet_idx][j % 3];
 | 
			
		||||
                t_edge edge = edges[edge_id];
 | 
			
		||||
                
 | 
			
		||||
                stl_vertex* a = &(this->stl.v_shared[edge.first]);
 | 
			
		||||
                stl_vertex* b = &(this->stl.v_shared[edge.second]);
 | 
			
		||||
                int a_id = this->stl.v_indices[facet_idx].vertex[j % 3];
 | 
			
		||||
                int b_id = this->stl.v_indices[facet_idx].vertex[(j+1) % 3];
 | 
			
		||||
                stl_vertex* a = &(this->stl.v_shared[a_id]);
 | 
			
		||||
                stl_vertex* b = &(this->stl.v_shared[b_id]);
 | 
			
		||||
                
 | 
			
		||||
                if (a->z == b->z && a->z == slice_z) {
 | 
			
		||||
                    // edge is horizontal and belongs to the current layer
 | 
			
		||||
| 
						 | 
				
			
			@ -266,21 +267,25 @@ TriangleMesh::slice(const std::vector<double> &z)
 | 
			
		|||
                    /* We assume that this method is never being called for horizontal
 | 
			
		||||
                       facets, so no other edge is going to be on this layer. */
 | 
			
		||||
                    IntersectionLine line;
 | 
			
		||||
                    line.a.x    = a->x;
 | 
			
		||||
                    line.a.y    = a->y;
 | 
			
		||||
                    line.b.x    = b->x;
 | 
			
		||||
                    line.b.y    = b->y;
 | 
			
		||||
                    line.a_id   = edge.first;
 | 
			
		||||
                    line.b_id   = edge.second;
 | 
			
		||||
                    
 | 
			
		||||
                    if (this->stl.v_indices[facet_idx].vertex[0] < slice_z
 | 
			
		||||
                        || this->stl.v_indices[facet_idx].vertex[1] < slice_z
 | 
			
		||||
                        || this->stl.v_indices[facet_idx].vertex[2] < slice_z) {
 | 
			
		||||
                        line.edge_type = feTop;
 | 
			
		||||
                        std::swap(a, b);
 | 
			
		||||
                        std::swap(a_id, b_id);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        line.edge_type = feBottom;
 | 
			
		||||
                    }
 | 
			
		||||
                    line.a.x    = a->x;
 | 
			
		||||
                    line.a.y    = a->y;
 | 
			
		||||
                    line.b.x    = b->x;
 | 
			
		||||
                    line.b.y    = b->y;
 | 
			
		||||
                    line.a_id   = a_id;
 | 
			
		||||
                    line.b_id   = b_id;
 | 
			
		||||
                    
 | 
			
		||||
                    lines[layer_idx].push_back(line);
 | 
			
		||||
                    found_horizontal_edge = true;
 | 
			
		||||
                    break;
 | 
			
		||||
                } else if (a->z == slice_z) {
 | 
			
		||||
                    #ifdef SLIC3R_DEBUG
 | 
			
		||||
                    printf("A point on plane!\n");
 | 
			
		||||
| 
						 | 
				
			
			@ -289,7 +294,7 @@ TriangleMesh::slice(const std::vector<double> &z)
 | 
			
		|||
                    IntersectionPoint point;
 | 
			
		||||
                    point.x         = a->x;
 | 
			
		||||
                    point.y         = a->y;
 | 
			
		||||
                    point.point_id  = edge.first;
 | 
			
		||||
                    point.point_id  = a_id;
 | 
			
		||||
                    points.push_back(point);
 | 
			
		||||
                    points_on_layer.push_back(points.size()-1);
 | 
			
		||||
                } else if (b->z == slice_z) {
 | 
			
		||||
| 
						 | 
				
			
			@ -300,7 +305,7 @@ TriangleMesh::slice(const std::vector<double> &z)
 | 
			
		|||
                    IntersectionPoint point;
 | 
			
		||||
                    point.x         = b->x;
 | 
			
		||||
                    point.y         = b->y;
 | 
			
		||||
                    point.point_id  = edge.second;
 | 
			
		||||
                    point.point_id  = b_id;
 | 
			
		||||
                    points.push_back(point);
 | 
			
		||||
                    points_on_layer.push_back(points.size()-1);
 | 
			
		||||
                } else if ((a->z < slice_z && b->z > slice_z) || (b->z < slice_z && a->z > slice_z)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -317,18 +322,20 @@ TriangleMesh::slice(const std::vector<double> &z)
 | 
			
		|||
                    intersection_points.push_back(points.size()-1);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (found_horizontal_edge) continue;
 | 
			
		||||
            
 | 
			
		||||
            if (points_on_layer.size() == 2) {
 | 
			
		||||
                if (intersection_points.size() == 1) {
 | 
			
		||||
                    points.erase( points.begin() + points_on_layer[1] );
 | 
			
		||||
                } else if (intersection_points.empty()) {
 | 
			
		||||
                    if (points[ points_on_layer[0] ].coincides_with(&points[ points_on_layer[1] ])) continue;
 | 
			
		||||
                    if (points[ points_on_layer[0] ].coincides_with(&points[ points_on_layer[1] ])) {
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            if (!points.empty()) {
 | 
			
		||||
                assert(points.size() == 2); // facets must intersect each plane 0 or 2 times
 | 
			
		||||
                
 | 
			
		||||
                IntersectionLine line;
 | 
			
		||||
                line.a.x        = points[1].x;
 | 
			
		||||
                line.a.y        = points[1].y;
 | 
			
		||||
| 
						 | 
				
			
			@ -349,12 +356,12 @@ TriangleMesh::slice(const std::vector<double> &z)
 | 
			
		|||
        int layer_idx = it - lines.begin();
 | 
			
		||||
        
 | 
			
		||||
        // remove tangent edges
 | 
			
		||||
        for (IntersectionLines::iterator line = (*it).begin(); line != (*it).end(); ++line) {
 | 
			
		||||
        for (IntersectionLines::iterator line = it->begin(); line != it->end(); ++line) {
 | 
			
		||||
            if (line->skip || line->edge_type == feNone) continue;
 | 
			
		||||
            
 | 
			
		||||
            /* if the line is a facet edge, find another facet edge
 | 
			
		||||
               having the same endpoints but in reverse order */
 | 
			
		||||
            for (IntersectionLines::iterator line2 = line + 1; line2 != (*it).end(); ++line2) {
 | 
			
		||||
            for (IntersectionLines::iterator line2 = line + 1; line2 != it->end(); ++line2) {
 | 
			
		||||
                if (line2->skip || line2->edge_type == feNone) continue;
 | 
			
		||||
                
 | 
			
		||||
                // are these facets adjacent? (sharing a common edge on this layer)
 | 
			
		||||
| 
						 | 
				
			
			@ -377,9 +384,9 @@ TriangleMesh::slice(const std::vector<double> &z)
 | 
			
		|||
        
 | 
			
		||||
        // build a map of lines by edge_a_id and a_id
 | 
			
		||||
        std::vector<IntersectionLinePtrs> by_edge_a_id, by_a_id;
 | 
			
		||||
        by_edge_a_id.resize(edges.size());
 | 
			
		||||
        by_edge_a_id.resize(this->stl.stats.number_of_facets * 3);
 | 
			
		||||
        by_a_id.resize(this->stl.stats.shared_vertices);
 | 
			
		||||
        for (IntersectionLines::iterator line = (*it).begin(); line != (*it).end(); ++line) {
 | 
			
		||||
        for (IntersectionLines::iterator line = it->begin(); line != it->end(); ++line) {
 | 
			
		||||
            if (line->skip) continue;
 | 
			
		||||
            if (line->edge_a_id != -1) by_edge_a_id[line->edge_a_id].push_back(&(*line));
 | 
			
		||||
            if (line->a_id != -1) by_a_id[line->a_id].push_back(&(*line));
 | 
			
		||||
| 
						 | 
				
			
			@ -388,7 +395,7 @@ TriangleMesh::slice(const std::vector<double> &z)
 | 
			
		|||
        CYCLE: while (1) {
 | 
			
		||||
            // take first spare line and start a new loop
 | 
			
		||||
            IntersectionLine* first_line = NULL;
 | 
			
		||||
            for (IntersectionLines::iterator line = (*it).begin(); line != (*it).end(); ++line) {
 | 
			
		||||
            for (IntersectionLines::iterator line = it->begin(); line != it->end(); ++line) {
 | 
			
		||||
                if (line->skip) continue;
 | 
			
		||||
                first_line = &(*line);
 | 
			
		||||
                break;
 | 
			
		||||
| 
						 | 
				
			
			@ -398,6 +405,12 @@ TriangleMesh::slice(const std::vector<double> &z)
 | 
			
		|||
            IntersectionLinePtrs loop;
 | 
			
		||||
            loop.push_back(first_line);
 | 
			
		||||
            
 | 
			
		||||
            /*
 | 
			
		||||
            printf("first_line edge_a_id = %d, edge_b_id = %d, a_id = %d, b_id = %d, a = %d,%d, b = %d,%d\n", 
 | 
			
		||||
                first_line->edge_a_id, first_line->edge_b_id, first_line->a_id, first_line->b_id,
 | 
			
		||||
                first_line->a.x, first_line->a.y, first_line->b.x, first_line->b.y);
 | 
			
		||||
            */
 | 
			
		||||
            
 | 
			
		||||
            while (1) {
 | 
			
		||||
                // find a line starting where last one finishes
 | 
			
		||||
                IntersectionLine* next_line = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -441,6 +454,11 @@ TriangleMesh::slice(const std::vector<double> &z)
 | 
			
		|||
                    //// push @failed_loops, [@loop];
 | 
			
		||||
                    goto CYCLE;
 | 
			
		||||
                }
 | 
			
		||||
                /*
 | 
			
		||||
                printf("next_line edge_a_id = %d, edge_b_id = %d, a_id = %d, b_id = %d, a = %d,%d, b = %d,%d\n", 
 | 
			
		||||
                    next_line->edge_a_id, next_line->edge_b_id, next_line->a_id, next_line->b_id,
 | 
			
		||||
                    next_line->a.x, next_line->a.y, next_line->b.x, next_line->b.y);
 | 
			
		||||
                */
 | 
			
		||||
                loop.push_back(next_line);
 | 
			
		||||
                next_line->skip = true;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@ use strict;
 | 
			
		|||
use warnings;
 | 
			
		||||
 | 
			
		||||
use Slic3r::XS;
 | 
			
		||||
use Test::More tests => 10;
 | 
			
		||||
use Test::More tests => 43;
 | 
			
		||||
 | 
			
		||||
is Slic3r::TriangleMesh::XS::hello_world(), 'Hello world!',
 | 
			
		||||
    'hello world';
 | 
			
		||||
| 
						 | 
				
			
			@ -44,7 +44,7 @@ my $cube = {
 | 
			
		|||
    ok abs($m->size->[0] - sqrt(2)*40) < 1E-4, 'rotate';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (0) {
 | 
			
		||||
{
 | 
			
		||||
    my $m = Slic3r::TriangleMesh::XS->new;
 | 
			
		||||
    $m->ReadFromPerl($cube->{vertices}, $cube->{facets});
 | 
			
		||||
    $m->Repair;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue