Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorbubnikv <bubnikv@gmail.com>2016-09-15 13:26:53 +0300
committerbubnikv <bubnikv@gmail.com>2016-09-15 13:26:53 +0300
commit6e97b9bb73fb6b028b23c98a5212c9162c836e53 (patch)
tree6ed9956b7c70b79b0cddcc14ba877e7959ebf91a /lib
parent459a42aab6103caf1de4e21c476e7ee16f5dd50d (diff)
Optimization of the layer offsets in 3D visualization.
Diffstat (limited to 'lib')
-rw-r--r--lib/Slic3r/GUI/3DScene.pm162
1 files changed, 92 insertions, 70 deletions
diff --git a/lib/Slic3r/GUI/3DScene.pm b/lib/Slic3r/GUI/3DScene.pm
index b7f0a1094..81693b6ed 100644
--- a/lib/Slic3r/GUI/3DScene.pm
+++ b/lib/Slic3r/GUI/3DScene.pm
@@ -634,7 +634,11 @@ sub Resize {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if ($self->_camera_type eq 'ortho') {
- my $depth = 1.05 * $self->max_bounding_box->radius();
+ #FIXME setting the size of the box 10x larger than necessary
+ # is only a workaround for an incorrectly set camera.
+ # This workaround harms Z-buffer accuracy!
+# my $depth = 1.05 * $self->max_bounding_box->radius();
+ my $depth = 10.0 * $self->max_bounding_box->radius();
glOrtho(
-$x/2, $x/2, -$y/2, $y/2,
-$depth, $depth,
@@ -678,7 +682,7 @@ sub InitGL {
glDisable(GL_LINE_SMOOTH);
glDisable(GL_POLYGON_SMOOTH);
glEnable(GL_MULTISAMPLE);
- glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST);
+# glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST);
# ambient lighting
glLightModelfv_p(GL_LIGHT_MODEL_AMBIENT, 0.3, 0.3, 0.3, 1);
@@ -909,8 +913,6 @@ sub draw_volumes {
foreach my $volume_idx (0..$#{$self->volumes}) {
my $volume = $self->volumes->[$volume_idx];
- glPushMatrix();
- glTranslatef(@{$volume->origin});
if ($fakecolor) {
# Object picking mode. Render the object with a color encoding the object index.
@@ -925,48 +927,49 @@ sub draw_volumes {
} else {
glColor4f(@{ $volume->color });
}
-
- my @sorted_z = ();
- my ($min_z, $max_z);
- if ($volume->range && $volume->offsets) {
- @sorted_z = sort { $a <=> $b } keys %{$volume->offsets};
-
- ($min_z, $max_z) = @{$volume->range};
- $min_z = first { $_ >= $min_z } @sorted_z;
- $max_z = first { $_ > $max_z } @sorted_z;
+
+ my $qverts_begin = 0;
+ my $qverts_end = defined($volume->qverts) ? $volume->qverts->size() : 0;
+ my $tverts_begin = 0;
+ my $tverts_end = defined($volume->tverts) ? $volume->tverts->size() : 0;
+ if ($volume->range && $volume->offsets && @{$volume->offsets}) {
+ # The Z layer range is specified.
+ # First test whether the Z span of this object is not out of ($min_z, $max_z) completely.
+ my ($min_z, $max_z) = @{$volume->range};
+ next if ($volume->offsets->[0] > $max_z || $volume->offsets->[-3] < $min_z);
+ # Then find the lowest layer to be displayed.
+ my $i = 0;
+ while ($i < @{$volume->offsets} && $volume->offsets->[$i] < $min_z) {
+ $i += 3;
+ }
+ # This shall not happen.
+ next if ($i == @{$volume->offsets});
+ # Some layers are above $min_z. Which?
+ $qverts_begin = $volume->offsets->[$i+1];
+ $tverts_begin = $volume->offsets->[$i+2];
+ while ($i < @{$volume->offsets} && $volume->offsets->[$i] <= $max_z) {
+ $i += 3;
+ }
+ if ($i < @{$volume->offsets}) {
+ $qverts_end = $volume->offsets->[$i+1];
+ $tverts_end = $volume->offsets->[$i+2];
+ }
}
+ glPushMatrix();
+ glTranslatef(@{$volume->origin});
+
glCullFace(GL_BACK);
- if ($volume->qverts) {
- my ($min_offset, $max_offset);
- if (defined $min_z) {
- $min_offset = $volume->offsets->{$min_z}->[0];
- }
- if (defined $max_z) {
- $max_offset = $volume->offsets->{$max_z}->[0];
- }
- $min_offset //= 0;
- $max_offset //= $volume->qverts->size;
-
+ if ($qverts_begin < $qverts_end) {
glVertexPointer_c(3, GL_FLOAT, 0, $volume->qverts->verts_ptr);
glNormalPointer_c(GL_FLOAT, 0, $volume->qverts->norms_ptr);
- glDrawArrays(GL_QUADS, $min_offset / 3, ($max_offset-$min_offset) / 3);
+ glDrawArrays(GL_QUADS, $qverts_begin / 3, ($qverts_end-$qverts_begin) / 3);
}
- if ($volume->tverts) {
- my ($min_offset, $max_offset);
- if (defined $min_z) {
- $min_offset = $volume->offsets->{$min_z}->[1];
- }
- if (defined $max_z) {
- $max_offset = $volume->offsets->{$max_z}->[1];
- }
- $min_offset //= 0;
- $max_offset //= $volume->tverts->size;
-
+ if ($tverts_begin < $tverts_end) {
glVertexPointer_c(3, GL_FLOAT, 0, $volume->tverts->verts_ptr);
glNormalPointer_c(GL_FLOAT, 0, $volume->tverts->norms_ptr);
- glDrawArrays(GL_TRIANGLES, $min_offset / 3, ($max_offset-$min_offset) / 3);
+ glDrawArrays(GL_TRIANGLES, $tverts_begin / 3, ($tverts_end-$tverts_begin) / 3);
}
glPopMatrix();
@@ -983,6 +986,34 @@ sub draw_volumes {
glDisableClientState(GL_VERTEX_ARRAY);
}
+sub _report_opengl_state
+{
+ my ($self, $comment) = @_;
+ my $err = glGetError();
+ return 0 if ($err == 0);
+
+ # gluErrorString() hangs. Don't use it.
+# my $errorstr = gluErrorString();
+ my $errorstr = '';
+ if ($err == 0x0500) {
+ $errorstr = 'GL_INVALID_ENUM';
+ } elsif ($err == GL_INVALID_VALUE) {
+ $errorstr = 'GL_INVALID_VALUE';
+ } elsif ($err == GL_INVALID_OPERATION) {
+ $errorstr = 'GL_INVALID_OPERATION';
+ } elsif ($err == GL_STACK_OVERFLOW) {
+ $errorstr = 'GL_STACK_OVERFLOW';
+ } elsif ($err == GL_OUT_OF_MEMORY) {
+ $errorstr = 'GL_OUT_OF_MEMORY';
+ } else {
+ $errorstr = 'unknown';
+ }
+ if (defined($comment)) {
+ printf("OpenGL error at %s, nr %d (0x%x): %s\n", $comment, $err, $err, $errorstr);
+ } else {
+ printf("OpenGL error nr %d (0x%x): %s\n", $err, $err, $errorstr);
+ }
+}
# Container for object geometry and selection status.
package Slic3r::GUI::3DScene::Volume;
@@ -1009,7 +1040,7 @@ has 'qverts' => (is => 'rw');
has 'tverts' => (is => 'rw');
# If the qverts or tverts contain thick extrusions, then offsets keeps pointers of the starts
# of the extrusions per layer.
-# [ z => [ qverts_idx, tverts_idx ] ]
+# The offsets stores tripples of (z_top, qverts_idx, tverts_idx) in a linear array.
has 'offsets' => (is => 'rw');
sub transformed_bounding_box {
@@ -1184,7 +1215,7 @@ sub load_print_toolpaths {
my $qverts = Slic3r::GUI::_3DScene::GLVertexArray->new;
my $tverts = Slic3r::GUI::_3DScene::GLVertexArray->new;
- my %offsets = (); # print_z => [ qverts, tverts ]
+ my $offsets = []; # triples stored in a linear array, sorted by print_z: print_z, qverts, tverts
my $skirt_height = 0; # number of layers
if ($print->has_infinite_skirt) {
@@ -1204,7 +1235,7 @@ sub load_print_toolpaths {
foreach my $i (0..($skirt_height-1)) {
my $top_z = $layers[$i]->print_z;
- $offsets{$top_z} = [$qverts->size, $tverts->size];
+ push @$offsets, ($top_z, $qverts->size, $tverts->size);
if ($i == 0) {
$self->_extrusionentity_to_verts($print->brim, $top_z, Slic3r::Point->new(0,0), $qverts, $tverts);
@@ -1212,7 +1243,7 @@ sub load_print_toolpaths {
$self->_extrusionentity_to_verts($print->skirt, $top_z, Slic3r::Point->new(0,0), $qverts, $tverts);
}
-
+
my $bb = Slic3r::Geometry::BoundingBoxf3->new;
{
my $pbb = $print->bounding_box;
@@ -1224,7 +1255,7 @@ sub load_print_toolpaths {
color => COLORS->[2],
qverts => $qverts,
tverts => $tverts,
- offsets => { %offsets },
+ offsets => $offsets,
);
}
@@ -1241,9 +1272,9 @@ sub load_print_object_toolpaths {
my $support_qverts = Slic3r::GUI::_3DScene::GLVertexArray->new;
my $support_tverts = Slic3r::GUI::_3DScene::GLVertexArray->new;
- my %perim_offsets = (); # print_z => [ qverts, tverts ]
- my %infill_offsets = ();
- my %support_offsets = ();
+ my $perim_offsets = []; # triples of (print_z, qverts, tverts), stored linearly, sorted by print_z
+ my $infill_offsets = [];
+ my $support_offsets = [];
# order layers by print_z
my @layers = sort { $a->print_z <=> $b->print_z }
@@ -1267,22 +1298,13 @@ sub load_print_object_toolpaths {
foreach my $layer (@layers) {
my $top_z = $layer->print_z;
- if (!exists $perim_offsets{$top_z}) {
- $perim_offsets{$top_z} = [
- $perim_qverts->size, $perim_tverts->size,
- ];
- }
- if (!exists $infill_offsets{$top_z}) {
- $infill_offsets{$top_z} = [
- $infill_qverts->size, $infill_tverts->size,
- ];
- }
- if (!exists $support_offsets{$top_z}) {
- $support_offsets{$top_z} = [
- $support_qverts->size, $support_tverts->size,
- ];
- }
-
+ push @$perim_offsets, ($top_z, $perim_qverts->size, $perim_tverts->size)
+ if (!@$perim_offsets || $perim_offsets->[-3] != $top_z);
+ push @$infill_offsets, ($top_z, $infill_qverts->size, $infill_tverts->size)
+ if (!@$infill_offsets || $infill_offsets->[-3] != $top_z);
+ push @$support_offsets, ($top_z, $support_qverts->size, $support_tverts->size)
+ if (!@$support_offsets || $support_offsets->[-3] != $top_z);
+
foreach my $copy (@{ $object->_shifted_copies }) {
foreach my $layerm (@{$layer->regions}) {
if ($object->step_done(STEP_PERIMETERS)) {
@@ -1312,11 +1334,11 @@ sub load_print_object_toolpaths {
color => COLORS->[0],
qverts => $perim_qverts,
tverts => $perim_tverts,
- offsets => { %perim_offsets },
+ offsets => $perim_offsets,
);
$perim_qverts = Slic3r::GUI::_3DScene::GLVertexArray->new;
$perim_tverts = Slic3r::GUI::_3DScene::GLVertexArray->new;
- %perim_offsets = ();
+ $perim_offsets = [];
}
if ($infill_qverts->size() > $alloc_size_max || $infill_tverts->size() > $alloc_size_max) {
@@ -1326,11 +1348,11 @@ sub load_print_object_toolpaths {
color => COLORS->[1],
qverts => $infill_qverts,
tverts => $infill_tverts,
- offsets => { %infill_offsets },
+ offsets => $infill_offsets,
);
$infill_qverts = Slic3r::GUI::_3DScene::GLVertexArray->new;
$infill_tverts = Slic3r::GUI::_3DScene::GLVertexArray->new;
- %infill_offsets = ();
+ $infill_offsets = [];
}
if ($support_qverts->size() > $alloc_size_max || $support_tverts->size() > $alloc_size_max) {
@@ -1340,11 +1362,11 @@ sub load_print_object_toolpaths {
color => COLORS->[2],
qverts => $support_qverts,
tverts => $support_tverts,
- offsets => { %support_offsets },
+ offsets => $support_offsets,
);
$support_qverts = Slic3r::GUI::_3DScene::GLVertexArray->new;
$support_tverts = Slic3r::GUI::_3DScene::GLVertexArray->new;
- %support_offsets = ();
+ $support_offsets = [];
}
}
@@ -1354,7 +1376,7 @@ sub load_print_object_toolpaths {
color => COLORS->[0],
qverts => $perim_qverts,
tverts => $perim_tverts,
- offsets => { %perim_offsets },
+ offsets => $perim_offsets,
);
}
@@ -1364,7 +1386,7 @@ sub load_print_object_toolpaths {
color => COLORS->[1],
qverts => $infill_qverts,
tverts => $infill_tverts,
- offsets => { %infill_offsets },
+ offsets => $infill_offsets,
);
}
@@ -1374,7 +1396,7 @@ sub load_print_object_toolpaths {
color => COLORS->[2],
qverts => $support_qverts,
tverts => $support_tverts,
- offsets => { %support_offsets },
+ offsets => $support_offsets,
);
}
}