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'] = []
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
643 def Value(self, x, y, size, orientation_degree=0):
645 As for references, draw the module
's value
647 @param x: the x position of the value
648 @param y: the y position of the value
649 @param size: the text size (
in both directions)
650 @param orientation_degree: text orientation
in degrees
659 def Box(self, x, y, w, h):
661 Draw a rectangular box, centred at (x,y), with given width
and
664 @param x: the x coordinate of the box
's centre
665 @param y: the y coordinate of the box
's centre
666 @param w: the width of the box
667 @param h: the height of the box
670 pts = [[x - w/2, y - h/2],
680 Circle radius r centred at (x, y) with a raised
or depressed notch
682 Notch height
is measured
from the top of the circle radius
684 @param x: the x coordinate of the circle
's centre
685 @param y: the y coordinate of the circle
's centre
686 @param r: the radius of the circle
687 @param notch_w: the width of the notch
688 @param notch_h: the height of the notch
689 @param rotate: the rotation of the whole figure,
in degrees
695 angle_intercept = math.asin(notch_w/(2 * r))
698 sx = math.sin(angle_intercept) * r
699 sy = -math.cos(angle_intercept) * r
702 arc_angle = (math.pi * 2 - angle_intercept * 2) * (1800/math.pi)
704 self.
Arc(x, y, sx, sy, arc_angle)
716 Draw a box with a notch
in the centre of the top edge
718 @param x: the x coordinate of the circle
's centre
719 @param y: the y coordinate of the circle
's centre
720 @param w: the width of the box
721 @param h: the height of the box
722 @param notchW: the width of the notch
723 @param notchH: the height of the notch
724 @param rotate: the rotation of the whole figure,
in degrees
730 notchW = min(x + w/2, notchW)
740 (notchW/2, y - h/2 + notchH),
741 (-notchW/2, y - h/2 + notchH),
742 (-notchW/2, y - h/2),
749 setback=pcbnew.FromMM(1.27), flip=flipNone):
751 Draw a box with a diagonal at the top left corner.
753 @param x: the x coordinate of the circle
's centre
754 @param y: the y coordinate of the circle
's centre
755 @param w: the width of the box
756 @param h: the height of the box
757 @param setback: the set-back of the diagonal,
in both x
and y
758 @param flip: one of flipNone, flipX, flipY
or flipBoth to change the
764 pts = [[x - w/2 + setback, y - h/2],
765 [x - w/2, y - h/2 + setback],
769 [x - w/2 + setback, y - h/2]]
776 setback=pcbnew.FromMM(1.27), flip=flipNone):
778 Draw a box with an opening at the top left corner
780 @param x: the x coordinate of the circle
's centre
781 @param y: the y coordinate of the circle
's centre
782 @param w: the width of the box
783 @param h: the height of the box
784 @param setback: the set-back of the opening,
in both x
and y
785 @param flip: one of flipNone, flipX, flipY
or flipBoth to change the
792 pts = [[- w/2, - h/2 + setback],
796 [- w/2 + setback, - h/2]]
804 Draw a box with rounded corners (i.e. a 90-degree circular arc)
806 :param x: the x coordinate of the box
's centre
807 :param y: the y coordinate of the box's centre
808 :param w: the width of the box
809 :param h: the height of the box
810 :param rad: the radius of the corner rounds
813 x_inner = w - rad * 2
814 y_inner = h - rad * 2
820 self.
HLine(x_left + rad, y_top, x_inner)
821 self.
HLine(x_left + rad, -y_top, x_inner)
823 self.
VLine(x_left, y_top + rad, y_inner)
824 self.
VLine(-x_left, y_top + rad, y_inner)
832 self.
Arc(+cx, +cy, +x_left, +cy, +ninety_deg)
833 self.
Arc(-cx, +cy, -x_left, +cy, -ninety_deg)
834 self.
Arc(+cx, -cy, +x_left, -cy, -ninety_deg)
835 self.
Arc(-cx, -cy, -x_left, -cy, +ninety_deg)
839 Draw a box with chamfered corners.
841 :param x: the x coordinate of the box
's centre
842 :param y: the y coordinate of the box's centre
843 :param w: the width of the box
844 :param h: the height of the box
845 :param chamfer_x: the size of the chamfer set-back in the x direction
846 :param chamfer_y: the size of the chamfer set-back
in the y direction
853 x_inner = x_left + chamfer_x
854 y_inner = y_top + chamfer_y
870 def MarkerArrow(self, x, y, direction=dirN, width=pcbnew.FromMM(1)):
872 Draw a marker arrow facing in the given direction,
with the
875 @param x: x position of the arrow tip
876 @param y: y position of the arrow tip
877 @param direction: arrow direction
in degrees (0
is "north", can use
879 @param width: arrow width
886 [width / 2, width / 2],
887 [-width / 2, width / 2],