def updated(self, ep): if self.p1_point.is_set: if self.p_bottom_corner.is_set: v = (self.p_bottom_corner.get() - self.p1_point.get()) mag = v.mag() v = v.norm() self._cmodel.theta = v.angle() self._model.pin_spacing = mag / (self._model.side1_pins - 1) self.v_base = Vec2.from_polar(self._cmodel.theta, 1) self.v_vert = Vec2(-self.v_base.y, self.v_base.x).norm() p_edge_center = self.v_base * self._model.pin_spacing * ( self._model.side1_pins - 1) / 2 if self.p_side_3_1.is_set: dv = self.p_side_3_1.get() - self.p1_point.get() v, _ = project_point_line(dv, Point2(0, 0), self.v_vert, False) self._model.dim_2_pincenter = v.mag() self._cmodel.center = self.v_vert * self._model.dim_2_pincenter / 2 + p_edge_center + self.p1_point.get( ) if self.p_side_2_1.is_set: v, _ = project_point_line( self.p_side_2_1.get() - self._cmodel.center, Point2(0, 0), self.v_base, False) self._model.dim_1_pincenter = v.mag() * 2
def test_keyPointCreation(self): p = self.p il1 = IL.ImageLayer(name="foo", data=bytes()) il2 = IL.ImageLayer(name="bar", data=bytes()) p.imagery.add_imagelayer(il1) p.imagery.add_imagelayer(il2) kp1 = IL.KeyPoint(Point2(5, 5)) kp2 = IL.KeyPoint(Point2(10, 20)) p.imagery.add_keypoint(kp1) p.imagery.add_keypoint(kp2) # Verify that keypoint indicies are working as expected self.assertEqual(kp1.index, 0) self.assertEqual(kp2.index, 1) # al = KeyPointAlignment() il1.set_alignment(al) al.set_keypoint_position(kp1, Point2(0, 2)) kp_set = il1.alignment.keypoint_positions kpp0 = list(kp_set)[0] self.assertEqual(kpp0.key_point, kp1) eps = numpy.absolute(kpp0.image_pos - Point2(0, 2)).max() self.assertLess(eps, 0.0000001) al.remove_keypoint(kp1) self.assertEqual(len(kp_set), 0)
def test_vias(self): p = self.__setup_via_pairs_layers() n1 = Net() p.nets.add_net(n1) n2 = Net() p.nets.add_net(n2) v = Via(Point2(3700, 2100), p.stackup.via_pairs[0], 31337, n1) v2 = Via(Point2(1234, 5678), p.stackup.via_pairs[1], 31339, n2) p.artwork.add_artwork(v) p.artwork.add_artwork(v2) p_new = self.__saverestore(p) v2_new = sorted(p_new.artwork.vias, key=lambda x: x.pt.x)[0] v_new = sorted(p_new.artwork.vias, key=lambda x: x.pt.x)[1] self.assertEqual(v_new._project, p_new) self.assertEqual(v2_new._project, p_new) for a, b in ((v, v_new), (v2, v2_new)): self.cmpMat(a.pt, b.pt) self.assertEqual(p.stackup.via_pairs.index(a.viapair), p_new.stackup.via_pairs.index(b.viapair)) self.assertEqual(a.r, b.r) self.assertEqual(p.nets.nets.index(a.net), p_new.nets.nets.index(b.net))
def test_airwires(self): p = self.__setup_via_pairs_layers() n1 = Net() p.nets.add_net(n1) v = Via(Point2(3700, 2100), p.stackup.via_pairs[0], 31337, n1) v2 = Via(Point2(1234, 5678), p.stackup.via_pairs[1], 31339, n1) airwire = Airwire(v.pt, v2.pt, v.viapair.layers[0], v2.viapair.layers[0], n1) p.artwork.add_artwork(v) p.artwork.add_artwork(v2) p.artwork.add_artwork(airwire) p_new = self.__saverestore(p) aw_new = list(p_new.artwork.airwires)[0] v2_new = sorted(p_new.artwork.vias, key=lambda x: x.pt.x)[0] v_new = sorted(p_new.artwork.vias, key=lambda x: x.pt.x)[1] self.cmpMat(aw_new.p0, airwire.p0) self.cmpMat(aw_new.p1, airwire.p1) self.assertEqual(aw_new.p0_layer, v_new.viapair.layers[0]) self.assertEqual(aw_new.p1_layer, v2_new.viapair.layers[0]) self.assertEqual(aw_new.net, v_new.net)
def test_sorted_query_regression(self): # Attempt to p = Project() l = Layer("t1", (1, 1, 1)) p.stackup.add_layer(l) cx = Point2(30000, 30000) ts = [] for i in range(100): r = 5000 - 40 * i r1 = 5000 - 40 * (i + 1) t = math.radians(30 * i) t1 = math.radians(30 * (i + 1)) v = Point2(math.cos(t) * r, math.sin(t) * r) v1 = Point2(math.cos(t1) * r1, math.sin(t1) * r1) t1 = Trace(v + cx, v1 + cx, 100, l) t1.STUFFED_ID = i p.artwork.merge_artwork(t1) ts.append(t1) t0 = ts[0] for n, a in enumerate(ts[1:], start=1): self.assertEqual(t0.net, a.net, "mismatch on %d" % n) self.assertIsNotNone(t0.net) p.save('/tmp/wtf.pcbre', False)
def test_keypoints(self): p = self.setup_i3() kp1 = KeyPoint(Point2(3,6)) kp2 = KeyPoint(Point2(5,5)) p.imagery.add_keypoint(kp1) p.imagery.add_keypoint(kp2) align = KeyPointAlignment() p.imagery.imagelayers[0].set_alignment(align) align.set_keypoint_position(kp1, Point2(-7,13)) align.set_keypoint_position(kp2, Point2(4, 5)) p_new = self.__saverestore(p) # Verify Keypoints saved/restored self.assertEqual(len(p_new.imagery.keypoints), len(p.imagery.keypoints)) for kp_old, kp_new in zip(p.imagery.keypoints, p_new.imagery.keypoints): self.check_obj(p_new, kp_new, kp_old) self.cmpMat(kp_new.world_position, kp_old.world_position) # Verify object align makes it through il_0_new = p_new.imagery.imagelayers[0] self.assertIsInstance(il_0_new.alignment, KeyPointAlignment) al = il_0_new.alignment new_kpl = sorted(al.keypoint_positions, key=lambda x: x.key_point.world_position.x) old_kpl = sorted(align.keypoint_positions, key=lambda x: x.key_point.world_position.x) self.cmpMat(new_kpl[0].image_pos, old_kpl[0].image_pos) self.cmpMat(new_kpl[1].image_pos, old_kpl[1].image_pos)
def render(self, mat, pad, render_mode=RENDER_STANDARD, render_hint=RENDER_HINT_NORMAL): """ :type pad: Pad :param mat: :param pad: :return: """ textcol = self.parent.text_color() textcol_a = textcol + [1] color = self.parent.color_for_pad(pad) color_a = color + [1] if render_mode & RENDER_SELECTED: color_a = [1, 1, 1, 1] if pad.is_through(): self.parent.via_renderer.deferred(pad.center, pad.l / 2, pad.th_diam / 2, render_mode, render_hint) r = Rect.fromCenterSize(Point2(0, 0), pad.l * 0.6, pad.w * 0.6) _text_to(self.view, pad, r, mat, textcol_a) else: t = pad.trace_repr self.parent.trace_renderer.deferred(t, render_mode, render_hint) r = Rect.fromCenterSize(Point2(0, 0), pad.l * 0.8, pad.w * 0.8) _text_to(self.view, pad, r, mat, textcol_a)
def __add(self, polygon): tris = polygon.get_tris_repr() tri_index_first = len(self.__tri_index_list) for t in tris: for p in t.a, t.b, t.c: self.__tri_index_list.append( self.__get_position_index(Point2(p.x, p.y))) tr = (tri_index_first, len(self.__tri_index_list)) self.__tri_draw_ranges[polygon] = tr outline_index_first = len(self.__outline_index_list) poly_repr = polygon.get_poly_repr() for edge in [poly_repr.exterior] + list(poly_repr.interiors): for pt in edge.coords: self.__outline_index_list.append( self.__get_position_index(Point2(pt))) self.__outline_index_list.append(self.__RESTART_INDEX) lr = (outline_index_first, len(self.__outline_index_list)) self.__outline_draw_ranges[polygon] = lr self.__index_vbo_current = False return tr, lr
def setUp(self): world = Project() for i in range(4): world.stackup.add_layer(Layer("l%d" % i, None)) world.stackup.add_via_pair( ViaPair(world.stackup.layers[0], world.stackup.layers[1])) world.stackup.add_via_pair( ViaPair(world.stackup.layers[2], world.stackup.layers[3])) world.stackup.add_via_pair( ViaPair(world.stackup.layers[0], world.stackup.layers[3])) world.stackup.add_via_pair( ViaPair(world.stackup.layers[1], world.stackup.layers[2])) # 0 1 2 3 # 0 x x x # 1 x x x # 2 x x x x # 3 x x x x n1 = Net() n2 = Net() world.nets.add_net(n1) world.nets.add_net(n2) self.v1 = Via(Point2(3, 3), world.stackup.via_pairs[0], 2, n1) world.artwork.add_artwork(self.v1) self.v2 = Via(Point2(11, 11), world.stackup.via_pairs[1], 2, n2) world.artwork.add_artwork(self.v2) self.world = world
def test_trace(self): p = self.__setup_via_pairs_layers() n1 = Net() p.nets.add_net(n1) n2 = Net() p.nets.add_net(n2) t1 = Trace(Point2(61, -300), Point2(848, 1300), 775, p.stackup.layers[0], n1) t2 = Trace(Point2(1234, 5678), Point2(90210, 84863), 775, p.stackup.layers[0], n2) p.artwork.add_artwork(t1) p.artwork.add_artwork(t2) self.assertEqual(t1._project, p) p_new = self.__saverestore(p) self.assertEqual(len(p_new.artwork.traces), 2) self.assertIs(list(p_new.artwork.traces)[0]._project, p_new) # Walk ordered traces l_old = sorted(p.artwork.traces, key=lambda x: x.p0.x) l_new = sorted(p_new.artwork.traces, key=lambda x: x.p0.x) for t_old, t_new in zip(l_old, l_new): self.cmpMat(t_old.p0, t_new.p0) self.cmpMat(t_old.p1, t_new.p1) self.assertEqual(t_old.thickness, t_new.thickness) # Check links to layer object and net object are restored self.assertEqual(p.nets.nets.index(t_old.net), p_new.nets.nets.index(t_new.net)) self.assertEqual(p.stackup.layers.index(t_old.layer), p_new.stackup.layers.index(t_new.layer))
def test_connected_island(self): self.world.artwork.merge_artwork( Trace(Point2(3, 3), Point2(11, 11), 3, self.world.stackup.layers[0])) connected = self.world.artwork.compute_connected( self.world.artwork.get_all_artwork()) self.assertEqual(len(connected), 2)
def __init__(self, view, model): self._model = model self.p1_point = EditablePoint(Point2(0, 0)) self.__theta = 0 self.__corner = Point2(0, 0) rmat = rotate(self.theta) dy = -(model.pin_count / 2 - 1) * model.pin_space v_aligned = Vec2(0, dy) v_delta = projectPoint(rmat, v_aligned) # the pin on the end of the same row as P1 self.p_bottom_corner = OffsetDefaultPoint(self.p1_point, v_delta) # Opposite corner point self.p_opposite = WidthProjectedPoint(self) points = [self.p1_point, self.p_bottom_corner, self.p_opposite] super(DIPEditFlow, self).__init__(view, points, True) if self.view.viewState.current_layer is None: self.side = SIDE.Top else: self.side = self.view.viewState.current_layer.side self.update_matrix()
def mouseMoveEvent(self, event): if self.lastPoint is None: self.lastPoint = event.pos() return delta_px = event.pos() - self.lastPoint lastpoint_real = self.viewState.tfV2P(Point2(self.lastPoint)) newpoint_real = self.viewState.tfV2P(Point2(event.pos())) lx,ly = lastpoint_real nx,ny = newpoint_real delta = nx-lx, ny-ly self.lastPoint = event.pos() needs_update = False if (event.buttons() & MOVE_MOUSE_BUTTON) and self.move_dragging: self.move_dragged = True self.viewState.transform = M.translate(*delta).dot(self.viewState.transform) needs_update = True elif (event.buttons() & QtCore.Qt.MiddleButton): delta = -10 * delta_px.y() self.wheelEvent(QtGui.QWheelEvent(event.pos(),delta, event.buttons(), event.modifiers())) needs_update = True elif not self.move_dragging and not self.mwemu: if self.interactionDelegate is not None: self.interactionDelegate.mouseMoveEvent(event) needs_update = True if needs_update: self.update()
def mousePressEvent(self, evt): pos = evt.pos() pt = Point2(self.view.viewState.tfV2W(Point2(pos))) g = self.view.query_point(pt) if g: dlg = NetDialog(self.view.project, self.view, g) dlg.exec_()
def mousePressEvent(self, evt): pt_screen = Point2(evt.pos()) pt_world = Point2(self.view.viewState.tfV2W(pt_screen)) # New object with dummy net if self.toolparammodel.current_layer_pair is not None: v = Via(pt_world, self.toolparammodel.current_layer_pair, self.toolparammodel.radius, None) self.project.artwork.merge_artwork(v)
def im2V(self, pt): """Translate normalized image coordinates to viewport coordinates. If in align mode, normalized-image coords == world coordinates""" pt = Point2(pt) if self.model.view_mode == 0: self._parent.il.p2n(pt) return Point2(vs.tfW2V(pt))
def serialize(self) -> ser.Artwork.Builder: _aw = ser.Artwork.new_message() _aw.init("vias", len(self.vias)) _aw.init("traces", len(self.traces)) _aw.init("polygons", len(self.polygons)) _aw.init("components", len(self.components)) _aw.init("airwires", len(self.airwires)) # Serialization done here to reduce instance size for n, i_via in enumerate(self.vias): v = _aw.vias[n] v.point = serialize_point2(i_via.pt) v.r = i_via.r v.viapairSid = self.__project.scontext.sid_for(i_via.viapair) v.netSid = self.__project.scontext.sid_for(i_via.net) # for n, i_trace in enumerate(self.traces): t = _aw.traces[n] t.p0 = serialize_point2(i_trace.p0) t.p1 = serialize_point2(i_trace.p1) t.thickness = int(i_trace.thickness) t.netSid = self.__project.scontext.sid_for(i_trace.net) t.layerSid = self.__project.scontext.sid_for(i_trace.layer) for n, i_comp in enumerate(self.components): t = _aw.components[n] i_comp._serializeTo(t) for n, i_poly in enumerate(self.polygons): p = _aw.polygons[n] p_repr = i_poly.get_poly_repr() p.init("exterior", len(p_repr.exterior.coords)) for nn, ii in enumerate(p_repr.exterior.coords): p.exterior[nn] = serialize_point2(Point2(ii.x, ii.y)) p.init("interiors", len(p_repr.interiors)) for n_interior, interior in enumerate(p_repr.interiors): p.interiors.init(n_interior, len(interior.coords)) for nn, ii in enumerate(interior.coords): p.interiors[n_interior][nn] = serialize_point2( Point2(ii.x, ii.y)) p.layerSid = self.__project.scontext.sid_for(i_poly.layer) p.netSid = self.__project.scontext.sid_for(i_poly.net) for n, i_ in enumerate(self.airwires): t = _aw.airwires[n] t.p0 = serialize_point2(i_.p0) t.p1 = serialize_point2(i_.p1) t.netSid = self.__project.scontext.sid_for(i_.net) t.p0LayerSid = self.__project.scontext.sid_for(i_.p0_layer) t.p1LayerSid = self.__project.scontext.sid_for(i_.p1_layer) return _aw
def get_tris_repr(self): if self.__triangulation is None: cdt = p2t.CDT( [Point2(*i) for i in self.__geometry.exterior.coords[:-1]]) for interior in self.__geometry.interiors: cdt.add_hole([Point2(*i) for i in interior.coords[:-1]]) self.__triangulation = cdt.triangulate() return self.__triangulation
def test_via_via(self): class FakeVP(): @property def all_layers(self): return [1] vp = FakeVP() v = Via(Point2(7, 13), vp, 3, None) v1 = Via(Point2(-5, 6), vp, 7, None) self.assertAlmostEqual((12**2 + 7**2)**0.5 - 10, dist_via_via(v, v1))
def test_remove_other_ep(self): airwire = Airwire(Point2(200, 201), Point2(50, 7000), self.top_layer, self.bottom_layer, None) self.p.artwork.merge_artwork(airwire) self.assertIn(airwire, self.p.artwork.airwires) self.p.artwork.remove_artwork(self.trace_bot) # Removal of endpoint geom should result in removal of airwire self.assertNotIn(airwire, self.p.artwork.airwires)
def V2im(self, pt): pt = Point2(pt) world = Point2(self.vs.tfV2W(pt)) if self.model.view_mode == 0: im = self._parent.il.n2p(world) else: im = world return im
def setUp(self): from test.common import setup2Layer setup2Layer(self) self.trace_top = Trace(Point2(50, 50), Point2(7000, 7000), 10, self.top_layer) self.trace_bot = Trace(Point2(7000, 50), Point2(50, 7000), 10, self.bottom_layer) self.p.artwork.merge_artwork(self.trace_top) self.p.artwork.merge_artwork(self.trace_bot) self.assertNotEqual(self.trace_top.net, self.trace_bot.net)
def test_basic_join(self): airwire = Airwire(Point2(200, 201), Point2(51, 7000), self.top_layer, self.bottom_layer, None) self.p.artwork.merge_artwork(airwire) # Validate airwire addition causes add self.assertEqual(self.trace_top.net, self.trace_bot.net) self.assertEqual(self.trace_top.net, airwire.net) self.p.artwork.remove_artwork(airwire) # Validate airwire removal causes unjoin self.assertNotEqual(self.trace_top.net, self.trace_bot.net)
def test_via_query_intersect_pass_distance(self): # Inclusive viapair v = Via(Point2(7, 7), self.world.stackup.via_pairs[2], 4, None) self.assertEqual(len(self.world.artwork.query_intersect(v)), 2) # Overlapping v = Via(Point2(7, 7), self.world.stackup.via_pairs[3], 4, None) self.assertEqual(len(self.world.artwork.query_intersect(v)), 2) # Only one via should overlap v = Via(Point2(7, 7), self.world.stackup.via_pairs[0], 4, None) self.assertEqual(len(self.world.artwork.query_intersect(v)), 1)
def __get_unrot_trace_points(self): if self.l > self.w: l = self.l - self.w w = self.w p0 = Point2(l / 2, 0) p1 = Point2(-l / 2, 0) else: l = self.w - self.l w = self.l p0 = Point2(0, l / 2) p1 = Point2(0, -l / 2) return w, p0, p1
def __get_unrot_trace_points(self) -> Tuple[float, Vec2, Vec2]: if self.length > self.width: length = self.length - self.width width = self.width p0 = Point2(length / 2, 0) p1 = Point2(-length / 2, 0) else: length = self.width - self.length width = self.length p0 = Point2(0, length / 2) p1 = Point2(0, -length / 2) return width, p0, p1
def __init__(self, layer, exterior, interiors=[], net=None): # Buffer 0 forces geom cleanup self.__geometry = ShapelyPolygon(exterior, interiors).buffer(0) minx, miny, maxx, maxy = self.__geometry.bounds self.bbox = Rect.fromPoints(Point2(minx, miny), Point2(maxx, maxy)) self.net = net self.layer = layer self._project = None self.__triangulation = None
def test_point_insert(self): p = Project() l1 = Layer("l1", None) l2 = Layer("l2", None) p.stackup.add_layer(l1) p.stackup.add_layer(l2) vp = ViaPair(l1, l2) p.stackup.add_via_pair(vp) t1 = Trace(Point2(200, 1000), Point2(2000, 1000), 10, l1) p.artwork.merge_artwork(t1) t2 = Trace(Point2(400, 0), Point2(400, 2000), 10, l2) p.artwork.merge_artwork(t2) # Should be two objects, not connected self.assertIsNotNone(t1.net) self.assertIsNotNone(t2.net) self.assertNotEqual(t1.net, t2.net) # Add two more traces, make sure they're connected to nets t3 = Trace(Point2(2000, 1001), Point2(2000, 3000), 10, l1) p.artwork.merge_artwork(t3) self.assertEqual(t1.net, t3.net) t4 = Trace(Point2(401, -1), Point2(-1000, -1000), 10, l2) p.artwork.merge_artwork(t4) self.assertEqual(t2.net, t4.net) # Now put a via between the two v = Via(Point2(400, 1000), vp, 10) p.artwork.merge_artwork(v) # Make sure net is not none self.assertIsNotNone(v.net) # Make sure net is all the same self.assertEqual(v.net, t1.net) self.assertEqual(v.net, t2.net) self.assertEqual(v.net, t3.net) self.assertEqual(v.net, t4.net) # Should only be one net in the project now, and it should be v.net self.assertEqual(len(p.nets.nets), 1) self.assertEqual(p.nets.nets[0], v.net) # Ok, now remove the via from the artwork. # via should then have no net, and the traces on each layer should split off p.artwork.remove_artwork(v) # We should now have two nets on separate layers self.assertEqual(len(p.nets.nets), 2) self.assertEqual(t1.net, t3.net) self.assertEqual(t2.net, t4.net) self.assertNotEqual(t1.net, t2.net)
def save(self): par = self._get_par_obj() cur = getattr(par, self.subattr) kw = {'x':cur.x, 'y':cur.y } kw[self.axis] = self.value v = Point2(**kw) setattr(par, self.subattr, v)
def mouseReleaseEvent(self, evt): pt = self.view.viewState.tfV2W(Point2(evt.pos())) aw = self.project.artwork.query_point(pt) aw_l = layer_for(aw) if aw is None: return if self.state == self.STATE_IDLE: self.pt0 = pt self.pt0_layer = aw_l self.state = self.STATE_WAIT_ADTL_POINT elif self.state == self.STATE_WAIT_ADTL_POINT: aw = Airwire(self.pt0, pt, self.pt0_layer, aw_l, None) self.project.artwork.merge_artwork(aw) # Here is where we emit the airwire if evt.modifiers() & QtCore.Qt.ShiftModifier: self.pt0 = pt self.pt0_layer = aw_l else: self.state = self.STATE_IDLE self.changed.emit()
def _build_points(self, cmp): """ :type cmp: pcbre.model.passivecomponent.PassiveComponent :param cmp: :return: """ circ_groups = [] if cmp.body_type == PassiveBodyType.CHIP: bx = cmp.body_corner_vec.x by = cmp.body_corner_vec.y circ_groups.append(map(Point2, [(-bx, by), (-bx,-by),(bx,-by),(bx,by) ])) elif cmp.body_type == PassiveBodyType.TH_AXIAL: bx = cmp.body_corner_vec.x by = cmp.body_corner_vec.y circ_groups.append(map(Point2, [(-bx, by), (-bx,-by),(bx,-by),(bx,by)])) d = cmp.pin_d - cmp.pin_corner_vec.x print(bx, d) circ_groups.append([Point2(bx, 0), Point2(d, 0)]) circ_groups.append([Point2(-bx, 0), Point2(-d, 0)]) elif cmp.body_type == PassiveBodyType.TH_RADIAL: g = [] m = cmp.body_corner_vec.mag() for i in range(32): p = Point2.fromPolar(i/16*math.pi, m) g.append(p) circ_groups.append(g) ll = [] for group in circ_groups: newpoints = projectPoints(cmp.matrix, group) ll += list(zip(newpoints, newpoints[1:] + newpoints[0:1])) return ll
def __get_rel_trace_repr(self): w, p0, p1 = self.__get_unrot_trace_points() p0 = Point2.fromHomol(self.__inv_p2p_mat.dot(p0.homol())) p1 = Point2.fromHomol(self.__inv_p2p_mat.dot(p1.homol())) return Trace(p0, p1, w, self.layer)
def __get_trace_repr(self): w, p0, p1 = self.__get_unrot_trace_points() p0 = Point2.fromHomol(self.pad_to_world_matrix.dot(p0.homol())) p1 = Point2.fromHomol(self.pad_to_world_matrix.dot(p1.homol())) return Trace(p0, p1, w, self.layer)
def pad_to_world(self, pt): return Point2.fromHomol(self.pad_to_world_matrix.dot(pt.homol()))
def world_to_pad(self, pt): pt = Point2(pt) return Point2.fromHomol(self.world_to_pad_matrix.dot(pt.homol()))