This is very rough and ready but it has saved me a great deal of time trying to manually place mount points for PCB cases
Basically I use the following python script to find where the mount holes are in the Kicad_pcb
MH = []
Valid_MH = ['MountingHole:MountingHole_4.3mm_M4','MountingHole:MountingHole_3.2mm_M3']
class MountHole():
def __init__(self,raw_text):
self.x = 0
self.y = 0
self.size = 3
self.raw = raw_text
self.parse()
def parse(self):
ls = self.raw.splitlines()
for a in ls:
if(a[:4] == "(at "):
loc = a.split(" ")
self.x = float(loc[1])
self.y = float(loc[2][:-1])
def OpenSCAD(self):
return ("mount(" + str(self.x) + ',' + str(self.y) + "," + str(self.size) + ");")
#print("m")
#return "mount(" + str(self.x,'utf-8') + "," + str(self.y,'utf-8') + "," + str(self.size,'utf-8') + ")\n"
class Line():
def __init__(self,raw):
self.raw = raw
#Start coords
self.s = self.raw.find("(start")
self.st = self.raw[self.s:]
self.sta = self.st[:self.st.find(")")].split(" ")
self.startx = float(self.sta[1])
self.starty = float(self.sta[2])
#End coords
self.e = self.raw.find("(end")
self.et = self.raw[self.e:]
self.eta = self.et[:self.et.find(")")].split(" ")
self.endx = float(self.eta[1])
self.endy = float(self.eta[2])
print(self.endx,self.endy)
class KCfile():
def __init__(self,path):
self.kfile = open(path,'r')
self.mounts = []
self.lins = []
self.mods_text = self.getmods()
self.getmounts()
def par(self,string):
return(string.count("(") - string.count(")"))
def getmods(self):
mods = []
module_text = ""
in_module = False
open_bracket = 0
for a in self.kfile.readlines():
a = a.strip()
if(a[:8] == "(gr_line"):
self.lins.append(Line(a))
if(a[:8] != "(module " and not in_module): continue
in_module = True
module_text = module_text + a + '\n'
open_bracket += self.par(a)
# print(a,open_bracket)
if(open_bracket == 0):
mods.append(module_text)
module_text = ""
in_module = False
return mods
def getmounts(self):
mcount = 0
for a in self.mods_text:
mtype = a.split(" ")[1]
if(mtype in Valid_MH):
mcount += 1
self.mounts.append(MountHole(a))
print(mcount, "mount holes found")
def OpenSCAD_mounts(self):
minusx = 9999999999
minusy = 9999999999
hy = 0
for a in self.mounts:
#print(a.x)
if(a.x < minusx): minusx = a.x
if(a.y < minusy): minusy = a.y
print("mirror([0,90,0])\nunion(){")
for a in self.mounts:
if(a.y - minusy >hy): hy=a.y - minusy
for a in self.mounts:
x = a.x-minusx
y = a.y-minusy
print("mount(" + str(x) + ',' + str(y - hy) + "," + str(a.size) + ");")
#print(a.OpenSCAD())
print("}")
def Gen_poly(self):
pass
fl = KCfile('YOUR-FILENAME-HERE.kicad_pcb')
#print(fl.mods_text)
fl.OpenSCAD_mounts()
#print(fl.lins)
That script spits out a few lines like for example
mirror([0,90,0])
union(){
mount(0.0,0.0,3);
mount(65.34076,-9.57002,3);
mount(3.4696399999999983,-53.507639999999995,3);
mount(66.23075999999999,-52.560019999999994,3);
}
This I can paste into openscad and once I have my my mount() module defined somewhere ( very simple just one cylinder minus another)
module mount(x,y,size = 2.4, support = false) { // For 3mm screw
translate([x,y,0])
difference(){
cylinder($mount_height,r=size);
cylinder($mount_height + 0.01,r=(size/2));
}
}
Once u have the mount points in the right place its very easy to design a box around it, I do have a script to generate the boxes as well but I really need to clean that up before I even consider posting it anywhere. Still I hope this is useful to someone