Grasshopper to Kicad eschema and PCBNEW

Good morning all,

The great thing about Kicad is that all of its files end up in text format and are mostly readable.

I have recurring need to generate regular and odd shaped arrays of LEDs on circuit boards. Consider a polar array of 4 rings of 40 LEDs. That is 160 LEDs, each with a specific location, rotation, and 6 pads to connect via traces to other LEDs. Turns out it is about 4000 mouse movements and/or keystrokes.

SO! After doing one or two of these I decided that the whole process needs to be automated. I have a tiny bit of ability in python, and maybe intermediate experience with grasshopper/rhino 6.

Thus far I have a grasshopper patch that totally works for making a layout in kicad PCBNEW, with nets and traces. AMAZING. However, it only works with a specific LED part. This is OK for me as I almost only use this type of LED in my work and if I have to change it for a different one, the amount of work to do so is FAR LESS than manually building LED arrays in Kicad.

However, working with only a PCB layout seems a bit risky, and what if later I want a very similar board with just a few easy tweaks. I need an associated schematic.

The short goal is to finish my grasshopper patch such that it generates both a schematic AND a PCB layout file for Kicad. This I can do with what I know. (And I do have a very clunky version working)

But ultimately I would love to generalize this system such that any Kicad component (both sch symbol AND pcb footprint) can be imported into grasshopper and arrayed based on generative and parametric geometry created within.

Back to the idea that Kicad stores everything as text files:
The symbol libraries and pcb footprints are text files in the S-Expression format and tokens are divided up with parentheses ( ) and whitespace “spaces”).
Kicad docs file formats

I will most likely be writing some python in GH to help with this, but right now I am stuck on how to parse the Kicad schematic Library files into Grasshopper on a part by part basis (as the symbols are all part of 1 larger library file). I suppose I could create single-part libraries, and this would certainly simplify things. But again…I am trying to generalize this system for the benefit of whomever else might want to use it.

Here is a truncated example of a kicad6 schematic symbol library

