def _render_component(self, i): output_file = self._get_component_file(i) for style in ('cut', 'etch'): logging.debug('Rendering component %d, %s', i, style) try: stdout, stderr = openscad.run( self.input_file, output_file, variables = self._get_variables({ 'render_3d': False, 'render_index': i, 'render_etch': style == 'etch', }), capture_output=True, ) except openscad.OpenSCADException as e: if 'Current top level object is not a 2D object.' in e.stderr: # This is expected if we try rendering an etch layer as a # cut, since there will be nothing to export continue else: raise processor = SvgProcessor(output_file) processor.fix_dimens() if style == 'cut': processor.apply_laser_cut_style() elif style == 'etch': processor.apply_laser_etch_style() break else: raise ValueError("Invalid component!", i) return processor
def _render_component(self, i, panel_horizontal, panel_vertical): output_file = self._get_component_file(i) for style in ('cut', 'etch'): logging.debug('Rendering component %d, %s', i, style) try: _ = openscad.run( self.input_file, output_file, variables=self._get_variables({ 'render_3d': False, 'render_index': i, 'render_etch': style == 'etch', 'panel_horizontal': panel_horizontal, 'panel_vertical': panel_vertical, }), capture_output=True, ) except openscad.OpenSCADException as e: if 'Current top level object is not a 2D object.' in e.stderr: # This is expected if we try rendering an etch layer as a # cut, since there will be nothing to export continue else: raise processor = SvgProcessor(output_file) processor.fix_dimens() if style == 'cut': processor.apply_laser_cut_style() elif style == 'etch': processor.apply_laser_etch_style() break else: raise ValueError("Invalid component!", i) return processor
def plot_to_directory(output_directory, temp_dir): layers = [ { 'layer': pcbnew.B_SilkS, 'color': '#CC00CC', 'alpha': 0.8, }, { 'layer': pcbnew.B_Cu, 'color': '#33EE33', 'alpha': 0.5, }, { 'layer': pcbnew.F_Cu, 'color': '#CC0000', 'alpha': 0.5, }, { 'layer': pcbnew.F_SilkS, 'color': '#00CCCC', 'alpha': 0.8, }, ] with pcb_util.get_plotter(PCB_FILENAME, temp_dir) as plotter: plotter.plot_options.SetExcludeEdgeLayer(False) processed_svg_files = [] for i, layer in enumerate(layers): output_filename = plotter.plot(layer['layer'], pcbnew.PLOT_FORMAT_SVG) logger.info('Post-processing %s...', output_filename) processor = SvgProcessor(output_filename) def colorize(original): if original.lower() == '#000000': return layer['color'] return original processor.apply_color_transform(colorize) processor.wrap_with_group({ 'opacity': str(layer['alpha']), }) output_filename2 = os.path.join(temp_dir, 'processed-' + os.path.basename(output_filename)) processor.write(output_filename2) processed_svg_files.append((output_filename2, processor)) logger.info('Merging layers...') final_svg = os.path.join(output_directory, 'merged.svg') shutil.copyfile(processed_svg_files[0][0], final_svg) output_processor = SvgProcessor(final_svg) for _, processor in processed_svg_files: output_processor.import_groups(processor) output_processor.write(final_svg) logger.info('Rasterizing...') final_png = os.path.join(output_directory, 'merged.png') subprocess.check_call([ 'inkscape', '--export-area-drawing', '--export-width=320', '--export-png', final_png, '--export-background', '#FFFFFF', final_svg, ])
def plot_job(job, output_directory, temp_dir): logger.info("processing job " + job["filename"]) with pcb_util.get_plotter(PCB_FILENAME, temp_dir) as plotter: plotter.plot_options.SetMirror(job["mirror"]) plotter.plot_options.SetExcludeEdgeLayer(False) processed_svg_files = [] for i, layer in enumerate(job["layers"]): output_filename = plotter.plot(layer['layer'], pcbnew.PLOT_FORMAT_SVG) logger.info('Post-processing %s...', output_filename) processor = SvgProcessor(output_filename) def colorize(original): if original.lower() == '#000000': return layer['color'] return original processor.apply_color_transform(colorize) processor.wrap_with_group({ 'opacity': str(layer['alpha']), }) output_filename2 = os.path.join(temp_dir, 'processed-' + os.path.basename(output_filename)) processor.write(output_filename2) processed_svg_files.append((output_filename2, processor)) logger.info('merging layers...') final_svg = os.path.join(output_directory, job["filename"] + '.svg') shutil.copyfile(processed_svg_files[0][0], final_svg) output_processor = SvgProcessor(final_svg) for _, processor in processed_svg_files: output_processor.import_groups(processor) output_processor.write(final_svg) logger.info('rasterizing...') final_png = os.path.join(output_directory, job["filename"] + '.png') subprocess.check_call([ 'inkscape', '--export-area-drawing', '--export-width=1010', '--export-png', final_png, '--export-background', '#FFFFFF', final_svg, ])
def screenshot(self): print("Taking a screenshot") self.board = pcbnew.GetBoard() board_path=self.board.GetFileName() # There doesn't seem to be a clean way to detect when KiCad is shutting down. # Check for an empty board path and return False to signal that the timer should not restart. if board_path == "": print("Shutting down") return False board_filename=os.path.basename(board_path) board_filename_noex=os.path.splitext(board_filename)[0] project_folder=os.path.dirname(board_path) timelapse_folder=board_filename_noex+'-timelapse' timelapse_folder_path=os.path.join(project_folder, timelapse_folder) if not os.path.exists(timelapse_folder_path): print('Timelapse folder does not exist. creating one now') os.mkdir(timelapse_folder_path) print('Timelapse folder created') timelapse_files=os.listdir(timelapse_folder_path) timelapse_number=extract_biggest_number(timelapse_files) pc = pcbnew.PLOT_CONTROLLER(self.board) po = pc.GetPlotOptions() po.SetOutputDirectory(timelapse_folder_path) po.SetPlotFrameRef(False) po.SetLineWidth(pcbnew.FromMM(0.35)) po.SetScale(1) po.SetUseAuxOrigin(True) po.SetMirror(False) po.SetExcludeEdgeLayer(True) # Set current layer # Plot single layer to file timelapse_number += 1 processed_svg_files = [] for layer in layers: pc.SetLayer(layer['layer']) layer['layer'] pc.OpenPlotfile('-'+layer['name']+'-'+str(timelapse_number).zfill(4), pcbnew.PLOT_FORMAT_SVG, layer['name']) pc.PlotLayer() pc.ClosePlot() output_filename = pc.GetPlotFileName() processor = SvgProcessor(output_filename) def colorize(original): if original.lower() == '#000000': return layer['color'] return original processor.apply_color_transform(colorize) processor.wrap_with_group({ 'opacity': str(layer['alpha']), }) output_filename2 = os.path.join(timelapse_folder_path, 'processed-' + os.path.basename(output_filename)) processor.write(output_filename2) processed_svg_files.append((output_filename2, processor)) os.remove(output_filename) final_svg = os.path.join(timelapse_folder_path, board_filename_noex+'-'+str(timelapse_number).zfill(4)+'.svg') shutil.copyfile(processed_svg_files[0][0], final_svg) output_processor = SvgProcessor(final_svg) for processed_svg_file, processor in processed_svg_files: output_processor.import_groups(processor) os.remove(processed_svg_file) output_processor.set_title(board_filename_noex) output_processor.write(final_svg) # Remove the exported file if there were no new changes if timelapse_number != 1: with open(os.path.join(timelapse_folder_path, board_filename_noex+'-'+str(timelapse_number - 1).zfill(4)+'.svg')) as old_file: with open(final_svg) as new_file: if old_file.read() == new_file.read(): timelapse_number -= 1 os.remove(final_svg) return True
def plot_to_directory(pcb_file, output_directory, temp_dir): layers = [ { 'layer': pcbnew.B_SilkS, 'color': '#CC00CC', 'alpha': 0.8, }, { 'layer': pcbnew.B_Cu, 'color': '#33EE33', 'alpha': 0.5, }, { 'layer': pcbnew.F_Cu, 'color': '#CC0000', 'alpha': 0.5, }, { 'layer': pcbnew.F_SilkS, 'color': '#00CCCC', 'alpha': 0.8, }, ] with pcb_util.get_plotter(pcb_file, temp_dir) as plotter: processed_svg_files = [] for i, layer in enumerate(layers): output_filename = plotter.plot(layer['layer'], pcbnew.PLOT_FORMAT_SVG) logger.info('Post-processing %s...', output_filename) processor = SvgProcessor(output_filename) def colorize(original): if original.lower() == '#000000': return layer['color'] return original processor.apply_color_transform(colorize) processor.wrap_with_group({ 'opacity': str(layer['alpha']), }) output_filename2 = os.path.join( temp_dir, 'processed-' + os.path.basename(output_filename)) processor.write(output_filename2) processed_svg_files.append((output_filename2, processor)) logger.info('Merging layers...') final_svg = os.path.join(output_directory, 'merged.svg') shutil.copyfile(processed_svg_files[0][0], final_svg) output_processor = SvgProcessor(final_svg) for _, processor in processed_svg_files: output_processor.import_groups(processor) output_processor.write(final_svg)
# (pcbnew.F_Mask , "F.Mask", "#800000", "0.8"), # (pcbnew.B_Mask , "B.Mask", "#800000", "0.8") ] processed_svg_files = [] # Plot each layer, in turn, to a temporary file, and then change the colour of the # generated svg. for a in layers: pc.SetLayer(a[0]) pc.OpenPlotfile("layer_ " + a[1], pcbnew.PLOT_FORMAT_SVG, "idk") layerFilename = pc.GetPlotFileName() pc.PlotLayer() pc.ClosePlot() processor = SvgProcessor(layerFilename) def colorize(original): if original.lower() == '#000000': return a[2] return original processor.apply_color_transform(colorize) processor.wrap_with_group({ 'opacity': a[3], }) processed_svg_files.append((processor, layerFilename)) # Finally, combine all the layers together. shutil.copyfile(layerFilename, svgfilename)
def plot_to_directory(pcb_filename, svg_filename_top, svg_filename_bot, temp_dir): sides = [ { 'svg_filename': svg_filename_bot, 'layers':[ { 'layer': pcbnew.B_SilkS, 'color': '#CC00CC', 'alpha': 0.8, }, { 'layer': pcbnew.B_Cu, 'color': '#33EE33', 'alpha': 0.5, }, ] }, { 'svg_filename': svg_filename_top, 'layers':[ { 'layer': pcbnew.F_Cu, 'color': '#CC0000', 'alpha': 0.5, }, { 'layer': pcbnew.F_SilkS, 'color': '#00CCCC', 'alpha': 0.8, }, ] } ] with pcb_util.get_plotter(pcb_filename, temp_dir) as plotter: plotter.plot_options.SetExcludeEdgeLayer(False) #plotter.plot_options.SetAutoScale(False) for i, side in enumerate(sides): processed_svg_files = [] for i, layer in enumerate(side['layers']): output_filename = plotter.plot(layer['layer'], pcbnew.PLOT_FORMAT_SVG) #logger.info('Post-processing %s...', output_filename) processor = SvgProcessor(output_filename) def colorize(original): if original.lower() == '#000000': return layer['color'] return original processor.apply_color_transform(colorize) processor.wrap_with_group({ 'opacity': str(layer['alpha']), }) output_filename2 = os.path.join(temp_dir, 'processed-' + os.path.basename(output_filename)) processor.write(output_filename2) processed_svg_files.append((output_filename2, processor)) shutil.copyfile(processed_svg_files[0][0], side['svg_filename']) output_processor = SvgProcessor(side['svg_filename']) for _, processor in processed_svg_files: output_processor.import_groups(processor) output_processor.write(side['svg_filename'])
def plot_to_directory(output_directory, temp_dir): layers = [ { 'layer': pcbnew.B_SilkS, 'color': '#CC00CC', 'alpha': 0.8, }, { 'layer': pcbnew.B_Cu, 'color': '#33EE33', 'alpha': 0.5, }, { 'layer': pcbnew.F_Cu, 'color': '#CC0000', 'alpha': 0.5, }, { 'layer': pcbnew.F_SilkS, 'color': '#00CCCC', 'alpha': 0.8, }, ] with pcb_util.get_plotter(PCB_FILENAME, temp_dir) as plotter: plotter.plot_options.SetExcludeEdgeLayer(False) processed_svg_files = [] for i, layer in enumerate(layers): output_filename = plotter.plot(layer['layer'], pcbnew.PLOT_FORMAT_SVG) logger.info('Post-processing %s...', output_filename) processor = SvgProcessor(output_filename) def colorize(original): if original.lower() == '#000000': return layer['color'] return original processor.apply_color_transform(colorize) processor.wrap_with_group({ 'opacity': str(layer['alpha']), }) output_filename2 = os.path.join( temp_dir, 'processed-' + os.path.basename(output_filename)) processor.write(output_filename2) processed_svg_files.append((output_filename2, processor)) logger.info('Merging layers...') final_svg = os.path.join(output_directory, 'merged.svg') shutil.copyfile(processed_svg_files[0][0], final_svg) output_processor = SvgProcessor(final_svg) for _, processor in processed_svg_files: output_processor.import_groups(processor) output_processor.write(final_svg) logger.info('Rasterizing...') final_png = os.path.join(output_directory, 'merged.png') subprocess.check_call([ 'inkscape', '--export-area-drawing', '--export-width=320', '--export-png', final_png, '--export-background', '#FFFFFF', final_svg, ])
'HEAD', ]).strip() extra_variables = { 'render_revision': git_rev, 'render_date': datetime.date.today().strftime('%Y-%m-%d'), } renderer = Renderer('splitflap.scad', laser_parts_directory, extra_variables) renderer.clean() svg_output = renderer.render_svgs() # Export to png raster_svg = os.path.join(laser_parts_directory, 'raster.svg') raster_png = os.path.join(laser_parts_directory, 'raster.png') processor = SvgProcessor(svg_output) processor.apply_raster_render_style() processor.write(raster_svg) logging.info('Resize SVG canvas') subprocess.check_call([ 'inkscape', '--verb=FitCanvasToDrawing', '--verb=FileSave', '--verb=FileClose', raster_svg, ]) logging.info('Export PNG') subprocess.check_call([ 'inkscape', '--export-width=320',
} if args.kerf is not None: extra_variables['kerf_width'] = args.kerf elif args.kerf_preset is not None: extra_variables['kerf_width'] = KERF_PRESETS[args.kerf_preset] if args.thickness is not None: extra_variables['thickness'] = args.thickness print('Variables:\n' + json.dumps(extra_variables, indent=4)) renderer = Renderer(os.path.join(source_parts_dir, 'splitflap.scad'), laser_parts_directory, extra_variables) renderer.clean() svg_output = renderer.render_svgs(panelize_quantity=args.panelize) processor = SvgProcessor(svg_output) redundant_lines, merged_lines = None, None if not args.skip_optimize: logging.info('Removing redundant lines') redundant_lines, merged_lines = processor.remove_redundant_lines() processor.write(svg_output) logging.info(f'\n\n\nDone rendering to SVG: {svg_output}') if args.calculate_dimensions: svg_for_dimensions = os.path.join( laser_parts_directory, os.path.splitext(os.path.basename(svg_output))[0] + '_dimensions.svg') processor.apply_dimension_calculation_style()
laser_parts_directory = os.path.join('build', 'laser_parts') extra_variables = { 'render_revision': rev_info.git_short_rev(), 'render_date': rev_info.current_date(), } renderer = Renderer('splitflap.scad', laser_parts_directory, extra_variables) renderer.clean() svg_output = renderer.render_svgs() # Export to png raster_svg = os.path.join(laser_parts_directory, 'raster.svg') raster_png = os.path.join(laser_parts_directory, 'raster.png') processor = SvgProcessor(svg_output) processor.apply_raster_render_style() processor.write(raster_svg) logging.info('Resize SVG canvas') subprocess.check_call([ 'inkscape', '--verb=FitCanvasToDrawing', '--verb=FileSave', '--verb=FileClose', raster_svg, ]) logging.info('Export PNG') subprocess.check_call([ 'inkscape', '--export-width=320',
extra_variables['letter_width'] = args.width if args.offset_x is not None: extra_variables['letter_offset_x'] = args.offset_x if args.offset_y is not None: extra_variables['letter_offset_y'] = args.offset_y if args.ncolumns is not None: extra_variables['num_columns'] = args.ncolumns if args.kerf is not None: extra_variables['kerf_width'] = args.kerf if args.fill is True: extra_variables['render_fill'] = True args.skip_optimize = True renderer = Renderer(os.path.join(source_parts_dir, 'font_generator.scad'), output_directory, extra_variables) renderer.clean() svg_output = renderer.render_svgs(panelize_quantity=1) processor = SvgProcessor(svg_output) redundant_lines, merged_lines = None, None if not args.skip_optimize: logging.info('Removing redundant lines') redundant_lines, merged_lines = processor.remove_redundant_lines() processor.write(svg_output) logging.info('\n\n\nDone rendering to SVG: ' + svg_output)