Advertisement
Guest User

Kicad teardrops

a guest
Jul 6th, 2016
1,947
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.43 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. # Teardrop for pcbnew using filled zones
  4. # (c) Niluje 2016 thewireddoesntexist.org
  5. #
  6. # Based on Teardrops for PCBNEW by svofski, 2014 http://sensi.org/~svo
  7.  
  8. import sys
  9. from math import cos, sin, asin, radians
  10. from pcbnew import *
  11.  
  12. ToUnits=ToMM
  13. FromUnits=FromMM
  14.  
  15. def GetAllVias(board):
  16.     """Just retreive all via from the given board"""
  17.     vias = []
  18.     for item in board.GetTracks():
  19.         if type(item) == VIA:
  20.             pos = item.GetPosition()
  21.             width = item.GetWidth()
  22.             drill = item.GetDrillValue()
  23.             vias.append((pos, width, drill))
  24.     return vias
  25.  
  26. def GetAllPads(board, filters=[]):
  27.     """Just retreive all pads from the given board"""
  28.     pads = []
  29.     for i in xrange(board.GetPadCount()):
  30.         pad = board.GetPad(i)
  31.         if pad.GetAttribute() in filters:
  32.             pos = pad.GetPosition()
  33.             drill = pad.GetDrillSize().x + FromUnits(0.2 * 2)
  34.             pads.append((pos, drill ))
  35.     return pads
  36.  
  37. def Zone(workfile, board, points, track):
  38.     """Add a zone to the board"""
  39.     z = ZONE_CONTAINER(board)
  40.  
  41.     #Add zone properties
  42.     z.SetLayer(track.GetLayer())
  43.     z.SetNetCode(track.GetNetCode())
  44.     z.SetZoneClearance(track.GetClearance())
  45.     z.SetMinThickness(25400) #The minimum
  46.     z.SetPadConnection(2) # 2 means solid
  47.     z.SetIsFilled(True)
  48.  
  49.     line=[]
  50.     for p in points:
  51.         z.AppendCorner(p)
  52.         line.append(str(p))
  53.  
  54.     line.sort()
  55.     z.BuildFilledSolidAreasPolygons(board)
  56.  
  57.     #Save zone properties
  58.     workfile.write(track.GetLayerName() + ':' + ''.join(line) + '\n')
  59.  
  60.     return z
  61.  
  62. def Compute4Points(track, via, hpercent, vpercent):
  63.     """Del all teardrops referenced by the teardrop file"""
  64.     start = track.GetStart()
  65.     end = track.GetEnd()
  66.  
  67.     # ensure that start is at the via/pad end
  68.     d = end - via[0]
  69.     if sqrt(d.x * d.x + d.y * d.y) < via[1]:
  70.         start, end = end, start
  71.  
  72.     # get normalized track vector
  73.     pt = end - start
  74.     norm = sqrt(pt.x * pt.x + pt.y * pt.y)
  75.     vec = [t / norm for t in pt]
  76.  
  77.     d = asin(vpercent/100.0);
  78.     vecB = [vec[0]*cos(d)+vec[1]*sin(d) , -vec[0]*sin(d)+vec[1]*cos(d)]
  79.     d = asin(-vpercent/100.0);
  80.     vecC = [vec[0]*cos(d)+vec[1]*sin(d) , -vec[0]*sin(d)+vec[1]*cos(d)]
  81.  
  82.     # find point on the track, sharp end of the teardrop
  83.     dist = via[1]*(1+hpercent/100.0)
  84.     pointA = start + wxPoint(int(vec[0] * dist), int(vec[1] * dist))
  85.  
  86.     # Introduce a last point in order to cover the via centre.
  87.     # If not, the zone won't be filled
  88.     vecD = [-vec[0], -vec[1]]
  89.  
  90.     radius = via[1] / 2
  91.  
  92.     # via side points
  93.     pointB = via[0] + wxPoint(int(vecB[0] * radius), int(vecB[1] * radius))
  94.     pointC = via[0] + wxPoint(int(vecC[0] * radius), int(vecC[1] * radius))
  95.  
  96.     # behind via center
  97.     radius = (via[1]/2)*0.5 #50% of via radius is enough to include
  98.     pointD = via[0] + wxPoint(int(vecD[0] * radius), int(vecD[1] * radius))
  99.  
  100.     return (pointA, pointB, pointD, pointC)
  101.  
  102. def SetTeardrops(hpercent=30, vpercent=70):
  103.     """Set teardrops on a teardrop free board"""
  104.  
  105.     pcb = GetBoard()
  106.     wf = open(pcb.GetFileName() + "_td", 'w')
  107.     vias = GetAllVias(pcb) + GetAllPads(pcb, [PAD_STANDARD])
  108.  
  109.     count = 0
  110.     for track in pcb.GetTracks():
  111.         if type(track) == TRACK:
  112.             for via in vias:
  113.                 if track.IsPointOnEnds(via[0], via[1]/2):
  114.                     if track.GetLength() < via[1]:
  115.                             continue
  116.                     coor = Compute4Points(track, via, hpercent, vpercent)
  117.                     pcb.Add(Zone(wf, pcb, coor, track))
  118.                     count = count + 1
  119.     print('{0} teardrops inserted'.format(count))
  120.  
  121. def RmTeardrops():
  122.     """Remove teardrops according to teardrops definition file"""
  123.  
  124.     pcb = GetBoard()
  125.     wf = open(pcb.GetFileName() + "_td", 'r')
  126.  
  127.     to_remove=[]
  128.     for line in wf:
  129.         for z in [ pcb.GetArea(i) for i in range(pcb.GetAreaCount()) ]:
  130.             corners = [str(z.GetCornerPosition(i)) for i in range(z.GetNumCorners())]
  131.             if len(corners) != 4:
  132.                 continue
  133.             if z.GetLayerName() != line.split(':')[0]:
  134.                 continue
  135.             corners.sort()
  136.             if line.rstrip() == z.GetLayerName() + ':' + ''.join(corners):
  137.                 to_remove.append(z)
  138.  
  139.     for tbr in to_remove:
  140.         pcb.Remove(tbr)
  141.     print('{0} teardrops removed'.format(len(to_remove)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement