← Back to team overview

kicad-developers team mailing list archive

[PATCH] Python FP wizard helper: docstrings and rounded/chamfered rects

 

Hi,

Here is a simple patch sequence for the Python Footprint Wizard helpers:

1) Minor spelling and formatting tidy-up
2) Add docstrings for the wizard base. As this is intended to be used
by writers of new plugins, having the functions documented is probably
a Good Idea (TM)
3) Add rounded rectangle and chamfered rectangle helpers. Useful for
some footprints or even board outlines.

I used Doxygen-style docstrings, but I haven't actually done anything
about building actual output docs with it. Any thoughts of if that
should be done, and if so, where to put it?

There shouldn't be anything here that will break existing plugins, the
only API changes are additions.

Cheers,

John
From 6073d002d607d0ba2ba9dac778997db0f93c6cb4 Mon Sep 17 00:00:00 2001
From: John Beard <john.j.beard@xxxxxxxxx>
Date: Fri, 1 Jun 2018 12:19:31 +0100
Subject: [PATCH 1/3] Pcbnew FP wizard: minor style fixes

This contains only a few minor style fixes according to PEP8
for FootprintWizardBase.py, and some spelling fixes
---
 pcbnew/python/plugins/FootprintWizardBase.py | 89 +++++++++++---------
 1 file changed, 48 insertions(+), 41 deletions(-)

diff --git a/pcbnew/python/plugins/FootprintWizardBase.py b/pcbnew/python/plugins/FootprintWizardBase.py
index 158128aea..023ee33a8 100644
--- a/pcbnew/python/plugins/FootprintWizardBase.py
+++ b/pcbnew/python/plugins/FootprintWizardBase.py
@@ -18,20 +18,21 @@ from __future__ import division
 import pcbnew
 import math
 
+
 # Base class for creating footprint wizards
 # Inherit this class to make a new wizard
 class FootprintWizard(pcbnew.FootprintWizardPlugin):
 
     # Copy units from pcbnew
-    uMM         = pcbnew.uMM
-    uMils       = pcbnew.uMils
-    uFloat      = pcbnew.uFloat
-    uInteger    = pcbnew.uInteger
-    uBool       = pcbnew.uBool
-    uRadians    = pcbnew.uRadians
-    uDegrees    = pcbnew.uDegrees
-    uPercent    = pcbnew.uPercent
-    uString     = pcbnew.uString
+    uMM = pcbnew.uMM
+    uMils = pcbnew.uMils
+    uFloat = pcbnew.uFloat
+    uInteger = pcbnew.uInteger
+    uBool = pcbnew.uBool
+    uRadians = pcbnew.uRadians
+    uDegrees = pcbnew.uDegrees
+    uPercent = pcbnew.uPercent
+    uString = pcbnew.uString
 
     """
     A class to simplify many aspects of footprint creation, leaving only
@@ -52,7 +53,7 @@ class FootprintWizard(pcbnew.FootprintWizardPlugin):
 
     def GetName(self):
         """
-        Retun the name of the footprint wizard
+        Return the name of the footprint wizard
         """
         raise NotImplementedError
 
@@ -72,7 +73,7 @@ class FootprintWizard(pcbnew.FootprintWizardPlugin):
         """
         Footprint parameter specification is done here
         """
-    	raise NotImplementedError
+        raise NotImplementedError
 
     def CheckParameters(self):
         """
@@ -84,43 +85,46 @@ class FootprintWizard(pcbnew.FootprintWizardPlugin):
         """
         Draw the footprint.
 
-        This is specific to each footprint class, you need to implment
+        This is specific to each footprint class, you need to implement
         this to draw what you want
         """
         raise NotImplementedError
 
     # Do not override this method!
-    def BuildFootprint( self ):
+    def BuildFootprint(self):
         """
-        Actually make the footprint. We defer all but the setup to
+        Actually make the footprint. We defer all but the set-up to
         the implementing class
         """
 
         self.buildmessages = ""
         self.module = pcbnew.MODULE(None)  # create a new module
 
-        # Perform default checks on all params
+        # Perform default checks on all parameters
         for p in self.params:
             p.ClearErrors()
-            p.Check() # use defaults
-
-        self.CheckParameters() # User error checks
+            p.Check()  # use defaults
 
+        self.CheckParameters()  # User error checks
 
         if self.AnyErrors():  # Errors were detected!
 
