Using the new IPC API to get a footprint size for top and bottom

Hi All.
The topic basically says it all. The plugin I am attempting to a duplicate of the hierarchical placement plugin using the old API by Dave Vandenbout (which places the components grouped like in the hierarchy of the schematic.) but I also want to use the top and bottom of the PCB.
I want to do component placements using the new API and I need the footprint size plus borders on the top and bottom layers for this. I have tried several ideas detailed below.

My background:

  • I am new to plugin development but have used KiCad for a couple of years for my own projects. - I am trying to write a plugin using the new API, both to learn something new and contribute back
  • I know it is experimental and I am happy to deal with the issues associated with that

Using:

  • KiCad v 9.0.2
  • kipy python package v 0.4.0 (checked out from git and locally compiled - this is to get passed the move component bug discussed in one of the posts)
  • Ubuntu 24.04 LTS
  • Python 3.12.3
  • I am running this from the commandline (in vscode in debug mode) and not as a plugin yet

What I have tried:

  1. Iterate through all the pads of the footprint and to find the edges. It works finding the extremities of the pads but can not include areas that have no pads, e.g. horizontally mounted TO220 should have an area that includes the package tab (silkscreen area) on one side of the board but should only include the through holes on the other side of the board
    e.g.
for pad in footprint.definition.pads: 
      for copper_layer in pad.padstack.copper_layers:
                if copper_layer.layer == layer_id:
                    pad_pos: Vector2 = pad.position
                    size: Vector2 = copper_layer.size
                    offset: Vector2 = copper_layer.offset
                    corners = Footprint._get_rotated_rect_corners(pad_pos, size, offset, pad_angle)
                    xs = [pt.x for pt in corners]
                    ys = [pt.y for pt in corners]
                    min_x = min(min_x, *xs)
                    min_y = min(min_y, *ys)
                    max_x = max(max_x, *xs)
                    max_y = max(max_y, *ys)
  1. I tried to use the shapes with the same kind of loop as above but shapes does not have a position so I can not use that?

  2. Using Board.get_item_bounding_box(…) does give me the bounding box of the component but I can not make a distinction between the top and bottom of the PCB?
    bb = brd.get_item_bounding_box(selected[0].m)

I hope there is an easy way of doing this and that I have just missed it?

Probably best approximation of what you want would be to go through footprint drawings on the courtyard layers (F and B separately) and compile the bounding box (simplified) or polygon (more accurate) out of that.

Of course it relies on the footprints having that courtyard drawn accurately which most footprints in standard library do. There is no other way for KiCad to really know what is a to220 laying flush on the board or just a connector head sticking out which doesnt interfere with smd components underneath it.

Thanks for the suggestion!
Sounds like a good idea. I will try it. Might post the code here if it works