realthunder / fcad_pcb

FreeCAD scripts for PCB CAD/CAM
MIT License
126 stars 25 forks source link

Boards created from Gerber files in Gerber Viewer #60

Closed nico-arnold closed 1 year ago

nico-arnold commented 1 year ago

Hi,

for a project we need to import Gerber files and visualize them in 3D. Sadly I'm experiencing problems importing KiCAD-PCB files created from Gerber files in KiCAD Gerber Viewer. I tested this using the following Layout files: https://github.com/antmicro/alvium-flexible-csi-adapter/tree/master/100mm-single-same-side

You can find the original file (renamed to "Original_project") and the version I exported from the KiCAD Gerber viewer ("Gerber2KICAD_raw" - automatic layer assignment after importing all the Gerber and Excellon files previously exported from the original KiCAD PCB) up here in my cloud: https://cloudstore.zih.tu-dresden.de/index.php/s/GMygxnZAoinEayS

First problem: FCAD_PCB is missing the "(Setup...)" structure within the KiCAD file. No problem to correct this one by hand or script ("Gerber2KiCAD_corrected". After that all renders fine until the point where pads are created:

16:36:32 Traceback (most recent call last): File "C:/Users/Nico/AppData/Roaming/FreeCAD/Macro/FreeCAD-OpenEMS-Export-main/FCAD_PCB.FCMacro", line 7, in pcb.make(copper_thickness=0.035, board_thickness=0.1, combo=False, fuseCoppers=True) File "C:\Users\Nico\AppData\Roaming\FreeCAD\Macro\fcad_pcb\kicad.py", line 2286, in make coppers = self.makeCoppers(shape_type='solid',holes=True,prefix=None, File "C:\Users\Nico\AppData\Roaming\FreeCAD\Macro\fcad_pcb\kicad.py", line 2121, in makeCoppers copper = self.makeCopper(shape_type,t,fit_arcs=fit_arcs, File "C:\Users\Nico\AppData\Roaming\FreeCAD\Macro\fcad_pcb\kicad.py", line 2034, in makeCopper obj = getattr(self,'make{}'.format(name))(fit_arcs=sub_fit_arcs, File "C:\Users\Nico\AppData\Roaming\FreeCAD\Macro\fcad_pcb\kicad.py", line 1756, in makePads objs.append(func(vias,'vias')) File "C:\Users\Nico\AppData\Roaming\FreeCAD\Macro\fcad_pcb\kicad.py", line 1615, in _face if not cut_wires and not cut_non_closed: <class 'NameError'>: free variable 'cut_wires' referenced before assignment in enclosing scope

This can be overcome by initializing _cutwires and _cut_nonclosed variables in the kicad.py around line 1604 or, which is better but still pretty uneglegant, by creating an empty module before the actual structures within the kicad_pcb file. (See file "Gerber2KiCAD_Module")

Still I end up with a PCB covered by tracks but lagging pads and polygons as those are exported as _grpoly or _grcircle no matter if they were a poly or rect or pad - and those don't seem to be drawn. I also managed to get around this by creating seperate modules for the top and bottom copper layer containing the corresponding geometries and replacing every _grrect with _fprect, forcing FCAD_PCB into thinking all are footprints. The via and segment geometries still have to stay out of the module. The corresponding file is saved in the cloud as "Gerber2KiCAD_Footprint" - as you can see, this renders nearly everything, but the poly at the bottom isn't fully drawn and an error is shown:

16:56:48 making 4 polys 16:56:50 Area.cpp(454): ccurve not closed

fcad_pcb_1

fcad_pcb_2

No wonder, as footprints rarely have the complexity as this polygon containing the whole geometry for a cut-out copper zone imported from the raw Gerber data. You can also see the point where everything seems to break down because the polygon line hits a via in its way (see mage attached) and is not drawn further after.

Another way to solve that would be to pack everything into a zone, but I'm curious, is there maybe a way to fix that without the need to apply a patching script like I did here? I would be really happy and thankful for any help. I'll also look into the code again tomorrow to have a try if I can fix that somehow. Still, big ups up for all your work here! With "real" KiCAD files not created externally from Gerber files there are absolutely no problems and it's working like a charm. Same for EAGLE Projects imported into KiCAD.

best wishes from Germany, Nico

nico-arnold commented 1 year ago

Made a fork here where the import works without correcting the input files: https://github.com/IFTE-EDA/fcad_pcb

realthunder commented 1 year ago

Thanks for taking the initiative. I referenced your code and made some modification of my own. Please check if the output is correct. Note that an easy way to handle the missing module field is to add the keyword to kicad_parser.KicadPCB._defaults.

nico-arnold commented 1 year ago

Hey Zheng, thanks a lot and sorry for taking so long! It's working now. I also had another incident where I was not able to render a PCB completely made from scratch in KiCAD. However, I was able to track it down to the script failing to parse a gr_poly outside of a fp, module or similar container:

09:46:19 Traceback (most recent call last): File "C:/Users/Nico/AppData/Roaming/FreeCAD/Macro/FreeCAD-OpenEMS-Export-main/FCAD_PCB.FCMacro", line 8, in <module> pcb.make(copper_thickness=0.035, board_thickness=0.1, combo=False, fuseCoppers=True) File "C:\Users\Nico\AppData\Roaming\FreeCAD\Macro\fcad_pcb\kicad.py", line 2288, in make coppers = self.makeCoppers(shape_type='solid',holes=True,prefix=None, File "C:\Users\Nico\AppData\Roaming\FreeCAD\Macro\fcad_pcb\kicad.py", line 2123, in makeCoppers copper = self.makeCopper(shape_type,t,fit_arcs=fit_arcs, File "C:\Users\Nico\AppData\Roaming\FreeCAD\Macro\fcad_pcb\kicad.py", line 2036, in makeCopper obj = getattr(self,'make{}'.format(name))(fit_arcs=sub_fit_arcs, File "C:\Users\Nico\AppData\Roaming\FreeCAD\Macro\fcad_pcb\kicad.py", line 1966, in makePolys objs = self._makePolygons(getattr(self.pcb, 'gr_poly', None), 'poly', File "C:\Users\Nico\AppData\Roaming\FreeCAD\Macro\fcad_pcb\kicad.py", line 1898, in _makePolygons pts = SexpList(p.pts.xy) <class 'AttributeError'>: 'str' object has no attribute 'pts'

Adding gr_poly to the aforementioned defaults fixed that.