Initial Commit
This commit is contained in:
79
BP.ger
Normal file
79
BP.ger
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
G04 NI AWR Design Environment 14.04 *
|
||||||
|
G04 RS274-X Output Version 0.1 *
|
||||||
|
%FSLAX36Y36*%
|
||||||
|
%MOMM*%
|
||||||
|
%SFA1B1*%
|
||||||
|
%ADD10C,.010*%
|
||||||
|
|
||||||
|
G36*
|
||||||
|
X0Y5000D02*
|
||||||
|
X145000D01*
|
||||||
|
Y575000D01*
|
||||||
|
X0D01*
|
||||||
|
Y5000D01*
|
||||||
|
G37*
|
||||||
|
G36*
|
||||||
|
X145000Y5000D02*
|
||||||
|
X1815000D01*
|
||||||
|
Y135000D01*
|
||||||
|
X145000D01*
|
||||||
|
Y5000D01*
|
||||||
|
G37*
|
||||||
|
G36*
|
||||||
|
X145000Y-250000D02*
|
||||||
|
X1815000D01*
|
||||||
|
Y-120000D01*
|
||||||
|
X145000D01*
|
||||||
|
Y-250000D01*
|
||||||
|
G37*
|
||||||
|
G36*
|
||||||
|
X1815000Y-475000D02*
|
||||||
|
X3405000D01*
|
||||||
|
Y-115000D01*
|
||||||
|
X1815000D01*
|
||||||
|
Y-475000D01*
|
||||||
|
G37*
|
||||||
|
G36*
|
||||||
|
X1815000Y-960000D02*
|
||||||
|
X3405000D01*
|
||||||
|
Y-600000D01*
|
||||||
|
X1815000D01*
|
||||||
|
Y-960000D01*
|
||||||
|
G37*
|
||||||
|
G36*
|
||||||
|
X3405000Y-960000D02*
|
||||||
|
X4995000D01*
|
||||||
|
Y-600000D01*
|
||||||
|
X3405000D01*
|
||||||
|
Y-960000D01*
|
||||||
|
G37*
|
||||||
|
G36*
|
||||||
|
X3405000Y-1445000D02*
|
||||||
|
X4995000D01*
|
||||||
|
Y-1085000D01*
|
||||||
|
X3405000D01*
|
||||||
|
Y-1445000D01*
|
||||||
|
G37*
|
||||||
|
G36*
|
||||||
|
X4995000Y-1440000D02*
|
||||||
|
X6665000D01*
|
||||||
|
Y-1310000D01*
|
||||||
|
X4995000D01*
|
||||||
|
Y-1440000D01*
|
||||||
|
G37*
|
||||||
|
G36*
|
||||||
|
X4995000Y-1695000D02*
|
||||||
|
X6665000D01*
|
||||||
|
Y-1565000D01*
|
||||||
|
X4995000D01*
|
||||||
|
Y-1695000D01*
|
||||||
|
G37*
|
||||||
|
G36*
|
||||||
|
X6665000Y-2135000D02*
|
||||||
|
X6810000D01*
|
||||||
|
Y-1565000D01*
|
||||||
|
X6665000D01*
|
||||||
|
Y-2135000D01*
|
||||||
|
G37*
|
||||||
|
M02*
|
||||||
|
G04 End of Data *
|
||||||
18
BP.kicad_mod
Normal file
18
BP.kicad_mod
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
(module Default:BP (layer F.Cu) (tedit 5EF5C08B)
|
||||||
|
(fp_text reference REF** (at 0.0 5.0) (layer F.SilkS) hide
|
||||||
|
(effects (font (size 1 1) (thickness 0.15)))
|
||||||
|
)
|
||||||
|
(fp_text value BP (at 0.0 -5.0) (layer F.Fab) hide
|
||||||
|
(effects (font (size 1 1) (thickness 0.15)))
|
||||||
|
)
|
||||||
|
(fp_poly (pts (xy -3.405 0.785) (xy -3.26 0.785) (xy -3.26 1.355) (xy -3.405 1.355) (xy -3.405 0.785)) (layer F.Cu) (width 0.001))
|
||||||
|
(fp_poly (pts (xy -3.26 0.785) (xy -1.59 0.785) (xy -1.59 0.915) (xy -3.26 0.915) (xy -3.26 0.785)) (layer F.Cu) (width 0.001))
|
||||||
|
(fp_poly (pts (xy -3.26 0.53) (xy -1.59 0.53) (xy -1.59 0.66) (xy -3.26 0.66) (xy -3.26 0.53)) (layer F.Cu) (width 0.001))
|
||||||
|
(fp_poly (pts (xy -1.59 0.305) (xy 0.0 0.305) (xy 0.0 0.665) (xy -1.59 0.665) (xy -1.59 0.305)) (layer F.Cu) (width 0.001))
|
||||||
|
(fp_poly (pts (xy -1.59 -0.18) (xy 0.0 -0.18) (xy 0.0 0.18) (xy -1.59 0.18) (xy -1.59 -0.18)) (layer F.Cu) (width 0.001))
|
||||||
|
(fp_poly (pts (xy 0.0 -0.18) (xy 1.59 -0.18) (xy 1.59 0.18) (xy 0.0 0.18) (xy 0.0 -0.18)) (layer F.Cu) (width 0.001))
|
||||||
|
(fp_poly (pts (xy 0.0 -0.665) (xy 1.59 -0.665) (xy 1.59 -0.305) (xy 0.0 -0.305) (xy 0.0 -0.665)) (layer F.Cu) (width 0.001))
|
||||||
|
(fp_poly (pts (xy 1.59 -0.66) (xy 3.26 -0.66) (xy 3.26 -0.53) (xy 1.59 -0.53) (xy 1.59 -0.66)) (layer F.Cu) (width 0.001))
|
||||||
|
(fp_poly (pts (xy 1.59 -0.915) (xy 3.26 -0.915) (xy 3.26 -0.785) (xy 1.59 -0.785) (xy 1.59 -0.915)) (layer F.Cu) (width 0.001))
|
||||||
|
(fp_poly (pts (xy 3.26 -1.355) (xy 3.405 -1.355) (xy 3.405 -0.785) (xy 3.26 -0.785) (xy 3.26 -1.355)) (layer F.Cu) (width 0.001))
|
||||||
|
)
|
||||||
258
Ger2KiCad.py
Normal file
258
Ger2KiCad.py
Normal file
@@ -0,0 +1,258 @@
|
|||||||
|
#################################Ger2KiCad####################################
|
||||||
|
#This script allows to transform gerber files into kicad_mod files #
|
||||||
|
##############################################################################
|
||||||
|
#Author: E-Mail: #
|
||||||
|
#Martin Obermaier Martin.Obermaier@posteo.de#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
# Imports #
|
||||||
|
##############################################################################
|
||||||
|
import gerber
|
||||||
|
import re
|
||||||
|
import numpy as np
|
||||||
|
##############################################################################
|
||||||
|
# Define Classes #
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
class Polygon:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.vertices = []
|
||||||
|
|
||||||
|
def add_vertex(self,x,y):
|
||||||
|
self.vertices.append([x,y])
|
||||||
|
|
||||||
|
def get_vertices(self):
|
||||||
|
return self.vertices
|
||||||
|
|
||||||
|
def remove_vertex(self,x,y):
|
||||||
|
self.vertices.remove([x,y])
|
||||||
|
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
# Variables and Constants #
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
# Regex Filters:
|
||||||
|
|
||||||
|
MODE = r"(Mode):\s([a-z]{1,})"
|
||||||
|
SCALE = r"(Scale) Factor:\sX:\s(\d+\.\d+|\d+)\sY:\s(\d+\.\d+|\d+)"
|
||||||
|
COOR = r"(Coordinate Statement):\s([X,Y]):\s(-?\d+\.\d+|\d+)\s(?:(Y):\s"+\
|
||||||
|
"(-?\d+\.\d+|\d+))?.{1,}Lights\s(On|Off)"
|
||||||
|
RMStmtStart = r"(RegionModeStmt) type=RegionMode units=(metric|inch) mode=(on)"
|
||||||
|
RMStmtStop = r"(RegionModeStmt) type=RegionMode units=(metric|inch) mode=(off)"
|
||||||
|
EOF = r"EOF Statement"
|
||||||
|
|
||||||
|
|
||||||
|
Scale = [0.0,0.0]
|
||||||
|
offset = [0.0, 0.0]
|
||||||
|
|
||||||
|
mm = 1.0
|
||||||
|
inch = 25.4
|
||||||
|
|
||||||
|
mode = ""
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
# Functions #
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
def setMode(Stmt):
|
||||||
|
global mode
|
||||||
|
mode = re.search(MODE,Stmt).group(2)
|
||||||
|
print(Stmt)
|
||||||
|
|
||||||
|
def setScale(Stmt):
|
||||||
|
global Scale
|
||||||
|
Scale[0] = np.float(re.search(SCALE,Stmt).group(2));
|
||||||
|
Scale[1] = np.float(re.search(SCALE,Stmt).group(3));
|
||||||
|
print(Stmt)
|
||||||
|
print(Scale)
|
||||||
|
|
||||||
|
def new_Polygon(Stmts):
|
||||||
|
LastStmt = 0;
|
||||||
|
unit = ""
|
||||||
|
poly = Polygon()
|
||||||
|
LastCoor = [0.0,0.0]
|
||||||
|
#print(Stmts)
|
||||||
|
for cnt in range(len(Stmts)):
|
||||||
|
res = re.search(RMStmtStart,Stmts[cnt])
|
||||||
|
if res != None:
|
||||||
|
unit = res.group(2)
|
||||||
|
LastStmt = cnt+1
|
||||||
|
break
|
||||||
|
|
||||||
|
if unit == "metric":
|
||||||
|
factor = mm
|
||||||
|
else:
|
||||||
|
factor = inch
|
||||||
|
|
||||||
|
for cnt in range(LastStmt,len(Stmts)):
|
||||||
|
coor = []
|
||||||
|
res = re.search(COOR,Stmts[cnt])
|
||||||
|
if res.group(6) == "Off":
|
||||||
|
x = np.float(res.group(3))*factor
|
||||||
|
y = np.float(res.group(5))*factor
|
||||||
|
coor = [x,y]
|
||||||
|
elif res.group(6) =="On":
|
||||||
|
if res.group(2) != None and res.group(4) != None:
|
||||||
|
x = np.float(res.group(3))*factor
|
||||||
|
y = np.float(res.group(5))*factor
|
||||||
|
else:
|
||||||
|
if res.group(2) == "X":
|
||||||
|
x = np.float(res.group(3))*factor
|
||||||
|
y = LastCoor[1]
|
||||||
|
else:
|
||||||
|
y = np.float(res.group(3))*factor
|
||||||
|
x = LastCoor[0]
|
||||||
|
coor = [x,y]
|
||||||
|
coor = np.round(coor,4)
|
||||||
|
poly.add_vertex(coor[0],coor[1])
|
||||||
|
LastCoor = coor
|
||||||
|
|
||||||
|
return poly
|
||||||
|
|
||||||
|
def find_center(polygons):
|
||||||
|
xmax = np.array([], dtype=np.float64)
|
||||||
|
xmin = np.array([], dtype=np.float64)
|
||||||
|
|
||||||
|
ymax = np.array([], dtype=np.float64)
|
||||||
|
ymin = np.array([], dtype=np.float64)
|
||||||
|
|
||||||
|
for pol in polygons:
|
||||||
|
poly_coor = np.asarray(pol.get_vertices())
|
||||||
|
|
||||||
|
xmax = np.append(xmax,np.amax(poly_coor[::,0]))
|
||||||
|
xmin = np.append(xmin,np.amin(poly_coor[::,0]))
|
||||||
|
|
||||||
|
ymax = np.append(ymax,np.amax(poly_coor[::,1]))
|
||||||
|
ymin = np.append(ymin,np.amin(poly_coor[::,1]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
x_c = (np.amax(xmax)+np.amin(xmin))/2
|
||||||
|
y_c = (np.amax(ymax)+np.amin(ymin))/2
|
||||||
|
return x_c,y_c
|
||||||
|
|
||||||
|
def readGerber(file):
|
||||||
|
top_copper = gerber.read(file).statements
|
||||||
|
polygons =[]
|
||||||
|
LastStmtIndex = 0;
|
||||||
|
|
||||||
|
#Find mode statement
|
||||||
|
for cnt in range(len(top_copper)):
|
||||||
|
Stmt = str(top_copper[cnt])
|
||||||
|
if re.search(MODE,Stmt) != None:
|
||||||
|
setMode(Stmt)
|
||||||
|
LaststmtIndex = cnt;
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
if mode == "":
|
||||||
|
raise Exception("FileFormat","No Unit mode Statement found")
|
||||||
|
|
||||||
|
#Find scale factors
|
||||||
|
for cnt in range(LastStmtIndex,len(top_copper)):
|
||||||
|
Stmt = str(top_copper[cnt])
|
||||||
|
if re.search(SCALE,Stmt) != None:
|
||||||
|
setScale(Stmt)
|
||||||
|
LaststmtIndex = cnt;
|
||||||
|
break
|
||||||
|
|
||||||
|
#Find polygons factors
|
||||||
|
|
||||||
|
|
||||||
|
for cnt in range(LastStmtIndex,len(top_copper)):
|
||||||
|
Stmt = str(top_copper[cnt])
|
||||||
|
if re.search(RMStmtStart ,Stmt) != None:
|
||||||
|
PolyStmt = []
|
||||||
|
i = 0
|
||||||
|
while cnt+i < len(top_copper):
|
||||||
|
Stmt = str(top_copper[cnt+i])
|
||||||
|
if re.search(RMStmtStop ,Stmt) != None:
|
||||||
|
LaststmtIndex = cnt+i;
|
||||||
|
poly = new_Polygon(PolyStmt)
|
||||||
|
polygons.append(poly)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
PolyStmt.append(Stmt)
|
||||||
|
i+=1
|
||||||
|
|
||||||
|
return polygons
|
||||||
|
|
||||||
|
def create_kicad_poly(polygons,x_c,y_c,layer="F.Cu"):
|
||||||
|
|
||||||
|
polygon_str = ""
|
||||||
|
for pol in polygons:
|
||||||
|
|
||||||
|
poly_frame =" (fp_poly (pts"
|
||||||
|
poly_end =") (layer "+ layer +") (width 0.001))"
|
||||||
|
|
||||||
|
new_poly = poly_frame
|
||||||
|
|
||||||
|
flat_list = pol.get_vertices()
|
||||||
|
for cnt in range(len(flat_list)):
|
||||||
|
cor = flat_list[cnt]
|
||||||
|
cor_x = np.round(float(cor[0])-x_c,4)
|
||||||
|
cor_y = np.round(float(cor[1])-y_c,4)
|
||||||
|
a="(xy "+str(cor_x)+" "+str(cor_y)+")"
|
||||||
|
new_poly+=" "+a
|
||||||
|
|
||||||
|
new_poly_com=new_poly+poly_end
|
||||||
|
polygon_str += new_poly_com + "\n"
|
||||||
|
return polygon_str
|
||||||
|
|
||||||
|
|
||||||
|
def create_kicad_mod(name,polygons,libary="Default",tedit="5EF5C08B"):
|
||||||
|
|
||||||
|
kicad_file = ""
|
||||||
|
|
||||||
|
header = "(module "+libary+":"+name+" (layer F.Cu) (tedit "+tedit+\
|
||||||
|
")"+"\n"+ \
|
||||||
|
"(fp_text reference REF** (at 0.0 5.0) (layer F.SilkS) hide"+\
|
||||||
|
"\n"+ \
|
||||||
|
"(effects (font (size 1 1) (thickness 0.15)))"+"\n"+ \
|
||||||
|
")"+"\n"+ \
|
||||||
|
"(fp_text value "+name+" (at 0.0 -5.0) (layer F.Fab) hide"+\
|
||||||
|
"\n"+ \
|
||||||
|
"(effects (font (size 1 1) (thickness 0.15)))"+"\n"+\
|
||||||
|
")"+"\n"
|
||||||
|
|
||||||
|
footer = ")"
|
||||||
|
kicad_file += header;
|
||||||
|
for poly in polygons:
|
||||||
|
kicad_file += poly
|
||||||
|
|
||||||
|
kicad_file += footer
|
||||||
|
|
||||||
|
return kicad_file
|
||||||
|
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
# Main #
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
poly=readGerber('BP.ger')
|
||||||
|
x_c,y_c = find_center(poly)
|
||||||
|
kicad_poly = create_kicad_poly(poly,x_c,y_c,layer="F.Cu")
|
||||||
|
output=create_kicad_mod("BP",kicad_poly)
|
||||||
|
|
||||||
|
f= open("BP.kicad_mod","w+")
|
||||||
|
f.write(output)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
|
exit();
|
||||||
|
##############################################################################
|
||||||
|
# END #
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
7
README.md
Normal file
7
README.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Ger2KiCad
|
||||||
|
|
||||||
|
A simple python script to convert Gerber files (RS274X) to .kicad_mod files that can be easily imported by KiCad. It is possible to read multiple files and specify the import layer (F.Cu, In1.Cu, ..., B.Cu).
|
||||||
|
|
||||||
|
This script was mainly designed to import RF structures in KiCad, but should handle all polygon based designs (Uses G36/G37 codes of the RS274X standard).
|
||||||
|
|
||||||
|
This script uses the [pcb-tools](https://github.com/curtacircuitos/pcb-tools) package.
|
||||||
Reference in New Issue
Block a user