diff --git a/lib/Slic3r/GUI/PreviewCanvas.pm b/lib/Slic3r/GUI/PreviewCanvas.pm index 0489ef663..282f2cb50 100644 --- a/lib/Slic3r/GUI/PreviewCanvas.pm +++ b/lib/Slic3r/GUI/PreviewCanvas.pm @@ -4,7 +4,7 @@ use warnings; use Wx::Event qw(EVT_PAINT EVT_SIZE EVT_ERASE_BACKGROUND EVT_IDLE EVT_MOUSEWHEEL EVT_MOUSE_EVENTS); # must load OpenGL *before* Wx::GLCanvas -use OpenGL qw(:glconstants :glfunctions :glufunctions); +use OpenGL qw(:glconstants :glfunctions :glufunctions :gluconstants); use base qw(Wx::GLCanvas Class::Accessor); use Math::Trig qw(asin); use List::Util qw(reduce min max first); @@ -22,6 +22,7 @@ __PACKAGE__->mk_accessors( qw(_quat _dirty init mview_init on_right_click on_instance_moved volumes + print _sphi _stheta cutting_plane_z cut_lines_vertices @@ -564,6 +565,11 @@ sub InitGL { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + # Set antialiasing/multisampling + glDisable(GL_LINE_SMOOTH); + glDisable(GL_POLYGON_SMOOTH); + glEnable(GL_MULTISAMPLE); + # ambient lighting glLightModelfv_p(GL_LIGHT_MODEL_AMBIENT, 0.1, 0.1, 0.1, 1); @@ -728,6 +734,70 @@ sub draw_volumes { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + if (defined($self->print) && !$fakecolor) { + my $tess = gluNewTess(); + gluTessCallback($tess, GLU_TESS_BEGIN, 'DEFAULT'); + gluTessCallback($tess, GLU_TESS_END, 'DEFAULT'); + gluTessCallback($tess, GLU_TESS_VERTEX, 'DEFAULT'); + gluTessCallback($tess, GLU_TESS_COMBINE, 'DEFAULT'); + gluTessCallback($tess, GLU_TESS_ERROR, 'DEFAULT'); + gluTessCallback($tess, GLU_TESS_EDGE_FLAG, 'DEFAULT'); + + foreach my $object (@{$self->print->objects}) { + foreach my $layer (@{$object->layers}) { + my $gap = 0; + my $top_z = $layer->print_z; + my $bottom_z = $layer->print_z - $layer->height + $gap; + + foreach my $copy (@{ $object->_shifted_copies }) { + glPushMatrix(); + glTranslatef(map unscale($_), @$copy, 0); + + foreach my $slice (@{$layer->slices}) { + glColor3f(@{COLORS->[0]}); + gluTessBeginPolygon($tess); + glNormal3f(0,0,1); + foreach my $polygon (@$slice) { + gluTessBeginContour($tess); + gluTessVertex_p($tess, (map unscale($_), @$_), $layer->print_z) for @$polygon; + gluTessEndContour($tess); + } + gluTessEndPolygon($tess); + + foreach my $polygon (@$slice) { + foreach my $line (@{$polygon->lines}) { + if (0) { + glLineWidth(1); + glColor3f(0,0,0); + glBegin(GL_LINES); + glVertex3f((map unscale($_), @{$line->a}), $bottom_z); + glVertex3f((map unscale($_), @{$line->b}), $bottom_z); + glEnd(); + } + + glLineWidth(0); + glColor3f(@{COLORS->[0]}); + glBegin(GL_QUADS); + glNormal3f((map $_/$line->length, @{$line->normal}), 0); + glVertex3f((map unscale($_), @{$line->a}), $bottom_z); + glVertex3f((map unscale($_), @{$line->b}), $bottom_z); + glVertex3f((map unscale($_), @{$line->b}), $top_z); + glVertex3f((map unscale($_), @{$line->a}), $top_z); + glEnd(); + } + } + } + + glPopMatrix(); # copy + } + } + } + + gluDeleteTess($tess); + return; + } + glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); diff --git a/utils/view-toolpaths.pl b/utils/view-toolpaths.pl index 0e05a15a7..66ee226db 100755 --- a/utils/view-toolpaths.pl +++ b/utils/view-toolpaths.pl @@ -20,6 +20,7 @@ my %opt = (); my %options = ( 'help' => sub { usage() }, 'load=s' => \$opt{load}, + '3D' => \$opt{d3}, 'duplicate=i' => \$opt{duplicate}, ); GetOptions(%options) or usage(1); @@ -46,6 +47,7 @@ my %opt = (); # visualize toolpaths $Slic3r::ViewToolpaths::print = $sprint->_print; + $Slic3r::ViewToolpaths::d3 = $opt{d3}; my $app = Slic3r::ViewToolpaths->new; $app->MainLoop; } @@ -67,9 +69,10 @@ EOF package Slic3r::ViewToolpaths; use Wx qw(:sizer); -use base qw(Wx::App); +use base qw(Wx::App Class::Accessor); our $print; +our $d3; sub OnInit { my $self = shift; @@ -77,8 +80,24 @@ sub OnInit { my $frame = Wx::Frame->new(undef, -1, 'Toolpaths', [-1, -1], [500, 500]); my $panel = Wx::Panel->new($frame, -1); + my $canvas; + if ($d3) { + $canvas = Slic3r::GUI::PreviewCanvas->new($panel); + $canvas->print($print); + + #$canvas->set_bounding_box($print->bounding_box); + $canvas->set_bed_shape($print->config->bed_shape); + $canvas->set_bounding_box($print->objects->[0]->model_object->bounding_box); + + foreach my $object (@{$print->objects}) { + $canvas->load_object($object->model_object); + } + } else { + $canvas = Slic3r::GUI::Plater::2DToolpaths->new($panel, $print); + } + my $sizer = Wx::BoxSizer->new(wxVERTICAL); - $sizer->Add(Slic3r::GUI::Plater::2DToolpaths->new($panel, $print), 1, wxEXPAND, 0); + $sizer->Add($canvas, 1, wxEXPAND, 0); $panel->SetSizer($sizer); $frame->Show(1); diff --git a/xs/src/libslic3r/Line.cpp b/xs/src/libslic3r/Line.cpp index d1b0310a0..42d85bb42 100644 --- a/xs/src/libslic3r/Line.cpp +++ b/xs/src/libslic3r/Line.cpp @@ -133,6 +133,12 @@ Line::vector() const return Vector(this->b.x - this->a.x, this->b.y - this->a.y); } +Vector +Line::normal() const +{ + return Vector((this->b.y - this->a.y), -(this->b.x - this->a.x)); +} + #ifdef SLIC3RXS REGISTER_CLASS(Line, "Line"); diff --git a/xs/src/libslic3r/Line.hpp b/xs/src/libslic3r/Line.hpp index 3f86ed4a7..8abbbdbcd 100644 --- a/xs/src/libslic3r/Line.hpp +++ b/xs/src/libslic3r/Line.hpp @@ -34,6 +34,7 @@ class Line double orientation() const; double direction() const; Vector vector() const; + Vector normal() const; #ifdef SLIC3RXS void from_SV(SV* line_sv); diff --git a/xs/xsp/Line.xsp b/xs/xsp/Line.xsp index d0552315f..bf31e6e95 100644 --- a/xs/xsp/Line.xsp +++ b/xs/xsp/Line.xsp @@ -32,6 +32,7 @@ Clone point_at(double distance); Polyline* as_polyline() %code{% RETVAL = new Polyline(*THIS); %}; + Clone normal(); %{ Line*