def _init(self): assert not self.n % 2 # Generate the pins for i in xrange(self.n): square = False if i == 0: square = True p = Pin(dia=self.drill, thickness=self.pad, clearance=self.clearance, mask=self.mask, square=square, id='_' + str(i + 1)) x = None y = None height = (self.n / 2) * self.spacing if i < self.n / 2: x = -(self.width / 2) y = (-i * self.spacing) + (height / 2) - self.spacing / 2 else: x = self.width / 2 y = -((-(i - self.n / 2) * self.spacing) + (height / 2) - self.spacing / 2) translate(p,V(x,y)) self.add(p)
def test_centerof(self): """centerof()""" def T(a,b): self.assert_((a == b).all()) e = Element() T(centerof(e),V(0,0)) translate(e,V(1,2)) T(centerof(e),V(1,2)) self.assertRaises(TypeError,lambda: centerof(V(0,0))) self.assertRaises(TypeError,lambda: centerof(Transformation())) self.assertRaises(TypeError,lambda: centerof('asdf'))
def test_apply_remove_context(self): """V._(apply|remove)_context""" def T(got,expected = True): self.assert_(expected == got,'got: %s expected: %s' % (got,expected)) a = Element(id=Id('a')) b = Element(id=Id('b')) a.add(b) c = Element(id=Id('c')) a.b.add(c) a.v = V(1,1) c.v = V(1,1) translate(a.b,V(0,1)) translate(a.b.c,V(1,0)) T((a.b.c.v == V(2,2)).all()) # The added d element here is important. It's transform is null, so any # optimizations that skip applying null transforms will hopefully # trigger bugs here. # # Secondly, if we used c, it still has a transform applied to any # results from it. For instance with a.b.c as uc, uc.v == V(2,1) right # now. Confusing! d = Element(id=Id('d')) a.b.c.add(d) with a.b.c.d as ud: # The original vertex is at 1,1 The two translations moved by # center point by 0,1 then 1,0 totaling 1,1 so the result cancels # out to 0,0 T((ud[Id('../../')].v == V(0,0)).all()) rotate(a,pi / 2) T(repr(a.b.c.v),repr(V(2,-2))) with a.b.c.d as ud: # Even with the rotation, the translates still cancel out, why? # Because the whole stack above a was rotated, which isn't "seen" # from the perspective of the stack above a. T((ud[Id('../../')].v == V(0,0)).all())
def _init(self): top_leds = [] bottom_leds = [] def dt(a, b): t = self.add(Trace(thickness=20 * MIL)) t.set_endpoints(a, b) for x in xrange(self.cols): prev = None for y in xrange(self.rows): l = Led(id=Id('LED%s_%s' % (str(x), str(y)))) translate( l, V((x * self.spacing) - ((self.cols - 1) * self.spacing / 2), (y * self.spacing) - ((self.rows - 0) * self.spacing / 2))) l = self.add(l) if prev is None: top_leds.append(l) else: dt(prev.footprint._2, l.footprint._1) prev = l bottom_leds.append(prev) # Create offset points for the common anodes and cathodes. top_points = [] for t in top_leds: p = Point() translate(p, centerof(t.footprint._1) + V(0, -self.spacing / 2)) p = self.add(p) dt(t.footprint._1, p) top_points.append(p) bottom_points = [] for t in bottom_leds: p = Point() translate(p, centerof(t.footprint._2) + V(0, self.spacing / 2)) p = self.add(p) dt(t.footprint._2, p) bottom_points.append(p) # Link common anodes and cathodes p = None for i in top_points: if p is not None: dt(p, i) p = i p = None for i in bottom_points: if p is not None: dt(p, i) p = i
def testElementIterlayout(self): """Element.iterlayout()""" def T(got,expected = True): self.assert_(expected == got,'expected: %s got: %s' % (expected,got)) e = Element(id='base') e.add(Element(id='chip')) e.chip.add(Element(id='pad')) e.chip.add(Geometry(layer='sch.lines',id='sym')) e.chip.pad.add(Geometry(layer='top.copper',id='pad')) # Check returned objects and Id auto-mangling T(set([elem.id for elem in e.iterlayout()]), set((Id('base/chip/pad/pad'), Id('base/chip/sym')))) # Check that transforms are working translate(e.chip,V(1,1)) [T(repr(elem.transform), repr(Translation(V(1.0, 1.0)))) for elem in e.iterlayout()] translate(e.chip.pad,V(2,3)) r = {Id('base/chip/sym'):Translation(V(1.0, 1.0)), Id('base/chip/pad/pad'):Translation(V(3.0, 4.0))} for elem in e.iterlayout(): T(repr(r[elem.id]), repr(elem.transform)) # Check layer filtering works T(set([elem.id for elem in e.iterlayout(layer_mask='top.*')]), set((Id('base/chip/pad/pad'),))) T(set([elem.id for elem in e.iterlayout(layer_mask='sch.*')]), set((Id('base/chip/sym'),)))
def _init(self): top_leds = [] bottom_leds = [] def dt(a,b): t = self.add(Trace(thickness=20 * MIL)) t.set_endpoints(a,b) for x in xrange(self.cols): prev = None for y in xrange(self.rows): l = Led(id=Id('LED%s_%s' % (str(x),str(y)))) translate(l,V((x * self.spacing) - ((self.cols - 1) * self.spacing / 2), (y * self.spacing) - ((self.rows - 0) * self.spacing / 2))) l = self.add(l) if prev is None: top_leds.append(l) else: dt(prev.footprint._2,l.footprint._1) prev = l bottom_leds.append(prev) # Create offset points for the common anodes and cathodes. top_points = [] for t in top_leds: p = Point() translate(p,centerof(t.footprint._1) + V(0,-self.spacing / 2)) p = self.add(p) dt(t.footprint._1,p) top_points.append(p) bottom_points = [] for t in bottom_leds: p = Point() translate(p,centerof(t.footprint._2) + V(0,self.spacing / 2)) p = self.add(p) dt(t.footprint._2,p) bottom_points.append(p) # Link common anodes and cathodes p = None for i in top_points: if p is not None: dt(p,i) p = i p = None for i in bottom_points: if p is not None: dt(p,i) p = i
def testElementIdAttr(self): """Auto-magical attribute lookup from sub-element Id's""" a = Element(id=Id('a')) translate(a,V(1,1)) foo = Element(id=Id('foo')) translate(foo,V(2,1)) bar = Element(id=Id('bar')) translate(bar,V(1,2)) a.add(foo) a.add(bar) self.assert_(a.foo.id == Id('a/foo')) self.assert_(repr(centerof(a.foo)) == repr(V(3,2))) self.assert_(a.bar.id == Id('a/bar')) self.assert_(repr(centerof(a.bar)) == repr(V(2,3))) self.assertRaises(AttributeError,lambda: a.foobar) foo.foo = 'foo' self.assert_(a.foo.foo is foo.foo) a.foo.bar = 'bar' self.assert_(a.foo.bar is foo.bar)
def _init(self): f = open(self.file,"r") for l in f: l = l.strip() tag = re.findall(r'^(ElementArc|ElementLine|Element|Pin|Pad)',l) if len(tag): v = re.findall(r'\[.*\]',l) # FIXME: add detection for mil units in () brackets source_units = CMIL v = v[0][1:-1].split(' ') if tag[0] == 'Element': (element_flags,description,pcb_name,value,mark_x,mark_y,text_x,text_y,text_direction,text_scale,text_flags) = v mark_x = float(mark_x) mark_y = float(mark_y) text_x = float(text_x) text_y = float(text_y) mark_x *= source_units mark_y *= source_units text_x *= source_units text_y *= source_units # Base translation translate(self,V(mark_x,mark_y)) elif tag[0] == 'Pin': (x,y,thickness,clearance,mask,dia,name,pin_number,flags) = v x = float(x) * source_units y = float(y) * source_units thickness = float(thickness) * source_units clearance = float(clearance) * source_units mask = float(mask) * source_units dia = float(dia) * source_units # Pin() defines pad thickness as the thickness of the # metalization surrounding the hole. gEDA simply defines # thickness as diameter of the metal, convert. thickness = (thickness - dia) / 2 # gEDA defines clearance as the sum of both clearance # thicknesses, Pin() defines it as a single thickness, # convert clearance = clearance / 2 pin_number = Id('_' + pin_number[1:-1]) # remove quotes p = Pin(dia=dia, thickness=thickness, clearance=clearance, mask=mask, id=pin_number) translate(p,V(x,y)) self.add(p) elif tag[0] == 'Pad': (x1,y1,x2,y2,thickness,clearance,mask,name,pad_number,flags) = v x1 = float(x1) * source_units y1 = float(y1) * source_units x2 = float(x2) * source_units y2 = float(y2) * source_units thickness = float(thickness) * source_units clearance = float(clearance) * source_units mask = float(mask) * source_units # gEDA defines clearance as the sum of both clearance # thicknesses, Pin() defines it as a single thickness, # convert clearance = clearance / 2 pad_number = Id('_' + pad_number[1:-1]) # remove quotes p = Pad(a=(x1,y1),b=(x2,y2), thickness=thickness, clearance=clearance, mask=mask, id=pad_number) self.add(p)