def testGeometryTransformation_applyremove_context(self): """Transformation._(apply|remove)_context""" def T(t, context, expected): elem = Element() elem.transform = context got = t._apply_context(context) self.assert_( repr(expected) == repr(got), 'apply_context - got: %s expected: %s' % (got, expected)) got = got._remove_context(context) expected = t self.assert_( repr(expected) == repr(got), 'apply_context - got: %s expected: %s' % (got, expected)) class e(object): def __init__(self, transform): self.transform = transform self._transform_real = transform T(Transformation(), e(Transformation()), Transformation()) T(Transformation(), e(Translation(V(1, 1))), Translation(V(1, 1))) T(Translation(V(-1, -1)), e(Translation(V(1, 1))), Transformation())
def testGeometryTransformation(self): """Transformation class""" def T(x): self.assert_(x) a = Transformation() T((a(V(5, 6.6)) == V(5, 6.6)).all())
def gen_pad_shape(dia, id, layer=None): if self.square: r = dia / 2 return Polygon(ext=(V(-r, -r), V(r, -r), V(r, r), V(-r, r)), id=id, layer=layer) else: return Circle(dia=dia, id=id, layer=layer)
def testV(self): """V class""" def T(x): self.assert_(x) v = V(5,6.6) T((v == V(5,6.6)).all()) T((v + v == V(10,13.2)).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 testVrepr(self): """repr(V)""" def T(v): v2 = eval(repr(v)) self.assert_(isinstance(v2,V)) self.assert_((v == v2).all()) T(V(0,0)) T(V(1,2)) T(V(1.0,2)) T(V(1.1,2))
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 from_ab(self, thickness, id, layer=None): """Returns a box generated from a,b with a given thickness. For makng pads, clearances etc. """ return Polygon(ext=(V(self.a[0] - thickness / 2, self.a[1] - thickness / 2), V(self.b[0] + thickness / 2, self.b[1] - thickness / 2), V(self.b[0] + thickness / 2, self.b[1] + thickness / 2), V(self.a[0] - thickness / 2, self.a[1] + thickness / 2)), id=id, layer=layer)
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 testVslice(self): """V[] reprs to matrix""" v = V(5,6) vs = v[0:,0] self.assert_(repr(vs) == 'matrix([[ 5.]])')
def centerof(e): """Calculate the center of an element. Basically just applies the elements transform to V(0,0) and returns. """ try: return e.transform(V(0,0)) except AttributeError: raise TypeError, "Can't take the centerof(%s)" % repr(e)
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 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 arc_points(a,b,r,segments): """Approximates an arc from a to b with a given radius and a specified number of segments. Returns a tuple of vertexes.""" assert(segments > 0) assert(a != b) assert(r) t = [] i = a for j in range(segments + 1): t += [V(cos(i) * r,sin(i) * r)] i += abs(b - a) / segments return t
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 testGeometryTransformation_build_context(self): """Transformation._build_context()""" def T(got, expected=True): self.assert_( repr(expected) == repr(got), 'got: %s expected: %s' % (got, expected)) T(Transformation()._build_context(Transformation(), False), Transformation()) T(Transformation()._build_context(Transformation(), True), Transformation()) T(Transformation()._build_context(Translation(V(1, 1)), False), Translation(V(1, 1))) T( Translation(V(1, 1))._build_context(Transformation(), True), Translation(V(-1, -1))) T( Translation(V(1, 1))._build_context(Translation(V(1, 1)), True), Transformation())
def test_make_line_vertexes(self): """geometry.line.make_line_vertexes()""" def T(a,b,thickness,segments,expected): v = make_line_vertexes(a,b,thickness,segments) self.assert_(common.vert_equal(v,expected)) # horizontal T(V(0,0),V(1,0),1,2, (V(0,0.5),V(-0.5,0),V(0,-0.5), V(1,-0.5),V(1.5,0),V(1,0.5))) T(V(1,0),V(0,0),1,2, (V(1,-0.5),V(1.5,0),V(1,+0.5), V(0,+0.5),V(-0.5,0),V(0,-0.5))) # vertical T(V(0,0),V(0,1),1,2, (V(-0.5,0),V(0,-0.5),V(+0.5,0), V(+0.5,1),V(0,+1.5),V(-0.5,1))) T(V(0,1),V(0,0),1,2, (V(+0.5,1),V(0,+1.5),V(-0.5,1), V(-0.5,0),V(0,-0.5),V(+0.5,0))) # 45degree diag # width is set such that everything ends up on even multiples T(V(0,0),V(1,1),sqrt(1+1),2, (V(-0.5,+0.5),V(-0.5,-0.5),V(+0.5,-0.5), V(+1.5,+0.5),V(+1.5,+1.5),V(+0.5,+1.5))) # point case should give a circle T(V(0,0),V(0,0),1,2, (V(+0.0,+0.5),V(-0.5,+0.0),V(+0.0,-0.5), V(+0.0,-0.5),V(+0.5,+0.0),V(+0.0,+0.5)))
def testThinLine(self): """geometry.ThinLine""" p = ThinLine(a=V(-10,2.5),b=V(34,4.3),thickness=2.2,layer='foo') self.assert_(p.render())
def testVert_equal(self): """vert_equal()""" from Tuke.geometry import V def T(a,b): self.assert_(common.vert_equal(a,b)) def F(a,b): self.assert_(not common.vert_equal(a,b)) # Test our new comparison function T((V(0,0),V(1,1)),(V(0,0),V(1,1))) F((V(1,0),V(1,1)),(V(0,0),V(1,1))) F((V(0,0),V(1,0)),(V(0,0),V(1,1))) # extra items must fail F((V(0,0),V(1,0)),(V(0,0),V(1,0),V(1,1)))
def testGeometryCircle_arc_points(self): """arc_points() utility function""" def T(a, b): self.assert_(common.vert_equal(a, b)) def F(a, b): self.assert_(not common.vert_equal(a, b)) # test arc_points() finally T(arc_points(0, pi, 1, 1), (V(1, 0), V(-1, 0))) T(arc_points(pi, 0, 1, 1), (V(-1, 0), V(1, 0))) # three points, note rotation is always anti-clockwise T(arc_points(0, pi, 1, 2), (V(1, 0), V(0, 1), V(-1, 0))) T(arc_points(pi, 0, 1, 2), (V(-1, 0), V(0, -1), V(1, 0))) # full circle T(arc_points(0, 2 * pi, 1, 4), (V(1, 0), V(0, 1), V(-1, 0), V(0, -1), V(1, 0))) T( arc_points(2 * pi, 0, 1, 4), # note same result as above (V(1, 0), V(0, 1), V(-1, 0), V(0, -1), V(1, 0))) T(arc_points(pi / 2, pi * 1.5, 0.5, 4), (V(0, 0.5), V(-cos(radians(45)) / 2, sin(radians(45)) / 2), V(-0.5, 0), V(-cos(radians(45)) / 2, -sin(radians(45)) / 2), V(0, -0.5)))
def testGeometrytranslate(self): """translate, rotate, rotate_around_center, scale""" def T(a, b, f, *args, **kwargs): """Element transform function test harness. Applies f(e,*args,**kwargs) to element e. Then applies e.transform to a and checks that the resulting vertex is == b. """ e = Element() f(e, *args, **kwargs) # The repr()-based comparison seems to avoid floating point # "almost" equal errors. self.assert_(repr(e.transform(a)) == repr(b)) T(V(2, 3), V(5, -1), translate, V(3, -4)) T(V(1, 1), V(-1, -1), rotate, pi) T(V(-1, 5), V(-2, 15), scale, V(2, 3)) T(V(1, 1), V(3, 3), rotate_around_center, pi, V(2, 2))
def testLine(self): """geometry.Line""" p = Line(a=V(-1,2),b=V(3,4),thickness=0.234,layer='foo') self.assert_(p.render())