Perl+OpenGL 重绘inkscape生成的svg矢量图
Perl+OpenGL 重绘inkscape生成的svg矢量图
还不够完善,先挖个坑,后面慢慢填
Code: [全选] [展开/收缩] [Download] (Untitled.pl)
=info
Author: 523066680
Date: 2016-11
=cut
use IO::Handle;
use OpenGL qw/ :all /;
use OpenGL::Config;
use Time::HiRes 'sleep';
use feature 'state';
STDOUT->autoflush(1);
open READ, "<:raw", "multi.svg";
my @all;
my $tl;
for my $line (<READ>)
{
if ( $line=~/\s+d="(.*)"/ )
{
@all = split(" ", $1 );
}
}
my @coords;
for my $e (@all)
{
if ( $e =~/[a-zA-Z]/ )
{
$head = $e;
next;
}
push @coords,
{
'head' => $head,
'data' => [ split(",", $e) ],
};
}
#相对坐标 叠加为绝对坐标
my ($ox, $oy);
for (my $i = 0; $i <= $#coords; $i++)
{
if ($coords[$i]->{head} eq 'c')
{
grep
{
$coords[ $i+$_ ]->{'data'}[0] += $ox;
$coords[ $i+$_ ]->{'data'}[1] += $oy;
} (0..2) ;
$i += 2;
}
else
{
}
#ox oy 始终是最后一点的坐标值
($ox, $oy) = ($coords[$i]->{'data'}[0], $coords[$i]->{'data'}[1]) ;
}
my ($xmin, $xmax, $ymin, $ymax) = (10000.0, -10000.0, 10000.0, -10000.0);
for my $e (@coords)
{
printf("%.2f, %.2f\n", $e->{'data'}[0], $e->{'data'}[1]);
$xmin = $e->{'data'}[0] if ($e->{'data'}[0] < $xmin);
$xmax = $e->{'data'}[0] if ($e->{'data'}[0] > $xmax);
$ymin = $e->{'data'}[1] if ($e->{'data'}[1] < $ymin);
$ymax = $e->{'data'}[1] if ($e->{'data'}[1] > $ymax);
}
printf("%f %f %f %f\n", $xmin, $xmax, $ymin, $ymax);
&Main();
sub display
{
glClear(GL_COLOR_BUFFER_BIT);
glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
glPushMatrix();
my $array;
my @points;
for (my $i = 0; $i <= $#coords; $i++)
{
if ($coords[$i]->{head} eq 'C')
{
glColor4f(0.0,0.5,0.0,1.0);
$array = OpenGL::Array->new( 3*4, GL_FLOAT);
@points = (
$coords[$i-1]->{'data'}[0], $coords[$i-1]->{'data'}[1], 0.0 ,
$coords[$i+0]->{'data'}[0], $coords[$i+0]->{'data'}[1], 0.0 ,
$coords[$i+1]->{'data'}[0], $coords[$i+1]->{'data'}[1], 0.0 ,
$coords[$i+2]->{'data'}[0], $coords[$i+2]->{'data'}[1], 0.0 ,
);
$array->assign(0, @points);
glMap1f_c(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, $array->ptr);
glMapGrid1f(20, 0.0, 1.0);
glEvalMesh1(GL_LINE, 0, 20);
$i+=2;
}
elsif ($coords[$i]->{head} eq 'c')
{
glColor4f(0.0,0.5,0.0,1.0);
$array = OpenGL::Array->new( 3*4, GL_FLOAT);
@points = ( $coords[$i-1]->{'data'}[0], $coords[$i-1]->{'data'}[1], 0.0,
$coords[$i+0]->{'data'}[0], $coords[$i+0]->{'data'}[1], 0.0 ,
$coords[$i+1]->{'data'}[0], $coords[$i+1]->{'data'}[1], 0.0 ,
$coords[$i+2]->{'data'}[0], $coords[$i+2]->{'data'}[1], 0.0 ,
);
$array->assign(0, @points);
glMap1f_c(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, $array->ptr);
glMapGrid1f(20, 0.0, 1.0);
glEvalMesh1(GL_LINE, 0, 20);
$i += 2;
}
elsif ($coords[$i]->{head} eq 'L')
{
glBegin(GL_LINES);
glVertex3f( $coords[$i-1]->{'data'}[0], $coords[$i-1]->{'data'}[1], 0.0 );
glVertex3f( $coords[$i]->{'data'}[0], $coords[$i]->{'data'}[1], 0.0 );
glEnd();
}
elsif ($coords[$i]->{head} =~/m/i)
{
glBegin(GL_POINTS);
glColor3f(1.0, 1.0, 1.0);
glVertex3f( $coords[$i]->{'data'}[0], $coords[$i]->{'data'}[1], 0.0 );
glEnd();
}
}
glPopMatrix();
glutSwapBuffers();
}
sub init
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glPointSize(2.0);
glLineWidth(2.0);
glEnable(GL_BLEND);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_MAP1_VERTEX_3);
}
sub idle
{
sleep 0.05;
glutPostRedisplay();
}
sub Reshape
{
my $half = 1000;
glViewport(0, 0, 500.0, 500.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
#glOrtho(-$half, $half, -$half, $half, 0.0, 200.0);
glOrtho($xmin, $xmax, $ymin, $ymax, 0.0, 200.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0,0.0,100.0,0.0,0.0,0.0, 0.0,1.0,100.0);
}
sub hitkey
{
my $keychar = lc(chr(shift));
if ($keychar eq 'q')
{
glutDestroyWindow($WinID);
}
}
sub Main
{
glutInit();
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE );
glutInitWindowSize(500, 500);
glutInitWindowPosition(1,1);
our $WinID = glutCreateWindow("title");
&init();
glutDisplayFunc(\&display);
glutReshapeFunc(\&Reshape);
glutKeyboardFunc(\&hitkey);
glutIdleFunc(\&idle);
glutMainLoop();
}
__END__
要使glMap1f_c 正常工作,需要借用OpenGL::Array 建立一个
仿C的指针
my $array = OpenGL::Array->new( 3*4, GL_FLOAT);
$array->assign(0, @points);
glMap1f_c(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, $array->ptr);
glEnable(GL_MAP1_VERTEX_3);
请将一下内容保存到multi.svg,保存后可以拖入IE或者火狐中浏览。
Code: [全选] [展开/收缩] [Download] (multi.svg)
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
viewBox="0 0 744.09448819 1052.3622047"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="penta.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4"
inkscape:cx="402.20655"
inkscape:cy="647.84062"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1440"
inkscape:window-height="837"
inkscape:window-x="-4"
inkscape:window-y="120"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
sodipodi:type="star"
style="fill-rule:evenodd"
id="path4140"
sodipodi:sides="11"
sodipodi:cx="421.86606"
sodipodi:cy="388.68654"
sodipodi:r1="219.29707"
sodipodi:r2="63.376858"
sodipodi:arg1="0.029801473"
sodipodi:arg2="-2.8262334"
inkscape:flatsided="false"
inkscape:rounded="-0.07"
inkscape:randomized="0"
d="m 641.06576,395.22096 c -0.58462,19.63861 -285.54568,-7.5131 -279.45113,-26.19125 6.09452,-18.67807 252.23038,127.45733 241.12118,143.66224 C 591.62657,528.89693 366.58139,351.99388 381.80662,339.57579 397.03179,327.15774 525.08769,583.16575 506.981,590.7921 488.87423,598.41849 395.1952,327.92957 414.7172,325.71418 c 19.52193,-2.21538 -11.15897,282.38451 -30.51441,279.01099 -19.35551,-3.37353 48.07402,-281.57 65.6947,-272.87931 17.62062,8.69065 -162.05612,231.52397 -176.51508,218.22165 -14.45903,-13.30238 192.67067,-210.88099 202.79559,-194.04345 10.12488,16.83746 -261.50159,107.1562 -266.47347,88.14847 -4.9719,-19.00782 276.09575,-73.23875 275.51032,-53.60016 -0.58543,19.6385 -277.92215,-51.2329 -271.82841,-69.91123 6.09378,-18.6784 271.86238,87.65628 260.75247,103.8608 -11.10987,16.20446 -206.1044,-193.35592 -190.87975,-205.77459 15.22471,-12.41873 181.31462,220.72105 163.20754,228.34669 -18.107,7.6256 -68.84995,-274.0898 -49.32811,-276.30599 19.52191,-2.2162 33.20075,283.70845 13.84538,280.33412 -19.3553,-3.37432 90.26387,-267.80211 107.88484,-259.11218 17.62105,8.68996 -125.45412,256.62042 -139.91259,243.31744 -14.45842,-13.30292 220.71955,-176.48913 230.84513,-159.65209 10.12562,16.83712 -244.2782,148.05723 -249.24931,129.04921 -4.97109,-19.00794 281.09833,-29.14211 280.51372,-9.50359 z" />
</g>
</svg>