Bugfix: incomplete slicing when a horizontal surface was tangent to the slicing plane and it shared an edge with an adjacent volume. #1672

Conflicts:

	xs/src/TriangleMesh.cpp
This commit is contained in:
Alessandro Ranellucci 2014-01-13 00:45:19 +01:00
parent a712284afb
commit 2d9c399d96
3 changed files with 28 additions and 12 deletions

View File

@ -253,16 +253,11 @@ TriangleMesh::slice(const std::vector<double> &z)
printf("z: min = %.2f, max = %.2f\n", min_z, max_z); printf("z: min = %.2f, max = %.2f\n", min_z, max_z);
#endif #endif
if (min_z == max_z) { // find layer extents
#ifdef SLIC3R_DEBUG
printf("Facet is horizontal; ignoring\n");
#endif
continue;
}
std::vector<double>::const_iterator min_layer, max_layer; std::vector<double>::const_iterator min_layer, max_layer;
min_layer = std::lower_bound(z.begin(), z.end(), min_z); // first layer whose slice_z is >= min_z min_layer = std::lower_bound(z.begin(), z.end(), min_z); // first layer whose slice_z is >= min_z
max_layer = std::upper_bound(z.begin() + (min_layer - z.begin()), z.end(), max_z) - 1; // last layer whose slice_z is <= max_z max_layer = std::upper_bound(z.begin() + (min_layer - z.begin()), z.end(), max_z) - 1; // last layer whose slice_z is <= max_z
/* If no layer is <= max_z, then max_layer == -1 */
#ifdef SLIC3R_DEBUG #ifdef SLIC3R_DEBUG
printf("layers: min = %d, max = %d\n", (int)(min_layer - z.begin()), (int)(max_layer - z.begin())); printf("layers: min = %d, max = %d\n", (int)(min_layer - z.begin()), (int)(max_layer - z.begin()));
#endif #endif
@ -298,7 +293,9 @@ 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;
if (facet->vertex[0].z < slice_z || facet->vertex[1].z < slice_z || facet->vertex[2].z < slice_z) { if (min_z == max_z) {
line.edge_type = feHorizontal;
} else if (facet->vertex[0].z < slice_z || facet->vertex[1].z < slice_z || facet->vertex[2].z < slice_z) {
line.edge_type = feTop; line.edge_type = feTop;
std::swap(a, b); std::swap(a, b);
std::swap(a_id, b_id); std::swap(a_id, b_id);
@ -314,7 +311,10 @@ TriangleMesh::slice(const std::vector<double> &z)
lines[layer_idx].push_back(line); lines[layer_idx].push_back(line);
found_horizontal_edge = true; found_horizontal_edge = true;
break;
// if this is a top or bottom edge, we can stop looping through edges
// because we won't find anything interesting
if (line.edge_type != feHorizontal) break;
} else if (a->z == slice_z) { } else if (a->z == slice_z) {
IntersectionPoint point; IntersectionPoint point;
point.x = a->x; point.x = a->x;
@ -375,6 +375,13 @@ TriangleMesh::slice(const std::vector<double> &z)
printf("Layer %d:\n", layer_idx); printf("Layer %d:\n", layer_idx);
#endif #endif
/*
SVG svg("lines.svg");
for (IntersectionLines::iterator line = it->begin(); line != it->end(); ++line)
svg.AddLine(*line);
svg.Close();
*/
// 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;
@ -398,6 +405,13 @@ TriangleMesh::slice(const std::vector<double> &z)
line->skip = true; line->skip = true;
break; break;
} }
} else if (line->a_id == line2->b_id && line->b_id == line2->a_id) {
/* if this edge joins two horizontal facets, remove both of them */
if (line->edge_type == feHorizontal && line2->edge_type == feHorizontal) {
line->skip = true;
line2->skip = true;
break;
}
} }
} }
} }

View File

@ -40,7 +40,7 @@ class TriangleMesh
#endif #endif
}; };
enum FacetEdgeType { feNone, feTop, feBottom }; enum FacetEdgeType { feNone, feTop, feBottom, feHorizontal };
class IntersectionPoint : public Point class IntersectionPoint : public Point
{ {

View File

@ -4,7 +4,8 @@ use strict;
use warnings; use warnings;
use Slic3r::XS; use Slic3r::XS;
use Test::More tests => 52; use List::Util qw(sum);
use Test::More tests => 53;
is Slic3r::TriangleMesh::hello_world(), 'Hello world!', is Slic3r::TriangleMesh::hello_world(), 'Hello world!',
'hello world'; 'hello world';
@ -96,6 +97,7 @@ my $cube = {
); );
$m->repair; $m->repair;
my $slices = $m->slice([ 5, 10 ]); my $slices = $m->slice([ 5, 10 ]);
is $slices->[0][0]->area, $slices->[1][0]->area, 'slicing a tangent plane includes its area'; is sum(map $_->area, @{$slices->[0]}), sum(map $_->area, @{$slices->[1]}),
'slicing a tangent plane includes its area';
} }
__END__ __END__