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_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_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 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 get_trace(self): sp = self.last_pt if sp is None: sp = self.cur_pt return Trace(sp, self.cur_pt, self.toolparammodel.thickness, self.view.current_layer_hack(), None)
def setUp(self): self.p = p = Project() l = Layer("foo", []) p.stackup.add_layer(l) self.l1 = Trace(Point2(-5, 0), Point2(-1, 0), thickness=1, layer=l) self.l2 = Trace(Point2(1, 0), Point2(5, 0), thickness=1, layer=l) p.artwork.merge_artwork(self.l1) p.artwork.merge_artwork(self.l2) self.assertIsNotNone(self.l1.net) self.assertIsNotNone(self.l2.net) self.assertNotEqual(self.l1.net, self.l2.net) class Dummy(Component): pass cmp = Dummy(Point2(0,0), 0, SIDE.Top, side_layer_oracle=p) self.pad = Pad(cmp, 0, Point2(0, 0), 0, 3, 3, th_diam=1)
def mousePressEvent(self, evt): pos = evt.pos() pt = QPoint_to_pair(pos) end_point = Point2(self.view.viewState.tfV2W(pt)) if self.last_pt is not None: t = Trace(self.last_pt, end_point, self.toolparammodel.thickness, self.view.current_layer_hack(), None) self.project.artwork.merge_artwork(t) self.last_pt = end_point
def test_fixup_broken_nets(self): p = Project() l = Layer("t1", (1, 1, 1)) p.stackup.add_layer(l) n1 = p.nets.new() n2 = p.nets.new() n3 = p.nets.new() # T1 and T2 should be joined # T2 and T3 should be split # T4 should stay the same t1 = Trace(Point2(0, 0), Point2(100, 100), 10, l, n1) t2 = Trace(Point2(200, 200), Point2(100, 100), 10, l, n2) t3 = Trace(Point2(400, 400), Point2(500, 500), 10, l, n2) t4 = Trace(Point2(600, 600), Point2(700, 700), 10, l, n3) p.artwork.add_artwork(t1) p.artwork.add_artwork(t2) p.artwork.add_artwork(t3) p.artwork.add_artwork(t4) self.assertNotEqual(t1.net, t2.net) p.artwork.rebuild_connectivity() self.assertEqual(t1.net, t2.net) self.assertNotEqual(t2.net, t3.net) self.assertEqual(t4.net, n3) # And all objects must have nets self.assertIsNotNone(t1.net) self.assertIsNotNone(t2.net) self.assertIsNotNone(t3.net) self.assertIsNotNone(t4.net)
def deserialize(self, msg: ser.Artwork) -> None: for i_via in msg.vias: v = Via(deserialize_point2(i_via.point), self.__project.scontext.get(i_via.viapairSid), i_via.r, self.__lookup_net_helper(i_via.netSid)) self.add_artwork(v) for i_trace in msg.traces: t = Trace(deserialize_point2(i_trace.p0), deserialize_point2(i_trace.p1), i_trace.thickness, self.__project.scontext.get(i_trace.layerSid), self.__lookup_net_helper(i_trace.netSid)) self.add_artwork(t) for i_poly in msg.polygons: exterior = [deserialize_point2(j) for j in i_poly.exterior] interiors = [[deserialize_point2(k) for k in j] for j in i_poly.interiors] p = Polygon(self.__project.scontext.get(i_poly.layerSid), exterior, interiors, self.__lookup_net_helper(i_poly.netSid)) self.add_artwork(p) for i_airwire in msg.airwires: aw = Airwire(deserialize_point2(i_airwire.p0), deserialize_point2(i_airwire.p1), self.__project.scontext.get(i_airwire.p0LayerSid), self.__project.scontext.get(i_airwire.p1LayerSid), self.__project.scontext.get(i_airwire.netSid)) self.add_artwork(aw) for i_cmp in msg.components: if i_cmp.which() == "dip": cmp = DIPComponent.deserialize(self.__project, i_cmp) elif i_cmp.which() == "sip": cmp = SIPComponent.deserialize(self.__project, i_cmp) elif i_cmp.which() == "smd4": cmp = SMD4Component.deserialize(self.__project, i_cmp) elif i_cmp.which() == "passive2": cmp = Passive2Component.deserialize(self.__project, i_cmp) else: raise NotImplementedError() self.add_component(cmp)
def deserialize(self, msg): for i in msg.vias: v = Via(deserialize_point2(i.point), self.__project.scontext.get(i.viapairSid), i.r, self.__project.scontext.get(i.netSid)) self.add_artwork(v) for i in msg.traces: t = Trace(deserialize_point2(i.p0), deserialize_point2(i.p1), i.thickness, self.__project.scontext.get(i.layerSid), self.__project.scontext.get(i.netSid)) self.add_artwork(t) for i in msg.polygons: exterior = [deserialize_point2(j) for j in i.exterior] interiors = [[deserialize_point2(k) for k in j] for j in i.interiors] p = Polygon(self.__project.scontext.get(i.layerSid), exterior, interiors, self.__project.scontext.get(i.netSid)) self.add_artwork(p) for i in msg.airwires: aw = Airwire(deserialize_point2(i.p0), deserialize_point2(i.p1), self.__project.scontext.get(i.p0LayerSid), self.__project.scontext.get(i.p1LayerSid), self.__project.scontext.get(i.netSid)) self.add_artwork(aw) for i in msg.components: if i.which() == "dip": cmp = DIPComponent.deserialize(self.__project, i) elif i.which() == "smd4": cmp = SMD4Component.deserialize(self.__project, i) else: raise NotImplementedError() self.add_component(cmp)
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 __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_artwork(self) -> Tuple[Optional[Via], List[Trace]]: if self.view.current_layer_hack() is None: return None, [] layer = self.view.current_layer_hack() # If no last-point is set, we return a trace stub 'circle' to visualize where the trace will go if self.last_pt is None: return None, [ Trace(self.cur_pt, self.cur_pt, self.toolsettings.thickness, layer, None) ] initial_via = None # If previous layer and current layer are the same, no via needed if self.last_layer != layer: # Look for a viapair between the layer @ self.last_layer vp = self.project.stackup.via_pair_for_layers( [self.last_layer, layer]) if vp is not None: initial_via = Via(self.last_pt, vp, self.toolsettings.via_radius) # Single straight trace if self.routing_mode == RoutingMode.STRAIGHT: return initial_via, [ Trace(self.last_pt, self.cur_pt, self.toolsettings.thickness, layer, None) ] # 90 degree bend elif self.routing_mode == RoutingMode._90: # position of bend point if self.routing_dir: pa = Vec2(self.last_pt.x, self.cur_pt.y) else: pa = Vec2(self.cur_pt.x, self.last_pt.y) return initial_via, [ Trace(self.last_pt, pa, self.toolsettings.thickness, layer, None), Trace(pa, self.cur_pt, self.toolsettings.thickness, layer, None) ] elif self.routing_mode == RoutingMode._45: d_v = self.cur_pt - self.last_pt d_nv = d_v.dup() if abs(d_v.y) < abs(d_v.x): if d_nv.x > 0: d_nv.x = abs(d_v.y) else: d_nv.x = -abs(d_v.y) else: if d_nv.y > 0: d_nv.y = abs(d_v.x) else: d_nv.y = -abs(d_v.x) d_vh = d_v - d_nv if self.routing_dir: pa = self.last_pt + d_nv else: pa = self.last_pt + d_vh return initial_via, [ Trace(self.last_pt, pa, self.toolsettings.thickness, layer, None), Trace(pa, self.cur_pt, self.toolsettings.thickness, layer, None) ]