diff options
-rw-r--r-- | gerbonara/aperture_macros/expression.py | 2 | ||||
-rw-r--r-- | gerbonara/aperture_macros/parse.py | 4 | ||||
-rw-r--r-- | gerbonara/cad/protoboard.py | 99 |
3 files changed, 83 insertions, 22 deletions
diff --git a/gerbonara/aperture_macros/expression.py b/gerbonara/aperture_macros/expression.py index 44abf51..af43d9a 100644 --- a/gerbonara/aperture_macros/expression.py +++ b/gerbonara/aperture_macros/expression.py @@ -167,7 +167,7 @@ class VariableExpression(Expression): def optimized(self, variable_binding={}): if self.number in variable_binding: - return ConstantExpression(variable_binding[self.number]) + return ConstantExpression(expr(variable_binding[self.number]).optimized(variable_binding)) return self def __eq__(self, other): diff --git a/gerbonara/aperture_macros/parse.py b/gerbonara/aperture_macros/parse.py index b8970ff..a4c2956 100644 --- a/gerbonara/aperture_macros/parse.py +++ b/gerbonara/aperture_macros/parse.py @@ -111,12 +111,12 @@ class ApertureMacro: def to_gerber(self, unit=None): comments = [ str(c) for c in self.comments ] - variable_defs = [ f'${var.to_gerber(unit)}={expr}' for var, expr in enumerate(self.variables, start=1) ] + variable_defs = [ f'${var}={expr}' for var, expr in enumerate(self.variables, start=1) if expr is not None ] primitive_defs = [ prim.to_gerber(unit) for prim in self.primitives ] return '*\n'.join(comments + variable_defs + primitive_defs) def to_graphic_primitives(self, offset, rotation, parameters : [float], unit=None, polarity_dark=True): - variables = {i: v for i, v in enumerate(self.variables, start=1)} + variables = {i: v for i, v in enumerate(self.variables, start=1) if v is not None} for number, value in enumerate(parameters, start=1): if number in variables: raise SyntaxError(f'Re-definition of aperture macro variable {number} through parameter {value}') diff --git a/gerbonara/cad/protoboard.py b/gerbonara/cad/protoboard.py index 09befde..b9a1065 100644 --- a/gerbonara/cad/protoboard.py +++ b/gerbonara/cad/protoboard.py @@ -551,6 +551,7 @@ class AlioCell(ObjectGroup): self.link_trace_width = link_trace_width or unit(0.5, MM) self.via_size = via_size or unit(0.4, MM) self.border_x, self.border_y = False, False + self.inst_x, self.inst_y = None, None @property def single_sided(self): @@ -559,6 +560,7 @@ class AlioCell(ObjectGroup): def inst(self, x, y, border_x, border_y): inst = copy(self) inst.border_x, inst.border_y = border_x, border_y + inst.inst_x, inst.inst_y = x, y return inst def bounding_box(self, unit): @@ -574,13 +576,68 @@ class AlioCell(ObjectGroup): fe.offset(x, y, self.unit) return fe - main_ap = RectangleAperture(self.pitch - self.clearance, self.pitch - self.clearance, unit=self.unit).rotated(rotation) + var = VariableExpression + # parameters: [1: total height = pad width, 2: pitch, 3: trace width, 4: corner radius, 5: rotation, 6: clearance] + alio_main_macro = ApertureMacro('ALIOM', ( + amp.CenterLine(MM, 1, var(2)-var(6), var(2)-var(3)-2*var(6), 0, 0, var(5)), + amp.Outline(MM, 0, 5, ( + -var(2)/2, -var(2)/2, + -var(2)/2, -(var(7)-var(8)), + -var(7), -(var(7)-var(8)), + -(var(7)-var(8)), -var(7), + -(var(7)-var(8)), -var(2)/2, + -var(2)/2, -var(2)/2, + ), var(5)), + amp.Outline(MM, 0, 5, ( + -var(2)/2, var(2)/2, + -var(2)/2, (var(7)-var(8)), + -var(7), (var(7)-var(8)), + -(var(7)-var(8)), var(7), + -(var(7)-var(8)), var(2)/2, + -var(2)/2, var(2)/2, + ), var(5)), + amp.Outline(MM, 0, 5, ( + var(2)/2, -var(2)/2, + var(2)/2, -(var(7)-var(8)), + var(7), -(var(7)-var(8)), + (var(7)-var(8)), -var(7), + (var(7)-var(8)), -var(2)/2, + var(2)/2, -var(2)/2, + ), var(5)), + amp.Outline(MM, 0, 5, ( + var(2)/2, var(2)/2, + var(2)/2, (var(7)-var(8)), + var(7), (var(7)-var(8)), + (var(7)-var(8)), var(7), + (var(7)-var(8)), var(2)/2, + var(2)/2, var(2)/2, + ), var(5)), + amp.Circle(MM, 0, 2*var(8), -var(7), -var(7), var(5)), + amp.Circle(MM, 0, 2*var(8), -var(7), var(7), var(5)), + amp.Circle(MM, 0, 2*var(8), var(7), -var(7), var(5)), + amp.Circle(MM, 0, 2*var(8), var(7), var(7), var(5)), + ), ( + None, # 1 + None, # 2 + None, # 3 + None, # 4 + None, # 5 + None, # 6 + var(2)/2 - var(1)/2 + var(4), # 7 + var(4)+var(6), # 8 + )) + corner_radius = (self.link_pad_width - self.link_trace_width)/3 + main_ap = ApertureMacroInstance(alio_main_macro, (self.link_pad_width, # 1 + self.pitch, # 2 + self.link_trace_width, # 3 + corner_radius, # 4 + rotation, # 5 + self.clearance), unit=MM) # 6 main_drill = ExcellonTool(self.drill, plated=True, unit=self.unit) via_drill = ExcellonTool(self.via_size, plated=True, unit=self.unit) - var = VariableExpression # parameters: [1: total height = pad width, 2: total width, 3: trace width, 4: corner radius, 5: rotation] - alio_macro = ApertureMacro('ALIO', ( + alio_macro = ApertureMacro('ALIOP', ( amp.CenterLine(MM, 1, var(1)-2*var(4), var(1), 0, 0, var(5)), amp.CenterLine(MM, 1, var(1), var(1)-2*var(4), 0, 0, var(5)), amp.Circle(MM, 1, 2*var(4), -var(1)/2+var(4), -var(1)/2+var(4), var(5)), @@ -589,22 +646,21 @@ class AlioCell(ObjectGroup): amp.Circle(MM, 1, 2*var(4), var(1)/2-var(4), var(1)/2-var(4), var(5)), amp.CenterLine(MM, 1, var(2), var(3), -var(2)/2 + var(1)/2, 0, var(5)), )) - corner_radius = (self.link_pad_width - self.link_trace_width)/3 - alio_clear = ApertureMacroInstance(alio_macro, (self.link_pad_width + 2*self.clearance, # 1 - self.pitch+self.clearance, # 2 - self.link_trace_width + 2*self.clearance, # 3 - corner_radius+self.clearance, # 4 - rotation), unit=MM) # 5 + #alio_clear = ApertureMacroInstance(alio_macro, (self.link_pad_width + 2*self.clearance, # 1 + # self.pitch+self.clearance, # 2 + # self.link_trace_width + 2*self.clearance, # 3 + # corner_radius+self.clearance, # 4 + # rotation), unit=MM) # 5 alio_dark = ApertureMacroInstance(alio_macro, (self.link_pad_width, # 1 self.pitch-self.clearance, # 2 self.link_trace_width, # 3 corner_radius, # 4 rotation), unit=MM) # 5 - alio_clear_90 = ApertureMacroInstance(alio_macro, (self.link_pad_width + 2*self.clearance, # 1 - self.pitch+self.clearance, # 2 - self.link_trace_width + 2*self.clearance,# 3 - corner_radius+self.clearance, # 4 - rotation+90), unit=MM) # 5 + #alio_clear_90 = ApertureMacroInstance(alio_macro, (self.link_pad_width + 2*self.clearance, # 1 + # self.pitch+self.clearance, # 2 + # self.link_trace_width + 2*self.clearance,# 3 + # corner_radius+self.clearance, # 4 + # rotation+90), unit=MM) # 5 alio_dark_90 = ApertureMacroInstance(alio_macro, (self.link_pad_width, # 1 self.pitch-self.clearance, # 2 self.link_trace_width, # 3 @@ -614,12 +670,17 @@ class AlioCell(ObjectGroup): # all layers are identical here for side, use in (('top', 'copper'), ('top', 'mask'), ('bottom', 'copper'), ('bottom', 'mask')): layer_stack[side, use].objects.insert(0, xf(Flash(0, 0, aperture=main_ap, unit=self.unit))) - if not (self.border_x or self.border_y): - if side == 'top': - layer_stack[side, use].objects.append(xf(Flash(self.pitch/2, self.pitch/2, aperture=alio_clear, polarity_dark=False, unit=self.unit))) + if side == 'top': + #layer_stack[side, use].objects.append(xf(Flash(self.pitch/2, self.pitch/2, aperture=alio_clear, polarity_dark=False, unit=self.unit))) + #if self.inst_y == 0: + # layer_stack[side, use].objects.append(xf(Flash(self.pitch/2, -self.pitch/2, aperture=alio_clear, polarity_dark=False, unit=self.unit))) + if not (self.border_x or self.border_y): layer_stack[side, use].objects.append(xf(Flash(self.pitch/2, self.pitch/2, aperture=alio_dark, unit=self.unit))) - else: - layer_stack[side, use].objects.append(xf(Flash(self.pitch/2, self.pitch/2, aperture=alio_clear_90, polarity_dark=False, unit=self.unit))) + else: + #layer_stack[side, use].objects.append(xf(Flash(self.pitch/2, self.pitch/2, aperture=alio_clear_90, polarity_dark=False, unit=self.unit))) + #if self.inst_x == 0: + # layer_stack[side, use].objects.append(xf(Flash(-self.pitch/2, self.pitch/2, aperture=alio_clear, polarity_dark=False, unit=self.unit))) + if not (self.border_x or self.border_y): layer_stack[side, use].objects.append(xf(Flash(self.pitch/2, self.pitch/2, aperture=alio_dark_90, unit=self.unit))) layer_stack.drill_pth.append(Flash(x, y, aperture=main_drill, unit=self.unit)) |