From e8e4bd5b4393d8abc3cdaa691a6ef099d919c150 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Thu, 31 Aug 2023 00:04:45 +0200 Subject: [PATCH] chip: Generate 3D models for resistors --- README.md | 2 +- generate_chip.py | 90 +++++++++++++++++++++++++++++++++++++++++---- requirements.txt | 1 + uuid_cache_chip.csv | 10 +++++ 4 files changed, 94 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 65aac92..358bafa 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ This is a collection of Python 3 based scripts to generate parts for the ## Requirements - Python 3.8+ -- For testing and type checking: See `requirements.txt` +- Dependencies in `requirements.txt` ## Introduction / Concepts diff --git a/generate_chip.py b/generate_chip.py index 71362e0..53f1f20 100644 --- a/generate_chip.py +++ b/generate_chip.py @@ -5,11 +5,13 @@ - Chip capacitors SMT """ -from os import path +from os import makedirs, path from uuid import uuid4 from typing import Any, Dict, Iterable, Optional, Tuple +import cadquery as cq + from common import format_ipc_dimension as fd from common import init_cache, now, save_cache from entities.common import ( @@ -19,9 +21,9 @@ from entities.component import SignalUUID from entities.device import ComponentPad, ComponentUUID, Device, PackageUUID from entities.package import ( - AssemblyType, AutoRotate, ComponentSide, CopperClearance, Footprint, FootprintPad, LetterSpacing, LineSpacing, - Mirror, Package, PackagePad, PackagePadUuid, PadFunction, Shape, ShapeRadius, Size, SolderPasteConfig, - StopMaskConfig, StrokeText, StrokeWidth + AssemblyType, AutoRotate, ComponentSide, CopperClearance, Footprint, Footprint3DModel, FootprintPad, LetterSpacing, + LineSpacing, Mirror, Package, Package3DModel, PackagePad, PackagePadUuid, PadFunction, Shape, ShapeRadius, Size, + SolderPasteConfig, StopMaskConfig, StrokeText, StrokeWidth ) generator = 'librepcb-parts-generator (generate_chip.py)' @@ -184,6 +186,7 @@ def __init__( def generate_pkg( library: str, author: str, + package_type: str, name: str, description: str, polarization: Optional[PolarizationConfig], @@ -206,6 +209,7 @@ def generate_pkg( 'height': fd(config.body.height), 'lead_length': fd(config.body.lead_length) if config.body.lead_length else None, 'lead_width': fd(config.body.lead_width) if config.body.lead_width else None, + 'package_type': package_type, } fmt_params_desc = { **fmt_params, @@ -581,9 +585,75 @@ def add_footprint_variant( else: raise ValueError('Either gap or footprints must be set') + # Generate 3D models + uuid_3d_model = generate_3d(library, package_type, full_name, uuid_pkg, config) + if uuid_3d_model is not None: + package.add_3d_model(Package3DModel(uuid_3d_model, Name(full_name))) + for footprint in package.footprints: + footprint.add_3d_model(Footprint3DModel(uuid_3d_model)) + package.serialize(path.join('out', library, category)) +def generate_3d( + library: str, + package_type: str, + full_name: str, + uuid_pkg: str, + config: ChipConfig, +) -> Optional[str]: + supported_package_types = ['RESC'] + + if package_type not in supported_package_types: + return None + + uuid_3d = uuid('pkg', full_name, '3d') + + print(f'Generating pkg 3D model "{full_name}": {uuid_3d}') + + length = config.body.length + width = config.body.width + height = config.body.height + + fillet = width * 0.05 + edge = min(length * 0.15, 0.4) + translation = (0, 0, height / 2) + edge_offset = length / 2 - edge + + inner = cq.Workplane("XY") \ + .box(length - 2 * edge, width, height) \ + .edges('+X').fillet(fillet) \ + .translate(translation) + left = cq.Workplane("XY") \ + .box(edge, width, height) \ + .edges('+X or X').fillet(fillet) \ + .translate(translation) \ + .translate((edge_offset + edge / 2, 0, 0)) + + assembly = cq.Assembly(name=full_name) \ + .add(inner, name="inner", color=cq.Color("gray16")) \ + .add(left, name="left", color=cq.Color("gainsboro")) \ + .add(right, name="right", color=cq.Color("gainsboro")) + + dir_path = path.join('out', library, 'pkg', uuid_pkg) + if not (path.exists(dir_path) and path.isdir(dir_path)): + makedirs(dir_path) + filename = f'{uuid_3d}.step' + + # Less verbose output + from OCP.Message import Message, Message_Gravity # type: ignore + for printer in Message.DefaultMessenger_s().Printers(): + printer.SetTraceLevel(Message_Gravity.Message_Fail) + + assembly.save(path.join(dir_path, filename), 'STEP', mode='fused', write_pcurves=False) + return uuid_3d + + def generate_dev( library: str, author: str, @@ -644,7 +714,8 @@ def _uuid(identifier: str) -> str: generate_pkg( library='LibrePCB_Base.lplib', author='Danilo B.', - name='RESC{size_metric} ({size_imperial})', + package_type='RESC', + name='{package_type}{size_metric} ({size_imperial})', description='Generic chip resistor {size_metric} (imperial {size_imperial}).\n\n' 'Length: {length}mm\nWidth: {width}mm', polarization=None, @@ -670,7 +741,8 @@ def _uuid(identifier: str) -> str: generate_pkg( library='LibrePCB_Base.lplib', author='Danilo B.', - name='RESJ{size_metric} ({size_imperial})', + package_type='RESJ', + name='{package_type}{size_metric} ({size_imperial})', description='Generic J-lead resistor {size_metric} (imperial {size_imperial}).\n\n' 'Length: {length}mm\nWidth: {width}mm', polarization=None, @@ -686,7 +758,8 @@ def _uuid(identifier: str) -> str: generate_pkg( library='LibrePCB_Base.lplib', author='murray', - name='CAPC{size_metric} ({size_imperial})', + package_type='CAPC', + name='{package_type}{size_metric} ({size_imperial})', description='Generic chip capacitor {size_metric} (imperial {size_imperial}).\n\n' 'Length: {length}mm\nWidth: {width}mm', polarization=None, @@ -728,7 +801,8 @@ def _uuid(identifier: str) -> str: generate_pkg( library='LibrePCB_Base.lplib', author='Danilo B.', - name='CAPPM{length}X{width}X{height}L{lead_length}X{lead_width}', + package_type='CAPPM', + name='{package_type}{length}X{width}X{height}L{lead_length}X{lead_width}', description='Generic polarized molded inward-L capacitor (EIA {meta[eia]}).\n\n' 'Length: {length}mm\nWidth: {width}mm\nMax height: {height}mm\n\n' 'EIA Size Code: {meta[eia]}\n' diff --git a/requirements.txt b/requirements.txt index fc70f68..1cb52c6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,4 @@ flake8~=4.0.1 mypy==1.5.1 git+https://github.com/numpy/numpy-stubs isort~=5.10.1 +cadquery==2.3.1 diff --git a/uuid_cache_chip.csv b/uuid_cache_chip.csv index 7c9da15..543daa4 100644 --- a/uuid_cache_chip.csv +++ b/uuid_cache_chip.csv @@ -774,6 +774,7 @@ pkg-cappm730x600x380l130x410-text-name-density~c,26eec489-c37c-4426-a709-14786bf pkg-cappm730x600x380l130x410-text-value-density~a,8751c57c-9249-4b2c-936c-2078247ba375 pkg-cappm730x600x380l130x410-text-value-density~b,d53356a9-57a1-4cb9-969f-6edd2ee5ac0f pkg-cappm730x600x380l130x410-text-value-density~c,6bc50c55-6ef4-4c80-a4e3-036a82aff3ca +pkg-resc0402~(01005)-3d,3e09bb48-d788-4dce-ad29-476e69382838 pkg-resc0402~(01005)-footprint-density~a,8c6d3f1c-f659-4df8-9c5f-e78b5276b216 pkg-resc0402~(01005)-footprint-density~b,6bc08ffc-d8b2-43c5-b927-6f24965a6fab pkg-resc0402~(01005)-line-silkscreen-bot-density~a,1ee09437-a55d-4503-9097-6c7bfa138bce @@ -801,6 +802,7 @@ pkg-resc0402~(01005)-text-name-density~a,654e8c62-d8f9-4797-8a1d-82230a577f8b pkg-resc0402~(01005)-text-name-density~b,816289f0-dfcf-4d54-b0c9-c363b986e14c pkg-resc0402~(01005)-text-value-density~a,a20d54fe-9179-41c0-8943-33e03c04bf8e pkg-resc0402~(01005)-text-value-density~b,110c490c-bae8-468a-a4dc-eabe337a8d5c +pkg-resc0603~(0201)-3d,0e4451c6-aff7-4b9b-a43b-cc61fc9cdde7 pkg-resc0603~(0201)-footprint-density~a,3739bd6f-bbde-43c9-bda8-72b801569276 pkg-resc0603~(0201)-footprint-density~b,69f24f45-ec80-4153-ad0a-25db491e3b41 pkg-resc0603~(0201)-line-silkscreen-bot-density~a,c96a6411-912d-4531-975b-7cae0569290e @@ -828,6 +830,7 @@ pkg-resc0603~(0201)-text-name-density~a,b936ef8c-71a2-4f16-bebc-2286d034ac43 pkg-resc0603~(0201)-text-name-density~b,a34cf139-68f2-4e2f-b232-85582e2ec58a pkg-resc0603~(0201)-text-value-density~a,dcfbd410-396c-45eb-a780-c29c1ebcca4f pkg-resc0603~(0201)-text-value-density~b,6caff316-474e-4b70-b96f-1dc3e8c88e06 +pkg-resc1005~(0402)-3d,e7f4446a-786e-46a8-bb07-a0d0bc73e98a pkg-resc1005~(0402)-footprint-density~a,1abd2df7-4393-46bb-8aa5-fb7c23b2717e pkg-resc1005~(0402)-footprint-density~b,244d2cbe-9562-46ad-a8d9-8b29e0a3c0cc pkg-resc1005~(0402)-line-silkscreen-bot-density~a,6742f214-0b5d-48d2-a182-a8717be29006 @@ -855,6 +858,7 @@ pkg-resc1005~(0402)-text-name-density~a,637a4a70-f61f-42cd-b153-ca8d0c2cb4ba pkg-resc1005~(0402)-text-name-density~b,4a8fbb61-7d39-4aea-b728-4553fbf9d277 pkg-resc1005~(0402)-text-value-density~a,bb2ad320-2956-402f-968a-ac4e51ed6364 pkg-resc1005~(0402)-text-value-density~b,b8e78b85-e09a-42e6-a42a-0b4838511154 +pkg-resc1608~(0603)-3d,2d9f20e6-c3dc-422c-ae1e-e278f6ae8328 pkg-resc1608~(0603)-footprint-density~a,4fceac63-0f89-46c4-8e93-d6ee67d33e69 pkg-resc1608~(0603)-footprint-density~b,2a40ad27-1ab7-41ee-8f60-d70df83927a5 pkg-resc1608~(0603)-line-silkscreen-bot-density~a,09a8ba9d-b5a5-4a4a-83da-9905af60b356 @@ -882,6 +886,7 @@ pkg-resc1608~(0603)-text-name-density~a,8e9560af-ad15-43c7-9089-5091c274409e pkg-resc1608~(0603)-text-name-density~b,0523853e-390b-480d-80f0-22df28be1042 pkg-resc1608~(0603)-text-value-density~a,2908ba24-cc11-4fab-8a0c-3afad79255b9 pkg-resc1608~(0603)-text-value-density~b,fa5fb8d1-fd3c-41ba-a14a-dc3c97f890d7 +pkg-resc2012~(0805)-3d,70a52ef3-ce4d-480a-a79b-5929f52ddf44 pkg-resc2012~(0805)-footprint-density~a,75d2f5cb-4920-4f04-a83d-21bd28174f10 pkg-resc2012~(0805)-footprint-density~b,e8596efa-bd51-4063-87aa-a44fa5640576 pkg-resc2012~(0805)-line-silkscreen-bot-density~a,07710817-ff2b-4348-8cf3-50894f67725a @@ -909,6 +914,7 @@ pkg-resc2012~(0805)-text-name-density~a,e72d97da-70f0-4595-b92d-2c67ab3eeac3 pkg-resc2012~(0805)-text-name-density~b,4950b973-32f3-4283-a608-5ba302ece963 pkg-resc2012~(0805)-text-value-density~a,ff99e004-056c-46d0-a157-acce83932e7f pkg-resc2012~(0805)-text-value-density~b,bb6f494d-576b-4b13-b10c-fd0781c5b8c3 +pkg-resc3216~(1206)-3d,a7b6870c-f390-4ad3-ae99-bc5b9e654210 pkg-resc3216~(1206)-footprint-density~a,95e55ff1-3db6-46b2-8319-0d0a7420d15f pkg-resc3216~(1206)-footprint-density~b,3983cdc8-617d-4016-b8ba-5bc3002994cb pkg-resc3216~(1206)-line-silkscreen-bot-density~a,99dc95f0-c7a0-42cb-a1f5-2e4e2d5b0904 @@ -936,6 +942,7 @@ pkg-resc3216~(1206)-text-name-density~a,dc46cfac-cd12-45c0-af56-4bc565c8bcb0 pkg-resc3216~(1206)-text-name-density~b,49a0d0fc-aeb5-43ac-a7d9-a5d687ab224c pkg-resc3216~(1206)-text-value-density~a,cbeaeee2-44a7-4a54-b1f1-bc74b9585cb7 pkg-resc3216~(1206)-text-value-density~b,a39099cd-ce19-488d-8e25-ba869e6e9fd5 +pkg-resc3225~(1210)-3d,b9c07ce0-72a4-486e-af31-f64d8d082553 pkg-resc3225~(1210)-footprint-density~a,bf5fe775-1694-4ab4-83f8-0981f878455e pkg-resc3225~(1210)-footprint-density~b,f43318d6-cdaf-45c5-a8c6-2855083fa8fb pkg-resc3225~(1210)-line-silkscreen-bot-density~a,00737d3c-57d4-4530-b0a1-9a5865318c71 @@ -963,6 +970,7 @@ pkg-resc3225~(1210)-text-name-density~a,7098d51d-705d-4714-8d82-ef1969f463a5 pkg-resc3225~(1210)-text-name-density~b,e0af076b-e3d0-4864-8e6f-16be85e9e2ca pkg-resc3225~(1210)-text-value-density~a,cb3e9c1a-08d2-4ccc-885f-c7548854e681 pkg-resc3225~(1210)-text-value-density~b,de9e465b-4753-482a-8e0d-f03b6bba3379 +pkg-resc3246~(1218)-3d,5c33b26e-3302-47ac-8e03-ca96dd3987cc pkg-resc3246~(1218)-footprint-density~a,3d38b934-b6be-439b-9a06-b4c359819908 pkg-resc3246~(1218)-footprint-density~b,6c06ffaf-bc52-4ef1-a5cf-e4941cb2a168 pkg-resc3246~(1218)-line-silkscreen-bot-density~a,65c30f1c-d81e-4952-9d66-0602f5401e22 @@ -990,6 +998,7 @@ pkg-resc3246~(1218)-text-name-density~a,58f0ffa3-2c9e-444e-a70b-667f25dda91b pkg-resc3246~(1218)-text-name-density~b,9f28365f-27c6-4e5b-aca6-4145007d787a pkg-resc3246~(1218)-text-value-density~a,0c918266-f8a7-4349-9db9-ed72fbb9526a pkg-resc3246~(1218)-text-value-density~b,c79e2fd9-c259-4966-8ecf-b5f6e24f3b0e +pkg-resc5025~(2010)-3d,e59e38f3-5ffd-447d-bda9-b1ef6aba4301 pkg-resc5025~(2010)-footprint-density~a,2534ea27-83f7-4913-9c69-7918afec2203 pkg-resc5025~(2010)-footprint-density~b,1e6bb096-359c-4a87-b29a-8c100f9ee5f5 pkg-resc5025~(2010)-line-silkscreen-bot-density~a,414e1fb9-fb2b-457c-86d2-62cb2311a4b0 @@ -1017,6 +1026,7 @@ pkg-resc5025~(2010)-text-name-density~a,31361b7f-3382-4d65-815b-c695b921f09b pkg-resc5025~(2010)-text-name-density~b,b836798a-708a-454c-86e3-fadcb58f5c22 pkg-resc5025~(2010)-text-value-density~a,adec4047-3988-4cf9-bdba-f70cb880c2e0 pkg-resc5025~(2010)-text-value-density~b,b6b4849b-45d0-43ff-8520-4833e5f79057 +pkg-resc6432~(2512)-3d,9e33cd83-86b3-4b6a-83e7-fe37c87a8d91 pkg-resc6432~(2512)-footprint-density~a,433d3637-0943-436a-b1c6-cac0b226a050 pkg-resc6432~(2512)-footprint-density~b,dd258204-3f2c-47fb-bac6-1346f03fcd1a pkg-resc6432~(2512)-line-silkscreen-bot-density~a,32d96587-c3dd-4825-a802-4e0ac3a66e5a