Use multiple colors for multimaterial models in 3D preview
This commit is contained in:
parent
2fb725405f
commit
fde6e371a9
3 changed files with 51 additions and 30 deletions
|
@ -119,7 +119,7 @@ sub new {
|
||||||
$self->{object} = $params{object};
|
$self->{object} = $params{object};
|
||||||
|
|
||||||
my $sizer = Wx::BoxSizer->new(wxVERTICAL);
|
my $sizer = Wx::BoxSizer->new(wxVERTICAL);
|
||||||
$sizer->Add(Slic3r::GUI::PreviewCanvas->new($self, $self->{object}->get_model_object->mesh), 1, wxEXPAND, 0);
|
$sizer->Add(Slic3r::GUI::PreviewCanvas->new($self, $self->{object}->get_model_object), 1, wxEXPAND, 0);
|
||||||
$self->SetSizer($sizer);
|
$self->SetSizer($sizer);
|
||||||
$sizer->SetSizeHints($self);
|
$sizer->SetSizeHints($self);
|
||||||
|
|
||||||
|
|
|
@ -7,37 +7,56 @@ use Wx::Event qw(EVT_PAINT EVT_SIZE EVT_ERASE_BACKGROUND EVT_IDLE EVT_MOUSEWHEEL
|
||||||
use OpenGL qw(:glconstants :glfunctions :glufunctions);
|
use OpenGL qw(:glconstants :glfunctions :glufunctions);
|
||||||
use base qw(Wx::GLCanvas Class::Accessor);
|
use base qw(Wx::GLCanvas Class::Accessor);
|
||||||
use Math::Trig qw(asin);
|
use Math::Trig qw(asin);
|
||||||
use List::Util qw(reduce min max);
|
use List::Util qw(reduce min max first);
|
||||||
use Slic3r::Geometry qw(X Y Z MIN MAX triangle_normal normalize deg2rad tan);
|
use Slic3r::Geometry qw(X Y Z MIN MAX triangle_normal normalize deg2rad tan);
|
||||||
use Wx::GLCanvas qw(:all);
|
use Wx::GLCanvas qw(:all);
|
||||||
|
|
||||||
__PACKAGE__->mk_accessors( qw(quat dirty init mview_init
|
__PACKAGE__->mk_accessors( qw(quat dirty init mview_init
|
||||||
mesh_center mesh_size
|
object_center object_size
|
||||||
verts norms initpos
|
volumes initpos
|
||||||
sphi stheta) );
|
sphi stheta) );
|
||||||
|
|
||||||
use constant TRACKBALLSIZE => 0.8;
|
use constant TRACKBALLSIZE => 0.8;
|
||||||
use constant TURNTABLE_MODE => 1;
|
use constant TURNTABLE_MODE => 1;
|
||||||
|
use constant COLORS => [ [1,1,1], [1,0.5,0.5], [0.5,1,0.5], [0.5,0.5,1] ];
|
||||||
|
|
||||||
sub new {
|
sub new {
|
||||||
my ($class, $parent, $mesh) = @_;
|
my ($class, $parent, $object) = @_;
|
||||||
my $self = $class->SUPER::new($parent);
|
my $self = $class->SUPER::new($parent);
|
||||||
|
|
||||||
$self->quat((0, 0, 0, 1));
|
$self->quat((0, 0, 0, 1));
|
||||||
$self->sphi(45);
|
$self->sphi(45);
|
||||||
$self->stheta(-45);
|
$self->stheta(-45);
|
||||||
|
|
||||||
# prepare mesh
|
$object->align_to_origin;
|
||||||
{
|
$self->object_center($object->center);
|
||||||
$mesh->align_to_origin;
|
$self->object_size($object->size);
|
||||||
$self->mesh_center($mesh->center);
|
|
||||||
$self->mesh_size($mesh->size);
|
|
||||||
|
|
||||||
my @verts = map @{ $mesh->vertices->[$_] }, map @$_, @{$mesh->facets};
|
# group mesh(es) by material
|
||||||
$self->verts(OpenGL::Array->new_list(GL_FLOAT, @verts));
|
my @materials = ();
|
||||||
|
$self->volumes([]);
|
||||||
|
foreach my $volume (@{$object->volumes}) {
|
||||||
|
my $mesh = $volume->mesh;
|
||||||
|
|
||||||
my @norms = map { @$_, @$_, @$_ } map normalize(triangle_normal(map $mesh->vertices->[$_], @$_)), @{$mesh->facets};
|
my $material_id = $volume->material_id // '_';
|
||||||
$self->norms(OpenGL::Array->new_list(GL_FLOAT, @norms));
|
my $color_idx = first { $materials[$_] eq $material_id } 0..$#materials;
|
||||||
|
if (!defined $color_idx) {
|
||||||
|
push @materials, $material_id;
|
||||||
|
$color_idx = $#materials;
|
||||||
|
}
|
||||||
|
push @{$self->volumes}, my $v = {
|
||||||
|
color => COLORS->[ $color_idx % scalar(@{&COLORS}) ],
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
my @verts = map @{ $mesh->vertices->[$_] }, map @$_, @{$mesh->facets};
|
||||||
|
$v->{verts} = OpenGL::Array->new_list(GL_FLOAT, @verts);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
my @norms = map { @$_, @$_, @$_ } map normalize(triangle_normal(map $mesh->vertices->[$_], @$_)), @{$mesh->facets};
|
||||||
|
$v->{norms} = OpenGL::Array->new_list(GL_FLOAT, @norms);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EVT_PAINT($self, sub {
|
EVT_PAINT($self, sub {
|
||||||
|
@ -277,7 +296,7 @@ sub ResetModelView {
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
my $win_size = $self->GetClientSize();
|
my $win_size = $self->GetClientSize();
|
||||||
my $ratio = $factor * min($win_size->width, $win_size->height) / max(@{ $self->mesh_size });
|
my $ratio = $factor * min($win_size->width, $win_size->height) / max(@{ $self->object_size });
|
||||||
glScalef($ratio, $ratio, 1);
|
glScalef($ratio, $ratio, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,8 +311,8 @@ sub Resize {
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
my $mesh_size = $self->mesh_size;
|
my $object_size = $self->object_size;
|
||||||
glOrtho(-$x/2, $x/2, -$y/2, $y/2, 0.5, 2 * max(@$mesh_size));
|
glOrtho(-$x/2, $x/2, -$y/2, $y/2, 0.5, 2 * max(@$object_size));
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
unless ($self->mview_init) {
|
unless ($self->mview_init) {
|
||||||
|
@ -350,19 +369,19 @@ sub Render {
|
||||||
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
|
||||||
my $mesh_size = $self->mesh_size;
|
my $object_size = $self->object_size;
|
||||||
glTranslatef(0, 0, -max(@$mesh_size[0..1]));
|
glTranslatef(0, 0, -max(@$object_size[0..1]));
|
||||||
my @rotmat = quat_to_rotmatrix($self->quat);
|
my @rotmat = quat_to_rotmatrix($self->quat);
|
||||||
glMultMatrixd_p(@rotmat[0..15]);
|
glMultMatrixd_p(@rotmat[0..15]);
|
||||||
glRotatef($self->stheta, 1, 0, 0);
|
glRotatef($self->stheta, 1, 0, 0);
|
||||||
glRotatef($self->sphi, 0, 0, 1);
|
glRotatef($self->sphi, 0, 0, 1);
|
||||||
glTranslatef(map -$_, @{ $self->mesh_center });
|
glTranslatef(map -$_, @{ $self->object_center });
|
||||||
|
|
||||||
$self->draw_mesh;
|
$self->draw_mesh;
|
||||||
|
|
||||||
# draw axes
|
# draw axes
|
||||||
{
|
{
|
||||||
my $axis_len = 2 * max(@{ $self->mesh_size });
|
my $axis_len = 2 * max(@{ $self->object_size });
|
||||||
glLineWidth(2);
|
glLineWidth(2);
|
||||||
glBegin(GL_LINES);
|
glBegin(GL_LINES);
|
||||||
# draw line for x axis
|
# draw line for x axis
|
||||||
|
@ -421,12 +440,14 @@ sub draw_mesh {
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
glEnableClientState(GL_NORMAL_ARRAY);
|
glEnableClientState(GL_NORMAL_ARRAY);
|
||||||
|
|
||||||
glVertexPointer_p(3, $self->verts);
|
foreach my $volume (@{$self->volumes}) {
|
||||||
|
glVertexPointer_p(3, $volume->{verts});
|
||||||
|
|
||||||
glCullFace(GL_BACK);
|
glCullFace(GL_BACK);
|
||||||
glNormalPointer_p($self->norms);
|
glNormalPointer_p($volume->{norms});
|
||||||
glColor3f(1, 1, 1);
|
glColor3f(@{ $volume->{color} });
|
||||||
glDrawArrays(GL_TRIANGLES, 0, $self->verts->elements / 3);
|
glDrawArrays(GL_TRIANGLES, 0, $volume->{verts}->elements / 3);
|
||||||
|
}
|
||||||
|
|
||||||
glDisableClientState(GL_NORMAL_ARRAY);
|
glDisableClientState(GL_NORMAL_ARRAY);
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
|
|
|
@ -27,7 +27,7 @@ my %opt = ();
|
||||||
{
|
{
|
||||||
my $model = Slic3r::Model->read_from_file($ARGV[0]);
|
my $model = Slic3r::Model->read_from_file($ARGV[0]);
|
||||||
|
|
||||||
$Slic3r::ViewMesh::mesh = $model->mesh;
|
$Slic3r::ViewMesh::object = $model->objects->[0];
|
||||||
my $app = Slic3r::ViewMesh->new;
|
my $app = Slic3r::ViewMesh->new;
|
||||||
$app->MainLoop;
|
$app->MainLoop;
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ package Slic3r::ViewMesh;
|
||||||
use Wx qw(:sizer);
|
use Wx qw(:sizer);
|
||||||
use base qw(Wx::App);
|
use base qw(Wx::App);
|
||||||
|
|
||||||
our $mesh;
|
our $object;
|
||||||
|
|
||||||
sub OnInit {
|
sub OnInit {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
@ -58,7 +58,7 @@ sub OnInit {
|
||||||
my $panel = Wx::Panel->new($frame, -1);
|
my $panel = Wx::Panel->new($frame, -1);
|
||||||
|
|
||||||
my $sizer = Wx::BoxSizer->new(wxVERTICAL);
|
my $sizer = Wx::BoxSizer->new(wxVERTICAL);
|
||||||
$sizer->Add(Slic3r::GUI::PreviewCanvas->new($panel, $mesh), 1, wxEXPAND, 0);
|
$sizer->Add(Slic3r::GUI::PreviewCanvas->new($panel, $object), 1, wxEXPAND, 0);
|
||||||
$panel->SetSizer($sizer);
|
$panel->SetSizer($sizer);
|
||||||
$sizer->SetSizeHints($panel);
|
$sizer->SetSizeHints($panel);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue