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 wxPoint
440 mat = self.
dc[
'transform']
443 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 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 _PolyLineInternal(pts)
608 if mirrorX
is not None and mirrorY
is not None:
610 _PolyLineInternal(pts)
613 elif mirrorX
is not None:
615 _PolyLineInternal(pts)
618 elif mirrorY
is not None:
620 _PolyLineInternal(pts)
625 Draw the module's reference as the given point.
627 The actual setting of the reference is not done
in this drawing
628 aid - that
is up to the wizard
630 @param x: the x position of the reference
631 @param y: the y position of the reference
632 @param size: the text size (
in both directions)
633 @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
661 self.
module.
Value().SetTextAngle(orientation_degree * 10)
663 def Box(self, x, y, w, h):
665 Draw a rectangular box, centred at (x,y), with given width
and
668 @param x: the x coordinate of the box
's centre
669 @param y: the y coordinate of the box
's centre
670 @param w: the width of the box
671 @param h: the height of the box
674 pts = [[x - w/2, y - h/2],
684 Circle radius r centred at (x, y) with a raised
or depressed notch
686 Notch height
is measured
from the top of the circle radius
688 @param x: the x coordinate of the circle
's centre
689 @param y: the y coordinate of the circle
's centre
690 @param r: the radius of the circle
691 @param notch_w: the width of the notch
692 @param notch_h: the height of the notch
693 @param rotate: the rotation of the whole figure,
in degrees
699 angle_intercept = math.asin(notch_w/(2 * r))
702 sx = math.sin(angle_intercept) * r
703 sy = -math.cos(angle_intercept) * r
706 arc_angle = (math.pi * 2 - angle_intercept * 2) * (1800/math.pi)
708 self.
Arc(x, y, sx, sy, arc_angle)
720 Draw a box with a notch
in the centre of the top edge
722 @param x: the x coordinate of the circle
's centre
723 @param y: the y coordinate of the circle
's centre
724 @param w: the width of the box
725 @param h: the height of the box
726 @param notchW: the width of the notch
727 @param notchH: the height of the notch
728 @param rotate: the rotation of the whole figure,
in degrees
734 notchW = min(x + w/2, notchW)
744 (notchW/2, y - h/2 + notchH),
745 (-notchW/2, y - h/2 + notchH),
746 (-notchW/2, y - h/2),
753 setback=pcbnew.FromMM(1.27), flip=flipNone):
755 Draw a box with a diagonal at the top left corner.
757 @param x: the x coordinate of the circle
's centre
758 @param y: the y coordinate of the circle
's centre
759 @param w: the width of the box
760 @param h: the height of the box
761 @param setback: the set-back of the diagonal,
in both x
and y
762 @param flip: one of flipNone, flipX, flipY
or flipBoth to change the
768 pts = [[x - w/2 + setback, y - h/2],
769 [x - w/2, y - h/2 + setback],
773 [x - w/2 + setback, y - h/2]]
780 setback=pcbnew.FromMM(1.27), flip=flipNone):
782 Draw a box with an opening at the top left corner
784 @param x: the x coordinate of the circle
's centre
785 @param y: the y coordinate of the circle
's centre
786 @param w: the width of the box
787 @param h: the height of the box
788 @param setback: the set-back of the opening,
in both x
and y
789 @param flip: one of flipNone, flipX, flipY
or flipBoth to change the
796 pts = [[- w/2, - h/2 + setback],
800 [- w/2 + setback, - h/2]]
808 Draw a box with rounded corners (i.e. a 90-degree circular arc)
810 :param x: the x coordinate of the box
's centre
811 :param y: the y coordinate of the box's centre
812 :param w: the width of the box
813 :param h: the height of the box
814 :param rad: the radius of the corner rounds
817 x_inner = w - rad * 2
818 y_inner = h - rad * 2
824 self.
HLine(x_left + rad, y_top, x_inner)
825 self.
HLine(x_left + rad, -y_top, x_inner)
827 self.
VLine(x_left, y_top + rad, y_inner)
828 self.
VLine(-x_left, y_top + rad, y_inner)
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)
839 self.
Arc(-cx, -cy, -x_left, -cy, +ninety_deg)
843 Draw a box with chamfered corners.
845 :param x: the x coordinate of the box
's centre
846 :param y: the y coordinate of the box's centre
847 :param w: the width of the box
848 :param h: the height of the box
849 :param chamfer_x: the size of the chamfer set-back in the x direction
850 :param chamfer_y: the size of the chamfer set-back
in the y direction
857 x_inner = x_left + chamfer_x
858 y_inner = y_top + chamfer_y
874 def MarkerArrow(self, x, y, direction=dirN, width=pcbnew.FromMM(1)):
876 Draw a marker arrow facing in the given direction,
with the
879 @param x: x position of the arrow tip
880 @param y: y position of the arrow tip
881 @param direction: arrow direction
in degrees (0
is "north", can use
883 @param width: arrow width
890 [width / 2, width / 2],
891 [-width / 2, width / 2],