diff --git a/generate_do.py b/generate_do.py index d80f7c7..ab9907c 100644 --- a/generate_do.py +++ b/generate_do.py @@ -4,6 +4,7 @@ - JEDEC DO-214 https://www.jedec.org/system/files/docs/DO-214D.PDF """ +import sys from os import path from uuid import uuid4 @@ -16,9 +17,9 @@ Layer, Name, Polygon, Position, Position3D, Rotation, Rotation3D, Value, Version, Vertex, Width ) 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_NAME = 'librepcb-parts-generator (generate_do.py)' @@ -76,6 +77,7 @@ def generate_pkg( author: str, config: DoConfig, polarity: bool, + generate_3d_models: bool, pkgcat: str, version: str, create_date: Optional[str], @@ -112,7 +114,7 @@ def _uuid(identifier: str) -> str: deprecated=Deprecated(False), generated_by=GeneratedBy(''), categories=[Category(pkgcat)], - assembly_type=AssemblyType.AUTO, + assembly_type=AssemblyType.SMT, ) pads = [('c', 'C', -1), ('a', 'A', 1)] if polarity else [('1', '1', -1), ('2', '2', 1)] @@ -159,7 +161,7 @@ def _add_pads( stop_mask=StopMaskConfig.AUTO, solder_paste=SolderPasteConfig.AUTO, copper_clearance=CopperClearance(0.0), - function=PadFunction.UNSPECIFIED, + function=PadFunction.STANDARD_PAD, package_pad=PackagePadUuid(pad_uuid), holes=[], )) @@ -205,17 +207,17 @@ def _add_footprint( # # Documentation # - outline = Polygon( - uuid=_uuid(uuid_ns + 'outline'), + body = Polygon( + uuid=_uuid(uuid_ns + 'body'), layer=Layer('top_documentation'), width=Width(line_width), fill=Fill(False), grab_area=GrabArea(True), ) - _rect(outline, + _rect(body, left_edge + line_offset, right_edge - line_offset, bottom_edge + line_offset, top_edge - line_offset) - footprint.add_polygon(outline) + footprint.add_polygon(body) if polarity: band = Polygon( @@ -272,6 +274,35 @@ def _add_silkscreen( ss.add_vertex(Vertex(Position(x1, y0), Angle(0))) footprint.add_polygon(ss) + # + # Package outlines + # + lead_dx = config.total_length / 2 + lead_dy = config.contact_width / 2 + outline = Polygon( + uuid=_uuid(uuid_ns + 'outline'), + layer=Layer('top_package_outlines'), + width=Width(0.0), + fill=Fill(False), + grab_area=GrabArea(False), + vertices=[ + Vertex(Position(left_edge, top_edge), Angle(0)), + Vertex(Position(right_edge, top_edge), Angle(0)), + Vertex(Position(right_edge, lead_dy), Angle(0)), + Vertex(Position(lead_dx, lead_dy), Angle(0)), + Vertex(Position(lead_dx, -lead_dy), Angle(0)), + Vertex(Position(right_edge, -lead_dy), Angle(0)), + Vertex(Position(right_edge, bottom_edge), Angle(0)), + Vertex(Position(left_edge, bottom_edge), Angle(0)), + Vertex(Position(left_edge, -lead_dy), Angle(0)), + Vertex(Position(-lead_dx, -lead_dy), Angle(0)), + Vertex(Position(-lead_dx, lead_dy), Angle(0)), + Vertex(Position(left_edge, lead_dy), Angle(0)), + ], + ) + _rect(outline, left_edge, right_edge, bottom_edge, top_edge) + footprint.add_polygon(outline) + # # Courtyard # @@ -323,10 +354,86 @@ def _add_silkscreen( _add_footprint(package, Name('default'), 'default-') + # Generate 3D models + uuid_3d = _uuid('3d') + if generate_3d_models: + generate_3d(library, pkg_name, uuid_pkg, uuid_3d, config, polarity) + package.add_3d_model(Package3DModel(uuid_3d, Name(pkg_name))) + for footprint in package.footprints: + footprint.add_3d_model(Footprint3DModel(uuid_3d)) + package.serialize(path.join('out', library, 'pkg')) +def generate_3d( + library: str, + pkg_name: str, + uuid_pkg: str, + uuid_3d: str, + config: DoConfig, + polarity: bool, +) -> None: + import cadquery as cq + + from cadquery_helpers import StepAssembly, StepColor + + print(f'Generating pkg 3D model "{pkg_name}": {uuid_3d}') + + body_standoff = 0.15 + (0.05 + 0.3) / 2 # A2 + A3 + leg_height = (0.15 + 0.41) / 2 # c + leg_z_top = body_standoff + (config.body_height / 2) + (leg_height / 2) + bend_radius = 0.1 + (leg_height / 2) + body_chamfer_xy = 0.15 # rough estimation + body_chamfer_z = (config.body_height - leg_height) / 2 + bar_length = 0.2 * config.body_length + bar_width = config.body_width - (3 * body_chamfer_xy) + bar_height = 0.02 + bar_x = -(config.body_length - bar_length) / 2 + (2 * body_chamfer_xy) + + body = cq.Workplane('XY', origin=(0, 0, body_standoff + (config.body_height / 2))) \ + .box(config.body_length, config.body_width, config.body_height) \ + .edges('|Y').chamfer(body_chamfer_z, body_chamfer_xy) \ + .edges('|X').chamfer(body_chamfer_z, body_chamfer_xy) + bar = cq.Workplane('XY', origin=(bar_x, 0, body_standoff + config.body_height)) \ + .box(bar_length, bar_width, bar_height) + leg_path = cq.Workplane("XZ") \ + .hLine(-config.contact_length + (leg_height / 2) + bend_radius) \ + .ellipseArc(x_radius=bend_radius, y_radius=bend_radius, angle1=180, angle2=270, sense=-1) \ + .vLine(leg_z_top - leg_height - (2 * bend_radius)) \ + .ellipseArc(x_radius=bend_radius, y_radius=bend_radius, angle1=90, angle2=180, sense=-1) \ + .hLine(config.contact_length) + leg = cq.Workplane("ZY") \ + .rect(leg_height, config.contact_width) \ + .sweep(leg_path) + + assembly = StepAssembly(pkg_name) + assembly.add_body(body, 'body', StepColor.IC_BODY) + if polarity: + assembly.add_body(bar, 'bar', StepColor.IC_PIN1_DOT) + lead_x = (config.total_length / 2) - config.contact_length + assembly.add_body(leg, 'leg-1', StepColor.LEAD_SMT, + location=cq.Location((-lead_x, 0, leg_height / 2))) + assembly.add_body(leg, 'leg-2', StepColor.LEAD_SMT, + location=cq.Location((lead_x, 0, leg_height / 2), (0, 0, 1), 180)) + + # Save without fusing for slightly better minification. + out_path = path.join('out', library, 'pkg', uuid_pkg, f'{uuid_3d}.step') + assembly.save(out_path, fused=False) + + if __name__ == '__main__': + if '--help' in sys.argv or '-h' in sys.argv: + print(f'Usage: {sys.argv[0]} [--3d]') + print() + print('Options:') + print(' --3d Generate 3D models using cadquery') + sys.exit(1) + + generate_3d_models = '--3d' in sys.argv + if not generate_3d_models: + warning = 'Note: Not generating 3D models unless the "--3d" argument is passed in!' + print(f'\033[1;33m{warning}\033[0m') + configs = [] # body_length_nom (E1); body_width_nom (D); body_height_nom (A1) @@ -359,8 +466,9 @@ def _add_silkscreen( author='murray', config=config, polarity=True, + generate_3d_models=generate_3d_models, pkgcat='dcaa6b6c-0c55-43fd-a320-5dd74a2cdc85', - version='0.1', + version='0.2', create_date='2023-08-15T22:33:08Z', ) generate_pkg( @@ -368,8 +476,9 @@ def _add_silkscreen( author='murray', config=config, polarity=False, + generate_3d_models=generate_3d_models, pkgcat='dcaa6b6c-0c55-43fd-a320-5dd74a2cdc85', - version='0.1', + version='0.2', create_date='2023-08-15T22:33:08Z', ) diff --git a/uuid_cache_do.csv b/uuid_cache_do.csv index 7740a93..8fa7a31 100644 --- a/uuid_cache_do.csv +++ b/uuid_cache_do.csv @@ -1,7 +1,9 @@ +pkg-diom5226x240-3d,03f09b29-31af-4f37-a67e-86ffff65b00b +pkg-diom5226x240-default-body,a98a77ba-852b-4f4f-9fb1-2d771cd6b00d pkg-diom5226x240-default-cathodeband,d2d47d2a-9d38-46b7-a238-4df579f193f2 pkg-diom5226x240-default-courtyard,5be08b28-4b26-4ac1-8aae-09307f077511 pkg-diom5226x240-default-footprint,edff5314-16dd-4655-90e6-2866020d7176 -pkg-diom5226x240-default-outline,a98a77ba-852b-4f4f-9fb1-2d771cd6b00d +pkg-diom5226x240-default-outline,978044b1-5ca1-4328-bbaf-ac7713bc7016 pkg-diom5226x240-default-pad-lead,29930d39-ae65-47d3-8073-4d66adccbe7b pkg-diom5226x240-default-silkscreen-main,56a4957b-e544-4768-a57d-215c4b46b1a9 pkg-diom5226x240-default-text-name,ef246f99-08e7-47c0-b8c5-d4015a9af026 @@ -9,10 +11,12 @@ pkg-diom5226x240-default-text-value,2174a448-8b22-4072-8fb4-ad93ccba590d pkg-diom5226x240-pad-a,70bb734f-a4c2-49c2-871c-e5ae843dd50e pkg-diom5226x240-pad-c,fa650833-d0d0-4c48-b73a-bf6137341842 pkg-diom5226x240-pkg,09222d37-5ed9-4409-aa3d-2f6d78a4fdd8 +pkg-diom5226x295-3d,e5b1d3ae-5d12-4a59-9103-dd89763c485c +pkg-diom5226x295-default-body,0bde6393-3a14-421d-b2c2-7f41cda9bb94 pkg-diom5226x295-default-cathodeband,cd25abf0-8d01-4c2e-a7d6-227816e8ffb5 pkg-diom5226x295-default-courtyard,bae933f3-644d-47a1-902c-214d31972ba8 pkg-diom5226x295-default-footprint,fb5fd378-7ea9-4fc3-b5a9-b84df7c20f52 -pkg-diom5226x295-default-outline,0bde6393-3a14-421d-b2c2-7f41cda9bb94 +pkg-diom5226x295-default-outline,af8763fd-e6dc-4756-a798-97a3c4fb9e0a pkg-diom5226x295-default-pad-lead,5dcd43e2-5641-413d-bc09-ce024912d8ee pkg-diom5226x295-default-silkscreen-main,2f799b5c-bcb2-4748-9368-583530cf1bde pkg-diom5226x295-default-text-name,efe76fdf-0af0-443b-a934-3ea4031ffe3d @@ -20,10 +24,12 @@ pkg-diom5226x295-default-text-value,3661aa06-6df6-4c8a-81c1-e14e0fcf5d50 pkg-diom5226x295-pad-a,2dff4cbc-d050-4658-8f57-4b0ed0f9b876 pkg-diom5226x295-pad-c,d89f5209-c457-431e-bcfe-98296d8535b3 pkg-diom5226x295-pkg,f7380b5e-1cc4-46e3-94b9-dfa7e2785056 +pkg-diom5436x230-3d,3ca99c30-7f5f-4048-a51a-bf9a7710a00b +pkg-diom5436x230-default-body,af9979e6-981d-4ac0-9e40-a596ffb460a6 pkg-diom5436x230-default-cathodeband,b00d514f-4304-48f4-a4b8-87550b94bc4e pkg-diom5436x230-default-courtyard,f4d4c0b4-dff1-4788-8f3a-bb07ed507336 pkg-diom5436x230-default-footprint,e1172e43-3f4b-4b2f-b976-c01936abd54e -pkg-diom5436x230-default-outline,af9979e6-981d-4ac0-9e40-a596ffb460a6 +pkg-diom5436x230-default-outline,a9b1a299-9041-4f04-a31e-a93c9feda654 pkg-diom5436x230-default-pad-lead,ea130e66-3b3e-4a2b-a91d-9ce479735ccc pkg-diom5436x230-default-silkscreen-main,4ecfd47b-58f0-49fe-b4af-2529e510f6e9 pkg-diom5436x230-default-text-name,3aed5754-3dc4-43c2-aa57-33072b7e3552 @@ -31,10 +37,12 @@ pkg-diom5436x230-default-text-value,7d38931f-28be-48a7-af5d-9f53270c5007 pkg-diom5436x230-pad-a,b782f0d8-3175-4405-ad7d-28132b5d535a pkg-diom5436x230-pad-c,8be51409-30aa-42d6-98e4-fead8c6c400f pkg-diom5436x230-pkg,4cfa109d-bc5f-4268-8901-cc2a4349704d +pkg-diom7959x230-3d,1ab7bd40-ca78-4fde-8f0e-2ee718c17030 +pkg-diom7959x230-default-body,9383bc4d-452d-4f76-a33a-5bbc9064189b pkg-diom7959x230-default-cathodeband,e8c93dd1-4e7d-41c9-8451-62d05fe8549e pkg-diom7959x230-default-courtyard,9dd926ae-6919-4180-bfa2-76d42d98b685 pkg-diom7959x230-default-footprint,1aa00b82-2bfe-4c4f-9149-dcf67033f0ac -pkg-diom7959x230-default-outline,9383bc4d-452d-4f76-a33a-5bbc9064189b +pkg-diom7959x230-default-outline,ac6998b6-7d17-4077-a38f-96946ca285ad pkg-diom7959x230-default-pad-lead,53798a86-ba7e-45d6-916f-a4e9d3b173ac pkg-diom7959x230-default-silkscreen-main,fdb2553c-9668-412f-bcc1-d4a81f3f4762 pkg-diom7959x230-default-text-name,d9d8cb9c-a8cd-451d-bdc0-b4046af51ef0 @@ -42,9 +50,11 @@ pkg-diom7959x230-default-text-value,4c785cb8-3275-434e-a0bd-23f5493e9f83 pkg-diom7959x230-pad-a,6170f57b-d9ef-4138-9747-12f56bd83427 pkg-diom7959x230-pad-c,66d018a3-81ba-4fb4-badc-8bbb0678e808 pkg-diom7959x230-pkg,4a0138a3-fa5f-4e17-8bd9-14a3d1817a98 +pkg-dionm5226x240-3d,0889a69a-5961-4e7e-9b29-3b52b1251efd +pkg-dionm5226x240-default-body,e3dc664f-db86-480c-b979-774782e56c88 pkg-dionm5226x240-default-courtyard,845ef858-e22d-4e61-8229-c8770994c325 pkg-dionm5226x240-default-footprint,82bf40ff-a368-4577-bc71-8034bed3ca8b -pkg-dionm5226x240-default-outline,e3dc664f-db86-480c-b979-774782e56c88 +pkg-dionm5226x240-default-outline,f6c49d7d-b057-4b56-b2c0-a7e9e8accaeb pkg-dionm5226x240-default-pad-lead,c95f42f7-51bb-412f-8541-1ca30ed2d392 pkg-dionm5226x240-default-silkscreen-bot,c26c01ac-3a48-4d59-86e7-195de3791bca pkg-dionm5226x240-default-silkscreen-top,a120d8ea-e8db-45e9-b848-1cc8cbb38447 @@ -53,9 +63,11 @@ pkg-dionm5226x240-default-text-value,8413a6d8-f61f-4676-a516-213f9daf557a pkg-dionm5226x240-pad-1,22313f50-6c0b-4e17-960b-03a57c0bf6a6 pkg-dionm5226x240-pad-2,36983fd8-d9c6-47b1-8fa2-bb55268f7397 pkg-dionm5226x240-pkg,11a510a7-e928-4797-8a5a-4e66bc126c7c +pkg-dionm5226x295-3d,caf6cb8b-9cce-49e0-be47-5935210440dc +pkg-dionm5226x295-default-body,8d9f8c9c-a29d-4453-9c80-434dd4097947 pkg-dionm5226x295-default-courtyard,b8e6f33e-8803-4d5f-b7c1-5aced330acdb pkg-dionm5226x295-default-footprint,bccdf787-faa0-4436-a96e-27a8665819a7 -pkg-dionm5226x295-default-outline,8d9f8c9c-a29d-4453-9c80-434dd4097947 +pkg-dionm5226x295-default-outline,6da94a9b-d1ca-47c9-8609-cfda9d87a22b pkg-dionm5226x295-default-pad-lead,013b241e-87a5-4ed0-81b4-7a835309f2b6 pkg-dionm5226x295-default-silkscreen-bot,8f37a2ea-a2b6-4db1-bac7-14944aa93116 pkg-dionm5226x295-default-silkscreen-top,e607bb3b-fc6d-4b67-9ffc-719955f6eec7 @@ -64,9 +76,11 @@ pkg-dionm5226x295-default-text-value,bb2f9eab-ca5a-4b92-bf49-709a5fa3203a pkg-dionm5226x295-pad-1,a2963994-0109-44b8-a1d9-13643aa1c986 pkg-dionm5226x295-pad-2,a21cd98c-6e8b-461f-a554-269b85cd6610 pkg-dionm5226x295-pkg,6cc5ff9c-4400-44ca-8671-870b490f8ab5 +pkg-dionm5436x230-3d,9150402b-3fec-4d15-bdc3-ebfd1ba39246 +pkg-dionm5436x230-default-body,755ef9a7-775e-489b-9e33-7e30285e77c7 pkg-dionm5436x230-default-courtyard,6078faf8-4a7d-4a8e-ad8b-14ec8d752d40 pkg-dionm5436x230-default-footprint,14647a56-930d-402b-89ea-fac72e7a98b6 -pkg-dionm5436x230-default-outline,755ef9a7-775e-489b-9e33-7e30285e77c7 +pkg-dionm5436x230-default-outline,53826685-4d8f-40d7-a1d5-a68484b10192 pkg-dionm5436x230-default-pad-lead,bdbcbd6d-7b39-48db-a60d-449b469257bc pkg-dionm5436x230-default-silkscreen-bot,311492e4-ba41-4ed9-8520-b250357fa339 pkg-dionm5436x230-default-silkscreen-top,776e3a00-0b79-4de9-b10f-eaa3617c6f4a @@ -75,9 +89,11 @@ pkg-dionm5436x230-default-text-value,0010d2e1-7192-4901-864a-ee52c8cf6b04 pkg-dionm5436x230-pad-1,bce9702a-6106-4ebc-9ce0-0f1ce3a1b837 pkg-dionm5436x230-pad-2,d03a99a6-5ef9-4c0c-9ea4-c18397f0cb5a pkg-dionm5436x230-pkg,fc5f3f2b-8773-4069-9961-7c14a6674568 +pkg-dionm7959x230-3d,e4a00e81-50a1-4256-94e6-35719b68be53 +pkg-dionm7959x230-default-body,746bb004-0e4b-4ee2-99ee-ef755fe2370a pkg-dionm7959x230-default-courtyard,a9531d97-7084-44b9-91a1-0e5ebf219e94 pkg-dionm7959x230-default-footprint,4f80d30d-9899-4208-96ed-69660c4d4c2b -pkg-dionm7959x230-default-outline,746bb004-0e4b-4ee2-99ee-ef755fe2370a +pkg-dionm7959x230-default-outline,f10a89da-fe19-43df-9a03-51d0d9d3eac5 pkg-dionm7959x230-default-pad-lead,899cc37b-6733-4030-9ba8-6373ab55d82f pkg-dionm7959x230-default-silkscreen-bot,e2c048ed-b439-4ca1-9186-34f9e62756bc pkg-dionm7959x230-default-silkscreen-top,8f7817e3-4b44-476c-9a7c-6a5aeea77450