def test_package() -> None: package = Package( '009e35ef-1f50-4bf3-ab58-11eb85bf5503', Name('Soldered Wire Connector 1x19 ⌀1.0mm'), Description( 'A 1x19 soldered wire connector with 2.54mm pin spacing and 1.0mm drill holes.\n\nGenerated with librepcb-parts-generator (generate_connectors.py)' ), Keywords('connector, 1x19, d1.0, connector, soldering, generic'), Author('Danilo B.'), Version('0.1'), Created('2018-10-17T19:13:41Z'), Deprecated(False), Category('56a5773f-eeb4-4b39-8cb9-274f3da26f4f')) package.add_pad( PackagePad('5c4d39d3-35cc-4836-a082-693143ee9135', Name('1'))) package.add_pad( PackagePad('6100dd55-d3b3-4139-9085-d5a75e783c37', Name('2'))) package.add_footprint(create_footprint()) assert str( package) == """(librepcb_package 009e35ef-1f50-4bf3-ab58-11eb85bf5503
def generate_pkg( dirpath: str, diameter: float, height: float, pitch: float, lead_width: float, author: str, version: str, create_date: Optional[str], ) -> None: # Name according IPC-7351 "Capacitor, Polarized Radial Diameter": # CAPPRD + Lead Spacing + W Lead Width + D Body Diameter + H Body Height name = 'CAPPRD{}W{}D{}H{}'.format(format_ipc_dimension(pitch), format_ipc_dimension(lead_width), format_ipc_dimension(diameter), format_ipc_dimension(height)) variant = get_variant(diameter, height, pitch, lead_width) def _pkg_uuid(identifier: str) -> str: return uuid('pkg', variant, identifier) def _create_footprint(footprint_identifier: str, name: str) -> Footprint: def _fpt_uuid(identifier: str) -> str: return _pkg_uuid(footprint_identifier + '-' + identifier) drill = LEAD_WIDTH_TO_DRILL[lead_width] restring = min( (0.4 if diameter >= 6.0 else 0.3), # preferred restring (pitch - drill - 0.25) / 2) # minimum required restring pad_diameter = drill + (2 * restring) # outer diameter of pad courtyard_diameter = diameter + (1.0 if diameter >= 10.0 else 0.8) def _generate_fill_polygon(identifier: str, layer: str) -> Polygon: polygon = Polygon( uuid=_fpt_uuid(identifier), layer=Layer(layer), width=Width(0.0), fill=Fill(True), grab_area=GrabArea(False), ) if ((pitch - pad_diameter) < 0.6): # not enough space, use a simplified polygon vertices = [ (0.0, (diameter / 2) - 0.2, 0.0), (0.0, (pad_diameter / 2) + 0.2, 0.0), (pitch / 2, (pad_diameter / 2) + 0.2, -180.0), (pitch / 2, -(pad_diameter / 2) - 0.2, 0.0), (0.0, -(pad_diameter / 2) - 0.2, 0.0), (0.0, -(diameter / 2) + 0.2, 180.0), (0.0, (diameter / 2) - 0.2, 0.0), ] else: vertices = [ (0.0, (diameter / 2) - 0.2, 0.0), (0.0, 0.0, 0.0), ((pitch / 2) - (pad_diameter / 2) - 0.2, 0.0, -180.0), ((pitch / 2) + (pad_diameter / 2) + 0.2, 0.0, -180.0), ((pitch / 2) - (pad_diameter / 2) - 0.2, 0.0, 0.0), (0.0, 0.0, 0.0), (0.0, -(diameter / 2) + 0.2, 180.0), (0.0, (diameter / 2) - 0.2, 0.0), ] for vertex in vertices: polygon.add_vertex( Vertex(Position(vertex[0], vertex[1]), Angle(vertex[2]))) return polygon footprint = Footprint( uuid=_fpt_uuid('footprint'), name=Name(name), description=Description(''), ) footprint.add_pad( FootprintPad( uuid=_pkg_uuid('pad-plus'), side=Side.THT, shape=Shape.RECT, position=Position(-pitch / 2, 0), rotation=Rotation(0), size=Size(pad_diameter, pad_diameter), drill=Drill(drill), )) footprint.add_pad( FootprintPad( uuid=_pkg_uuid('pad-minus'), side=Side.THT, shape=Shape.ROUND, position=Position(pitch / 2, 0), rotation=Rotation(0), size=Size(pad_diameter, pad_diameter), drill=Drill(drill), )) # placement footprint.add_circle( Circle( uuid=_fpt_uuid('circle-placement'), layer=Layer('top_placement'), width=Width(0.2), fill=Fill(False), grab_area=GrabArea(False), diameter=Diameter(diameter + 0.2), position=Position(0.0, 0.0), )) footprint.add_polygon( _generate_fill_polygon( identifier='polygon-placement-fill', layer='top_placement', )) # documentation footprint.add_circle( Circle( uuid=_fpt_uuid('circle-documentation'), layer=Layer('top_documentation'), width=Width(0.2), fill=Fill(False), grab_area=GrabArea(False), diameter=Diameter(diameter - 0.2), position=Position(0.0, 0.0), )) footprint.add_polygon( _generate_fill_polygon( identifier='polygon-documentation-fill', layer='top_documentation', )) # courtyard footprint.add_circle( Circle( uuid=_fpt_uuid('circle-courtyard'), layer=Layer('top_courtyard'), width=Width(0.2), fill=Fill(False), grab_area=GrabArea(False), diameter=Diameter(courtyard_diameter), position=Position(0.0, 0.0), )) # texts footprint.add_text( StrokeText( uuid=_fpt_uuid('text-name'), layer=Layer('top_names'), height=Height(1.0), stroke_width=StrokeWidth(0.2), letter_spacing=LetterSpacing.AUTO, line_spacing=LineSpacing.AUTO, align=Align('center bottom'), position=Position(0.0, (diameter / 2) + 0.8), rotation=Rotation(0.0), auto_rotate=AutoRotate(True), mirror=Mirror(False), value=Value('{{NAME}}'), )) footprint.add_text( StrokeText( uuid=_fpt_uuid('text-value'), layer=Layer('top_values'), height=Height(1.0), stroke_width=StrokeWidth(0.2), letter_spacing=LetterSpacing.AUTO, line_spacing=LineSpacing.AUTO, align=Align('center top'), position=Position(0.0, -(diameter / 2) - 0.8), rotation=Rotation(0.0), auto_rotate=AutoRotate(True), mirror=Mirror(False), value=Value('{{VALUE}}'), )) return footprint # package package = Package( uuid=_pkg_uuid('pkg'), name=Name(name), description=Description( 'Polarized radial electrolytic capacitor.\\n\\n' + 'Diameter: {} mm\\n'.format(diameter) + 'Height: {} mm\\n'.format(height) + 'Lead Spacing: {} mm\\n'.format(pitch) + 'Max. Lead Diameter: {} mm\\n\\n'.format(lead_width) + 'Generated with {}'.format(generator)), keywords=Keywords( 'electrolytic,capacitor,polarized,radial,c,cap,cpol'), author=Author(author), version=Version(version), created=Created(create_date or now()), deprecated=Deprecated(False), category=Category('ee75e31d-f231-41d9-8a3b-bea5114f41e3'), ) package.add_pad(PackagePad(uuid=_pkg_uuid('pad-plus'), name=Name('+'))) package.add_pad(PackagePad(uuid=_pkg_uuid('pad-minus'), name=Name('-'))) package.add_footprint( _create_footprint( footprint_identifier='default', name='default', )) # write files pkg_dir_path = path.join(dirpath, package.uuid) if not (path.exists(pkg_dir_path) and path.isdir(pkg_dir_path)): makedirs(pkg_dir_path) with open(path.join(pkg_dir_path, '.librepcb-pkg'), 'w') as f: f.write('0.1\n') with open(path.join(pkg_dir_path, 'package.lp'), 'w') as f: f.write(str(package)) f.write('\n') print('Wrote package {}'.format(name))