Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the beginning of a very simplistic kicad board file parser #94

Merged
merged 16 commits into from
Dec 26, 2023

Conversation

bschwind
Copy link
Owner

@bschwind bschwind commented Jul 19, 2023

Relates to #59

This is a very naively written parser, which is quite specific and targeted to just extracting the info we want from the boards. It's much more manual work. I wouldn't view this as a permanent solution, but more of a short-term thing to get the data we want.

Currently just graphic lines (gr_line) are extracted, but the code is structured in a way that it's fairly easy to add more extractors.

Ideally, the kicad parser would integrate with serde or work with streaming data for larger files (probably not necessary for now).

This PR is mostly just for discussion and to see if we'd want to go this direction for short-term file parsing.

@bschwind
Copy link
Owner Author

I see now this is very similar to what kicad-rs is doing.

I think it's a good approach to just extract a subset of data we want from the file, but maybe not too maintainable if we wanted to parse the entire file.

@tuna-f1sh
Copy link
Collaborator

I checked this out and it does seem like a nice simple option - since we only need the gr_* parts. It also feels easier to add the other sections as required.

Have you thought about the next step? I had a quick look at .DXF format and dxf crate since it looks like there is a lot cross-over in 2d shapes: https://docs.rs/dxf/latest/dxf/entities/index.html.

But perhaps it is just as simple a to_wire for a passed layer in the KicadBoard, perhaps with an enum for a BoardLayer:

pub enum BoardLayer {
    FCu,
    BCu,
    FAdhes,
    BAdhes,
    FPaste,
    BPaste,
    FSilkS,
    BSilkS,
    FMask,
    BFask,
    DwgsUser,
    CmtsUser,
    Eco1User,
    Eco2User,
    EdgeCuts,
    Margin,
    BCrtYd,
    FCrtYd,
    BFab,
    FFab,
    In1Cu,
    In2Cu,
    In3Cu,
    In4Cu,
    User(String)
}

@tuna-f1sh
Copy link
Collaborator

@bschwind had chance to play with this a bit today. I've implemented the gr_* types that match our primitives. Some Into for converting them to primitives and some methods to the KicadBoard to get these for a BoardLayer. Also split stuff into files since it was getting a bit busy - hope that's okay.

I think that the Graphic* types could perhaps have some elements made generic since there is some duplication. Maybe not though.

The result is a .stl file output...well very simple shape one (the sample.kicad_pcb does not work). Basically I can use Kicad as a simple sketching tool 😄; rectangles, circles and lines . What isn't working is GraphicLine and GraphicArc combinations - perhaps what I am doing here is at fault: cc726da#diff-4ada67e285da4eb727355d07da45ba9924bc9608b44873a85d4a818dc9694a9fR184

Some quick testing, it seems like them being out of order causes issue - but there is no guarantee they will be in order in the file. Not 100% this is the issue but here is an example:

Works

Screenshot 2023-07-22 at 17 30 47 Screenshot 2023-07-22 at 17 30 51

Not closed properly

Screenshot 2023-07-22 at 17 31 23 Screenshot 2023-07-22 at 17 31 27

@tuna-f1sh
Copy link
Collaborator

@bschwind ah, I just read https://dev.opencascade.org/doc/refman/html/class_b_rep_builder_a_p_i___make_wire.html#a8a6bc22ee4601968fe013021875f06b9

E must be connectable to the wire under construction, and, unless it is the first edge of the wire, must satisfy the following condition: one of its vertices must be geometrically coincident with one of the vertices of the wire (provided that the highest tolerance factor is assigned to the two vertices). It could also be the same vertex. Warning If E is not connectable to the wire under construction it is not added

That explains it then. So I guess we need to sort the lines and edges so this is obeyed.

@tuna-f1sh
Copy link
Collaborator

Came back to this a slightly dirty fix. It turns out that MakeWire will return false for IsDone if the last Edge was not added. It's possible to use this to loop around until they are all added or the missing ones stop reducing: 58f7799

Not sure whether from_edges should provide this behavior or expect the Edges to be passed in connecting order. It should probably return a Result if we add this behavior.

Screenshot 2023-07-22 at 21 13 49

@bschwind
Copy link
Owner Author

bschwind commented Jul 23, 2023

@tuna-f1sh I'm on my phone so I'll link better references later, but I'm pretty sure OCC has the ability to take in a set of wires and connect them properly. I think CadQuery was using that functionality under the name "AssembleEdges" or something like that.

It was likely this function:

https://dev.opencascade.org/doc/refman/html/class_shape_analysis___free_bounds.html#a4809fe812b6a663a286df71b4d7bda3b

@bschwind bschwind force-pushed the kicad-parser branch 2 times, most recently from 87b540b to 42b3ed8 Compare September 2, 2023 09:24
@bschwind bschwind marked this pull request as ready for review December 26, 2023 12:51
@bschwind
Copy link
Owner Author

This has enough functionality to be able to import the edge cuts on a board now, including footprints which have edge cuts. I'll go ahead and merge it and refine it more later.

@bschwind bschwind merged commit af09d3d into main Dec 26, 2023
4 checks passed
@bschwind bschwind deleted the kicad-parser branch December 26, 2023 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants