def _extract_lp(self, name, tok): """ Extract "layer param" and reset image layer. """ if self.img_buff.not_empty(): self.layer_buff.images.append(self.img_buff) self.img_buff = Image('', self.img_buff.is_additive) self.trace_buff = TraceBuffer() self.status.update({ 'x': 0, 'y': 0, 'draw': 'OFF', 'interpolation': 'LINEAR', 'aperture': None, 'outline_fill': False, 'multi_quadrant': False, 'units': None, 'incremental_coords': None }) if name == 'LN': self.img_buff.name = tok elif name == 'LP': self.img_buff.is_additive = IMAGE_POLARITIES[tok] elif name == 'SR': tok, j = self._pop_val('J', tok, coerce_='float') tok, i = self._pop_val('I', tok, coerce_='float') tok, y = self._pop_val('Y', tok) tok, x = self._pop_val('X', tok) self.img_buff.x_repeats = x self.img_buff.x_step = i self.img_buff.y_repeats = y self.img_buff.y_step = j
def test_images(self): """ Capture images with no data. """ layer = Layer() layer.images.append(Image()) layout = Layout() layout.units = 'mm' layout.layers.append(layer) design = Design() design.layout = layout writer = Writer() writer.write(design)
def __init__(self, ignore_unknown=True): self.ignore_unknown = ignore_unknown self.layout = Layout() self.layer_buff = None self.macro_buff = None self.img_buff = Image() self.trace_buff = TraceBuffer() self.fill_buff = [] # establish gerber defaults self.params = { 'AS': AxisDef('x', 'y'), # axis select 'FS': None, # format spec 'MI': AxisDef(0, 0), # mirror image 'MO': 'IN', # mode: inches/mm 'OF': AxisDef(0, 0), # offset 'SF': AxisDef(1, 1), # scale factor 'IJ': AxisDef( ('L', 0), # image justify ('L', 0)), 'IO': AxisDef(0, 0), # image offset 'IP': True, # image polarity 'IR': 0 } # image rotation # simulate a photo plotter self.status = { 'x': 0, 'y': 0, 'draw': 'OFF', 'interpolation': 'LINEAR', 'aperture': None, 'outline_fill': False, 'multi_quadrant': False, 'units': None, 'incremental_coords': None }
def _define_images(self, design, layer_name): """ Define the images that make up the layer information. """ log.debug('creating images for layer "%s"', layer_name) # trace segments on this layer traces_image = Image(layer_name + '_traces', font_renderer=self.face) for segment in design.trace_segments: if segment.layer != layer_name: continue log.debug('Creating smear for trace: %s', segment) # Assumes segment is rounded, straignt trace_smear = Smear(Line(segment.p1, segment.p2), Circle(0, 0, segment.width / 2.0)) traces_image.smears.append(trace_smear) # Generated objects in the design (vias, PTHs) zero_pos = FootprintPos(0, 0, 0.0, False, 'top') for gen_obj in design.layout_objects: # XXX(shamer): body attr is only being used to hold the layer, other placement details are contained # elsewhere for body_attr, body in gen_obj.bodies(zero_pos, {}): if body_attr.layer == layer_name: for shape in body.shapes: traces_image.add_shape(shape, design, zero_pos, body_attr) self.images.append(traces_image) # Pours on this layer for pour in design.pours: log.debug('adding body for pour: %s points, %s', len(pour.points), pour.layer) if layer_name == pour.layer: log.debug('adding body for pour: %s points, %s subtractive shapes', len(pour.points), len(pour.subtractive_shapes)) fill_image = Image('pour fill', font_renderer=self.face) fill_image.fills.append(Fill(pour.points)) self.images.append(fill_image) subtractive_image = Image('pour subtractive shapes', font_renderer=self.face, is_additive=False) for shape in pour.subtractive_shapes: if shape.type == 'rounded_segment': trace_smear = Smear(Line(shape.p1, shape.p2), Circle(0, 0, shape.width / 2.0)) subtractive_image.smears.append(trace_smear) else: subtractive_image.add_shape(shape, None, FootprintPos(0, 0, 0.0, False, ''), FootprintPos(0, 0, 0.0, False, '')) self.images.append(subtractive_image) readded_image = Image('pour readded shapes', font_renderer=self.face, is_additive=True) for shape in pour.readded_shapes: if shape.type == 'rounded_segment': trace_smear = Smear(Line(shape.p1, shape.p2), Circle(0, 0, shape.width / 2.0)) readded_image.smears.append(trace_smear) else: readded_image.add_shape(shape, None, FootprintPos(0, 0, 0.0, False, ''), FootprintPos(0, 0, 0.0, False, '')) self.images.append(readded_image) # trace segments on this layer traces_image = Image(layer_name + '_traces', font_renderer=self.face) for segment in design.trace_segments: if segment.layer != layer_name: continue log.debug('Creating smear for trace: %s', segment) # Assumes segment is rounded, straignt trace_smear = Smear(Line(segment.p1, segment.p2), Circle(0, 0, segment.width / 2.0)) traces_image.smears.append(trace_smear) # Generated objects in the design (vias, PTHs) zero_pos = FootprintPos(0, 0, 0.0, False, 'top') for gen_obj in design.layout_objects: # XXX(shamer): body attr is only being used to hold the layer, other placement details are contained # elsewhere for body_attr, body in gen_obj.bodies(zero_pos, {}): if body_attr.layer == layer_name: for shape in body.shapes: traces_image.add_shape(shape, design, zero_pos, body_attr) self.images.append(traces_image) # Component aspects on this layer # a separate image is used for each component for component_instance in design.component_instances: component = design.components.components[component_instance.library_id] component_image = Image(layer_name + ' component ' + component_instance.instance_id, font_renderer=self.face) footprint_pos = component_instance.footprint_pos if footprint_pos.side is None: continue for idx, footprint_attr in enumerate(component_instance.footprint_attributes): log.debug('footprint pos: %s, side %s, flip %s', footprint_attr.layer, footprint_pos.side, footprint_pos.flip_horizontal) fp_attr_cpy = copy.deepcopy(footprint_attr) if footprint_attr.layer: if footprint_pos.side == 'bottom': rev_sides = {'top': 'bottom', 'bottom': 'top'} fp_attr_cpy.layer = ' '.join([rev_sides.get(piece, piece) for piece in footprint_attr.layer.split(' ')]) if fp_attr_cpy.layer == layer_name: footprint_body = component.footprints[component_instance.footprint_index].bodies[idx] log.debug('adding footprint attribute: %s, %d shapes', fp_attr_cpy, len(footprint_body.shapes)) for shape in footprint_body.shapes: component_image.add_shape(shape, component_instance, footprint_pos, fp_attr_cpy) for idx, gen_obj_attr in enumerate(component_instance.gen_obj_attributes): gen_obj = component.footprints[component_instance.footprint_index].gen_objs[idx] # FIXME(shamer): check for unplaced generated objects. # XXX(shamer): body attr is only being used to hold the layer, other placement details are contained # elsewhere for body_attr, body in gen_obj.bodies(footprint_pos, gen_obj_attr.attributes): if body_attr.layer == layer_name: log.debug('adding body for generated object: %s, %s', footprint_pos, gen_obj_attr) for shape in body.shapes: component_image.add_shape(shape, component_instance, footprint_pos, body_attr) if component_image.not_empty(): self.images.append(component_image) # paths on the layer for path in design.paths: if layer_name == path.layer: log.debug('adding body for path: %s points, %s, %s, is closed: %s', len(path.points), path.width, path.layer, path.is_closed) path_image = Image('path', font_renderer=self.face) start = path.points[0] for point in path.points[1:]: path_image.add_shape(Line(start, point), Circle(0, 0, path.width), zero_pos, zero_pos) start = point if path.is_closed: path_image.add_shape(Line(path.points[0], path.points[-1]), Circle(0, 0, path.width), zero_pos, zero_pos) self.images.append(path_image) # stand alone text on the layer text_image = Image('text', font_renderer=self.face) for text in design.pcb_text: if layer_name == text.layer: log.debug('adding body for text: "%s"', text.value) text_image.add_shape(text.label, design, text, zero_pos) if text_image.not_empty(): self.images.append(text_image)