mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	More porting work
This commit is contained in:
		
							parent
							
								
									346c17d483
								
							
						
					
					
						commit
						5adb187dd2
					
				
					 5 changed files with 184 additions and 6 deletions
				
			
		|  | @ -414,10 +414,13 @@ sub intersect_facet { | |||
|     my $self = shift; | ||||
|     my ($facet_id, $z) = @_; | ||||
|      | ||||
|     my @vertices_ids        = @{$self->facets->[$facet_id]}[-3..-1]; | ||||
|     my %vertices            = map { $_ => $self->vertices->[$_] } @vertices_ids;  # cache vertices | ||||
|     my @edge_ids            = @{$self->facets_edges->[$facet_id]}; | ||||
|     my @edge_vertices_ids   = $self->_facet_edges($facet_id); | ||||
|     my %vertices; | ||||
|     { | ||||
|         my @vertices_ids    = @{$self->facets->[$facet_id]}[-3..-1]; | ||||
|         %vertices           = map { $_ => $self->vertices->[$_] } @vertices_ids;  # cache vertices | ||||
|     } | ||||
|      | ||||
|     my (@points, @intersection_points, @points_on_layer) = (); | ||||
|          | ||||
|  | @ -428,7 +431,7 @@ sub intersect_facet { | |||
|          | ||||
|         if ($a->[Z] == $b->[Z] && $a->[Z] == $z) { | ||||
|             # edge is horizontal and belongs to the current layer | ||||
|             my $edge_type = (grep $vertices{$_}[Z] < $z, @vertices_ids) ? FE_TOP : FE_BOTTOM; | ||||
|             my $edge_type = (grep $_->[Z] < $z, values %vertices) ? FE_TOP : FE_BOTTOM; | ||||
|             if ($edge_type == FE_TOP) { | ||||
|                 ($a, $b) = ($b, $a); | ||||
|                 ($a_id, $b_id) = ($b_id, $a_id); | ||||
|  |  | |||
|  | @ -24,7 +24,7 @@ my $build = Module::Build::WithXSpp->new( | |||
|     # _GLIBCXX_USE_C99 : to get the long long type for g++ | ||||
|     # HAS_BOOL         : stops Perl/lib/CORE/handy.h from doing "#  define bool char" for MSVC | ||||
|     # NOGDI            : prevents inclusion of wingdi.h which defines functions Polygon() and Polyline() in global namespace | ||||
|     extra_compiler_flags => [qw(-D_GLIBCXX_USE_C99 -DHAS_BOOL -DNOGDI), ($ENV{SLIC3R_DEBUG} ? ' -DSLIC3R_DEBUG' : '')], | ||||
|     extra_compiler_flags => [qw(-D_GLIBCXX_USE_C99 -DHAS_BOOL -DNOGDI), ($ENV{SLIC3R_DEBUG} ? ' -DSLIC3R_DEBUG -g' : '')], | ||||
|      | ||||
|     # Provides extra C typemaps that are auto-merged | ||||
|     extra_typemap_modules => { | ||||
|  |  | |||
|  | @ -1,6 +1,10 @@ | |||
| #include "TriangleMesh.hpp" | ||||
| #include <vector> | ||||
| #include <map> | ||||
| #include <utility> | ||||
| #include <algorithm> | ||||
| #include <math.h> | ||||
| #include <assert.h> | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| 
 | ||||
|  | @ -160,12 +164,55 @@ TriangleMesh::slice(const std::vector<double> &z) | |||
|         FUTURE: parallelize slice_facet() and make_loops() | ||||
|     */ | ||||
|      | ||||
|     // build a table to map a facet_idx to its three edge indices
 | ||||
|     if (this->stl.v_shared == NULL) stl_generate_shared_vertices(&(this->stl)); | ||||
|     typedef std::pair<int,int>              t_edge; | ||||
|     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_map edges_map; | ||||
|         for (int facet_idx = 0; facet_idx < this->stl.stats.number_of_facets; facet_idx++) { | ||||
|             facets_edges[facet_idx].resize(3); | ||||
|             for (int i = 0; i <= 2; i++) { | ||||
|                 int a_id = this->stl.v_indices[facet_idx].vertex[i]; | ||||
|                 int b_id = this->stl.v_indices[facet_idx].vertex[(i+1) % 3]; | ||||
|                  | ||||
|                 int edge_idx; | ||||
|                 t_edges_map::const_iterator my_edge = edges_map.find(std::make_pair(b_id,a_id)); | ||||
|                 if (my_edge == edges_map.end()) { | ||||
|                     // edge isn't listed in table, so we insert it
 | ||||
|                     edge_idx = edges.size(); | ||||
|                     edges.push_back(std::make_pair(a_id,b_id)); | ||||
|                     edges_map[ edges[edge_idx] ] = edge_idx; | ||||
|                 } else { | ||||
|                     edge_idx = my_edge->second; | ||||
|                 } | ||||
|                 facets_edges[facet_idx][i] = edge_idx; | ||||
|                  | ||||
|                 #ifdef SLIC3R_DEBUG | ||||
|                 printf("  [facet %d, edge %d] a_id = %d, b_id = %d   --> edge %d\n", facet_idx, i, a_id, b_id, edge_idx); | ||||
|                 #endif | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     std::vector<IntersectionLines> lines(z.size()); | ||||
|      | ||||
|     for (int facet_idx = 0; facet_idx < this->stl.stats.number_of_facets; facet_idx++) { | ||||
|         stl_facet facet = this->stl.facet_start[facet_idx];  // this is a copy
 | ||||
|          | ||||
|         /* 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 | ||||
|            (external on the right of the line) */ | ||||
|         /*
 | ||||
|         float min_z; | ||||
|         if (facet.vertex[1].z < facet.vertex[0].z && facet.vertex[1].z < facet.vertex[2].z) { | ||||
|             // vertex 1 has lowest Z
 | ||||
|  | @ -184,6 +231,8 @@ TriangleMesh::slice(const std::vector<double> &z) | |||
|         } else { | ||||
|             min_z = facet.vertex[0].z; | ||||
|         } | ||||
|         */ | ||||
|         float min_z = fminf(facet.vertex[0].z, fminf(facet.vertex[1].z, facet.vertex[2].z)); | ||||
|         float max_z = fmaxf(facet.vertex[0].z, fmaxf(facet.vertex[1].z, facet.vertex[2].z)); | ||||
|          | ||||
|         #ifdef SLIC3R_DEBUG | ||||
|  | @ -208,12 +257,114 @@ TriangleMesh::slice(const std::vector<double> &z) | |||
|         printf("layers: min = %d, max = %d\n", (int)(min_layer - z.begin()), (int)(max_layer - z.begin())); | ||||
|         #endif | ||||
|          | ||||
|         for (std::vector<double>::const_iterator it = z.begin(); it != z.end(); ++it) { | ||||
|         for (std::vector<double>::const_iterator it = min_layer; it != max_layer + 1; ++it) { | ||||
|             std::vector<double>::size_type layer_idx = it - z.begin(); | ||||
|             double slice_z = *it; | ||||
|             std::vector<IntersectionPoint> points; | ||||
|             std::vector< std::vector<IntersectionPoint>::size_type > points_on_layer, intersection_points; | ||||
|              | ||||
|             for (int i = 0; i <= 2; i++) {  // loop through facet edges
 | ||||
|                 int edge_id = facets_edges[facet_idx][i]; | ||||
|                 t_edge edge = edges[edge_id]; | ||||
|                  | ||||
|                 stl_vertex* a = &(this->stl.v_shared[edge.first]); | ||||
|                 stl_vertex* b = &(this->stl.v_shared[edge.second]); | ||||
|                  | ||||
|                 #ifdef SLIC3R_DEBUG | ||||
|                 printf("  a = %f, b = %f, slice_z = %f\n", a->z, b->z, slice_z); | ||||
|                 #endif | ||||
|                  | ||||
|                 if (a->z == b->z && a->z == slice_z) { | ||||
|                     // edge is horizontal and belongs to the current layer
 | ||||
|                     #ifdef SLIC3R_DEBUG | ||||
|                     printf("Edge is horizontal!\n"); | ||||
|                     #endif | ||||
|                      | ||||
|                     /* 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; | ||||
|                     } else { | ||||
|                         line.edge_type = feBottom; | ||||
|                     } | ||||
|                     lines[layer_idx].push_back(line); | ||||
|                 } else if (a->z == slice_z) { | ||||
|                     #ifdef SLIC3R_DEBUG | ||||
|                     printf("A point on plane!\n"); | ||||
|                     #endif | ||||
|                      | ||||
|                     IntersectionPoint point; | ||||
|                     point.x         = a->x; | ||||
|                     point.y         = a->y; | ||||
|                     point.point_id  = edge.first; | ||||
|                     points.push_back(point); | ||||
|                     points_on_layer.push_back(points.size()-1); | ||||
|                 } else if (b->z == slice_z) { | ||||
|                     #ifdef SLIC3R_DEBUG | ||||
|                     printf("B point on plane!\n"); | ||||
|                     #endif | ||||
|                      | ||||
|                     IntersectionPoint point; | ||||
|                     point.x         = b->x; | ||||
|                     point.y         = b->y; | ||||
|                     point.point_id  = edge.second; | ||||
|                     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)) { | ||||
|                     // edge intersects the current layer; calculate intersection
 | ||||
|                     #ifdef SLIC3R_DEBUG | ||||
|                     printf("Intersects!\n"); | ||||
|                     #endif | ||||
|                      | ||||
|                     IntersectionPoint point; | ||||
|                     point.x         = b->x + (a->x - b->x) * (slice_z - b->z) / (a->z - b->z); | ||||
|                     point.y         = b->y + (a->y - b->y) * (slice_z - b->z) / (a->z - b->z); | ||||
|                     point.edge_id  = edge_id; | ||||
|                     points.push_back(point); | ||||
|                     intersection_points.push_back(points.size()-1); | ||||
|                 } | ||||
|             } | ||||
|              | ||||
|             if (points_on_layer.size() == 2) { | ||||
|                 if (intersection_points.size() == 1) { | ||||
|                      | ||||
|                 } else if (intersection_points.empty()) { | ||||
|                     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; | ||||
|                 line.b.x        = points[0].x; | ||||
|                 line.b.y        = points[0].y; | ||||
|                 line.a_id       = points[1].point_id; | ||||
|                 line.b_id       = points[0].point_id; | ||||
|                 line.edge_a_id  = points[1].edge_id; | ||||
|                 line.edge_b_id  = points[0].edge_id; | ||||
|                 lines[layer_idx].push_back(line); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     // build loops
 | ||||
|     std::vector<Polygons>* layers = new std::vector<Polygons>(z.size()); | ||||
|     for (std::vector<IntersectionLines>::const_iterator it = lines.begin(); it != lines.end(); ++it) { | ||||
|          | ||||
|     } | ||||
|      | ||||
|     // ...
 | ||||
|     // add a Polygon p to layer n:
 | ||||
|  |  | |||
|  | @ -26,6 +26,30 @@ class TriangleMesh | |||
|     stl_file stl; | ||||
| }; | ||||
| 
 | ||||
| enum FacetEdgeType { feNone, feTop, feBottom }; | ||||
| 
 | ||||
| class IntersectionPoint : public Point | ||||
| { | ||||
|     public: | ||||
|     int point_id; | ||||
|     int edge_id; | ||||
|     IntersectionPoint() : point_id(-1), edge_id(-1) {}; | ||||
| }; | ||||
| 
 | ||||
| class IntersectionLine | ||||
| { | ||||
|     public: | ||||
|     Point           a; | ||||
|     Point           b; | ||||
|     int             a_id; | ||||
|     int             b_id; | ||||
|     int             edge_a_id; | ||||
|     int             edge_b_id; | ||||
|     FacetEdgeType   edge_type; | ||||
|     IntersectionLine() : a_id(-1), b_id(-1), edge_a_id(-1), edge_b_id(-1), edge_type(feNone) {}; | ||||
| }; | ||||
| typedef std::vector<IntersectionLine> IntersectionLines; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -48,7 +48,7 @@ my $cube = { | |||
|     my $m = Slic3r::TriangleMesh::XS->new; | ||||
|     $m->ReadFromPerl($cube->{vertices}, $cube->{facets}); | ||||
|     $m->Repair; | ||||
|     my $result = $m->slice([2,4,8,6,8,10,12,14,16,18]); | ||||
|     my $result = $m->slice([2,4,8,6,8,10,12,14,16,18,20]); | ||||
| } | ||||
| 
 | ||||
| __END__ | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci