Hello there, you programming and open source maniac! Here’s a story for you:
As a reasonably sized project, I am trying to build a bridge that will help me simulate KiCAD designs, using one of the few open-source Electromagnetic Simulation libraries out there, openEMS. It’s a Finite-Difference Time-Domain (FDTD) simulation tool with both python and Matlab\Octave interfaces.
During this process, one of the first things I needed to do was to import, well… The layout. I used the tools I already built in my 2D FEM solver I started writing a few years back, to import DXFs and handle the polygons.
For all you guys this is gibberish for, here is a short review:
There are many ways to export circuits. One is to parse and read the layout software file directly. I started doing that, and saw it’s going to take way too long. The other way is to use more comfortable format, that hopefully KiCAD allows. I chose DXF because it has a well documented structure and mostly because the other option is GERBER, which is way harder to import.
The Problem
After importing the polygons, I tried reading them directly into the openEMS environment, as instructed. For the first polygon, I got the following:

Double checking myself, and plotting the polygon back in Octave…

This seems more appropriate. So why this massive difference? Well, Octave is apparently well equipped to display polygons “with holes”. A more appropriate term would be non-simply connected polygon, but that’s irrelevant now.
The (Suggested) Solution
I am, by any means, not proficient in computational geometry. Hence, I need a brute force solution. What I did was ask the program (nicely) to split the polygon at the holes. If several bits were created during these splits, they were also separated. Hold on to your seat, the next image is trippy.

Imported all of these bits into openEMS and viola!

I know, I already added the vias and substrates here, but this makes the point of progress even more apparent.
How would you approach this? I am entirely sure this isn’t a very robust solution, but I am still making it “quick and dirty”