{"id":76,"date":"2017-02-01T10:39:22","date_gmt":"2017-02-01T10:39:22","guid":{"rendered":"https:\/\/kicad.mmccoo.com\/?p=31"},"modified":"2017-02-01T10:39:22","modified_gmt":"2017-02-01T10:39:22","slug":"querying-pcbnew-to-generate-a-basic-svg-file","status":"publish","type":"post","link":"https:\/\/kicad.mmccoo.com\/index.php\/2017\/02\/01\/querying-pcbnew-to-generate-a-basic-svg-file\/","title":{"rendered":"Querying pcbnew to generate a basic svg file"},"content":{"rendered":"In a&#160;<a class=\"broken_link\" href=\"https:\/\/kicad.mmccoo.com\/2017\/02\/01\/the-basics-of-scripting-in-pcbnew\/\">previous post<\/a>, I gave some basic query capabilies in pcbnew. In this post, I&#8217;ll use that to generate a simple <a class=\"broken_link\" href=\"https:\/\/en.wikipedia.org\/wiki\/Scalable_Vector_Graphics\">svg<\/a> file.<br\/>The result looks like this:<br\/>\n<a class=\"broken_link\" href=\"https:\/\/kicad.mmccoo.com\/wp-content\/uploads\/2017\/01\/sample-layout.png\"><img decoding=\"async\" alt=\"\" class=\"alignnone size-medium wp-image-31\" height=\"181\" loading=\"lazy\" src=\"https:\/\/kicad.mmccoo.com\/wp-content\/uploads\/2017\/01\/sample-layout-300x181.png\" width=\"300\"\/><\/a><br\/>\nNot the most interesting layout and a bunch of detail is missing, but I was happy to get this far. The code is hopefully self-explanatory. After the last post, I don&#8217;t really know what I can add.<br\/>\nThe code can be found <a class=\"broken_link\" href=\"https:\/\/github.com\/mmccoo\/kicad_mmccoo\/tree\/master\/gensvg\">in my github<\/a>\n<!-- wp:heading{\"level\":1} --><h1>Preliminaries<\/h1>\n<!-- \/wp:post-content --><!-- wp:paragraph -->I need to get each of pcbnew&#8217;s layer colors. Some of the color names are modified to match svr colors. The real answer is to get the rgb values from colorrefs, but those aren&#8217;t exposed in python today<br\/>\n<strong>Edit Nov 15, 2017<\/strong>&#160;RGB values are now available in the form of the COLOR4D structure.<br\/>\n[code]<br\/>\ncolors = board.Colors()<br\/>\nc4 = colors.GetLayerColor(track.GetLayer())<br\/>\nr =&#160;int(round(c4.r*255)<br\/>\ng = int(round(c4.g*255)),<br\/>\nb = int(round(c4.b*255))<br\/>\n[\/code]<br\/>\nThe colornames map below won&#8217;t work anymore.<br\/>\n<strong>End edit<\/strong>\n<pre>colornames = {\n pcbnew.BLACK: 'BLACK',\n pcbnew.DARKDARKGRAY: 'DARKSLATEGRAY', # 'DARKDARKGRAY',\n pcbnew.DARKGRAY: 'DARKGRAY',\n pcbnew.LIGHTGRAY: 'LIGHTGRAY',\n pcbnew.WHITE: 'WHITE',\n pcbnew.LIGHTYELLOW: 'LIGHTYELLOW',\n pcbnew.DARKBLUE: 'DARKBLUE',\n pcbnew.DARKGREEN: 'DARKGREEN',\n pcbnew.DARKCYAN: 'DARKCYAN',\n pcbnew.DARKRED: 'DARKRED',\n pcbnew.DARKMAGENTA: 'DARKMAGENTA',\n pcbnew.DARKBROWN: 'MAROON', # 'DARKBROWN',\n pcbnew.BLUE: 'BLUE',\n pcbnew.GREEN: 'GREEN',\n pcbnew.CYAN: 'CYAN',\n pcbnew.RED: 'RED',\n pcbnew.MAGENTA: 'MAGENTA',\n pcbnew.BROWN: 'BROWN',\n pcbnew.LIGHTBLUE: 'LIGHTBLUE',\n pcbnew.LIGHTGREEN: 'LIGHTGREEN',\n pcbnew.LIGHTCYAN: 'LIGHTCYAN',\n pcbnew.LIGHTRED: 'INDIANRED', # 'LIGHTRED',\n pcbnew.LIGHTMAGENTA: 'LIGHTPINK', # 'LIGHTMAGENTA',\n pcbnew.YELLOW: 'YELLOW',\n pcbnew.PUREBLUE: 'MEDIUMBLUE', # 'PUREBLUE',\n pcbnew.PUREGREEN: 'LAWNGREEN', # 'PUREGREEN',\n pcbnew.PURECYAN: 'DARKTURQUOISE', # 'PURECYAN',\n pcbnew.PURERED: 'FIREBRICK', # 'PURERED',\n pcbnew.PUREMAGENTA: 'DARKORCHID', # PUREMAGENTA',\n pcbnew.PUREYELLOW: 'KHAKI', # PUREYELLOW'\n}\npadshapes = {\n pcbnew.PAD_SHAPE_CIRCLE: \"PAD_SHAPE_CIRCLE\",\n pcbnew.PAD_SHAPE_OVAL: \"PAD_SHAPE_OVAL\",\n pcbnew.PAD_SHAPE_RECT: \"PAD_SHAPE_RECT\",\n pcbnew.PAD_SHAPE_TRAPEZOID: \"PAD_SHAPE_TRAPEZOID\"\n}\n# new in the most recent kicad code\nif hasattr(pcbnew, 'PAD_SHAPE_ROUNDRECT'):\n padshapes[pcbnew.PAD_SHAPE_ROUNDRECT] = \"PAD_SHAPE_ROUNDRECT\",<\/pre>\n<!-- \/wp:paragraph -->\n<!-- wp:paragraph -->Now we can get to it. Need to get the board, get the boundary coordinates, and set the scale factor\n<pre>board = pcbnew.GetBoard()\nboardbbox = board.ComputeBoundingBox()\nboardxl = boardbbox.GetX()\nboardyl = boardbbox.GetY()\nboardwidth = boardbbox.GetWidth()\nboardheight = boardbbox.GetHeight()\n# the internal coorinate space of pcbnew is 10E-6 mm. (a millionth of a mm)\n# the coordinate 121550000 corresponds to 121.550000\nSCALE = 1000000.0<\/pre>\n<!-- \/wp:paragraph --><!-- wp:heading{\"level\":1} --><h1>Writing an SVG<\/h1>\n<!-- \/wp:heading --><!-- wp:paragraph -->Here is where things happen. I&#8217;m sure if kicad include the svgwrite package or if it picks it up from my python install area. I did need to install it to python to do some experiments before doing anything in Kicad.<br\/>\n<strong>Edit Nov 15, 2017&#160;<\/strong><br\/>\nDue to kicad&#8217;s change to color management (in favor of RGB over colornames), the code below is not uptodate. Go to github for <a class=\"broken_link\" href=\"https:\/\/github.com\/mmccoo\/kicad_mmccoo\/blob\/master\/gensvg\/gensvg.py\">the latest working version<\/a>.<br\/>\n<strong>End edit<\/strong>\n<pre>import sys, os\nimport svgwrite\nprint(\"working in the dir \" + os.getcwd())\nname = \"output.svg\"\n# A4 is approximately 21x29\ndwg = svgwrite.Drawing(name, size=('21cm', '29cm'), profile='full', debug=True)\ndwg.viewbox(width=boardwidth, height=boardheight, minx=boardxl, miny=boardyl)\nbackground = dwg.add(dwg.g(id='bg', stroke='white'))\nbackground.add(dwg.rect(insert=(boardxl, boardyl), size=(boardwidth, boardheight), fill='white'))\nsvglayers = {}\nfor colorcode, colorname in colornames.items():\n layer = dwg.add(dwg.g(id='layer_'+colorname, stroke=colorname.lower(), stroke_linecap=\"round\"))\n svglayers[colorcode] = layer\nalltracks = board.GetTracks()\nfor track in alltracks:\n # print(\"{}-&gt;{}\".format(track.GetStart(), track.GetEnd()))\n # print(\"{},{}-&gt;{},{} width {} layer {}\".format(track.GetStart().x\/SCALE, track.GetStart().y\/SCALE,\n # track.GetEnd().x\/SCALE, track.GetEnd().y\/SCALE,\n # track.GetWidth()\/SCALE,\n # track.GetLayer())\n # )\n layercolor = board.GetLayerColor(track.GetLayer())\n svglayers[layercolor].add(dwg.line(start=(track.GetStart().x,\n track.GetStart().y),\n end=(track.GetEnd().x,\n track.GetEnd().y),\n stroke_width=track.GetWidth()\n ))\nsvgpads = dwg.add(dwg.g(id='pads', stroke='red',fill='orange'))\nallpads = board.GetPads()\nfor pad in allpads:\n mod = pad.GetParent()\n name = pad.GetPadName()\n if (0):\n print(\"pad {}({}) on {}({}) at {},{} shape {} size {},{}\"\n .format(name,\n pad.GetNet().GetNetname(),\n mod.GetReference(),\n mod.GetValue(),\n pad.GetPosition().x, pad.GetPosition().y,\n padshapes[pad.GetShape()],\n pad.GetSize().x, pad.GetSize().y\n ))\n if (pad.GetShape() == pcbnew.PAD_SHAPE_RECT):\n if ((pad.GetOrientationDegrees()==270) | (pad.GetOrientationDegrees()==90)):\n svgpads.add(dwg.rect(insert=(pad.GetPosition().x-pad.GetSize().x\/2,\n pad.GetPosition().y-pad.GetSize().y\/2),\n size=(pad.GetSize().y, pad.GetSize().x)))\n else:\n svgpads.add(dwg.rect(insert=(pad.GetPosition().x-pad.GetSize().x\/2,\n pad.GetPosition().y-pad.GetSize().y\/2),\n size=(pad.GetSize().x, pad.GetSize().y)))\n elif (pad.GetShape() == pcbnew.PAD_SHAPE_CIRCLE):\n svgpads.add(dwg.circle(center=(pad.GetPosition().x, pad.GetPosition().y),\n r=pad.GetSize().x))\n elif (pad.GetShape() == pcbnew.PAD_SHAPE_OVAL):\n svgpads.add(dwg.ellipse(center=(pad.GetPosition().x, pad.GetPosition().y),\n r=(pad.GetSize().x\/2, pad.GetSize().y\/2)))\n else:\n print(\"unknown pad shape {}({})\".format(pad.GetShape(), padshapes[pad.GetShape()]))\ndwg.save()<\/pre>\n<!-- \/wp:paragraph -->\n<!-- wp:paragraph -->&#160;\n<div class=\"extra-hatom-entry-title\"><span class=\"entry-title\">Querying pcbnew to generate a basic svg file<\/span><\/div> <!-- \/wp:paragraph -->","protected":false},"excerpt":{"rendered":"<p>In a&#160;previous post, I gave some basic query capabilies in pcbnew. In this post, I&#8217;ll use that to generate a simple svg file.The result looks like this: Not the most interesting layout and a bunch of detail is missing, but I was happy to get this far. The code is hopefully self-explanatory. After the last &hellip; <a href=\"https:\/\/kicad.mmccoo.com\/index.php\/2017\/02\/01\/querying-pcbnew-to-generate-a-basic-svg-file\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Querying pcbnew to generate a basic svg file&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-76","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/kicad.mmccoo.com\/index.php\/wp-json\/wp\/v2\/posts\/76","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kicad.mmccoo.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kicad.mmccoo.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kicad.mmccoo.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kicad.mmccoo.com\/index.php\/wp-json\/wp\/v2\/comments?post=76"}],"version-history":[{"count":0,"href":"https:\/\/kicad.mmccoo.com\/index.php\/wp-json\/wp\/v2\/posts\/76\/revisions"}],"wp:attachment":[{"href":"https:\/\/kicad.mmccoo.com\/index.php\/wp-json\/wp\/v2\/media?parent=76"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kicad.mmccoo.com\/index.php\/wp-json\/wp\/v2\/categories?post=76"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kicad.mmccoo.com\/index.php\/wp-json\/wp\/v2\/tags?post=76"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}