Python scripting, classes and functions

Another peculiar scripting issue:

When getting the corners of the bounding boxes for pads and text, it’s a little strange. I’m not sure this is definitive, but seems to work for my layout. I haven’t specifically tried all different combinations of rotated module (footprint) and rotated text.

This procedure works for free text (i.e. at the top level) and for text/pads within modules. The idea here is to get a bounding box (which is always reported at orientation 0) and to get a rotation to apply to the bounding box. Applying the rotation to the bounding box gets the final region on the board.

Pad (only orthogonal tested): always take the bounding box. It is oriented correctly regardless of footprint orientation. That is, rotation applied is zero.
I would expect that a non-orthogonal rotation applied to either pad or footprint would require different code.

Text:
bounding_box = textobject.GetTextBox()
textobject.GetOrientation() + textobject.GetParent().GetOrientation()

If the textobject is free text (i.e. it’s at the top level instead of in a footprint), the parent will not have a GetOrientation attribute. Here’s the code:

    try:
        m=object.GetParent().Cast_to_MODULE()
        parentorientation = m.GetOrientation()
    except:
        parentorientation = 0.0
    orientation = object.GetOrientation()
    return self.GetCornersRotatedRect(
        object.GetTextBox().getWxRect(),
        object.GetCenter(),
        orientation+parentorientation)

And the GetCornersRotatedRect function:

def GetCornersRotatedRect(self,rect,center,orientation):
    # rect is entered as a KiCAD boundingbox in a wxRect format (indexable)
    # rect format is (upper left x, upper left y, width, height)
    # orientation for this algorithm is -(kicad orientation).
    # This is because algorithm orientation is in the opposite direction
    # of kicad orientation.
    # (note that orientation is returned as tenths of a degree,
    #  so this also converts to floating point degrees)
    orientation = -orientation/10.0
    
    # the center is the rotation point
    ox,oy = center
    
    rpoints = []
    #initial points
    for px,py in (
        (rect[0]        ,rect[1]),
        (rect[0]+rect[2],rect[1]),
        (rect[0]+rect[2],rect[1]+rect[3]),
        (rect[0]        ,rect[1]+rect[3]),
        ):
        
        # rotate point around center
        cos= math.cos(math.radians(orientation))
        sin= math.sin(math.radians(orientation))
        pox = px-ox
        poy = py-oy
        
        nx = cos * (pox) - sin * (poy) + ox
        ny = sin * (pox) + cos * (poy) + oy
        
        rpoints.append(pcbnew.wxPoint(int(nx),int(ny)))

    # add the start point to form a closed polygon
    rpoints.append(rpoints[0]) 
    
    return rpoints