# Copyright (c) 1997-2006
# Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
# http://www.math.tu-berlin.de/polymake, mailto:polymake@math.tu-berlin.de
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version: http://www.gnu.org/licenses/gpl.txt.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#-----------------------------------------------------------------------------
# $Project: polymake $$Id: JReality.pm 7574 2007-01-19 12:18:11Z thilosch $
use strict;
use JavaView;
require 'JReality.def';
package JReality::File;
use Struct (
[ '@ISA' => 'JavaView::File' ],
);
sub header
{
my ($self) = shift;
my $obj_name = shift;
my $title=$self->title;
if (!length($title)) {
$title="unnamed";
}
return <<".";
/*--------------------HEADER $title--------------------*/
import de.jreality.shader.CommonAttributes;
setAccessibility(true);
synchronized(root) {
$obj_name = new SceneGraphComponent();
$obj_name.setName("$title");
root.addChild($obj_name);
/*----------------------------------------*/
.
}
sub trailer {
return <<".";
root.notify();
}
return;
.
}
sub toString
{
dbg_print(" called JReality::File->toString .. ") if $Switches::d;
my ($self) = shift;
my $n_geom = shift;
my $obj_name = "geom$n_geom";
my $text = $self->header($obj_name);
my $number = 0;
foreach my $geometry (@{$self->geometries}) {
$text .= $geometry->toString($number, $obj_name);
$number++;
}
$text .= $self->trailer;
return $text;
}
sub print_it { my ($self) = @_; $self->SUPER::print_it; }
##############################################################################################
#
# Basis class for all graphical objects handled by jreality
#
package JReality::geometry;
my $thickness_factor = 40;
sub new
{
my $class = shift;
my $self = { @_ }; #hashmap
bless $self, $class;
$self->initialize;
return $self;
}
sub initialize
{
my $self=shift;
if (! exists $self->{name}) {
$self->{name}="geometry";
}
if (! exists $self->{points}) {
croak( ref($self), "::initialize: parameter 'points' missing" );
}
if (! exists $self->{pointSet_dim}) {
croak( ref($self), "::initialize: parameter 'pointSet_dim' missing" );
}
$self->{pointSet_point_flag} ||= "show";
if (! exists $self->{points_thickness}) {
$self->{points_thickness}=$JReality::default::points_thickness;
}
$self->{pointSet_thicknesses_flag} ||= exists $self->{points_thicknesses_list} ? "show" : "hide";
if (! exists $self->{points_color}) {
$self->{points_color}= $Visual::Color::vertices;
#$JReality::default::points_color;
}
## JReality "bug" (see above comment)
#if(! exists $self->{number_of_points}) {
# $self->{number_of_points} = @{$self->{points}} ;
#}
}
sub appearance
{
my $self = shift;
my $obj_name = shift;
# print "name 2:" . "$obj_name";
my @colors = ($self->{points_color} =~ /\d+/g);
map {$_ = $_ / 255} @colors;
#FIXME: points thickness
my $point_thickness = $self->{points_thickness} / $thickness_factor;
my $text =<<".";
appearance = new Appearance();
.
if($self->{pointSet_point_flag} eq "show") {
$text .=<<".";
appearance.setAttribute(de.jreality.shader.CommonAttributes.VERTEX_DRAW, true);
appearance.setAttribute(de.jreality.shader.CommonAttributes.SPHERES_DRAW, true);
.
} else {
$text .=<<".";
appearance.setAttribute(de.jreality.shader.CommonAttributes.VERTEX_DRAW, false);
appearance.setAttribute(de.jreality.shader.CommonAttributes.SPHERES_DRAW, false);
.
}
$text .=<<".";
$obj_name.setAppearance(appearance);
.
return $text;
}
sub add_point_colors
{
my $self = shift;
my $text = "";
$text .= "colors = new double[]{ ";
for(my $i=0; $i < (@{$self->{points}}); $i++)
{
my @colors;
if (exists $self->{points_colors_list}) {
@colors = split(" ",${$self->{points_colors_list}}[$i]);
} else {
@colors = ($self->{points_color} =~ /\d+/g);
}
map {$_ = $_ / 255} @colors;
$text .= join(",", @colors);
if($i + 1 != @{$self->{points}}) {
$text .= ", \n";
}
}
$text .= " }; \n";
return $text;
}
## scale coordinates such that mean distance to barycenter == 1;
## TODO: for interactive components this does not make sense,
## in particular for the schlegel interactive where coordinates
## are here (1,0,0),(2,0,0),(3,0,0) ...
## TODO: for geometries with multiple elements this does
## not work properly
sub scale
{
my $self = shift(@_);
my @coords = @_;
## barycenter
my @c;
my $N = scalar @{$self->{points}};
for(my $i=0; $i < $N; $i++)
{
for(my $k=0; $k < 3; $k++)
{
@c[$k] += 1/$N * @coords[3*$i + $k];
}
}
## mean distance to barycenter
my $dist = 0;
for(my $i=0; $i < $N; ++$i)
{
my @p;
for(my $k=0; $k < 3; ++$k)
{
@p[$k] += (@c[$k] - @coords[3*$i+$k]);
}
$dist += sqrt(@p[0]*@p[0] + @p[1]*@p[1] + @p[2]*@p[2]);
}
$dist = $dist/$N;
## change coordinates
if($dist != 0)
{
for(my $i=0; $i < $N; $i++)
{
for(my $k=0; $k < 3; $k++)
{
@coords[3*$i+$k] = @c[$k] + (1/$dist)*(@coords[3*$i+$k] - @c[$k]);
}
}
}
return @coords;
}
sub pointSet
{
my ($self) = @_;
my $text=<<".";
/*--------------------$self->{name}--------------------*/
pts = new double[][]{
.
dbg_print ("generating pointset for jreality ...") if $Switches::d;
my @points;
foreach my $point (@{$self->{points}}) {
# chomp $point;
my @coord = split /\s+/, $point;
## HACK; for Visual::Graph dimension ($pointSet_dim) is set to 3, although
## the graph is the Schlegel diagram of a 3-polytope
if(@coord == 2) {
push @coord, "0";
}
my $line = "{".(join(",", @coord))."}";
push @points, $line;
}
$text .= (join(",\n",@points))."\n};//pts \n";
$text .= $self->pointLabels;
return $text;
}
sub pointLabels
{
my ($self) = @_;
my $labels = $self->{points_labels_list};
my $text = "labels = new String[]{";
my @labels;
if(defined($labels)) {
for(my $i=0; $i < @{$self->{points}}; ++$i) {
push @labels, "\"".($labels->($i))."\"";
}
}
$text .= join(",",@labels);
$text .= "};\n";
return $text;
}
# use only for displaying pointsets
sub trailer
{
my ($self) = shift;
my $number = shift;
my $obj_name = shift;
my $n_points = @{$self->{points}};
my $text .=<<".";
psf = new PointSetFactory();
psf.setVertexCount($n_points);
psf.setVertexCoordinates(pts);
if(labels.length == $n_points) psf.setVertexLabels(labels);
.
$text .= $self->add_point_colors;
$text .=<<".";
psf.setVertexColors( new DoubleArrayArray.Inlined(colors, 3));
psf.update();
part1=new SceneGraphComponent();
part1.setGeometry(psf.getGeometry());
part1.setName("PointSet $number");
part1.setAppearance(appearance);
$obj_name.addChild(part1);
/*----------------------------------------*/
.
return $text;
}
# use only for displaying pointsets
sub toString
{
## generate data for jreality application
dbg_print("called JReality::geometry->toString ..") if $Switches::d;
my ($self) = shift;
my $number = shift;
my $obj_name = shift;
return $self->pointSet . $self->pointLabels . $self->appearance($obj_name) . $self->trailer($number, $obj_name) ;
}
##############################################################################################
#
# Wire model (e.g. a graph)
#
package JReality::wire;
use vars '@ISA';
@ISA=qw( JReality::geometry );
sub new
{
my $class = shift;
my $self = { @_ }; #hashmap
bless $self, $class;
$self->initialize;
return $self;
}
sub appearance
{
my $self = shift;
my $obj_name = shift;
my $text = $self->SUPER::appearance($obj_name);
if($self->{lines_color} =~ /\s*0\s+0\s+0\s*/) {
$self->{lines_color} = "70 70 70";
}
my @line_colors = ($self->{lines_color} =~ /\d+/g);
map {$_ = $_ / 255} @line_colors;
my $lines_thickness = $self->{lines_thickness} / $thickness_factor;
if( $self->{lineSet_line_flag} eq "hide") {
$text .= "appearance.setAttribute(CommonAttributes.TUBES_DRAW,false);\nappearance.setAttribute(CommonAttributes.EDGE_DRAW,false);\n";
} else {
$text .= "appearance.setAttribute(CommonAttributes.TUBES_DRAW,true);\nappearance.setAttribute(CommonAttributes.EDGE_DRAW,true);\n";
}
$text .= <<".";
appearance.setAttribute(
"lineShader.diffuseColor",
new java.awt.Color((float)@line_colors[0] ,(float)@line_colors[1],(float)@line_colors[2])
);
.
return $text;
}
sub initialize
{
my $self=shift;
$self->SUPER::initialize;
if (! exists $self->{lines}) {
croak( ref($self), "::initialize: parameter 'lines' missing" );
}
$self->{lineSet_line_flag} ||= "show";
$self->{lineSet_arrow_flag} ||= "hide";
if (! exists $self->{lines_thickness}) {
$self->{lines_thickness}=$JReality::default::lines_thickness;
}
$self->{lineSet_thicknesses_flag} ||= exists $self->{lines_thicknesses_list} ? "show" : "hide";
if (! exists $self->{lines_color}) {
$self->{lines_color}= $Visual::Color::edges;
#$JReality::default::lines_color;
}
}
sub add_line_colors
{
my $self = shift;
my $text = "";
$text .= "lineColors = new double[]{ ";
for(my $i=0; $i < (@{$self->{lines}}); $i++)
{
my @colors;
if (exists $self->{lines_colors_list}) {
map { s/\s*0\s+0\s+0\s*/70 70 70/; } @{$self->{lines_colors_list}};
@colors = split(" ",${$self->{lines_colors_list}}[$i]);
} else {
@colors = ($self->{lines_color} =~ /\d+/g);
}
map {$_ = $_ / 255} @colors;
$text .= join(",", @colors);
if($i + 1 != @{$self->{lines}}) {
$text .= ", \n";
}
}
$text .= " }; \n";
return $text;
}
sub lineSet {
my ($self) = @_;
my $text .="lines = new int[][]{ ";
dbg_print ("generating lineset for jreality ...") if $Switches::d;
my @lines = (@{$self->{lines}});
map { $_=$self->process_line($_)} @lines;
$text .= join(",", @lines);
$text .= " }; \n";
return $text;
}
sub process_line {
my ($self, $line) = @_;
my $text .= "{ ";
my @indices = ( $line =~ /\d+/g);
@indices = reverse @indices;
$text .= join(",", @indices);
$text .= " } \n";
return $text;
}
sub trailer {
my $self = shift;
my $number = shift;
my $obj_name = shift;
my $n_points = @{$self->{points}};
my $n_lines = @{$self->{lines}};
my $text .=<<".";
ilsf = new IndexedFaceSetFactory();
ilsf.setLineCount($n_lines);
ilsf.setVertexCount($n_points);
ilsf.setEdgeIndices(lines);
ilsf.setVertexCoordinates(pts);
if(labels.length == $n_points) ilsf.setVertexLabels(labels);
.
## point appearance
$text .= $self->SUPER::add_point_colors;
$text .=<<".";
ilsf.setVertexColors(new DoubleArrayArray.Inlined(colors, 3) );
.
$text .= $self->add_line_colors;
$text .=<<".";
ilsf.setEdgeColors( new DoubleArrayArray.Inlined(lineColors, 3) );
ilsf.update();
part1=new SceneGraphComponent();
part1.setGeometry(ilsf.getGeometry());
part1.setAppearance(appearance);
part1.setName("LineSet $number");
$obj_name.addChild(part1);
/*----------------------------------------*/
.
return $text;
}
sub toString {
dbg_print("called JReality::wire->toString ..") if $Switches::d;
my $self = shift;
my $number = shift;
my $obj_name = shift;
my $text = "";
$text .= $self->SUPER::pointSet;
$text .= $self->lineSet;
$text .= $self->appearance($obj_name);
$text .= $self->trailer($number, $obj_name);
return $text;
}
################################################################
#
# Solid 2-d or 3-d body
#
package JReality::solid;
use vars '@ISA';
@ISA=qw( JReality::geometry );
sub initialize
{
my $self=shift;
$self->SUPER::initialize;
if (! exists $self->{faces}) {
croak( ref($self), "::initialize: parameter 'faces; missing\n" );
}
$self->{faceSet_face_flag} ||= "show";
$self->{faceSet_backface_flag} ||= "hide";
$self->{faceSet_edge_flag} ||= "show";
if (! exists $self->{faces_color}) {
$self->{faces_color}= $Visual::Color::facets;
#$JReality::default::faces_color;
}
if (! exists $self->{edges_thickness}) {
$self->{edges_thickness}=$JReality::default::lines_thickness;
}
if (! exists $self->{edges_color}) {
#$self->{edges_color}=$JReality::default::lines_color;
$self->{edges_color}=$Visual::Color::edges;
}
if(defined $self->{material_flag}) {
$self->{faceSet_backface_flag} = $self->{material_flag};
$self->{material_diffuseColor} ||= $JReality::default::diffuseColor;
$self->{material_emissiveColor} ||= $JReality::default::emissiveColor;
$self->{material_shininess} ||= $JReality::default::shininess;
$self->{material_specularColor} ||= $JReality::default::specularColor;
$self->{material_transparency} ||= $JReality::default::transparency;
} else {
$self->{material_flag} = "hide";
}
}
sub add_face_colors
{
my $self = shift;
my $text = "";
$text .= "faceColors = new double[]{ ";
for(my $i=0; $i < (@{$self->{faces}}); $i++)
{
my @colors;
if (exists $self->{faces_colors_list}) {
@colors = split(" ",${$self->{faces_colors_list}}[$i]);
} else {
@colors = ($self->{faces_color} =~ /\d+/g);
}
map {$_ = $_ / 255} @colors;
$text .= join(",", @colors);
if($i + 1 != @{$self->{faces}}) {
$text .= ", \n";
}
}
$text .= " }; \n";
return $text;
}
sub appearance {
my $self = shift;
my $obj_name = shift;
my $text = $self->SUPER::appearance($obj_name);
$text .= <<".";
appearance.setAttribute(CommonAttributes.POLYGON_SHADER +"."+CommonAttributes.SMOOTH_SHADING,false);
.
if( $self->{material_flag} =~ "show")
{
my $transparency = ($self->{material_transparency});
$text .= <<".";
appearance.setAttribute(CommonAttributes.TRANSPARENCY_ENABLED,true);
appearance.setAttribute(CommonAttributes.TRANSPARENCY,$transparency);
.
}
if( $self->{faceSet_edge_flag} eq "hide") {
$text .= "appearance.setAttribute(CommonAttributes.TUBES_DRAW,false);\nappearance.setAttribute(CommonAttributes.EDGE_DRAW,false);\n";
} else {
$text .= "appearance.setAttribute(CommonAttributes.TUBES_DRAW,true);\nappearance.setAttribute(CommonAttributes.EDGE_DRAW,true);\n";
}
if( $self->{faceSet_face_flag} eq "hide")
{
$text .= <<".";
appearance.setAttribute(CommonAttributes.FACE_DRAW, false);
.
}
if($self->{edges_color} =~ /\s*0\s+0\s+0\s*/) {
$self->{edges_color} = "70 70 70";
}
my @edge_colors = ($self->{edges_color} =~ /\d+/g);
map {$_ = $_ / 255} @edge_colors;
#FIXME: edge thicknesses
my $edges_thickness = $self->{edges_thickness} / $thickness_factor;
# $text .= "appearance.setAttribute(CommonAttributes.LINE_SHADER+\".\"+CommonAttributes.TUBE_RADIUS,$edges_thickness);\n";
$text .= <<".";
appearance.setAttribute(CommonAttributes.LINE_SHADER +"."+ CommonAttributes.DIFFUSE_COLOR,
new java.awt.Color((float)@edge_colors[0] ,(float)@edge_colors[1],(float)@edge_colors[2]));
.
return $text;
}
sub faceSet {
my ($self) = @_;
my $text .="faces = new int[][]{ ";
dbg_print ("generating faceset for jreality ...") if $Switches::d;
my @faces = (@{$self->{faces}});
map { $_=$self->process_face($_)} @faces;
$text .= join(",", @faces);
$text .= " }; \n";
return $text;
}
sub process_face {
my ($self, $face) = @_;
my $text .= "{ ";
my @indices = ( $face =~ /\d+/g);
@indices = reverse @indices;
$text .= join(",", @indices);
$text .= " } \n";
return $text;
}
sub trailer {
my $self = shift;
my $number = shift;
my $obj_name = shift;
my $n_faces = @{$self->{faces}};
my $n_points = @{$self->{points}};
my $text .=<<".";
IndexedFaceSetFactory ifsf = new de.jreality.geometry.IndexedFaceSetFactory();
ifsf.setGenerateFaceNormals(true);
ifsf.setGenerateVertexNormals(true);
ifsf.setGenerateEdgesFromFaces(true);
ifsf.setVertexCount($n_points);
ifsf.setFaceCount($n_faces);
ifsf.setVertexCoordinates(pts);
ifsf.setFaceIndices(faces);
if(labels.length == $n_points) { ifsf.setVertexLabels(labels); }
.
$text .= $self->SUPER::add_point_colors;
$text .=<<".";
ifsf.setVertexColors( new DoubleArrayArray.Inlined(colors, 3));
.
$text .= $self->add_face_colors;
$text .=<<".";
ifsf.setFaceColors( new DoubleArrayArray.Inlined(faceColors, 3));
ifsf.update();
part1=new SceneGraphComponent();
part1.setGeometry(ifsf.getGeometry());
part1.setName("FaceSet $number");
part1.setAppearance(appearance);
$obj_name.addChild(part1);
/*----------------------------------------*/
.
return $text;
}
sub toString {
dbg_print("called JReality::solid->toString ..") if $Switches::d;
my $self = shift;
my $number = shift;
my $obj_name = shift;
my $text = "";
$text .= $self->SUPER::pointSet;
$text .= $self->faceSet;
$text .= $self->appearance($obj_name);
$text .= $self->trailer($number, $obj_name);
return $text;
}
1
# Local Variables:
# mode:perl
# c-basic-offset:3
# End:
syntax highlighted by Code2HTML, v. 0.9.1