More porting work

This commit is contained in:
Alessandro Ranellucci 2013-09-07 21:08:53 +02:00
parent 346c17d483
commit 5adb187dd2
5 changed files with 184 additions and 6 deletions

View file

@ -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: