Almost finished porting slice()
This commit is contained in:
parent
46bd407da4
commit
dbf739318a
@ -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::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::map<t_edge,int> t_edges_map; // a_id,b_id => edge_idx
|
||||||
typedef std::vector< std::vector<int> > t_facets_edges;
|
typedef std::vector< std::vector<int> > t_facets_edges;
|
||||||
t_edges edges;
|
|
||||||
t_facets_edges facets_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);
|
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;
|
t_edges_map edges_map;
|
||||||
for (int facet_idx = 0; facet_idx < this->stl.stats.number_of_facets; facet_idx++) {
|
for (int facet_idx = 0; facet_idx < this->stl.stats.number_of_facets; facet_idx++) {
|
||||||
facets_edges[facet_idx].resize(3);
|
facets_edges[facet_idx].resize(3);
|
||||||
@ -238,6 +238,7 @@ TriangleMesh::slice(const std::vector<double> &z)
|
|||||||
double slice_z = *it;
|
double slice_z = *it;
|
||||||
std::vector<IntersectionPoint> points;
|
std::vector<IntersectionPoint> points;
|
||||||
std::vector< std::vector<IntersectionPoint>::size_type > points_on_layer, intersection_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
|
/* 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
|
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
|
for (int j = i; (j-i) < 3; j++) { // loop through facet edges
|
||||||
int edge_id = facets_edges[facet_idx][j % 3];
|
int edge_id = facets_edges[facet_idx][j % 3];
|
||||||
t_edge edge = edges[edge_id];
|
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[edge.first]);
|
stl_vertex* a = &(this->stl.v_shared[a_id]);
|
||||||
stl_vertex* b = &(this->stl.v_shared[edge.second]);
|
stl_vertex* b = &(this->stl.v_shared[b_id]);
|
||||||
|
|
||||||
if (a->z == b->z && a->z == slice_z) {
|
if (a->z == b->z && a->z == slice_z) {
|
||||||
// edge is horizontal and belongs to the current layer
|
// 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
|
/* We assume that this method is never being called for horizontal
|
||||||
facets, so no other edge is going to be on this layer. */
|
facets, so no other edge is going to be on this layer. */
|
||||||
IntersectionLine line;
|
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
|
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[1] < slice_z
|
||||||
|| this->stl.v_indices[facet_idx].vertex[2] < slice_z) {
|
|| this->stl.v_indices[facet_idx].vertex[2] < slice_z) {
|
||||||
line.edge_type = feTop;
|
line.edge_type = feTop;
|
||||||
|
std::swap(a, b);
|
||||||
|
std::swap(a_id, b_id);
|
||||||
} else {
|
} else {
|
||||||
line.edge_type = feBottom;
|
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);
|
lines[layer_idx].push_back(line);
|
||||||
|
found_horizontal_edge = true;
|
||||||
|
break;
|
||||||
} else if (a->z == slice_z) {
|
} else if (a->z == slice_z) {
|
||||||
#ifdef SLIC3R_DEBUG
|
#ifdef SLIC3R_DEBUG
|
||||||
printf("A point on plane!\n");
|
printf("A point on plane!\n");
|
||||||
@ -289,7 +294,7 @@ TriangleMesh::slice(const std::vector<double> &z)
|
|||||||
IntersectionPoint point;
|
IntersectionPoint point;
|
||||||
point.x = a->x;
|
point.x = a->x;
|
||||||
point.y = a->y;
|
point.y = a->y;
|
||||||
point.point_id = edge.first;
|
point.point_id = a_id;
|
||||||
points.push_back(point);
|
points.push_back(point);
|
||||||
points_on_layer.push_back(points.size()-1);
|
points_on_layer.push_back(points.size()-1);
|
||||||
} else if (b->z == slice_z) {
|
} else if (b->z == slice_z) {
|
||||||
@ -300,7 +305,7 @@ TriangleMesh::slice(const std::vector<double> &z)
|
|||||||
IntersectionPoint point;
|
IntersectionPoint point;
|
||||||
point.x = b->x;
|
point.x = b->x;
|
||||||
point.y = b->y;
|
point.y = b->y;
|
||||||
point.point_id = edge.second;
|
point.point_id = b_id;
|
||||||
points.push_back(point);
|
points.push_back(point);
|
||||||
points_on_layer.push_back(points.size()-1);
|
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)) {
|
} 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);
|
intersection_points.push_back(points.size()-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (found_horizontal_edge) continue;
|
||||||
|
|
||||||
if (points_on_layer.size() == 2) {
|
if (points_on_layer.size() == 2) {
|
||||||
if (intersection_points.size() == 1) {
|
if (intersection_points.size() == 1) {
|
||||||
points.erase( points.begin() + points_on_layer[1] );
|
points.erase( points.begin() + points_on_layer[1] );
|
||||||
} else if (intersection_points.empty()) {
|
} 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()) {
|
if (!points.empty()) {
|
||||||
assert(points.size() == 2); // facets must intersect each plane 0 or 2 times
|
assert(points.size() == 2); // facets must intersect each plane 0 or 2 times
|
||||||
|
|
||||||
IntersectionLine line;
|
IntersectionLine line;
|
||||||
line.a.x = points[1].x;
|
line.a.x = points[1].x;
|
||||||
line.a.y = points[1].y;
|
line.a.y = points[1].y;
|
||||||
@ -349,12 +356,12 @@ TriangleMesh::slice(const std::vector<double> &z)
|
|||||||
int layer_idx = it - lines.begin();
|
int layer_idx = it - lines.begin();
|
||||||
|
|
||||||
// remove tangent edges
|
// 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 (line->skip || line->edge_type == feNone) continue;
|
||||||
|
|
||||||
/* if the line is a facet edge, find another facet edge
|
/* if the line is a facet edge, find another facet edge
|
||||||
having the same endpoints but in reverse order */
|
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;
|
if (line2->skip || line2->edge_type == feNone) continue;
|
||||||
|
|
||||||
// are these facets adjacent? (sharing a common edge on this layer)
|
// 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
|
// build a map of lines by edge_a_id and a_id
|
||||||
std::vector<IntersectionLinePtrs> by_edge_a_id, by_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);
|
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->skip) continue;
|
||||||
if (line->edge_a_id != -1) by_edge_a_id[line->edge_a_id].push_back(&(*line));
|
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));
|
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) {
|
CYCLE: while (1) {
|
||||||
// take first spare line and start a new loop
|
// take first spare line and start a new loop
|
||||||
IntersectionLine* first_line = NULL;
|
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;
|
if (line->skip) continue;
|
||||||
first_line = &(*line);
|
first_line = &(*line);
|
||||||
break;
|
break;
|
||||||
@ -398,6 +405,12 @@ TriangleMesh::slice(const std::vector<double> &z)
|
|||||||
IntersectionLinePtrs loop;
|
IntersectionLinePtrs loop;
|
||||||
loop.push_back(first_line);
|
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) {
|
while (1) {
|
||||||
// find a line starting where last one finishes
|
// find a line starting where last one finishes
|
||||||
IntersectionLine* next_line = NULL;
|
IntersectionLine* next_line = NULL;
|
||||||
@ -441,6 +454,11 @@ TriangleMesh::slice(const std::vector<double> &z)
|
|||||||
//// push @failed_loops, [@loop];
|
//// push @failed_loops, [@loop];
|
||||||
goto CYCLE;
|
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);
|
loop.push_back(next_line);
|
||||||
next_line->skip = true;
|
next_line->skip = true;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
use Slic3r::XS;
|
use Slic3r::XS;
|
||||||
use Test::More tests => 10;
|
use Test::More tests => 43;
|
||||||
|
|
||||||
is Slic3r::TriangleMesh::XS::hello_world(), 'Hello world!',
|
is Slic3r::TriangleMesh::XS::hello_world(), 'Hello world!',
|
||||||
'hello world';
|
'hello world';
|
||||||
@ -44,7 +44,7 @@ my $cube = {
|
|||||||
ok abs($m->size->[0] - sqrt(2)*40) < 1E-4, 'rotate';
|
ok abs($m->size->[0] - sqrt(2)*40) < 1E-4, 'rotate';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0) {
|
{
|
||||||
my $m = Slic3r::TriangleMesh::XS->new;
|
my $m = Slic3r::TriangleMesh::XS->new;
|
||||||
$m->ReadFromPerl($cube->{vertices}, $cube->{facets});
|
$m->ReadFromPerl($cube->{vertices}, $cube->{facets});
|
||||||
$m->Repair;
|
$m->Repair;
|
||||||
|
Loading…
Reference in New Issue
Block a user