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

@ -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);

View File

@ -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 => {

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:

View File

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

View File

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