diff --git a/ViaStitching/FillArea.py b/ViaStitching/FillArea.py index 3ff9fdf..614c182 100644 --- a/ViaStitching/FillArea.py +++ b/ViaStitching/FillArea.py @@ -64,6 +64,7 @@ FillArea.FillArea().SetDebug().SetNetname("GND").SetStepMM(1.27).SetSizeMM(0.6). # with # SetDebug: Activate debug mode (print evolution of the board in ascii art) +# SetViaThroughAreas: Ignores areas on other layers # SetNetname: Change the netname to consider for the filling # (default is /GND or fallback to GND) # SetStepMM: Change step between Via (in mm) @@ -130,6 +131,7 @@ class FillArea: self.SetClearanceMM(0.2) self.only_selected_area = False self.delete_vias = False + self.via_through_areas = False if self.pcb is not None: for lnet in ["GND", "/GND"]: if self.pcb.FindNet(lnet) is not None: @@ -162,6 +164,10 @@ class FillArea: self.random = r return self + def SetViaThroughAreas(self, r): + self.via_through_areas = r + return self + def SetType(self, type): self.fill_type = type return self @@ -294,8 +300,17 @@ STEP = '-' point_to_test = wxPoint(via.PosX + dx, via.PosY + dy) hit_test_area = False - for layer_id in area.GetLayerSet().CuStack(): - hit_test_area = hit_test_area or area.HitTestFilledArea(layer_id, VECTOR2I(point_to_test)) # Collides with a filled area + if Version() < '7': + # below 7.0.0 + for layer_id in area.GetLayerSet().CuStack(): + hit_test_area = hit_test_area or area.HitTestFilledArea(layer_id, VECTOR2I(point_to_test)) # Collides with a filled area + else: + # 7.0.0 and above + for layer_id in area.GetLayerSet().CuStack(): + for i in range(0, area.Outline().OutlineCount()): + area_outline = area.Outline().Outline(i) + if area.GetLayerSet().Contains(layer_id) and (layer_id != Edge_Cuts): + hit_test_area = hit_test_area or area_outline.PointInside(VECTOR2I(point_to_test)) hit_test_edge = area.HitTestForEdge(VECTOR2I(point_to_test), 1) # Collides with an edge/corner try: hit_test_zone = area.HitTestInsideZone(VECTOR2I(point_to_test)) # Is inside a zone (e.g. KeepOut/Rules) @@ -308,11 +323,11 @@ STEP = '-' if is_rule_exclude_via_area and (hit_test_area or hit_test_edge or hit_test_zone): return self.REASON_KEEPOUT # Collides with keepout/rules - elif (hit_test_area or hit_test_edge) and not is_rules_area: + elif (not self.via_through_areas) and (hit_test_area or hit_test_edge) and not is_rules_area: # Collides with another signal (e.g. on another layer) but not a rule zone return self.REASON_OTHER_SIGNAL - elif hit_test_zone and not is_rules_area: + elif (not self.via_through_areas) and hit_test_zone and not is_rules_area: # Check if the zone is higher priority than other zones of the target net in the same point # target_areas_on_same_layer = filter(lambda x: ((x.GetPriority() > area_priority) and (x.GetLayer() == area_layer) and (x.GetNetname().upper() == self.netname)), all_areas) target_areas_on_same_layer = filter(lambda x: ((x.GetPriority() > area_priority) and ( @@ -417,7 +432,12 @@ STEP = '-' for zone in zones: if zone.IsOnLayer(layer_id): if poly_set is not None or not self.only_selected_area or zone.IsSelected(): - poly_set_layer.Append(zone.RawPolysList(layer_id)) + if Version() < '7': + # below 7.0.0 + poly_set_layer.Append(zone.RawPolysList(layer_id)) + else: + # 7.0.0 and above + poly_set_layer.Append(zone.Outline()) if poly_set is None: poly_set = poly_set_layer @@ -602,8 +622,16 @@ STEP = '-' # Offset is half the size of the via plus the clearance of the via or the area offset = 0 # Use an exact zone match point_to_test = wxPoint(int(current_x), int(current_y)) - hit_test_area = area.HitTestFilledArea( - area.GetLayer(), VECTOR2I(point_to_test), int(offset)) # Collides with a filled area + hit_test_area = False + if Version() < '7': + # below 7.0.0 + hit_test_area = area.HitTestFilledArea( + area.GetLayer(), VECTOR2I(point_to_test), int(offset)) # Collides with a filled area + else: + # 7.0.0 and above + for i in range(0, area.Outline().OutlineCount()): + area_outline = area.Outline().Outline(i) + hit_test_area = hit_test_area or area_outline.PointInside(VECTOR2I(point_to_test)) # Collides with an edge/corner hit_test_edge = area.HitTestForEdge(VECTOR2I(point_to_test), int(max(area_clearance, offset))) # test_result only remains true if the via is inside an area and not on an edge @@ -639,7 +667,7 @@ STEP = '-' if self.debug: print("%s: Line %u" % (time.time(), currentframe().f_lineno)) for pad in all_pads: - local_offset = max(pad.GetLocalClearance(), self.clearance, max_target_area_clearance) + (self.size / 2) + local_offset = max(pad.GetOwnClearance(UNDEFINED_LAYER,""), self.clearance, max_target_area_clearance) + (self.size / 2) max_size = max(pad.GetSize().x, pad.GetSize().y) start_x = int(floor(((pad.GetPosition().x - (max_size / 2.0 + local_offset)) - origin.x) / l_clearance)) @@ -700,7 +728,7 @@ STEP = '-' opx = stop_x opy = stop_y - clearance = max(track.GetLocalClearance(""), self.clearance, max_target_area_clearance) + \ + clearance = max(track.GetOwnClearance(UNDEFINED_LAYER,""), self.clearance, max_target_area_clearance) + \ (self.size / 2) + (track.GetWidth() / 2) start_x = int(floor(((start_x - clearance) - origin.x) / l_clearance)) @@ -764,8 +792,9 @@ STEP = '-' ran_y = 0 if self.random: - ran_x = (random.random() * l_clearance / 2.0) - (l_clearance / 4.0) - ran_y = (random.random() * l_clearance / 2.0) - (l_clearance / 4.0) + max_offset = max(self.step - (self.clearance + self.size), 0) / 2.0 + ran_x = (random.random() * max_offset) - (max_offset / 2.0) + ran_y = (random.random() * max_offset) - (max_offset / 2.0) self.AddVia(wxPoint(via.PosX + ran_x, via.PosY + ran_y), via.X, via.Y) via_placed += 1 diff --git a/ViaStitching/FillAreaAction.py b/ViaStitching/FillAreaAction.py index 802d7de..8de119f 100644 --- a/ViaStitching/FillAreaAction.py +++ b/ViaStitching/FillAreaAction.py @@ -81,6 +81,7 @@ class FillAreaAction(pcbnew.ActionPlugin): if a.m_Debug.IsChecked(): fill.SetDebug() fill.SetRandom(a.m_Random.IsChecked()) + fill.SetViaThroughAreas(a.m_viaThroughAreas.IsChecked()) fill.SetType(a.m_cbFillType.GetStringSelection()) if a.m_only_selected.IsChecked(): fill.OnlyOnSelectedArea() diff --git a/ViaStitching/FillAreaDialog.py b/ViaStitching/FillAreaDialog.py index 1347fa1..e0a4d1c 100644 --- a/ViaStitching/FillAreaDialog.py +++ b/ViaStitching/FillAreaDialog.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- ########################################################################### -## Python code generated with wxFormBuilder (version 3.10.1) +## Python code generated with wxFormBuilder (version 3.10.1-0-g8feb16b) ## http://www.wxformbuilder.org/ ## ## PLEASE DO *NOT* EDIT THIS FILE! @@ -102,6 +102,14 @@ class FillAreaDialog ( wx.Dialog ): self.m_only_selected = wx.CheckBox( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) fgSizer1.Add( self.m_only_selected, 0, wx.ALL, 5 ) + self.m_staticText71 = wx.StaticText( self, wx.ID_ANY, u"Ignore areas on other layers", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_staticText71.Wrap( -1 ) + + fgSizer1.Add( self.m_staticText71, 0, wx.ALL, 5 ) + + self.m_viaThroughAreas = wx.CheckBox( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) + fgSizer1.Add( self.m_viaThroughAreas, 0, wx.ALL, 5 ) + self.m_staticText7 = wx.StaticText( self, wx.ID_ANY, u"Debug mode", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_staticText7.Wrap( -1 ) diff --git a/ViaStitching/FillAreaTpl.fbp b/ViaStitching/FillAreaTpl.fbp index d11834f..be8e59e 100644 --- a/ViaStitching/FillAreaTpl.fbp +++ b/ViaStitching/FillAreaTpl.fbp @@ -1147,6 +1147,131 @@ + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Ignore areas on other layers + 0 + + 0 + + + 0 + + 1 + m_staticText71 + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + + 0 + + + 0 + + 1 + m_viaThroughAreas + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + 5 wxALL|wxEXPAND