realthunder / FreeCAD

Link branch FreeCAD
Other
799 stars 46 forks source link

layout2fc: a python script to import a 3D structure from klayout (work in progress) #422

Open wsteffe opened 2 years ago

wsteffe commented 2 years ago

layout2fc.py.zip. Usage: layout2fc.py -stack stack_file dxf_file

Following an example of stack file (PH10 is a UMS process for GaAS MMIC). Format is: layerNum/LayerDataType : zstart zstop #user layer name (not parsed) File extension must be .stack.

"UMS_PH10.stack":
scale:  0.001 0
10/0:  0.0 70.0              # TR
4/0:  70.0 71.0              # N1
6/0:  70.0 71.0              # RM
16/0: 70.0 71.0              # RHWH
5/0:  71.0 71.19             # DPC
40/0: 71.19 74.19            # EL
40/2: 74.19 77.19            # EL2
40/1: 77.19 80.19            # EL1

First line is a scale factor. In my project the stack heights are in micron and I have assumed that FC unit is mm. Same scaling must be set also in the FC dxf Import Options.

I am sorry I may not share the dxf file of my project but it is quite easy to make a test case with klayout.

Works is still in progress. I have made the extrudes but I not able to set visibility of pads. The lines 91 and 112 of this script have no effect:

91: body.Visibility = True
112: pad.Visibility =True

PS The script has been improved with respect with first snipped posted at https://github.com/realthunder/FreeCAD/issues/419. Now it uses the python module klayout.db instead of pya which is deprecated because this name was already taken by another project. On ubuntu the klayout module is made available with the installation of "klayout_0.27.9-1_amd64.deb".

Any help to improve this script would be appreciated. Thanks.

wsteffe commented 2 years ago

I have just seen at https://doc.cgal.org/latest/Boolean_set_operations_2/Boolean_set_operations_2_2circle_segment_8cpp-example.html that CGAL library can do 2D booleans with general polygons (polygons composed of lines and arcs). Perhaps we could use CGAL instead of klayout to merge the shapes of a layer avoiding discretization of circles. We could also remove dependence on klayout if FC had the capability of extracting name and shapes associated with each layer defined in the input dxf file. RT, is perhaps your recent commit named "change readDXF() to keyword method" serving to this purpose ?

realthunder commented 2 years ago

There is a greater problem here. Why does klayout reads and writes to DXF format? Are there any other native formats? How do you get the test_case2.dxf file in the first place?

I found out that with DXF format, we lost the crucial information about wires, i.e. edge connections. DXF only gives us a bunch of disconnected edges. We need to perform very expensive search to find out all possible loops before we can make faces and extrusion, etc.. No matter what kind of geometry library you use, the search algo is going to be expensive for the real life test case you provided.

There is a pretty good 2D geometry library inside Path workbench, the ClipperLib. I use it to import kicad PCB to FreeCAD. If the wire information is there, it can easily handle 2D union and even cut.

realthunder commented 2 years ago

There is actually an algorithm implemented in Path which is written by me to find out the outline given a bunch of edges. It is meant to be used to find out the outline given the edges produced by OCC projection. The following single layer took about several minutes to get the result. The green selected lines are the outline, while the internal black edges are eliminated. Looks like there is still some problem with the result, such as self intersected wires.

outline

wsteffe commented 2 years ago

How do you get the test_case2.dxf file in the first place? That project was done (not by me) using a commercial EDA Tool (probably AWR) and then exported into a dxf file. I have just modified a little bit the original file to change layer names. Basically there are only two format to choose in the export from EDA tools (DXF or GDS) and I think that DXF is better because it has analytic arcs and circles.

Regarding the wires I think that it should be possible to extract them from the DXF file. DXF format is very poorly documented and I do not really understand it, but it seems to me that a polyline is just a sequence of vertices (not edges) and that the edges/wires data structure is implicitly defined by consecutive vertices. Otherwise how could KLayout, in a very short time, generate the faces after reading the DXF file and also merge them (making a 2D boolean) ?

wsteffe commented 2 years ago

Looks like there is still some problem with the result, such as self intersected wires. Yes, Also I have seen that there are such kind of problems in the original file. I tried to fix some of them using "partial" command in the klayout menu in order to move some edge before merging (some faces were very close but not touching). But not always I was able to to that. The Klayout IF for selection of edges doesn't work very well.

wsteffe commented 2 years ago

Hi RT, perhaps you may use ezdxf library to read dxf file and retreive Polyline data: https://ezdxf.readthedocs.io/en/stable/dxfentities/polyline.html I think you will have to distinguish between Polyline and LWPolyline (which is a more recent and more efficient kind of Polyline). There are also other geometries to be parsed: Arc, Trace, Circle ...

wsteffe commented 2 years ago

I think that also the bulge concept may be expoited in a layout file to define a polyline with mixed straight and curved segments https://ezdxf.readthedocs.io/en/stable/dxfentities/lwpolyline.html#bulge-value

wsteffe commented 2 years ago

I changed my mind about ezdxf. While the ezdxf pages are very useful to undersand the dxf data structure, the ezdxf implementation is not very efficient.

Some time ago I wrote the annexed script which splits the layers of a dxf file into separate files. Now I have tried it with test_cas2.dxf. It does the job but it takes a very long time.

splitdxf.zip

wsteffe commented 2 years ago

Hi RT, I have updated test_case2.dxf after having seen that many analytic circles were lost after opening/saving and minor changes done with klayout. I have also understood that layer numbers and data types used by klayout are not native dxf concepts. So I have changed the syntax of test_case2.stack to use layer name as data key. But the script is not yet updated to parse the new stack syntax.