Join extrusions properly in 3D preview

This commit is contained in:
Alessandro Ranellucci 2015-01-17 22:28:24 +01:00
parent ce1d368037
commit d781371d66

View File

@ -1041,8 +1041,7 @@ sub load_print_object_slices {
sub load_print_object_toolpaths { sub load_print_object_toolpaths {
my ($self, $object) = @_; my ($self, $object) = @_;
my @quad_verts = (); my (@qverts, @qnorms, @tverts, @tnorms) = ();
my @quad_norms = ();
foreach my $layer (@{$object->layers}) { foreach my $layer (@{$object->layers}) {
my $top_z = $layer->print_z; my $top_z = $layer->print_z;
my $bottom_z = $layer->print_z - $layer->height; my $bottom_z = $layer->print_z - $layer->height;
@ -1051,9 +1050,9 @@ sub load_print_object_toolpaths {
foreach my $layerm (@{$layer->regions}) { foreach my $layerm (@{$layer->regions}) {
foreach my $entity (map @$_, @{$layerm->perimeters}) { foreach my $entity (map @$_, @{$layerm->perimeters}) {
if ($entity->isa('Slic3r::ExtrusionPath')) { if ($entity->isa('Slic3r::ExtrusionPath')) {
$self->_extrusionpath_to_verts($entity, $top_z, $copy, \@quad_verts, \@quad_norms); $self->_extrusionpath_to_verts($entity, $top_z, $copy, \@qverts, \@qnorms, \@tverts, \@tnorms);
} else { } else {
$self->_extrusionpath_to_verts($_, $top_z, $copy, \@quad_verts, \@quad_norms) for @$entity; $self->_extrusionloop_to_verts($entity, $top_z, $copy, \@qverts, \@qnorms, \@tverts, \@tnorms);
} }
} }
} }
@ -1068,8 +1067,10 @@ sub load_print_object_toolpaths {
push @{$self->volumes}, my $v = Slic3r::GUI::3DScene::Volume->new( push @{$self->volumes}, my $v = Slic3r::GUI::3DScene::Volume->new(
bounding_box => $bb, bounding_box => $bb,
color => COLORS->[0], color => COLORS->[0],
quad_verts => OpenGL::Array->new_list(GL_FLOAT, @quad_verts), quad_verts => OpenGL::Array->new_list(GL_FLOAT, @qverts),
quad_norms => OpenGL::Array->new_list(GL_FLOAT, @quad_norms), quad_norms => OpenGL::Array->new_list(GL_FLOAT, @qnorms),
verts => OpenGL::Array->new_list(GL_FLOAT, @tverts),
norms => OpenGL::Array->new_list(GL_FLOAT, @tnorms),
); );
} }
@ -1102,19 +1103,54 @@ sub _expolygons_to_verts {
} }
sub _extrusionpath_to_verts { sub _extrusionpath_to_verts {
my ($self, $path, $top_z, $copy, $verts, $norms) = @_; my ($self, $path, $top_z, $copy, $qverts, $qnorms, $tverts, $tnorms) = @_;
my $bottom_z = $top_z - $path->height; my $polyline = $path->polyline->clone;
my $middle_z = ($top_z + $bottom_z) / 2; $polyline->translate(@$copy);
my $dist = scale $path->width/2; my $lines = $polyline->lines;
my $widths = [ map scale($path->width), 0..$#$lines ];
my $heights = [ map $path->height, 0..$#$lines ];
$self->_extrusionentity_to_verts($lines, $widths, $heights, 0, $top_z, $qverts, $qnorms, $tverts, $tnorms);
}
sub _extrusionloop_to_verts {
my ($self, $loop, $top_z, $copy, $qverts, $qnorms, $tverts, $tnorms) = @_;
foreach my $line (@{$path->polyline->lines}) { my $lines = [];
my $widths = [];
my $heights = [];
foreach my $path (@$loop) {
my $polyline = $path->polyline->clone;
$polyline->translate(@$copy);
my $path_lines = $polyline->lines;
push @$lines, @$path_lines;
push @$widths, map scale($path->width), 0..$#$path_lines;
push @$heights, map $path->height, 0..$#$path_lines;
}
$self->_extrusionentity_to_verts($lines, $widths, $heights, 1, $top_z, $qverts, $qnorms, $tverts, $tnorms);
}
sub _extrusionentity_to_verts {
my ($self, $lines, $widths, $heights, $closed, $top_z, $qverts, $qnorms, $tverts, $tnorms) = @_;
my ($prev_line, $prev_b1, $prev_b2, $prev_xy_left_normal, $prev_xy_right_normal);
# loop once more in case of closed loops
my $first_done = 0;
for my $i (0..$#$lines, 0) {
my $line = $lines->[$i];
last if $i == 0 && $first_done && !$closed;
my $len = $line->length; my $len = $line->length;
my $unscaled_len = unscale $len;
next if $len == 0; next if $len == 0;
$line->translate(@$copy);
my $bottom_z = $top_z - $heights->[$i];
my $middle_z = ($top_z + $bottom_z) / 2;
my $dist = $widths->[$i]/2; # scaled
my $v = Slic3r::Pointf3->new_unscale(@{$line->vector}); my $v = Slic3r::Pointf3->new_unscale(@{$line->vector});
$v->scale(1/unscale $len); $v->scale(1/$unscaled_len);
my $a = $line->a; my $a = $line->a;
my $b = $line->b; my $b = $line->b;
@ -1127,58 +1163,169 @@ sub _extrusionpath_to_verts {
$b1->translate(+$dist*$v->y, -$dist*$v->x); #,, $b1->translate(+$dist*$v->y, -$dist*$v->x); #,,
$b2->translate(-$dist*$v->y, +$dist*$v->x); #,, $b2->translate(-$dist*$v->y, +$dist*$v->x); #,,
# calculate normal going to the right # calculate new XY normals
my $xy_normal = Slic3r::Pointf3->new_unscale(@{$line->normal}, 0); my $xy_right_normal = Slic3r::Pointf3->new_unscale(@{$line->normal}, 0);
$xy_normal->scale(1/unscale $len); $xy_right_normal->scale(1/$unscaled_len);
my $xy_left_normal = $xy_right_normal->clone;
$xy_left_normal->scale(-1);
if ($first_done) {
# if we're making a ccw turn, draw the triangles on the right side, otherwise draw them on the left side
if ($b->ccw(@$prev_line) > 0) {
# top-right vertex triangle between previous line and this one
{
# use the normal going to the right calculated for the previous line
push @$tnorms, @$prev_xy_right_normal;
push @$tverts, (map unscale($_), @$prev_b1), $middle_z;
# use the normal going to the right calculated for this line
push @$tnorms, @$xy_right_normal;
push @$tverts, (map unscale($_), @$a1), $middle_z;
# normal going upwards
push @$tnorms, (0,0,1);
push @$tverts, (map unscale($_), @$a), $top_z;
}
# bottom-right vertex triangle between previous line and this one
{
# use the normal going to the right calculated for the previous line
push @$tnorms, @$prev_xy_right_normal;
push @$tverts, (map unscale($_), @$prev_b1), $middle_z;
# normal going downwards
push @$tnorms, (0,0,-1);
push @$tverts, (map unscale($_), @$a), $bottom_z;
# use the normal going to the right calculated for this line
push @$tnorms, @$xy_right_normal;
push @$tverts, (map unscale($_), @$a1), $middle_z;
}
} else {
# top-left vertex triangle between previous line and this one
{
# use the normal going to the left calculated for the previous line
push @$tnorms, @$prev_xy_left_normal;
push @$tverts, (map unscale($_), @$prev_b2), $middle_z;
# normal going upwards
push @$tnorms, (0,0,1);
push @$tverts, (map unscale($_), @$a), $top_z;
# use the normal going to the right calculated for this line
push @$tnorms, @$xy_left_normal;
push @$tverts, (map unscale($_), @$a2), $middle_z;
}
# bottom-left vertex triangle between previous line and this one
{
# use the normal going to the left calculated for the previous line
push @$tnorms, @$prev_xy_left_normal;
push @$tverts, (map unscale($_), @$prev_b2), $middle_z;
# use the normal going to the right calculated for this line
push @$tnorms, @$xy_left_normal;
push @$tverts, (map unscale($_), @$a2), $middle_z;
# normal going downwards
push @$tnorms, (0,0,-1);
push @$tverts, (map unscale($_), @$a), $bottom_z;
}
}
}
# if this was the extra iteration we were only interested in the triangles
last if $first_done && $i == 0;
$prev_line = $line;
$prev_b1 = $b1;
$prev_b2 = $b2;
$prev_xy_right_normal = $xy_right_normal;
$prev_xy_left_normal = $xy_left_normal;
if (!$closed) {
# terminate open paths with caps
if ($i == 0) {
# normal pointing downwards
push @$qnorms, (0,0,-1);
push @$qverts, (map unscale($_), @$a), $bottom_z;
# normal pointing to the right
push @$qnorms, @$xy_right_normal;
push @$qverts, (map unscale($_), @$a1), $middle_z;
# normal pointing upwards
push @$qnorms, (0,0,1);
push @$qverts, (map unscale($_), @$a), $top_z;
# normal pointing to the left
push @$qnorms, @$xy_left_normal;
push @$qverts, (map unscale($_), @$a2), $middle_z;
} elsif ($i == $#$lines) {
# normal pointing downwards
push @$qnorms, (0,0,-1);
push @$qverts, (map unscale($_), @$b), $bottom_z;
# normal pointing to the left
push @$qnorms, @$xy_left_normal;
push @$qverts, (map unscale($_), @$b2), $middle_z;
# normal pointing upwards
push @$qnorms, (0,0,1);
push @$qverts, (map unscale($_), @$b), $top_z;
# normal pointing to the right
push @$qnorms, @$xy_right_normal;
push @$qverts, (map unscale($_), @$b1), $middle_z;
}
}
# bottom-right face # bottom-right face
{ {
# normal going downwards # normal going downwards
push @$norms, (0,0,-1), (0,0,-1); push @$qnorms, (0,0,-1), (0,0,-1);
push @$verts, (map unscale($_), @$a), $bottom_z; push @$qverts, (map unscale($_), @$a), $bottom_z;
push @$verts, (map unscale($_), @$b), $bottom_z; push @$qverts, (map unscale($_), @$b), $bottom_z;
push @$norms, @$xy_normal, @$xy_normal; push @$qnorms, @$xy_right_normal, @$xy_right_normal;
push @$verts, (map unscale($_), @$b1), $middle_z; push @$qverts, (map unscale($_), @$b1), $middle_z;
push @$verts, (map unscale($_), @$a1), $middle_z; push @$qverts, (map unscale($_), @$a1), $middle_z;
} }
# top-right face # top-right face
{ {
push @$norms, @$xy_normal, @$xy_normal; push @$qnorms, @$xy_right_normal, @$xy_right_normal;
push @$verts, (map unscale($_), @$a1), $middle_z; push @$qverts, (map unscale($_), @$a1), $middle_z;
push @$verts, (map unscale($_), @$b1), $middle_z; push @$qverts, (map unscale($_), @$b1), $middle_z;
# normal going upwards # normal going upwards
push @$norms, (0,0,1), (0,0,1); push @$qnorms, (0,0,1), (0,0,1);
push @$verts, (map unscale($_), @$b), $top_z; push @$qverts, (map unscale($_), @$b), $top_z;
push @$verts, (map unscale($_), @$a), $top_z; push @$qverts, (map unscale($_), @$a), $top_z;
} }
# top-left face # top-left face
{ {
push @$norms, (0,0,1), (0,0,1); push @$qnorms, (0,0,1), (0,0,1);
push @$verts, (map unscale($_), @$a), $top_z; push @$qverts, (map unscale($_), @$a), $top_z;
push @$verts, (map unscale($_), @$b), $top_z; push @$qverts, (map unscale($_), @$b), $top_z;
# calculate normal going to the left push @$qnorms, @$xy_left_normal, @$xy_left_normal;
$xy_normal->scale(-1); push @$qverts, (map unscale($_), @$b2), $middle_z;
push @$norms, @$xy_normal, @$xy_normal; push @$qverts, (map unscale($_), @$a2), $middle_z;
push @$verts, (map unscale($_), @$b2), $middle_z;
push @$verts, (map unscale($_), @$a2), $middle_z;
} }
# bottom-left face # bottom-left face
{ {
push @$norms, @$xy_normal, @$xy_normal; push @$qnorms, @$xy_left_normal, @$xy_left_normal;
push @$verts, (map unscale($_), @$a2), $middle_z; push @$qverts, (map unscale($_), @$a2), $middle_z;
push @$verts, (map unscale($_), @$b2), $middle_z; push @$qverts, (map unscale($_), @$b2), $middle_z;
# normal going downwards # normal going downwards
push @$norms, (0,0,-1), (0,0,-1); push @$qnorms, (0,0,-1), (0,0,-1);
push @$verts, (map unscale($_), @$b), $bottom_z; push @$qverts, (map unscale($_), @$b), $bottom_z;
push @$verts, (map unscale($_), @$a), $bottom_z; push @$qverts, (map unscale($_), @$a), $bottom_z;
} }
$first_done++;
} }
} }