(kicad_symbol_lib (version 20211014) (generator kicad_symbol_editor)
  (symbol ".1-PAD" (pin_names (offset 1.016)) (in_bom yes) (on_board yes)
    (property "Reference" "P" (id 0) (at 0 0 0)
      (effects (font (size 1.27 1.27)))
    )
    (property "Value" ".1-PAD" (id 1) (at 0 0 0)
      (effects (font (size 1.27 1.27)))
    )
    (property "Footprint" "" (id 2) (at 0 0 0)
      (effects (font (size 1.27 1.27)) hide)
    )
    (property "Datasheet" "" (id 3) (at 0 0 0)
      (effects (font (size 1.27 1.27)) hide)
    )
    (symbol ".1-PAD_1_1"
      (pin input line (at 0 -1.27 0) (length 2.54)
        (name "~" (effects (font (size 1.27 1.27))))
        (number "~" (effects (font (size 1.27 1.27))))
      )
    )
  )
  (symbol "10-BITD-TYPELATCH" (pin_names (offset 1.016)) (in_bom yes) (on_board yes)
    (property "Reference" "U" (id 0) (at 0 -34.29 0)
      (effects (font (size 1.27 1.27)))
    )
    (property "Value" "10-BITD-TYPELATCH" (id 1) (at 0 0 0)
      (effects (font (size 1.27 1.27)))
    )
    (property "Footprint" "" (id 2) (at 0 0 0)
      (effects (font (size 1.27 1.27)) hide)
    )
    (property "Datasheet" "" (id 3) (at 0 0 0)
      (effects (font (size 1.27 1.27)) hide)
    )
    (symbol "10-BITD-TYPELATCH_0_1"
      (rectangle (start -7.62 -2.54) (end 6.35 -33.02)
        (stroke (width 0) (type default) (color 0 0 0 0))
        (fill (type none))
      )
    )
    (symbol "10-BITD-TYPELATCH_1_1"
      (pin input line (at -12.7 -3.81 0) (length 5.08)
        (name "OE_BAR" (effects (font (size 1.27 1.27))))
        (number "1" (effects (font (size 1.27 1.27))))
      )
      (pin input line (at -12.7 -26.67 0) (length 5.08)
        (name "9D" (effects (font (size 1.27 1.27))))
        (number "10" (effects (font (size 1.27 1.27))))
      )
      (pin input line (at -12.7 -29.21 0) (length 5.08)
        (name "10D" (effects (font (size 1.27 1.27))))
        (number "11" (effects (font (size 1.27 1.27))))
      )
      (pin power_in line (at -12.7 -31.75 0) (length 5.08)
        (name "GND" (effects (font (size 1.27 1.27))))
        (number "12" (effects (font (size 1.27 1.27))))
      )
      (pin power_in line (at 11.43 -31.75 180) (length 5.08)
        (name "LE" (effects (font (size 1.27 1.27))))
        (number "13" (effects (font (size 1.27 1.27))))
      )
      (pin output line (at 11.43 -29.21 180) (length 5.08)
        (name "10Q" (effects (font (size 1.27 1.27))))
        (number "14" (effects (font (size 1.27 1.27))))
      )
      (pin output line (at 11.43 -26.67 180) (length 5.08)
        (name "9Q" (effects (font (size 1.27 1.27))))
        (number "15" (effects (font (size 1.27 1.27))))
      )
      (pin output line (at 11.43 -24.13 180) (length 5.08)
        (name "8Q" (effects (font (size 1.27 1.27))))
        (number "16" (effects (font (size 1.27 1.27))))
      )
      (pin output line (at 11.43 -21.59 180) (length 5.08)
        (name "7Q" (effects (font (size 1.27 1.27))))
        (number "17" (effects (font (size 1.27 1.27))))
      )
      (pin output line (at 11.43 -19.05 180) (length 5.08)
        (name "6Q" (effects (font (size 1.27 1.27))))
        (number "18" (effects (font (size 1.27 1.27))))
      )
      (pin output line (at 11.43 -16.51 180) (length 5.08)
        (name "5Q" (effects (font (size 1.27 1.27))))
        (number "19" (effects (font (size 1.27 1.27))))
      )
      (pin input line (at -12.7 -6.35 0) (length 5.08)
        (name "1D" (effects (font (size 1.27 1.27))))
        (number "2" (effects (font (size 1.27 1.27))))
      )
      (pin output line (at 11.43 -13.97 180) (length 5.08)
        (name "4Q" (effects (font (size 1.27 1.27))))
        (number "20" (effects (font (size 1.27 1.27))))
      )
      (pin output line (at 11.43 -11.43 180) (length 5.08)
        (name "3Q" (effects (font (size 1.27 1.27))))
        (number "21" (effects (font (size 1.27 1.27))))
      )
      (pin output line (at 11.43 -8.89 180) (length 5.08)
        (name "2Q" (effects (font (size 1.27 1.27))))
        (number "22" (effects (font (size 1.27 1.27))))
      )
      (pin output line (at 11.43 -6.35 180) (length 5.08)
        (name "1Q" (effects (font (size 1.27 1.27))))
        (number "23" (effects (font (size 1.27 1.27))))
      )
      (pin power_in line (at 11.43 -3.81 180) (length 5.08)
        (name "VCC" (effects (font (size 1.27 1.27))))
        (number "24" (effects (font (size 1.27 1.27))))
      )
      (pin input line (at -12.7 -8.89 0) (length 5.08)
        (name "2D" (effects (font (size 1.27 1.27))))
        (number "3" (effects (font (size 1.27 1.27))))
      )
      (pin input line (at -12.7 -11.43 0) (length 5.08)
        (name "3D" (effects (font (size 1.27 1.27))))
        (number "4" (effects (font (size 1.27 1.27))))
      )
      (pin input line (at -12.7 -13.97 0) (length 5.08)
        (name "4D" (effects (font (size 1.27 1.27))))
        (number "5" (effects (font (size 1.27 1.27))))
      )
      (pin input line (at -12.7 -16.51 0) (length 5.08)
        (name "5D" (effects (font (size 1.27 1.27))))
        (number "6" (effects (font (size 1.27 1.27))))
      )
      (pin input line (at -12.7 -19.05 0) (length 5.08)
        (name "6D" (effects (font (size 1.27 1.27))))
        (number "7" (effects (font (size 1.27 1.27))))
      )
      (pin input line (at -12.7 -21.59 0) (length 5.08)
        (name "7D" (effects (font (size 1.27 1.27))))
        (number "8" (effects (font (size 1.27 1.27))))
      )
      (pin input line (at -12.7 -24.13 0) (length 5.08)
        (name "8D" (effects (font (size 1.27 1.27))))
        (number "9" (effects (font (size 1.27 1.27))))
      )
    )
  )
  (symbol "39-30-3047" (pin_names (offset 0.762)) (in_bom yes) (on_board yes)
    (property "Reference" "J" (id 0) (at 16.51 7.62 0)
      (effects (font (size 1.27 1.27)) (justify left))
    )
    (property "Value" "39-30-3047" (id 1) (at 16.51 5.08 0)
      (effects (font (size 1.27 1.27)) (justify left))
    )
    (property "Footprint" "39303047" (id 2) (at 16.51 2.54 0)
      (effects (font (size 1.27 1.27)) (justify left) hide)
    )
    (property "Datasheet" "http://de.rs-online.com/web/p/leiterplatten-header/6705868" (id 3) (at 16.51 0 0)
      (effects (font (size 1.27 1.27)) (justify left) hide)
    )
    (property "Description" "Molex MINI-FIT JR. Series, Series Number 5569, 4.2mm Pitch 4 Way 1 Row Right Angle PCB Header, Solder Termination, 12A" (id 4) (at 16.51 -2.54 0)
      (effects (font (size 1.27 1.27)) (justify left) hide)
    )
    (property "Height" "6.18" (id 5) (at 16.51 -5.08 0)
      (effects (font (size 1.27 1.27)) (justify left) hide)
    )
    (property "Manufacturer_Name" "Molex" (id 6) (at 16.51 -7.62 0)
      (effects (font (size 1.27 1.27)) (justify left) hide)
    )
    (property "Manufacturer_Part_Number" "39-30-3047" (id 7) (at 16.51 -10.16 0)
      (effects (font (size 1.27 1.27)) (justify left) hide)
    )
    (property "Mouser Part Number" "538-39-30-3047" (id 8) (at 16.51 -12.7 0)
      (effects (font (size 1.27 1.27)) (justify left) hide)
    )
    (property "Mouser Price/Stock" "https://www.mouser.co.uk/ProductDetail/Molex/39-30-3047/?qs=404muyNbhLFMA7DI2g4beQ%3D%3D" (id 9) (at 16.51 -15.24 0)
      (effects (font (size 1.27 1.27)) (justify left) hide)
    )
    (property "ki_description" "Molex MINI-FIT JR. Series, Series Number 5569, 4.2mm Pitch 4 Way 1 Row Right Angle PCB Header, Solder Termination, 12A" (id 10) (at 0 0 0)
      (effects (font (size 1.27 1.27)) hide)
    )
    (symbol "39-30-3047_0_0"
      (pin passive line (at 0 -7.62 0) (length 5.08)
        (name "1" (effects (font (size 1.27 1.27))))
        (number "1" (effects (font (size 1.27 1.27))))
      )
      (pin passive line (at 0 -5.08 0) (length 5.08)
        (name "2" (effects (font (size 1.27 1.27))))
        (number "2" (effects (font (size 1.27 1.27))))
      )
      (pin passive line (at 0 -2.54 0) (length 5.08)
        (name "3" (effects (font (size 1.27 1.27))))
        (number "3" (effects (font (size 1.27 1.27))))
      )
      (pin passive line (at 0 0 0) (length 5.08)
        (name "4" (effects (font (size 1.27 1.27))))
        (number "4" (effects (font (size 1.27 1.27))))
      )
    )
    (symbol "39-30-3047_0_1"
      (polyline
        (pts
          (xy 5.08 2.54)
          (xy 15.24 2.54)
          (xy 15.24 -10.16)
          (xy 5.08 -10.16)
          (xy 5.08 2.54)
        )
        (stroke (width 0.1524) (type default) (color 0 0 0 0))
        (fill (type none))
      )
    )
  )
  (symbol "43650-0303" (pin_names (offset 0.762)) (in_bom yes) (on_board yes)
    (property "Reference" "J" (id 0) (at 16.51 7.62 0)
      (effects (font (size 1.27 1.27)) (justify left))
    )
    (property "Value" "43650-0303" (id 1) (at 16.51 5.08 0)
      (effects (font (size 1.27 1.27)) (justify left))
    )
    (property "Footprint" "43650-03-03040559" (id 2) (at 16.51 2.54 0)
      (effects (font (size 1.27 1.27)) (justify left) hide)
    )
    (property "Datasheet" "https://www.molex.com/pdm_docs/sd/436500203_sd.pdf" (id 3) (at 16.51 0 0)
      (effects (font (size 1.27 1.27)) (justify left) hide)
    )
    (property "Description" "Micro-Fit 3.0 Right-Angle Header, 3.00mm Pitch, Single Row, 3 Circuits, with PCB Press-fit Metal Retention Clip, Glow-Wire Capable, Black" (id 4) (at 16.51 -2.54 0)
      (effects (font (size 1.27 1.27)) (justify left) hide)
    )
    (property "Height" "5.57" (id 5) (at 16.51 -5.08 0)
      (effects (font (size 1.27 1.27)) (justify left) hide)
    )
    (property "Manufacturer_Name" "Molex" (id 6) (at 16.51 -7.62 0)
      (effects (font (size 1.27 1.27)) (justify left) hide)
    )
    (property "Manufacturer_Part_Number" "43650-0303" (id 7) (at 16.51 -10.16 0)
      (effects (font (size 1.27 1.27)) (justify left) hide)
    )
    (property "Mouser Part Number" "538-43650-0303" (id 8) (at 16.51 -12.7 0)
      (effects (font (size 1.27 1.27)) (justify left) hide)
    )
    (property "Mouser Price/Stock" "https://www.mouser.co.uk/ProductDetail/Molex/43650-0303/?qs=P7cO%252B%252BFDLzRIPB7V1gsyvg%3D%3D" (id 9) (at 16.51 -15.24 0)
      (effects (font (size 1.27 1.27)) (justify left) hide)
    )
    (property "ki_description" "Micro-Fit 3.0 Right-Angle Header, 3.00mm Pitch, Single Row, 3 Circuits, with PCB Press-fit Metal Retention Clip, Glow-Wire Capable, Black" (id 10) (at 0 0 0)
      (effects (font (size 1.27 1.27)) hide)
    )
    (symbol "43650-0303_0_0"
      (pin passive line (at 20.32 -5.08 180) (length 5.08)
        (name "1" (effects (font (size 1.27 1.27))))
        (number "1" (effects (font (size 1.27 1.27))))
      )
      (pin passive line (at 20.32 -2.54 180) (length 5.08)
        (name "2" (effects (font (size 1.27 1.27))))
        (number "2" (effects (font (size 1.27 1.27))))
      )
      (pin passive line (at 20.32 0 180) (length 5.08)
        (name "3" (effects (font (size 1.27 1.27))))
        (number "3" (effects (font (size 1.27 1.27))))
      )
      (pin passive line (at 0 -2.54 0) (length 5.08)
        (name "4" (effects (font (size 1.27 1.27))))
        (number "4" (effects (font (size 1.27 1.27))))
      )
      (pin passive line (at 0 0 0) (length 5.08)
        (name "5" (effects (font (size 1.27 1.27))))
        (number "5" (effects (font (size 1.27 1.27))))
      )
    )
    (symbol "43650-0303_0_1"
      (polyline
        (pts
          (xy 5.08 2.54)
          (xy 15.24 2.54)
          (xy 15.24 -7.62)
          (xy 5.08 -7.62)
          (xy 5.08 2.54)
        )
        (stroke (width 0.1524) (type default) (color 0 0 0 0))
        (fill (type none))
      )
    )
  )
  (symbol "43650-0320" (pin_names (offset 0.762)) (in_bom yes) (on_board yes)
    (property "Reference" "J" (id 0) (at 16.51 7.62 0)
      (effects (font (size 1.27 1.27)) (justify left))
    )
    (property "Value" "43650-0320" (id 1) (at 16.51 5.08 0)
      (effects (font (size 1.27 1.27)) (justify left))
    )
    (property "Footprint" "436500320" (id 2) (at 16.51 2.54 0)
      (effects (font (size 1.27 1.27)) (justify left) hide)
    )
    (property "Datasheet" "https://www.molex.com/pdm_docs/sd/436500320_sd.pdf" (id 3) (at 16.51 0 0)
      (effects (font (size 1.27 1.27)) (justify left) hide)
    )
    (property "Description" "MOLEX - 43650-0320 - WTB CONNECTOR, HEADER, 3POS, 1ROW, 3MM" (id 4) (at 16.51 -2.54 0)
      (effects (font (size 1.27 1.27)) (justify left) hide)
    )
    (property "Height" "9.9" (id 5) (at 16.51 -5.08 0)
      (effects (font (size 1.27 1.27)) (justify left) hide)
    )
    (property "Manufacturer_Name" "Molex" (id 6) (at 16.51 -7.62 0)
      (effects (font (size 1.27 1.27)) (justify left) hide)
    )
    (property "Manufacturer_Part_Number" "43650-0320" (id 7) (at 16.51 -10.16 0)
      (effects (font (size 1.27 1.27)) (justify left) hide)
    )
    (property "Mouser Part Number" "538-43650-0320" (id 8) (at 16.51 -12.7 0)
      (effects (font (size 1.27 1.27)) (justify left) hide)
    )
    (property "Mouser Price/Stock" "https://www.mouser.co.uk/ProductDetail/Molex/43650-0320?qs=ELX02gy%2F6bhyW2r1pYZDww%3D%3D" (id 9) (at 16.51 -15.24 0)
      (effects (font (size 1.27 1.27)) (justify left) hide)
    )
    (property "ki_description" "MOLEX - 43650-0320 - WTB CONNECTOR, HEADER, 3POS, 1ROW, 3MM" (id 10) (at 0 0 0)
      (effects (font (size 1.27 1.27)) hide)
    )
    (symbol "43650-0320_0_0"
      (pin passive line (at 0 -5.08 0) (length 5.08)
        (name "1" (effects (font (size 1.27 1.27))))
        (number "1" (effects (font (size 1.27 1.27))))
      )
      (pin passive line (at 0 -2.54 0) (length 5.08)
        (name "2" (effects (font (size 1.27 1.27))))
        (number "2" (effects (font (size 1.27 1.27))))
      )
      (pin passive line (at 0 0 0) (length 5.08)
        (name "3" (effects (font (size 1.27 1.27))))
        (number "3" (effects (font (size 1.27 1.27))))
      )
    )
    (symbol "43650-0320_0_1"
      (polyline
        (pts
          (xy 5.08 2.54)
          (xy 15.24 2.54)
          (xy 15.24 -7.62)
          (xy 5.08 -7.62)
          (xy 5.08 2.54)
        )
        (stroke (width 0.1524) (type default) (color 0 0 0 0))
        (fill (type none))
      )
    )
  )
  (symbol "632-tight-fit" (pin_names (offset 1.016) hide) (in_bom yes) (on_board yes)
    (property "Reference" "J" (id 0) (at 0 2.54 0)
      (effects (font (size 1.27 1.27)))
    )
    (property "Value" "632-tight-fit" (id 1) (at 0 -2.54 0)
      (effects (font (size 1.27 1.27)))
    )
    (property "Footprint" "" (id 2) (at 0 0 0)
      (effects (font (size 1.27 1.27)) hide)
    )
    (property "Datasheet" "~" (id 3) (at 0 0 0)
      (effects (font (size 1.27 1.27)) hide)
    )
    (property "ki_keywords" "connector" (id 4) (at 0 0 0)
      (effects (font (size 1.27 1.27)) hide)
    )
    (property "ki_description" "Generic connector, single row, 01x01, script generated (kicad-library-utils/schlib/autogen/connector/)" (id 5) (at 0 0 0)
      (effects (font (size 1.27 1.27)) hide)
    )
    (property "ki_fp_filters" "Connector*:*_1x??_*" (id 6) (at 0 0 0)
      (effects (font (size 1.27 1.27)) hide)
    )
    (symbol "632-tight-fit_1_1"
      (rectangle (start -1.27 0.127) (end 0 -0.127)
        (stroke (width 0.1524) (type default) (color 0 0 0 0))
        (fill (type none))
      )
      (rectangle (start -1.27 1.27) (end 1.27 -1.27)
        (stroke (width 0.254) (type default) (color 0 0 0 0))
        (fill (type background))
      )
      (pin passive line (at -5.08 0 0) (length 3.81)
        (name "Pin_1" (effects (font (size 1.27 1.27))))
        (number "1" (effects (font (size 1.27 1.27))))
      )
    )
  )
  (symbol "APA102" (in_bom yes) (on_board yes)
    (property "Reference" "D" (id 0) (at 5.08 5.715 0)
      (effects (font (size 1.27 1.27)) (justify right bottom))
    )
    (property "Value" "APA102" (id 1) (at 1.27 -5.715 0)
      (effects (font (size 1.27 1.27)) (justify left top))
    )
    (property "Footprint" "LED_SMD:LED_RGB_5050-6" (id 2) (at 1.27 -7.62 0)
      (effects (font (size 1.27 1.27)) (justify left top) hide)
    )
    (property "Datasheet" "http://www.led-color.com/upload/201506/APA102%20LED.pdf" (id 3) (at 2.54 -9.525 0)
      (effects (font (size 1.27 1.27)) (justify left top) hide)
    )
    (property "ki_keywords" "RGB LED addressable 8bit pwm 5bit greyscale" (id 4) (at 0 0 0)
      (effects (font (size 1.27 1.27)) hide)
    )
    (property "ki_description" "RGB LED with integrated controller" (id 5) (at 0 0 0)
      (effects (font (size 1.27 1.27)) hide)
    )
    (property "ki_fp_filters" "LED*RGB*5050*" (id 6) (at 0 0 0)
      (effects (font (size 1.27 1.27)) hide)
    )
    (symbol "APA102_0_0"
      (text "RGB" (at 2.286 -4.191 0)
        (effects (font (size 0.762 0.762)))
      )
    )
    (symbol "APA102_0_1"
      (polyline
        (pts
          (xy 1.27 -3.556)
          (xy 1.778 -3.556)
        )
        (stroke (width 0) (type default) (color 0 0 0 0))
        (fill (type none))
      )
      (polyline
        (pts
          (xy 1.27 -2.54)
          (xy 1.778 -2.54)
        )
        (stroke (width 0) (type default) (color 0 0 0 0))
        (fill (type none))
      )
      (polyline
        (pts
          (xy 4.699 -3.556)
          (xy 2.667 -3.556)
        )
        (stroke (width 0) (type default) (color 0 0 0 0))
        (fill (type none))
      )
      (polyline
        (pts
          (xy 2.286 -2.54)
          (xy 1.27 -3.556)
          (xy 1.27 -3.048)
        )
        (stroke (width 0) (type default) (color 0 0 0 0))
        (fill (type none))
      )
      (polyline
        (pts
          (xy 2.286 -1.524)
          (xy 1.27 -2.54)
          (xy 1.27 -2.032)
        )
        (stroke (width 0) (type default) (color 0 0 0 0))
        (fill (type none))
      )
      (polyline
        (pts
          (xy 3.683 -1.016)
          (xy 3.683 -3.556)
          (xy 3.683 -4.064)
        )
        (stroke (width 0) (type default) (color 0 0 0 0))
        (fill (type none))
      )
      (polyline
        (pts
          (xy 4.699 -1.524)
          (xy 2.667 -1.524)
          (xy 3.683 -3.556)
          (xy 4.699 -1.524)
        )
        (stroke (width 0) (type default) (color 0 0 0 0))
        (fill (type none))
      )
      (rectangle (start 5.08 5.08) (end -5.08 -5.08)
        (stroke (width 0.254) (type default) (color 0 0 0 0))
        (fill (type background))
      )
    )
    (symbol "APA102_1_1"
      (pin input line (at -7.62 2.54 0) (length 2.54)
        (name "DI" (effects (font (size 1.27 1.27))))
        (number "1" (effects (font (size 1.27 1.27))))
      )
      (pin input line (at -7.62 0 0) (length 2.54)
        (name "CI" (effects (font (size 1.27 1.27))))
        (number "2" (effects (font (size 1.27 1.27))))
      )
      (pin power_in line (at 0 -7.62 90) (length 2.54)
        (name "GND" (effects (font (size 1.27 1.27))))
        (number "3" (effects (font (size 1.27 1.27))))
      )
      (pin power_in line (at 0 7.62 270) (length 2.54)
        (name "VCC" (effects (font (size 1.27 1.27))))
        (number "4" (effects (font (size 1.27 1.27))))
      )
      (pin output line (at 7.62 0 180) (length 2.54)
        (name "CO" (effects (font (size 1.27 1.27))))
        (number "5" (effects (font (size 1.27 1.27))))
      )
      (pin output line (at 7.62 2.54 180) (length 2.54)
        (name "DO" (effects (font (size 1.27 1.27))))
        (number "6" (effects (font (size 1.27 1.27))))
      )
    )
  )

I can load this into GH with a file read component and view it in a panel, but I am at a loss as to how to parse out each symbol from the larger file (this file will change over time, so index or line specific parsing is not optional)(How do I parse indentations/whitespace?)

I would like to separate each ‘symbol’ from the larger list, prepare each symbol for text formatting, and extract numerical info from the ‘symbol’ to use in the creation of geometry for visualization and for wire/trace routing.

Once I figure out how to separate the ‘symbols’, then getting the other bits of info out of each text fragment should be trivial.

Any advice on how to parse this kind of file?

Thanks

You should be able to find a Python module for digesting S-exprs and populating an easier to handle data structure like a Python dict. The problem with S-exprs is that, like Lisp, you have to know what the CARs and CDRs represent at each level.

1 Like

Well…Thanks!

I didn’t even know what CARs and CDRs are. Now that I know what they are, I see a nice rabbit hole of LISP and ATOMS.

An additional complication is getting py modules to run in Grasshopper’s version of ‘IRONpython’ (circa python 2.7) but there are workarounds for that.

There was a forum discussion about automatically generating an LED clock face. It might pertain to what you’re doing.

1 Like

Also:
The thread linked to by devbisme also mentions SKiDL.

SKiDL is a python script for generating netlists. I see it as an sort of VHDL for schematic replacement.
You can use loops, arrays and all the other Python stuff for reducing repetitive work in the schematic and this seems pretty close to what you want to do.

1 Like

These are great links, thanks all!

I’m really trying to use rhino and grasshopper (and some python within) to load schematic symbols and PCBNEW footprints in as 2D geometry from the Kicad symbols and footprint libraries. Ultimately I want to use grasshopper to generate board shapes and schematic layouts, then be able to load the results onto Kicad and generate gerbers. Learning about parsing Kicad’s LISP-like files, SKiDL, and VHDL will be very helpful.


Above is the result from my grasshopper patch, loaded into PCBNEW. Complete with nets. There will always be some cleanup to do, but this takes MANY HOURS out of my process.

The boards I create are part of sculpture and the shapes are driven by the sculpture geometry. They won’t always be simple shapes like circles, annuli, or rectangles.

I have a very clunky version working, but again… only for 1 specific LED part. So, I will pursue learning as much as I can to see if I can generalize it some more. Honestly, I am a bit surprised no one has done this yet.

Someone mentioned in the studio clock thread that manufacturers would hate this kind of design, but I disagree. I got a NEODEN pick and place machine and it handles 0.1 degree rotation of components without issue.

@ devbisme

Wow, a lot of work has been done there. Thanks!

I hope I don’t lose credibility by saying this, but I just started a beginner’s python course. I have been dabbling and tooting around in a general state of confusion and it is high time to fill in all my fundamental blanks. Almost all my previous experience is embedded C.

I will try to keep this thread alive with updates on my progress.

I don’t know much about Grasshopper/Rhino so it will be interesting to see what you can incorporate from the Python world. In any event, getting more automation into the design process is always good.

1 Like

Have you seen the Kicad S-expression parser?

https://docs.kicad.org/doxygen/namespaceSEXPR.html

1 Like

More amazing rabbit holes!

This is super helpful, thank you.

In case you missed it, you might want to go down another rabbit hole. S-expressions are recursive. A “find library symbol” subroutine can call itself. Recursion is my all time favorite coding method.

There are also standalone ones in Python:

https://sexpdata.readthedocs.io/en/latest/

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.