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>

posted @ 2017-05-15 10:04  vicyang  阅读(1046)  评论(0编辑  收藏  举报