-            self.buildmessages = "Cannot build footprint: Parameters have errors:\n"
+            self.buildmessages = ("Cannot build footprint: "
+                                  "Parameters have errors:\n")
 
             for p in self.params:
                 if len(p.error_list) > 0:
-                    self.buildmessages +="['{page}']['{name}']:\n".format(page=p.page,name=p.name)
+                    self.buildmessages += "['{page}']['{name}']:\n".format(
+                        page=p.page, name=p.name)
 
                     for error in p.error_list:
                         self.buildmessages += "\t" + error + "\n"
 
             return
 
-        self.buildmessages = ("Building new {name} footprint with the following parameters:\n".format(name=self.name))
+        self.buildmessages = (
+            "Building new {name} footprint with the following parameters:\n"
+            .format(name=self.name))
 
         self.buildmessages += self.Show()
 
@@ -133,7 +137,7 @@ class FootprintWizard(pcbnew.FootprintWizardPlugin):
         fpid = pcbnew.LIB_ID(self.module.GetValue())  # the name in library
         self.module.SetFPID(fpid)
 
-        self.SetModule3DModel()  # add a 3d module if specified
+        self.SetModule3DModel()  # add a 3D module if specified
 
         thick = self.GetTextThickness()
 
@@ -160,6 +164,7 @@ class FootprintWizard(pcbnew.FootprintWizardPlugin):
         """
         return pcbnew.FromMM(0.15)
 
+
 class FootprintWizardDrawingAids:
     """
     Collection of handy functions to simplify drawing shapes from within
@@ -180,10 +185,10 @@ class FootprintWizardDrawingAids:
     dirNW = 315
 
     # flip constants
-    flipNone = 0
-    flipX = 1  # flip X values, i.e. about Y
-    flipY = 2  # flip Y valuersabout X
-    flipBoth = 3
+    flipNone = 0  # no flip transform
+    flipX = 1  # flip X values, i.e. about the Y-axis
+    flipY = 2  # flip Y values, i.e. about the X-axis
+    flipBoth = 3  # flip X and Y values, equivalent to a 180-degree rotation
 
     xfrmIDENTITY = [1, 0, 0, 0, 1, 0]  # no transform
 
@@ -235,13 +240,13 @@ class FootprintWizardDrawingAids:
     def _ComposeMatricesWithIdentity(self, mats):
         """
         Compose a sequence of matrices together by sequential
-        pre-mutiplciation with the identity matrix
+        pre-multiplication with the identity matrix
         """
 
         x = self.xfrmIDENTITY
 
         for mat in mats:
