From 48886dd80cf5a05dad279363e8fc9743dd7770ae Mon Sep 17 00:00:00 2001 From: Antoine Villeret Date: Thu, 27 Dec 2012 14:41:22 +0000 Subject: clean up directory fix help patch dependency improve REAMDE svn path=/trunk/externals/pix_opencv/; revision=16770 --- Makefile | 2 +- README.txt | 8 + examples/06_GPU_opticalflow/06_GPU_opticalflow.pd | 169 ++++++++++++++++++++++ examples/06_GPU_opticalflow/of.frag | 47 ++++++ of.frag | 47 ------ pix_opencv_contours-help.pd | 104 ++++++++++++- pix_opencv_opticalflow.pd | 150 ------------------- 7 files changed, 322 insertions(+), 205 deletions(-) create mode 100644 examples/06_GPU_opticalflow/06_GPU_opticalflow.pd create mode 100644 examples/06_GPU_opticalflow/of.frag delete mode 100644 of.frag delete mode 100644 pix_opencv_opticalflow.pd diff --git a/Makefile b/Makefile index 5c6d82a..e71fc00 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ UNITTESTS = #------------------------------------------------------------------------------# ALL_CFLAGS = -I"$(PD_INCLUDE)" -CFLAGS_linux = -I/usr/include/Gem +CFLAGS_linux = -I/usr/local/include/Gem `pkg-config --cflags opencv` CFLAGS_macosx = -I/Library/Frameworks/OpenCV.framework/Headers/ \ -I$(PD_PATH)/include/Gem -I$(PD_PATH)/include ALL_LDFLAGS = diff --git a/README.txt b/README.txt index 426f5da..3fd8108 100644 --- a/README.txt +++ b/README.txt @@ -6,6 +6,8 @@ get the source version through svn : svn co https://pure-data.svn.sourceforge.net/svnroot/pure-data pure-data cd pure-data/trunk/externals/pix_opencv +pix_opencv depends on OpenCV 2.x and >1.5 (for old externals) + ===== GNU/Linux ===== (actually only tested in GNU/Linux Ubuntu) @@ -49,6 +51,12 @@ first install openCV MacOS framework download openCV private framework from http://www.ient.rwth-aachen.de/cms/software/opencv/ copy the provided OpenCV.framework folder in your /Library/Frameworks/ directory :: cp -Rf /Volumes/OpenCV\ Private\ Framework/OpenCV.framework /Library/Frameworks/ +this will only install OpenCV 1.5 + +you need OpenCV 2.x to use recent pix_opencv externals +you will find a step by step how to install it on Mac OSX here : +http://opencv.willowgarage.com/wiki/Mac_OS_X_OpenCV_Port +but this document is quite old... get the _SOURCES_ of the pd you are using and of the GEM that you are loading diff --git a/examples/06_GPU_opticalflow/06_GPU_opticalflow.pd b/examples/06_GPU_opticalflow/06_GPU_opticalflow.pd new file mode 100644 index 0000000..c607683 --- /dev/null +++ b/examples/06_GPU_opticalflow/06_GPU_opticalflow.pd @@ -0,0 +1,169 @@ +#N canvas 371 215 1451 649 10; +#X obj 936 450 cnv 15 200 40 empty empty empty 20 12 0 14 -261234 -66577 +0; +#X obj 149 397 gemframebuffer; +#X obj 149 424 translateXYZ 0 0 -4; +#X obj 149 558 pix_texture; +#X obj 194 511 loadbang; +#X obj 162 343 loadbang; +#X obj 568 438 gemframebuffer; +#X obj 568 476 translateXYZ 0 0 -4; +#X obj 568 577 pix_texture; +#X obj 603 521 loadbang; +#X obj 594 359 loadbang; +#X msg 600 542 rectangle 1 \, quality 1; +#X obj 1057 537 loadbang; +#X msg 1057 557 rectangle 1 \, quality 1; +#X obj 149 587 rectangle 4 4; +#X obj 568 603 square 4; +#X msg 1204 461 previousFrame 1 \, currentFrame 2; +#X msg 1224 432 lambda \$1; +#X msg 1288 431 scale \$1 \$1; +#X msg 194 533 rectangle 1 \, quality 1; +#X obj 608 419 r of_dim; +#X obj 1047 587 pix_texture; +#X obj 342 179 gemwin; +#X msg 325 140 create \, 1; +#X msg 398 140 0 \, destroy; +#N canvas 493 216 473 548 glsl_frag 0; +#X obj 104 413 glsl_program; +#X msg 61 190 print; +#X obj 179 255 change; +#X msg 60 360 print; +#X obj 104 232 glsl_fragment; +#X floatatom 179 281 2 0 0 0 ID - -; +#X obj 197 327 print linking; +#X text 123 361 after linking \, click "print" to get some info about +the compiled shader program; +#X obj 41 16 inlet; +#X obj 104 449 outlet; +#X obj 262 57 inlet; +#X obj 41 39 route bang; +#X obj 114 140 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 +-1 -1; +#X obj 168 51 gemhead 1; +#X msg 168 73 1; +#X obj 168 97 change; +#X obj 168 121 t b; +#X obj 183 455 t b; +#X obj 183 476 outlet; +#X msg 179 306 link \$1; +#X obj 114 166 t b; +#X msg 113 189 open of.frag; +#X connect 0 0 9 0; +#X connect 0 1 17 0; +#X connect 1 0 4 0; +#X connect 2 0 5 0; +#X connect 3 0 0 0; +#X connect 4 0 0 0; +#X connect 4 1 2 0; +#X connect 5 0 19 0; +#X connect 8 0 11 0; +#X connect 10 0 0 0; +#X connect 11 0 20 0; +#X connect 11 1 4 0; +#X connect 12 0 20 0; +#X connect 13 0 14 0; +#X connect 14 0 15 0; +#X connect 15 0 16 0; +#X connect 16 0 20 0; +#X connect 17 0 18 0; +#X connect 19 0 0 0; +#X connect 19 0 6 0; +#X connect 20 0 21 0; +#X connect 21 0 4 0; +#X restore 1047 464 pd glsl_frag; +#X obj 529 66 pix_info _____________; +#X msg 639 116 \$1; +#X obj 529 5 gemhead; +#X obj 529 45 pix_video; +#X obj 529 113 pix_texture; +#X obj 529 179 spigot; +#X obj 586 250 loadbang; +#X msg 586 271 0; +#X msg 162 362 rectangle 1 \, format RGB32 \, type FLOAT \, texunit +2 \, dimen 640 480; +#X msg 594 386 rectangle 1 \, texunit 1 \, format RGB32 \, dimen 640 +480; +#X obj 529 210 t b b b; +#X obj 529 138 t b b; +#X obj 568 323 gemhead; +#X obj 149 314 gemhead; +#X obj 1047 347 gemhead; +#X text 941 464 shader inside -->; +#X obj 1219 407 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -8 0 +10 -262144 -1 -1 0 256; +#X obj 1289 404 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -8 0 +10 -262144 -1 -1 1 256; +#X obj 1289 359 loadbang; +#X msg 1289 382 1; +#X text 815 119 this is an example of how to compute optical flow on +GPU; +#X obj 1240 212 loadbang; +#X msg 1240 232 rectangle 1 \, quality 1; +#X obj 1230 262 pix_texture; +#X obj 1230 140 gemhead; +#X text 571 179 <-- only render when a new image arrived; +#X obj 1044 498 translateXYZ 0 -4 -4; +#X obj 1229 174 translateXYZ 0 4 -4; +#X obj 1231 282 rectangle 4 3; +#X obj 1047 607 rectangle 4 3; +#X connect 1 0 2 0; +#X connect 1 1 8 1; +#X connect 1 1 21 1; +#X connect 2 0 3 0; +#X connect 3 0 14 0; +#X connect 4 0 19 0; +#X connect 5 0 34 0; +#X connect 6 0 7 0; +#X connect 7 0 8 0; +#X connect 8 0 15 0; +#X connect 9 0 11 0; +#X connect 10 0 35 0; +#X connect 11 0 8 0; +#X connect 12 0 13 0; +#X connect 13 0 21 0; +#X connect 16 0 25 1; +#X connect 17 0 25 1; +#X connect 18 0 25 1; +#X connect 19 0 3 0; +#X connect 20 0 6 0; +#X connect 21 0 55 0; +#X connect 23 0 22 0; +#X connect 24 0 22 0; +#X connect 25 0 52 0; +#X connect 25 1 16 0; +#X connect 25 1 42 0; +#X connect 25 1 43 0; +#X connect 26 0 30 0; +#X connect 26 6 27 0; +#X connect 27 0 31 1; +#X connect 28 0 29 0; +#X connect 29 0 26 0; +#X connect 30 0 37 0; +#X connect 30 1 3 1; +#X connect 30 1 49 1; +#X connect 31 0 36 0; +#X connect 32 0 33 0; +#X connect 33 0 38 0; +#X connect 33 0 39 0; +#X connect 33 0 40 0; +#X connect 34 0 1 0; +#X connect 35 0 6 0; +#X connect 36 1 39 0; +#X connect 36 2 38 0; +#X connect 37 0 40 0; +#X connect 37 1 31 0; +#X connect 38 0 6 0; +#X connect 39 0 1 0; +#X connect 40 0 25 0; +#X connect 42 0 17 0; +#X connect 43 0 18 0; +#X connect 44 0 45 0; +#X connect 45 0 43 0; +#X connect 47 0 48 0; +#X connect 48 0 49 0; +#X connect 49 0 54 0; +#X connect 50 0 53 0; +#X connect 52 0 21 0; +#X connect 53 0 49 0; diff --git a/examples/06_GPU_opticalflow/of.frag b/examples/06_GPU_opticalflow/of.frag new file mode 100644 index 0000000..af7d99e --- /dev/null +++ b/examples/06_GPU_opticalflow/of.frag @@ -0,0 +1,47 @@ +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect currentFrame, previousFrame; +uniform float lambda; +uniform vec2 scale; + +vec2 offset = vec2(1.,1.); +vec2 texcoord0 = gl_TexCoord[0].st; +vec2 texcoord1 = gl_TexCoord[1].st; + +void main() +{ + vec4 a = texture2DRect(currentFrame, texcoord0); + vec4 b = texture2DRect(previousFrame , texcoord1); + vec2 x1 = vec2(offset.x,0.); + vec2 y1 = vec2(0.,offset.y); + + //get the difference + vec4 curdif = b-a; + + //calculate the gradient + vec4 gradx = texture2DRect(previousFrame, texcoord1+x1)-texture2DRect(previousFrame, texcoord1-x1); + gradx += texture2DRect(currentFrame, texcoord0+x1)-texture2DRect(currentFrame, texcoord0-x1); + vec4 grady = texture2DRect(previousFrame, texcoord1+y1)-texture2DRect(previousFrame, texcoord1-y1); + grady += texture2DRect(currentFrame, texcoord0+y1)-texture2DRect(currentFrame, texcoord0-y1); + vec4 gradmag = sqrt((gradx*gradx)+(grady*grady)+vec4(lambda)); + + if ( gradmag.r == 0. ) { + gl_FragColor = vec4(0.5,0.5,0.5,1); + return; + } + + vec4 vx = curdif*(gradx/gradmag); + float vxd = vx.r;//assumes greyscale + //format output for flowrepos, out(-x,+x,-y,+y) + //~ vec2 xout = vec2(max(vxd,0.),abs(min(vxd,0.)))*scale.x; + float xout = ((vxd/2.)*scale.x+0.5); + + vec4 vy = curdif*(grady/gradmag); + float vyd = vy.r;//assumes greyscale + //format output for flowrepos, out(-x,+x,-y,+y) + //~ vec2 yout = vec2(max(vyd,0.),abs(min(vyd,0.)))*scale.y; + float yout = ((vyd/2.)*scale.y+0.5); + + //~ gl_FragColor = vec4(xout.xy,yout.xy); + gl_FragColor = vec4(xout,yout,0.5,1.); +} diff --git a/of.frag b/of.frag deleted file mode 100644 index af7d99e..0000000 --- a/of.frag +++ /dev/null @@ -1,47 +0,0 @@ -#extension GL_ARB_texture_rectangle : enable - -uniform sampler2DRect currentFrame, previousFrame; -uniform float lambda; -uniform vec2 scale; - -vec2 offset = vec2(1.,1.); -vec2 texcoord0 = gl_TexCoord[0].st; -vec2 texcoord1 = gl_TexCoord[1].st; - -void main() -{ - vec4 a = texture2DRect(currentFrame, texcoord0); - vec4 b = texture2DRect(previousFrame , texcoord1); - vec2 x1 = vec2(offset.x,0.); - vec2 y1 = vec2(0.,offset.y); - - //get the difference - vec4 curdif = b-a; - - //calculate the gradient - vec4 gradx = texture2DRect(previousFrame, texcoord1+x1)-texture2DRect(previousFrame, texcoord1-x1); - gradx += texture2DRect(currentFrame, texcoord0+x1)-texture2DRect(currentFrame, texcoord0-x1); - vec4 grady = texture2DRect(previousFrame, texcoord1+y1)-texture2DRect(previousFrame, texcoord1-y1); - grady += texture2DRect(currentFrame, texcoord0+y1)-texture2DRect(currentFrame, texcoord0-y1); - vec4 gradmag = sqrt((gradx*gradx)+(grady*grady)+vec4(lambda)); - - if ( gradmag.r == 0. ) { - gl_FragColor = vec4(0.5,0.5,0.5,1); - return; - } - - vec4 vx = curdif*(gradx/gradmag); - float vxd = vx.r;//assumes greyscale - //format output for flowrepos, out(-x,+x,-y,+y) - //~ vec2 xout = vec2(max(vxd,0.),abs(min(vxd,0.)))*scale.x; - float xout = ((vxd/2.)*scale.x+0.5); - - vec4 vy = curdif*(grady/gradmag); - float vyd = vy.r;//assumes greyscale - //format output for flowrepos, out(-x,+x,-y,+y) - //~ vec2 yout = vec2(max(vyd,0.),abs(min(vyd,0.)))*scale.y; - float yout = ((vyd/2.)*scale.y+0.5); - - //~ gl_FragColor = vec4(xout.xy,yout.xy); - gl_FragColor = vec4(xout,yout,0.5,1.); -} diff --git a/pix_opencv_contours-help.pd b/pix_opencv_contours-help.pd index 446e838..2aa9bb1 100644 --- a/pix_opencv_contours-help.pd +++ b/pix_opencv_contours-help.pd @@ -1,4 +1,4 @@ -#N canvas 759 213 794 706 10; +#N canvas 757 219 794 706 10; #X obj 472 35 cnv 15 300 400 empty empty empty 20 12 0 14 -228992 -66577 0; #X obj 11 56 cnv 15 450 200 empty empty empty 20 12 0 14 -233017 -66577 @@ -174,7 +174,6 @@ point (2 floats)> depth; #X connect 35 0 26 0; #X restore 658 323 pd draw_rotrect; #X obj 487 240 pix_opencv_contours; -#X obj 479 320 pix_opencv_drawcontours; #X obj 514 96 pix_image examples/dessin.tif; #N canvas 969 295 674 695 drawdefects 0; #X obj 191 301 gemhead; @@ -298,13 +297,104 @@ point (2 floats)> depth; #X text 534 385 blue = convexhull; #X text 534 397 pink = convexhull edge with defects; #X text 540 409 red = farthest point from convexhull; +#N canvas 1 86 632 734 draw_contours 0; +#X obj 178 132 list split 2; +#X obj 170 593 GEMglEnd; +#X obj 300 590 GEMglVertex2d; +#X obj 212 263 list append; +#X obj 241 237 t b a; +#X obj 241 216 list split 2; +#X obj 341 495 unpack; +#X obj 310 257 t b a; +#X obj 429 319 color 1 0 0 1; +#X obj 405 545 * -8; +#X obj 405 565 + 4; +#X obj 429 377 GEMglLineWidth 2; +#X obj 341 545 * 10.6666; +#X obj 341 565 - 5.33333; +#X obj 170 564 gemlist; +#X obj 300 421 gemlist; +#X obj 468 227 gemhead; +#X obj 468 172 loadbang; +#X msg 468 193 0; +#X obj 133 161 unpack 0 0; +#X floatatom 133 182 5 0 0 0 nb_of_segments - -; +#X obj 107 -65 inlet CONTOUR; +#X obj 429 289 gemlist; +#X obj 212 159 t b a b b; +#X obj 106 -44 route convexhull contour convexitydefects; +#X obj 187 1 t a b; +#X msg 513 275 0 0 1 1; +#X msg 505 254 0 1 0 1; +#X obj 106 0 t a b; +#X obj 268 1 list split 2; +#X obj 290 96 list append; +#X obj 319 76 t b a; +#X obj 302 28 t b a b b; +#X obj 268 -19 t a b; +#X msg 523 295 1 0 1 1; +#X obj 319 55 list split 7; +#X obj 346 116 list split 4; +#X obj 429 414 GEMglBegin GL_LINE_LOOP; +#X connect 0 0 19 0; +#X connect 0 1 23 0; +#X connect 3 0 5 0; +#X connect 4 0 3 0; +#X connect 4 1 7 0; +#X connect 5 0 4 0; +#X connect 5 1 3 1; +#X connect 6 0 12 0; +#X connect 6 1 9 0; +#X connect 7 0 15 0; +#X connect 7 1 6 0; +#X connect 8 0 11 0; +#X connect 9 0 10 0; +#X connect 10 0 2 2; +#X connect 11 0 37 0; +#X connect 12 0 13 0; +#X connect 13 0 2 1; +#X connect 14 0 1 0; +#X connect 15 0 2 0; +#X connect 16 0 15 1; +#X connect 16 0 14 1; +#X connect 16 0 22 1; +#X connect 17 0 18 0; +#X connect 18 0 16 0; +#X connect 19 0 20 0; +#X connect 21 0 24 0; +#X connect 22 0 8 0; +#X connect 23 0 14 0; +#X connect 23 1 5 0; +#X connect 23 2 22 0; +#X connect 23 3 16 0; +#X connect 24 0 28 0; +#X connect 24 1 25 0; +#X connect 24 2 33 0; +#X connect 25 0 0 0; +#X connect 25 1 27 0; +#X connect 26 0 8 1; +#X connect 27 0 8 1; +#X connect 28 0 0 0; +#X connect 28 1 26 0; +#X connect 29 1 32 0; +#X connect 30 0 35 0; +#X connect 31 0 30 0; +#X connect 31 1 36 0; +#X connect 32 1 35 0; +#X connect 33 0 29 0; +#X connect 33 1 34 0; +#X connect 34 0 8 1; +#X connect 35 0 31 0; +#X connect 35 1 30 1; +#X connect 36 0 23 0; +#X restore 486 320 pd draw_contours; #X connect 13 0 14 0; #X connect 14 0 13 0; #X connect 40 0 48 0; #X connect 41 0 55 0; #X connect 42 0 41 0; #X connect 43 0 42 0; -#X connect 43 1 57 0; +#X connect 43 1 56 0; #X connect 44 0 43 0; #X connect 45 0 55 0; #X connect 46 0 45 0; @@ -316,8 +406,8 @@ point (2 floats)> depth; #X connect 51 0 50 0; #X connect 52 0 51 0; #X connect 53 0 46 0; -#X connect 55 1 56 0; -#X connect 55 1 58 0; +#X connect 55 1 57 0; +#X connect 55 1 65 0; #X connect 55 2 54 0; -#X connect 57 0 49 0; -#X connect 59 0 55 0; +#X connect 56 0 49 0; +#X connect 58 0 55 0; diff --git a/pix_opencv_opticalflow.pd b/pix_opencv_opticalflow.pd deleted file mode 100644 index 9b7fa89..0000000 --- a/pix_opencv_opticalflow.pd +++ /dev/null @@ -1,150 +0,0 @@ -#N canvas 464 288 1451 649 10; -#X obj 936 450 cnv 15 200 40 empty empty empty 20 12 0 14 -261234 -66577 -0; -#X obj 149 397 gemframebuffer; -#X obj 149 424 translateXYZ 0 0 -4; -#X obj 149 558 pix_texture; -#X obj 194 511 loadbang; -#X obj 162 343 loadbang; -#X obj 568 438 gemframebuffer; -#X obj 568 476 translateXYZ 0 0 -4; -#X obj 568 577 pix_texture; -#X obj 603 521 loadbang; -#X obj 594 359 loadbang; -#X msg 600 542 rectangle 1 \, quality 1; -#X obj 1047 500 translateXYZ 0 0 -4; -#X obj 1047 607 square 4; -#X obj 1057 537 loadbang; -#X msg 1057 557 rectangle 1 \, quality 1; -#X obj 149 587 rectangle 4 4; -#X obj 568 603 square 4; -#X msg 1204 461 previousFrame 1 \, currentFrame 2; -#X msg 1224 432 lambda \$1; -#X msg 1288 431 scale \$1 \$1; -#X msg 194 533 rectangle 1 \, quality 1; -#X obj 608 419 r of_dim; -#X obj 1047 587 pix_texture; -#X obj 342 179 gemwin; -#X msg 325 140 create \, 1; -#X msg 398 140 0 \, destroy; -#N canvas 493 216 473 548 glsl_frag 0; -#X obj 104 413 glsl_program; -#X msg 61 190 print; -#X obj 179 255 change; -#X msg 60 360 print; -#X obj 104 232 glsl_fragment; -#X floatatom 179 281 2 0 0 0 ID - -; -#X obj 197 327 print linking; -#X text 123 361 after linking \, click "print" to get some info about -the compiled shader program; -#X obj 41 16 inlet; -#X obj 104 449 outlet; -#X obj 262 57 inlet; -#X obj 41 39 route bang; -#X obj 114 140 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 --1 -1; -#X obj 168 51 gemhead 1; -#X msg 168 73 1; -#X obj 168 97 change; -#X obj 168 121 t b; -#X obj 183 455 t b; -#X obj 183 476 outlet; -#X msg 179 306 link \$1; -#X obj 114 166 t b; -#X msg 113 189 open of.frag; -#X connect 0 0 9 0; -#X connect 0 1 17 0; -#X connect 1 0 4 0; -#X connect 2 0 5 0; -#X connect 3 0 0 0; -#X connect 4 0 0 0; -#X connect 4 1 2 0; -#X connect 5 0 19 0; -#X connect 8 0 11 0; -#X connect 10 0 0 0; -#X connect 11 0 20 0; -#X connect 11 1 4 0; -#X connect 12 0 20 0; -#X connect 13 0 14 0; -#X connect 14 0 15 0; -#X connect 15 0 16 0; -#X connect 16 0 20 0; -#X connect 17 0 18 0; -#X connect 19 0 0 0; -#X connect 19 0 6 0; -#X connect 20 0 21 0; -#X connect 21 0 4 0; -#X restore 1047 464 pd glsl_frag; -#X obj 529 66 pix_info _____________; -#X msg 639 116 \$1; -#X obj 529 5 gemhead; -#X obj 529 45 pix_video; -#X obj 529 113 pix_texture; -#X obj 529 179 spigot; -#X obj 586 250 loadbang; -#X msg 586 271 0; -#X msg 162 362 rectangle 1 \, format RGB32 \, type FLOAT \, texunit -2 \, dimen 640 480; -#X msg 594 386 rectangle 1 \, texunit 1 \, format RGB32 \, dimen 640 -480; -#X obj 529 210 t b b b; -#X obj 529 138 t b b; -#X obj 568 323 gemhead; -#X obj 149 314 gemhead; -#X obj 1047 347 gemhead; -#X text 941 464 shader inside -->; -#X obj 1219 407 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -8 0 -10 -262144 -1 -1 0 256; -#X obj 1289 404 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -8 0 -10 -262144 -1 -1 4 256; -#X connect 1 0 2 0; -#X connect 1 1 8 1; -#X connect 1 1 23 1; -#X connect 2 0 3 0; -#X connect 3 0 16 0; -#X connect 4 0 21 0; -#X connect 5 0 36 0; -#X connect 6 0 7 0; -#X connect 7 0 8 0; -#X connect 8 0 17 0; -#X connect 9 0 11 0; -#X connect 10 0 37 0; -#X connect 11 0 8 0; -#X connect 12 0 23 0; -#X connect 14 0 15 0; -#X connect 15 0 23 0; -#X connect 18 0 27 1; -#X connect 19 0 27 1; -#X connect 20 0 27 1; -#X connect 21 0 3 0; -#X connect 22 0 6 0; -#X connect 23 0 13 0; -#X connect 25 0 24 0; -#X connect 26 0 24 0; -#X connect 27 0 12 0; -#X connect 27 1 18 0; -#X connect 27 1 44 0; -#X connect 27 1 45 0; -#X connect 28 0 32 0; -#X connect 28 6 29 0; -#X connect 29 0 33 1; -#X connect 30 0 31 0; -#X connect 31 0 28 0; -#X connect 32 0 39 0; -#X connect 32 1 3 1; -#X connect 33 0 38 0; -#X connect 34 0 35 0; -#X connect 35 0 40 0; -#X connect 35 0 41 0; -#X connect 35 0 42 0; -#X connect 36 0 1 0; -#X connect 37 0 6 0; -#X connect 38 1 41 0; -#X connect 38 2 40 0; -#X connect 39 0 42 0; -#X connect 39 1 33 0; -#X connect 40 0 6 0; -#X connect 41 0 1 0; -#X connect 42 0 27 0; -#X connect 44 0 19 0; -#X connect 45 0 20 0; -- cgit v1.2.1