Products > 3D printing

KiCAD to OpenSCAD for PCB case generation

(1/1)

Pineapple Dan:
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


--- Code: ---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)


--- End code ---

That script spits out a few lines like for example


--- Code: ---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);
}
--- End code ---

This I can paste into openscad and once I have my my mount() module defined somewhere ( very simple just one cylinder minus another)


--- Code: ---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));
   
       
}
}
--- End code ---

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

Doctorandus_P:
Are you aware of the KiCadStepUp workbench in FreeCAD?

kripton2035:
+1. exporting a kicad pcb to freecad is really easy. once you tried it !

thinkfat:
You don't even need StepUp for that. The standard STEP export from KiCAD is totally sufficient to get a model into FreeCAD that you can then use for checking collisions with your box etc.

However, not everyone is a FreeCAD user and having an automated way to export mounting points to OpenSCAD, which many engineers seem to like, is definitely appreciated.

kripton2035:

--- Quote from: thinkfat on April 06, 2022, 08:51:59 am ---However, not everyone is a FreeCAD user and having an automated way to export mounting points to OpenSCAD, which many engineers seem to like, is definitely appreciated.

--- End quote ---
absolutely !

Navigation

[0] Message Index

There was an error while thanking
Thanking...
Go to full version