-            #precompose with each transform in turn
+            # Pre-compose with each transform in turn
             x = [
                 x[0] * mat[0] + x[1] * mat[3],
                 x[0] * mat[1] + x[1] * mat[4],
@@ -262,7 +267,7 @@ class FootprintWizardDrawingAids:
 
     def TransformTranslate(self, x, y, push=True):
         """
-        Set up and return a transform matrix representing a translartion
+        Set up and return a transform matrix representing a translation
         optionally pushing onto the stack
 
         (   1  0   x  )
@@ -307,7 +312,7 @@ class FootprintWizardDrawingAids:
                 self.TransformFlipOrigin(flip, push=False),
                 self.TransformTranslate(-x, -y, push=False)]
 
-        #distill into a single matrix
+        # Distil into a single matrix
         mat = self._ComposeMatricesWithIdentity(mats)
 
         if push:
@@ -343,7 +348,7 @@ class FootprintWizardDrawingAids:
                 self.TransformRotationOrigin(rot, push=False),
                 self.TransformTranslate(-x, -y, push=False)]
 
-        #distill into a single matrix
+        # Distil into a single matrix
         mat = self._ComposeMatricesWithIdentity(mats)
 
         if push:
@@ -390,7 +395,8 @@ class FootprintWizardDrawingAids:
     def SetLineTickness(self, lineThickness):
         """
         Old version of SetLineThickness.
-        Does the same thing, but is is only here for compatibility with old scripts
+        Does the same thing, but is is only here for compatibility with old
+        scripts.
         Set the current pen lineThickness used for subsequent drawing
         operations
         """
@@ -457,7 +463,7 @@ class FootprintWizardDrawingAids:
         The transform matrix is applied
 
         Note that this won't work properly if the result is not a
-        circular arc (eg a horizontal scale)
+        circular arc (e.g. a horizontal scale)
         """
         circle = pcbnew.EDGE_MODULE(self.module)
         circle.SetWidth(self.dc['lineThickness'])
@@ -491,7 +497,7 @@ class FootprintWizardDrawingAids:
 
     def Polyline(self, pts, mirrorX=None, mirrorY=None):
         """
-        Draw a polyline, optinally mirroring around the given points
+        Draw a polyline, optionally mirroring around the given points
         """
 
         def _PolyLineInternal(pts):
@@ -518,8 +524,7 @@ class FootprintWizardDrawingAids:
             _PolyLineInternal(pts)
             self.PopTransform()
 
-
-    def Reference(self, x, y, size, orientation_degree = 0):
+    def Reference(self, x, y, size, orientation_degree=0):
         """
         Draw the module's reference as the given point.
 
@@ -533,9 +538,10 @@ class FootprintWizardDrawingAids:
         self.module.Reference().SetPosition(
             self.module.Reference().GetPos0())
         self.module.Reference().SetTextSize(text_size)
-        self.module.Reference().SetTextAngle(orientation_degree*10)   # internal angles are in 0.1 deg
+        # internal angles are in 0.1 deg
+        self.module.Reference().SetTextAngle(orientation_degree * 10)
 
-    def Value(self, x, y, size, orientation_degree = 0):
+    def Value(self, x, y, size, orientation_degree=0):
         """
         As for references, draw the module's value
         """
@@ -545,7 +551,8 @@ class FootprintWizardDrawingAids:
         self.module.Value().SetPosition(self.module.Value().GetPos0())
         self.module.Value().SetTextSize(text_size)
         self.module.Value().SetLayer(self.DefaultTextValueLayer())
-        self.module.Value().SetTextAngle(orientation_degree*10)   # internal angles are in 0.1 deg
+        # internal angles are in 0.1 deg
+        self.module.Value().SetTextAngle(orientation_degree * 10)
 
     def Box(self, x, y, w, h):
         """
@@ -563,7 +570,7 @@ class FootprintWizardDrawingAids:
 
     def NotchedCircle(self, x, y, r, notch_w, notch_h, rotate=0):
         """
-        Circle radus r centred at (x, y) with a raised or depressed notch
+        Circle radius r centred at (x, y) with a raised or depressed notch
         at the top
         Notch height is measured from the top of the circle radius
         """
@@ -580,7 +587,7 @@ class FootprintWizardDrawingAids:
         # NOTE: this may be out by a factor of ten one day
         arc_angle = (math.pi * 2 - angle_intercept * 2) * (1800/math.pi)
 
-        self.Arc(x,y, sx, sy, arc_angle)
+        self.Arc(x, y, sx, sy, arc_angle)
 
         pts = [[sx,  sy],
                [sx,  -r - notch_h],
-- 
2.17.1

From 13e55c9e29c7b99a9784ce6bb2b3897b9c5e9883 Mon Sep 17 00:00:00 2001
From: John Beard <john.j.beard@xxxxxxxxx>
Date: Fri, 1 Jun 2018 13:11:03 +0100
Subject: [PATCH 2/3] Pcbnew FP wizard: add docstring for parameters

Adds more verbose and complete explanations of the
FootprintWizardBase and FootprintWizardDrawingAids functions.
---
 pcbnew/python/plugins/FootprintWizardBase.py | 265 ++++++++++++++-----
 1 file changed, 197 insertions(+), 68 deletions(-)

diff --git a/pcbnew/python/plugins/FootprintWizardBase.py b/pcbnew/python/plugins/FootprintWizardBase.py
index 023ee33a8..5f8306499 100644
--- a/pcbnew/python/plugins/FootprintWizardBase.py
+++ b/pcbnew/python/plugins/FootprintWizardBase.py
@@ -19,24 +19,15 @@ import pcbnew
 import math
 
 
-# Base class for creating footprint wizards
-# Inherit this class to make a new wizard
 class FootprintWizard(pcbnew.FootprintWizardPlugin):
+    """!
+    A class to simplify many aspects of footprint creation, leaving only
+    the foot-print specific routines to the wizards themselves.
 
-    # Copy units from pcbnew
-    uMM = pcbnew.uMM
-    uMils = pcbnew.uMils
-    uFloat = pcbnew.uFloat
-    uInteger = pcbnew.uInteger
-    uBool = pcbnew.uBool
-    uRadians = pcbnew.uRadians
-    uDegrees = pcbnew.uDegrees
-    uPercent = pcbnew.uPercent
-    uString = pcbnew.uString
+    Inherit this class to make a new wizard.
 
-    """
-    A class to simplify many aspects of footprint creation, leaving only
-    the foot-print specific routines to the wizards themselves
+    Provides simplified access to helpers like drawing functions, a transform
+    matrix stack and simple parameter checking.
 
     Generally, you need to implement:
         GetValue()
@@ -47,42 +38,53 @@ class FootprintWizard(pcbnew.FootprintWizardPlugin):
         GetDescription()
     """
 
+    # Copy units from pcbnew
+    uMM = pcbnew.uMM
+    uMils = pcbnew.uMils
+    uFloat = pcbnew.uFloat
+    uInteger = pcbnew.uInteger
+    uBool = pcbnew.uBool
+    uRadians = pcbnew.uRadians
+    uDegrees = pcbnew.uDegrees
+    uPercent = pcbnew.uPercent
+    uString = pcbnew.uString
+
     def __init__(self):
         pcbnew.FootprintWizardPlugin.__init__(self)
         self.GenerateParameterList()
 
     def GetName(self):
-        """
+        """!
         Return the name of the footprint wizard
         """
         raise NotImplementedError
 
     def GetDescription(self):
-        """
+        """!
         Return the footprint wizard description
         """
         raise NotImplementedError
 
     def GetValue(self):
-        """
+        """!
         Return the value (name) of the generated footprint
         """
         raise NotImplementedError
 
     def GenerateParameterList(self):
-        """
+        """!
         Footprint parameter specification is done here
         """
         raise NotImplementedError
 
     def CheckParameters(self):
-        """
+        """!
         Any custom parameter checking should be performed here
         """
         raise NotImplementedError
 
     def BuildThisFootprint(self):
-        """
+        """!
         Draw the footprint.
 
         This is specific to each footprint class, you need to implement
@@ -92,7 +94,7 @@ class FootprintWizard(pcbnew.FootprintWizardPlugin):
 
     # Do not override this method!
     def BuildFootprint(self):
-        """
+        """!
         Actually make the footprint. We defer all but the set-up to
         the implementing class
         """
@@ -149,16 +151,21 @@ class FootprintWizard(pcbnew.FootprintWizardPlugin):
         return
 
     def SetModule3DModel(self):
+        """!
+        If your plug-in sets a 3D model, override this function
+        """
         pass
 
     def GetTextSize(self):
-        """
-        IPC nominal
+        """!
+        Get the default text size for the footprint. Override to change it.
+
+        Defaults to IPC nominal of 1.0mm
         """
         return pcbnew.FromMM(1.0)
 
     def GetTextThickness(self):
-        """
+        """!
         Thicker than IPC guidelines (10% of text height = 0.12mm)
         as 5 wires/mm is a common silk screen limitation
         """
@@ -166,12 +173,14 @@ class FootprintWizard(pcbnew.FootprintWizardPlugin):
 
 
 class FootprintWizardDrawingAids:
-    """
+    """!
     Collection of handy functions to simplify drawing shapes from within
     footprint wizards
 
     A "drawing context" is provided which can be used to set and retain
-    settings such as line thickness and layer
+    settings such as line thickness and layer. The DC also contains a
+    "transform stack", which allows easy positioning and transforming of
+    drawn elements without lots of geometric book-keeping.
     """
 
     # directions (in degrees, compass-like)
@@ -184,7 +193,7 @@ class FootprintWizardDrawingAids:
     dirW = 270
     dirNW = 315
 
-    # flip constants
+    # Flip constants
     flipNone = 0  # no flip transform
     flipX = 1  # flip X values, i.e. about the Y-axis
     flipY = 2  # flip Y values, i.e. about the X-axis
@@ -212,17 +221,22 @@ class FootprintWizardDrawingAids:
         }
 
     def PushTransform(self, mat):
-        """
+        """!
         Add a transform to the top of the stack and recompute the
         overall transform
+
+        @param mat: the transform matrix to add to the stack
         """
         self.dc['transforms'].append(mat)
         self.RecomputeTransforms()
 
     def PopTransform(self, num=1):
-        """
+        """!
         Remove a transform from the top of the stack and recompute the
         overall transform
+
+        @param num: the number of transforms to pop from the stack.
+        @return the last popped transform
         """
 
         for i in range(num):
@@ -231,16 +245,19 @@ class FootprintWizardDrawingAids:
         return mat
 
     def ResetTransform(self):
-        """
-        Reset the transform stack to the identity matrix
+        """!
+        Reset the transform stack to the identity matrix.
         """
         self.dc['transforms'] = []
         self.RecomputeTransforms()
 
     def _ComposeMatricesWithIdentity(self, mats):
-        """
+        """!
         Compose a sequence of matrices together by sequential
-        pre-multiplication with the identity matrix
+        pre-multiplication with the identity matrix.
+
+        @param mats: list of matrices to compose
+        @return: the composed transform matrix
         """
 
         x = self.xfrmIDENTITY
@@ -258,7 +275,7 @@ class FootprintWizardDrawingAids:
         return x
 
     def RecomputeTransforms(self):
-        """
+        """!
         Re-compute the transform stack into a single transform and
         store in the DC
         """
@@ -266,12 +283,17 @@ class FootprintWizardDrawingAids:
             self.dc['transforms'])
 
     def TransformTranslate(self, x, y, push=True):
-        """
+        """!
         Set up and return a transform matrix representing a translation
         optionally pushing onto the stack
 
         (   1  0   x  )
         (   0  1   y  )
+
+        @param x: translation in x-direction
+        @param y: translation in y-direction
+        @param push: add this transform to the current stack
+        @return the generated transform matrix
         """
         mat = [1, 0, x, 0, 1, y]
 
@@ -280,9 +302,13 @@ class FootprintWizardDrawingAids:
         return mat
 
     def TransformFlipOrigin(self, flip, push=True):
-        """
+        """!
         Set up and return a transform matrix representing a horizontal,
         vertical or both flip about the origin
+
+        @param flip: one of flipNone, flipX, flipY, flipBoth
+        @param push: add this transform to the current stack
+        @return the generated transform matrix
         """
         mat = None
         if flip == self.flipX:
@@ -301,12 +327,18 @@ class FootprintWizardDrawingAids:
         return mat
 
     def TransformFlip(self, x, y, flip=flipNone, push=True):
-        """
+        """!
         Set up and return a transform matrix representing a horizontal,
         vertical or both flip about a point (x,y)
 
         This is performed by a translate-to-origin, flip, translate-
-        back sequence
+        back sequence.
+
+        @param x: the x co-ordinate of the flip point
+        @param y: the y co-ordinate of the flip point
+        @param flip: one of flipNone, flipX, flipY, flipBoth
+        @param push: add this transform to the current stack
+        @return the generated transform matrix
         """
         mats = [self.TransformTranslate(x, y, push=False),
                 self.TransformFlipOrigin(flip, push=False),
@@ -320,12 +352,16 @@ class FootprintWizardDrawingAids:
         return mat
 
     def TransformRotationOrigin(self, rot, push=True):
-        """
+        """!
         Set up and return a transform matrix representing a rotation
         about the origin, and optionally push onto the stack
 
         (   cos(t)  -sin(t)   0  )
         (   sin(t)   cos(t)   0  )
+
+        @param rot: the rotation angle in degrees
+        @param push: add this transform to the current stack
+        @return the generated transform matrix
         """
         rads = rot * math.pi / 180
         mat = [math.cos(rads), -math.sin(rads), 0,
@@ -336,12 +372,18 @@ class FootprintWizardDrawingAids:
         return mat
 
     def TransformRotation(self, x, y, rot, push=True):
-        """
+        """!
         Set up and return a transform matrix representing a rotation
         about the point (x,y), and optionally push onto the stack
 
         This is performed by a translate-to-origin, rotate, translate-
         back sequence
+
+        @param x: the x co-ordinate of the rotation centre
+        @param y: the y co-ordinate of the rotation centre
+        @param rot: the rotation angle in degrees
+        @param push: add this transform to the current stack
+        @return the generated transform matrix
         """
 
         mats = [self.TransformTranslate(x, y, push=False),
@@ -356,12 +398,17 @@ class FootprintWizardDrawingAids:
         return mat
 
     def TransformScaleOrigin(self, sx, sy=None, push=True):
-        """
+        """!
         Set up and return a transform matrix representing a scale about
         the origin, and optionally push onto the stack
 
         (   sx   0   0  )
         (    0  sy   0  )
+
+        @param sx: the scale factor in the x direction
+        @param sy: the scale factor in the y direction
+        @param push: add this transform to the current stack
+        @return the generated transform matrix
         """
 
         if sy is None:
@@ -374,9 +421,14 @@ class FootprintWizardDrawingAids:
         return mat
 
     def TransformPoint(self, x, y, mat=None):
-        """
+        """!
         Return a point (x, y) transformed by the given matrix, or if
         that is not given, the drawing context transform
+
+        @param x: the x co-ordinate of the point to transform
+        @param y: the y co-ordinate of the point to transform
+        @param mat: the transform matrix to use or None to use the current DC's
+        @return: the transformed point as a wxPoint
         """
 
         if not mat:
@@ -386,43 +438,47 @@ class FootprintWizardDrawingAids:
                               x * mat[3] + y * mat[4] + mat[5])
 
     def SetLineThickness(self, lineThickness):
-        """
+        """!
         Set the current pen lineThickness used for subsequent drawing
         operations
+
+        @param lineThickness: the new line thickness to set
         """
         self.dc['lineThickness'] = lineThickness
 
     def SetLineTickness(self, lineThickness):
-        """
+        """!
         Old version of SetLineThickness.
         Does the same thing, but is is only here for compatibility with old
         scripts.
         Set the current pen lineThickness used for subsequent drawing
         operations
+
+        @param lineThickness: the new line thickness to set
         """
-        self.dc['lineThickness'] = lineThickness
+        self.SetLineThickness(lineThickness)
 
     def GetLineThickness(self):
-        """
+        """!
         Get the current drawing context line thickness
         """
         return self.dc['lineThickness']
 
     def SetLayer(self, layer):
-        """
+        """!
         Set the current drawing layer, used for subsequent drawing
         operations
         """
         self.dc['layer'] = layer
 
     def GetLayer(self):
-        """
-        return the current drawing layer, used drawing operations
+        """!
+        Return the current drawing layer, used for drawing operations
         """
         return self.dc['layer']
 
     def Line(self, x1, y1, x2, y2):
-        """
+        """!
         Draw a line from (x1, y1) to (x2, y2)
         """
         outline = pcbnew.EDGE_MODULE(self.module)
@@ -435,10 +491,16 @@ class FootprintWizardDrawingAids:
         self.module.Add(outline)
 
     def Circle(self, x, y, r, filled=False):
-        """
+        """!
         Draw a circle at (x,y) of radius r
         If filled is true, the thickness and radius of the line will be set
         such that the circle appears filled
+
+        @param cx: the x co-ordinate of the arc centre
+        @param cy: the y co-ordinate of the arc centre
+        @param r: the circle's radius
+        @param filled: True to draw a filled circle, False to use the current
+                       DC line thickness
         """
 
         circle = pcbnew.EDGE_MODULE(self.module)
@@ -457,13 +519,19 @@ class FootprintWizardDrawingAids:
         self.module.Add(circle)
 
     def Arc(self, cx, cy, sx, sy, a):
-        """
+        """!
         Draw an arc based on centre, start and angle
 
         The transform matrix is applied
 
         Note that this won't work properly if the result is not a
         circular arc (e.g. a horizontal scale)
+
+        @param cx: the x co-ordinate of the arc centre
+        @param cy: the y co-ordinate of the arc centre
+        @param sx: the x co-ordinate of the arc start point
+        @param sy: the y co-ordinate of the arc start point
+        @param a: the arc's central angle (in deci-degrees)
         """
         circle = pcbnew.EDGE_MODULE(self.module)
         circle.SetWidth(self.dc['lineThickness'])
@@ -482,22 +550,33 @@ class FootprintWizardDrawingAids:
         circle.SetStartEnd(center, start)
         self.module.Add(circle)
 
-    # extends from (x1,y1) right
     def HLine(self, x, y, l):
-        """
+        """!
         Draw a horizontal line from (x,y), rightwards
+
+        @param x: line start x co-ordinate
+        @param y: line start y co-ordinate
+        @param l: line length
         """
         self.Line(x, y, x + l, y)
 
     def VLine(self, x, y, l):
-        """
+        """!
         Draw a vertical line from (x1,y1), downwards
+
+        @param x: line start x co-ordinate
+        @param y: line start y co-ordinate
+        @param l: line length
         """
         self.Line(x, y, x, y + l)
 
     def Polyline(self, pts, mirrorX=None, mirrorY=None):
-        """
+        """!
         Draw a polyline, optionally mirroring around the given points
+
+        @param pts: list of polyline vertices (list of (x, y))
+        @param mirrorX: x co-ordinate of mirror point (None for no x-flip)
+        @param mirrorY: y co-ordinate of mirror point (None for no y-flip)
         """
 
         def _PolyLineInternal(pts):
@@ -525,11 +604,16 @@ class FootprintWizardDrawingAids:
             self.PopTransform()
 
     def Reference(self, x, y, size, orientation_degree=0):
-        """
+        """!
         Draw the module's reference as the given point.
 
         The actual setting of the reference is not done in this drawing
         aid - that is up to the wizard
+
+        @param x: the x position of the reference
+        @param y: the y position of the reference
+        @param size: the text size (in both directions)
+        @param orientation_degree: text orientation in degrees
         """
 
         text_size = pcbnew.wxSize(size, size)
@@ -542,8 +626,13 @@ class FootprintWizardDrawingAids:
         self.module.Reference().SetTextAngle(orientation_degree * 10)
 
     def Value(self, x, y, size, orientation_degree=0):
-        """
+        """!
         As for references, draw the module's value
+
+        @param x: the x position of the value
+        @param y: the y position of the value
+        @param size: the text size (in both directions)
+        @param orientation_degree: text orientation in degrees
         """
         text_size = pcbnew.wxSize(size, size)
 
@@ -555,9 +644,14 @@ class FootprintWizardDrawingAids:
         self.module.Value().SetTextAngle(orientation_degree * 10)
 
     def Box(self, x, y, w, h):
-        """
+        """!
         Draw a rectangular box, centred at (x,y), with given width and
         height
+
+        @param x: the x co-ordinate of the box's centre
+        @param y: the y co-ordinate of the box's centre
+        @param w: the width of the box
+        @param h: the height of the box
         """
 
         pts = [[x - w/2, y - h/2],  # left
@@ -569,10 +663,17 @@ class FootprintWizardDrawingAids:
         self.Polyline(pts)
 
     def NotchedCircle(self, x, y, r, notch_w, notch_h, rotate=0):
-        """
+        """!
         Circle radius r centred at (x, y) with a raised or depressed notch
         at the top
         Notch height is measured from the top of the circle radius
+
+        @param x: the x co-ordinate of the circle's centre
+        @param y: the y co-ordinate of the circle's centre
+        @param r: the radius of the circle
+        @param notch_w: the width of the notch
+        @param notch_h: the height of the notch
+        @param rotate: the rotation of the whole figure, in degrees
         """
 
         self.TransformRotation(x, y, rotate)
@@ -598,8 +699,16 @@ class FootprintWizardDrawingAids:
         self.PopTransform()
 
     def NotchedBox(self, x, y, w, h, notchW, notchH, rotate=0):
-        """
-        Draw a box with a notch in the top edge
+        """!
+        Draw a box with a notch in the centre of the top edge
+
+        @param x: the x co-ordinate of the circle's centre
+        @param y: the y co-ordinate of the circle's centre
+        @param w: the width of the box
+        @param h: the height of the box
+        @param notchW: the width of the notch
+        @param notchH: the height of the notch
+        @param rotate: the rotation of the whole figure, in degrees
         """
 
         self.TransformRotation(x, y, rotate)
@@ -625,8 +734,16 @@ class FootprintWizardDrawingAids:
 
     def BoxWithDiagonalAtCorner(self, x, y, w, h,
                                 setback=pcbnew.FromMM(1.27), flip=flipNone):
-        """
-        Draw a box with a diagonal at the top left corner
+        """!
+        Draw a box with a diagonal at the top left corner.
+
+        @param x: the x co-ordinate of the circle's centre
+        @param y: the y co-ordinate of the circle's centre
+        @param w: the width of the box
+        @param h: the height of the box
+        @param setback: the set-back of the diagonal, in both x and y
+        @param flip: one of flipNone, flipX, flipY or flipBoth to change the
+         diagonal corner
         """
 
         self.TransformFlip(x, y, flip, push=True)
@@ -644,8 +761,16 @@ class FootprintWizardDrawingAids:
 
     def BoxWithOpenCorner(self, x, y, w, h,
                           setback=pcbnew.FromMM(1.27), flip=flipNone):
-        """
+        """!
         Draw a box with an opening at the top left corner
+
+        @param x: the x co-ordinate of the circle's centre
+        @param y: the y co-ordinate of the circle's centre
+        @param w: the width of the box
+        @param h: the height of the box
+        @param setback: the set-back of the opening, in both x and y
+        @param flip: one of flipNone, flipX, flipY or flipBoth to change the
+         open corner position
         """
 
         self.TransformTranslate(x, y)
@@ -662,11 +787,15 @@ class FootprintWizardDrawingAids:
         self.PopTransform(num=2)
 
     def MarkerArrow(self, x, y, direction=dirN, width=pcbnew.FromMM(1)):
-        """
+        """!
         Draw a marker arrow facing in the given direction, with the
         point at (x,y)
 
-        Direction of 0 is north
+        @param x: x position of the arrow tip
+        @param y: y position of the arrow tip
+        @param direction: arrow direction in degrees (0 is "north", can use
+         dir* shorthands)
+        @param width: arrow width
         """
 
         self.TransformTranslate(x, y)
-- 
2.17.1

From 2a9af9b95c23633bd4a05fbbf44bad74ce052141 Mon Sep 17 00:00:00 2001
From: John Beard <john.j.beard@xxxxxxxxx>
Date: Fri, 1 Jun 2018 12:08:26 +0100
Subject: [PATCH 3/3] Pcbnew FP wizard: add rounded and chamfered box aids

These functions are fairly common drawing operations that otherwise
require fairly complex calculations, which would be better not to
have to repeat.
---
 pcbnew/python/plugins/FootprintWizardBase.py | 70 +++++++++++++++++++-
 1 file changed, 69 insertions(+), 1 deletion(-)

diff --git a/pcbnew/python/plugins/FootprintWizardBase.py b/pcbnew/python/plugins/FootprintWizardBase.py
index 5f8306499..ee783ae0f 100644
--- a/pcbnew/python/plugins/FootprintWizardBase.py
+++ b/pcbnew/python/plugins/FootprintWizardBase.py
@@ -786,6 +786,74 @@ class FootprintWizardDrawingAids:
 
         self.PopTransform(num=2)
 
+    def RoundedBox(self, x, y, w, h, rad):
+        """
+        Draw a box with rounded corners (i.e. a 90-degree circular arc)
+
+        :param x: the x co-ordinate of the box's centre
+        :param y: the y co-ordinate of the box's centre
+        :param w: the width of the box
+        :param h: the height of the box
+        :param rad: the radius of the corner rounds
+        """
+
+        x_inner = w - rad * 2
+        y_inner = h - rad * 2
+
+        x_left = x - w / 2
+        y_top = y - h / 2
+
+        # Draw straight sections
+        self.HLine(x_left + rad, y_top, x_inner)
+        self.HLine(x_left + rad, -y_top, x_inner)
+
+        self.VLine(x_left, y_top + rad, y_inner)
+        self.VLine(-x_left, y_top + rad, y_inner)
+
+        # corner arcs
+        ninety_deg = 90 * 10  # deci-degs
+        cx = x - w / 2 + rad
+        cy = y - h / 2 + rad
+
+        # top left
+        self.Arc(+cx, +cy, +x_left, +cy, +ninety_deg)
+        self.Arc(-cx, +cy, -x_left, +cy, -ninety_deg)
+        self.Arc(+cx, -cy, +x_left, -cy, -ninety_deg)
+        self.Arc(-cx, -cy, -x_left, -cy, +ninety_deg)
+
+    def ChamferedBox(self, x, y, w, h, chamfer_x, chamfer_y):
+        """
+        Draw a box with chamfered corners.
+
+        :param x: the x co-ordinate of the box's centre
+        :param y: the y co-ordinate of the box's centre
+        :param w: the width of the box
+        :param h: the height of the box
+        :param chamfer_x: the size of the chamfer set-back in the x direction
+        :param chamfer_y: the size of the chamfer set-back in the y direction
+        """
+        # outermost dimensions
+        x_left = x - w / 2
+        y_top = y - h / 2
+
+        # x and y co-ordinates of inner edges of chamfers
+        x_inner = x_left + chamfer_x
+        y_inner = y_top + chamfer_y
+
+        pts = [
+            [+x_inner, +y_top],
+            [-x_inner, +y_top],
+            [-x_left,  +y_inner],
+            [-x_left,  -y_inner],
+            [-x_inner, -y_top],
+            [+x_inner, -y_top],
+            [+x_left,  -y_inner],
+            [+x_left,  +y_inner],
+            [+x_inner, +y_top],
+        ]
+
+        self.draw.Polyline(pts)
+
     def MarkerArrow(self, x, y, direction=dirN, width=pcbnew.FromMM(1)):
         """!
         Draw a marker arrow facing in the given direction, with the
@@ -807,4 +875,4 @@ class FootprintWizardDrawingAids:
                [0,          0]]
 
         self.Polyline(pts)
-        self.PopTransform(2)
\ No newline at end of file
+        self.PopTransform(2)
-- 
2.17.1


Follow ups