Use multiple colors for multimaterial models in 3D preview

xsdata-boost
Alessandro Ranellucci 2013-08-25 16:35:21 +02:00
parent 2fb725405f
commit fde6e371a9
3 changed files with 51 additions and 30 deletions

View File

@ -119,7 +119,7 @@ sub new {
$self->{object} = $params{object};
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);
$sizer->SetSizeHints($self);

View File

@ -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 base qw(Wx::GLCanvas Class::Accessor);
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 Wx::GLCanvas qw(:all);
__PACKAGE__->mk_accessors( qw(quat dirty init mview_init
mesh_center mesh_size
verts norms initpos
object_center object_size
volumes initpos
sphi stheta) );
use constant TRACKBALLSIZE => 0.8;
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 {
my ($class, $parent, $mesh) = @_;
my ($class, $parent, $object) = @_;
my $self = $class->SUPER::new($parent);
$self->quat((0, 0, 0, 1));
$self->sphi(45);
$self->stheta(-45);
# prepare mesh
{
$mesh->align_to_origin;
$self->mesh_center($mesh->center);
$self->mesh_size($mesh->size);
$object->align_to_origin;
$self->object_center($object->center);
$self->object_size($object->size);
# group mesh(es) by material
my @materials = ();
$self->volumes([]);
foreach my $volume (@{$object->volumes}) {
my $mesh = $volume->mesh;
my @verts = map @{ $mesh->vertices->[$_] }, map @$_, @{$mesh->facets};
$self->verts(OpenGL::Array->new_list(GL_FLOAT, @verts));
my $material_id = $volume->material_id // '_';
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 @norms = map { @$_, @$_, @$_ } map normalize(triangle_normal(map $mesh->vertices->[$_], @$_)), @{$mesh->facets};
$self->norms(OpenGL::Array->new_list(GL_FLOAT, @norms));
{
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 {
@ -277,7 +296,7 @@ sub ResetModelView {
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
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);
}
@ -292,8 +311,8 @@ sub Resize {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
my $mesh_size = $self->mesh_size;
glOrtho(-$x/2, $x/2, -$y/2, $y/2, 0.5, 2 * max(@$mesh_size));
my $object_size = $self->object_size;
glOrtho(-$x/2, $x/2, -$y/2, $y/2, 0.5, 2 * max(@$object_size));
glMatrixMode(GL_MODELVIEW);
unless ($self->mview_init) {
@ -350,19 +369,19 @@ sub Render {
glPushMatrix();
my $mesh_size = $self->mesh_size;
glTranslatef(0, 0, -max(@$mesh_size[0..1]));
my $object_size = $self->object_size;
glTranslatef(0, 0, -max(@$object_size[0..1]));
my @rotmat = quat_to_rotmatrix($self->quat);
glMultMatrixd_p(@rotmat[0..15]);
glRotatef($self->stheta, 1, 0, 0);
glRotatef($self->sphi, 0, 0, 1);
glTranslatef(map -$_, @{ $self->mesh_center });
glTranslatef(map -$_, @{ $self->object_center });
$self->draw_mesh;
# draw axes
{
my $axis_len = 2 * max(@{ $self->mesh_size });
my $axis_len = 2 * max(@{ $self->object_size });
glLineWidth(2);
glBegin(GL_LINES);
# draw line for x axis
@ -421,12 +440,14 @@ sub draw_mesh {
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer_p(3, $self->verts);
glCullFace(GL_BACK);
glNormalPointer_p($self->norms);
glColor3f(1, 1, 1);
glDrawArrays(GL_TRIANGLES, 0, $self->verts->elements / 3);
foreach my $volume (@{$self->volumes}) {
glVertexPointer_p(3, $volume->{verts});
glCullFace(GL_BACK);
glNormalPointer_p($volume->{norms});
glColor3f(@{ $volume->{color} });
glDrawArrays(GL_TRIANGLES, 0, $volume->{verts}->elements / 3);
}
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

View File

@ -27,7 +27,7 @@ my %opt = ();
{
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;
$app->MainLoop;
}
@ -49,7 +49,7 @@ package Slic3r::ViewMesh;
use Wx qw(:sizer);
use base qw(Wx::App);
our $mesh;
our $object;
sub OnInit {
my $self = shift;
@ -58,7 +58,7 @@ sub OnInit {
my $panel = Wx::Panel->new($frame, -1);
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);
$sizer->SetSizeHints($panel);