22from __future__
import division
29 A class to simplify many aspects of footprint creation, leaving only
30 the footprint specific routines to the wizards themselves.
32 Inherit this
class to make a new wizard.
34 Provides simplified access to helpers like drawing functions, a transform
35 matrix stack
and simple parameter checking.
37 Generally, you need to implement:
49 uFloat = pcbnew.uFloat
50 uInteger = pcbnew.uInteger
52 uRadians = pcbnew.uRadians
53 uDegrees = pcbnew.uDegrees
54 uPercent = pcbnew.uPercent
55 uString = pcbnew.uString
63 Return the name of the footprint wizard
65 raise NotImplementedError
69 Return the footprint wizard description
71 raise NotImplementedError
75 Return the value (name) of the generated footprint
77 raise NotImplementedError
81 Footprint parameter specification is done here
83 raise NotImplementedError
87 Any custom parameter checking should be performed here
89 raise NotImplementedError
95 This is specific to each footprint
class, you need to implement
96 this to draw what you want
98 raise NotImplementedError
103 Actually make the footprint. We defer all but the set-up to
104 the implementing class
120 "Parameters have errors:\n")
123 if len(p.error_list) > 0:
125 page=p.page, name=p.name)
127 for error
in p.error_list:
133 "Building new {name} footprint with the following parameters:\n"
134 .format(name=self.
name))
160 If your plug-in sets a 3D model, override this function
166 Get the default text size for the footprint. Override to change it.
168 Defaults to IPC nominal of 1.0mm
174 Thicker than IPC guidelines (10% of text height = 0.12mm)
175 as 5 wires/mm
is a common silk screen limitation
182 Collection of handy functions to simplify drawing shapes from within
185 A
"drawing context" is provided which can be used to set
and retain
186 settings such
as line thickness
and layer. The DC also contains a
187 "transform stack", which allows easy positioning
and transforming of
188 drawn elements without lots of geometric book-keeping.
207 xfrmIDENTITY = [1, 0, 0, 0, 1, 0]
213 return pcbnew.F_SilkS
230 Add a transform to the top of the stack and recompute the
233 @param mat: the transform matrix to add to the stack
235 self.dc['transforms'].append(mat)
240 Remove a transform from the top of the stack
and recompute the
243 @param num: the number of transforms to pop
from the stack.
244 @return the last popped transform
248 mat = self.
dc[
'transforms'].pop()
254 Reset the transform stack to the identity matrix.
256 self.dc['transforms'] = []
259 def _ComposeMatricesWithIdentity(self, mats):
261 Compose a sequence of matrices together by sequential
262 pre-multiplication with the identity matrix.
264 @param mats: list of matrices to compose
265 @return: the composed transform matrix
273 x[0] * mat[0] + x[1] * mat[3],
274 x[0] * mat[1] + x[1] * mat[4],
275 x[0] * mat[2] + x[1] * mat[5] + x[2],
276 x[3] * mat[0] + x[4] * mat[3],
277 x[3] * mat[1] + x[4] * mat[4],
278 x[3] * mat[2] + x[4] * mat[5] + x[5]]
284 Re-compute the transform stack into a single transform and
288 self.
dc[
'transforms'])
292 Set up and return a transform matrix representing a translation
293 optionally pushing onto the stack
298 @param x: translation
in x-direction
299 @param y: translation
in y-direction
300 @param push: add this transform to the current stack
301 @return the generated transform matrix
303 mat = [1, 0, x, 0, 1, y]
311 Set up and return a transform matrix representing a horizontal,
312 vertical
or both flip about the origin
314 @param flip: one of flipNone, flipX, flipY, flipBoth
315 @param push: add this transform to the current stack
316 @return the generated transform matrix
319 if flip == self.
flipX:
320 mat = [-1, 0, 0, 0, 1, 0]
321 elif flip == self.
flipY:
322 mat = [1, 0, 0, 0, -1, 0]
324 mat = [-1, 0, 0, 0, -1, 0]
336 Set up and return a transform matrix representing a horizontal,
337 vertical
or both flip about a point (x,y)
339 This
is performed by a translate-to-origin, flip, translate-
342 @param x: the x coordinate of the flip point
343 @param y: the y coordinate of the flip point
344 @param flip: one of flipNone, flipX, flipY, flipBoth
345 @param push: add this transform to the current stack
346 @return the generated transform matrix
361 Set up and return a transform matrix representing a rotation
362 about the origin,
and optionally push onto the stack
367 @param rot: the rotation angle
in degrees
368 @param push: add this transform to the current stack
369 @return the generated transform matrix
371 rads = rot * math.pi / 180
372 mat = [math.cos(rads), -math.sin(rads), 0,
373 math.sin(rads), math.cos(rads), 0]
381 Set up and return a transform matrix representing a rotation
382 about the point (x,y),
and optionally push onto the stack
384 This
is performed by a translate-to-origin, rotate, translate-
387 @param x: the x coordinate of the rotation centre
388 @param y: the y coordinate of the rotation centre
389 @param rot: the rotation angle
in degrees
390 @param push: add this transform to the current stack
391 @return the generated transform matrix
407 Set up and return a transform matrix representing a scale about
408 the origin,
and optionally push onto the stack
413 @param sx: the scale factor
in the x direction
414 @param sy: the scale factor
in the y direction
415 @param push: add this transform to the current stack
416 @return the generated transform matrix
422 mat = [sx, 0, 0, 0, sy, 0]
430 Return a point (x, y) transformed by the given matrix, or if
431 that
is not given, the drawing context transform
433 @param x: the x coordinate of the point to transform
434 @param y: the y coordinate of the point to transform
435 @param mat: the transform matrix to use
or None to use the current DC
's
436 @return: the transformed point
as a VECTOR2I
440 mat = self.
dc[
'transform']
443 (int)(x * mat[3] + y * mat[4] + mat[5]) )
447 Set the current pen lineThickness used for subsequent drawing
450 @param lineThickness: the new line thickness to set
452 self.dc['lineThickness'] = lineThickness
456 Old version of SetLineThickness.
457 Does the same thing, but is only here
for compatibility
with old
459 Set the current pen lineThickness used
for subsequent drawing
462 @param lineThickness: the new line thickness to set
468 Get the current drawing context line thickness
470 return self.
dc[
'lineThickness']
474 Set the current drawing layer, used for subsequent drawing
477 self.dc['layer'] = layer
481 Return the current drawing layer, used for drawing operations
483 return self.
dc[
'layer']
485 def Line(self, x1, y1, x2, y2):
487 Draw a line from (x1, y1) to (x2, y2)
492 outline.SetShape(pcbnew.S_SEGMENT)
495 outline.SetStartEnd(start, end)
500 Draw a circle at (x,y) of radius r
501 If filled is true, the thickness
and radius of the line will be set
502 such that the circle appears filled
504 @param x: the x coordinate of the arc centre
505 @param y: the y coordinate of the arc centre
506 @param r: the circle
's radius
507 @param filled:
True to draw a filled circle,
False to use the current
518 circle.SetWidth(self.
dc[
'lineThickness'])
521 circle.SetLayer(self.
dc[
'layer'])
522 circle.SetShape(pcbnew.S_CIRCLE)
523 circle.SetStartEnd(start, end)
528 replace the cmp() of python2
536 def Arc(self, cx, cy, sx, sy, angle):
538 Draw an arc based on centre, start and angle
540 The transform matrix
is applied
542 Note that this won
't work properly if the result is not a
543 circular arc (e.g. a horizontal scale)
545 @param cx: the x coordinate of the arc centre
546 @param cy: the y coordinate of the arc centre
547 @param sx: the x coordinate of the arc start point
548 @param sy: the y coordinate of the arc start point
549 @param angle: the arc
's central angle (in deci-degrees)
552 arc.SetShape(pcbnew.SHAPE_T_ARC)
553 arc.SetWidth(self.dc['lineThickness'])
558 arc.SetLayer(self.
dc[
'layer'])
561 if self.
MyCmp(self.
dc[
'transform'][0], 0) != self.
MyCmp(self.
dc[
'transform'][4], 0):
564 arc.SetCenter(center)
566 arc.SetArcAngleAndEnd(angle,
True)
572 Draw a horizontal line from (x,y), rightwards
574 @param x: line start x coordinate
575 @param y: line start y coordinate
576 @param l: line length
578 self.Line(x, y, x + l, y)
582 Draw a vertical line from (x1,y1), downwards
584 @param x: line start x coordinate
585 @param y: line start y coordinate
586 @param l: line length
588 self.Line(x, y, x, y + l)
590 def Polyline(self, pts, mirrorX=None, mirrorY=None):
592 Draw a polyline, optionally mirroring around the given points
594 @param pts: list of polyline vertices (list of (x, y))
595 @param mirrorX: x coordinate of mirror point (
None for no x-flip)
596 @param mirrorY: y coordinate of mirror point (
None for no y-flip)
599 def _PolyLineInternal(pts):
603 for i
in range(0, len(pts) - 1):
604 self.
Line(pts[i][0], pts[i][1], pts[i+1][0], pts[i+1][1])
606 if mirrorX
is None and mirrorY
is None:
607 _PolyLineInternal(pts)
609 elif mirrorX
is not None and mirrorY
is not None:
611 _PolyLineInternal(pts)
614 elif mirrorX
is not None:
616 _PolyLineInternal(pts)
619 elif mirrorY
is not None:
621 _PolyLineInternal(pts)
626 Draw the module's reference as the given point.
628 The actual setting of the reference is not done
in this drawing
629 aid - that
is up to the wizard
631 @param x: the x position of the reference
632 @param y: the y position of the reference
633 @param size: the text size (
in both directions)
634 @param orientation_degree: text orientation
in degrees
645 def Value(self, x, y, size, orientation_degree=0):
647 As for references, draw the module
's value
649 @param x: the x position of the value
650 @param y: the y position of the value
651 @param size: the text size (
in both directions)
652 @param orientation_degree: text orientation
in degrees
662 def Box(self, x, y, w, h):
664 Draw a rectangular box, centred at (x,y), with given width
and
667 @param x: the x coordinate of the box
's centre
668 @param y: the y coordinate of the box
's centre
669 @param w: the width of the box
670 @param h: the height of the box
673 pts = [[x - w/2, y - h/2],
683 Circle radius r centred at (x, y) with a raised
or depressed notch
685 Notch height
is measured
from the top of the circle radius
687 @param x: the x coordinate of the circle
's centre
688 @param y: the y coordinate of the circle
's centre
689 @param r: the radius of the circle
690 @param notch_w: the width of the notch
691 @param notch_h: the height of the notch
692 @param rotate: the rotation of the whole figure,
in degrees
698 angle_intercept = math.asin(notch_w/(2 * r))
701 sx = math.sin(angle_intercept) * r
702 sy = -math.cos(angle_intercept) * r
705 arc_angle = (math.pi * 2 - angle_intercept * 2) * (1800/math.pi)
707 self.
Arc(x, y, sx, sy, arc_angle)
719 Draw a box with a notch
in the centre of the top edge
721 @param x: the x coordinate of the circle
's centre
722 @param y: the y coordinate of the circle
's centre
723 @param w: the width of the box
724 @param h: the height of the box
725 @param notchW: the width of the notch
726 @param notchH: the height of the notch
727 @param rotate: the rotation of the whole figure,
in degrees
733 notchW = min(x + w/2, notchW)
743 (notchW/2, y - h/2 + notchH),
744 (-notchW/2, y - h/2 + notchH),
745 (-notchW/2, y - h/2),
752 setback=pcbnew.FromMM(1.27), flip=flipNone):
754 Draw a box with a diagonal at the top left corner.
756 @param x: the x coordinate of the circle
's centre
757 @param y: the y coordinate of the circle
's centre
758 @param w: the width of the box
759 @param h: the height of the box
760 @param setback: the set-back of the diagonal,
in both x
and y
761 @param flip: one of flipNone, flipX, flipY
or flipBoth to change the
767 pts = [[x - w/2 + setback, y - h/2],
768 [x - w/2, y - h/2 + setback],
772 [x - w/2 + setback, y - h/2]]
779 setback=pcbnew.FromMM(1.27), flip=flipNone):
781 Draw a box with an opening at the top left corner
783 @param x: the x coordinate of the circle
's centre
784 @param y: the y coordinate of the circle
's centre
785 @param w: the width of the box
786 @param h: the height of the box
787 @param setback: the set-back of the opening,
in both x
and y
788 @param flip: one of flipNone, flipX, flipY
or flipBoth to change the
795 pts = [[- w/2, - h/2 + setback],
799 [- w/2 + setback, - h/2]]
807 Draw a box with rounded corners (i.e. a 90-degree circular arc)
809 :param x: the x coordinate of the box
's centre
810 :param y: the y coordinate of the box's centre
811 :param w: the width of the box
812 :param h: the height of the box
813 :param rad: the radius of the corner rounds
816 x_inner = w - rad * 2
817 y_inner = h - rad * 2
823 self.
HLine(x_left + rad, y_top, x_inner)
824 self.
HLine(x_left + rad, -y_top, x_inner)
826 self.
VLine(x_left, y_top + rad, y_inner)
827 self.
VLine(-x_left, y_top + rad, y_inner)
835 self.
Arc(+cx, +cy, +x_left, +cy, +ninety_deg)
836 self.
Arc(-cx, +cy, -x_left, +cy, -ninety_deg)
837 self.
Arc(+cx, -cy, +x_left, -cy, -ninety_deg)
838 self.
Arc(-cx, -cy, -x_left, -cy, +ninety_deg)
842 Draw a box with chamfered corners.
844 :param x: the x coordinate of the box
's centre
845 :param y: the y coordinate of the box's centre
846 :param w: the width of the box
847 :param h: the height of the box
848 :param chamfer_x: the size of the chamfer set-back in the x direction
849 :param chamfer_y: the size of the chamfer set-back
in the y direction
856 x_inner = x_left + chamfer_x
857 y_inner = y_top + chamfer_y
873 def MarkerArrow(self, x, y, direction=dirN, width=pcbnew.FromMM(1)):
875 Draw a marker arrow facing in the given direction,
with the
878 @param x: x position of the arrow tip
879 @param y: y position of the arrow tip
880 @param direction: arrow direction
in degrees (0
is "north", can use
882 @param width: arrow width
889 [width / 2, width / 2],
890 [-width / 2, width / 2],