diff --git a/.gitignore b/.gitignore index 1d34517579..d2c71f2214 100644 --- a/.gitignore +++ b/.gitignore @@ -117,8 +117,9 @@ CMakeSettings.json i18n_status.svg i18n_status.csv -# Project local settings files (in demos and qa tests) +# Project local settings files and backups (in demos and qa tests) *.kicad_prl +*-backups # Don't actually ignore any of these files, since we need them in the tree !resources/linux/icons/hicolor/**/**/* diff --git a/pcbnew/swig/board.i b/pcbnew/swig/board.i index 1d906069a3..33ce757eef 100644 --- a/pcbnew/swig/board.i +++ b/pcbnew/swig/board.i @@ -94,6 +94,20 @@ HANDLE_EXCEPTIONS(BOARD::TracksInNetBetweenPoints) return %} } +%extend std::deque +{ + %pythoncode + %{ + def __iter__(self): + it = self.iterator() + try: + while True: + item = it.next() # throws StopIteration when iterator reached the end. + yield item.Cast() + except StopIteration: + return + %} +} %extend BOARD { diff --git a/pcbnew/swig/board_item.i b/pcbnew/swig/board_item.i index 143e68818b..8b2483110e 100644 --- a/pcbnew/swig/board_item.i +++ b/pcbnew/swig/board_item.i @@ -62,6 +62,7 @@ class FP_SHAPE; class PAD; class TRACK; class VIA; +class ARC; class ZONE; class FP_ZONE; class PCB_TARGET; @@ -87,6 +88,7 @@ static FP_SHAPE* Cast_to_FP_SHAPE( BOARD_ITEM* ); static PAD* Cast_to_PAD( BOARD_ITEM* ); static TRACK* Cast_to_TRACK( BOARD_ITEM* ); static VIA* Cast_to_VIA( BOARD_ITEM* ); +static ARC* Cast_to_ARC( BOARD_ITEM* ); static ZONE* Cast_to_ZONE( BOARD_ITEM* ); static FP_ZONE* Cast_to_FP_ZONE( BOARD_ITEM* ); static PCB_TARGET* Cast_to_PCB_TARGET( BOARD_ITEM* ); @@ -112,6 +114,7 @@ static FP_SHAPE* Cast_to_FP_SHAPE( BOARD_ITEM* ); static PAD* Cast_to_PAD( BOARD_ITEM* ); static TRACK* Cast_to_TRACK( BOARD_ITEM* ); static VIA* Cast_to_VIA( BOARD_ITEM* ); +static ARC* Cast_to_ARC( BOARD_ITEM* ); static ZONE* Cast_to_ZONE( BOARD_ITEM* ); static FP_ZONE* Cast_to_FP_ZONE( BOARD_ITEM* ); static PCB_TARGET* Cast_to_PCB_TARGET( BOARD_ITEM* ); @@ -153,6 +156,8 @@ static PCB_TARGET* Cast_to_PCB_TARGET( BOARD_ITEM* ); return Cast_to_VIA(self) elif ct=="TRACK": return Cast_to_TRACK(self) + elif ct=="ARC": + return Cast_to_ARC(self) elif ct=="PCB_TARGET": return Cast_to_PCB_TARGET(self) elif ct=="ZONE": @@ -200,6 +205,7 @@ static FP_SHAPE* Cast_to_FP_SHAPE( BOARD_ITEM* self ) { static PAD* Cast_to_PAD( BOARD_ITEM* self ) { return dynamic_cast(self); } static TRACK* Cast_to_TRACK( BOARD_ITEM* self ) { return dynamic_cast(self); } static VIA* Cast_to_VIA( BOARD_ITEM* self ) { return dynamic_cast(self); } +static ARC* Cast_to_ARC( BOARD_ITEM* self ) { return dynamic_cast(self); } static ZONE* Cast_to_ZONE( BOARD_ITEM* self ) { return dynamic_cast(self); } static FP_ZONE* Cast_to_FP_ZONE( BOARD_ITEM* self ) { return dynamic_cast(self); } static PCB_TARGET* Cast_to_PCB_TARGET( BOARD_ITEM* self ) { return dynamic_cast(self); } diff --git a/qa/data/tracks_arcs_vias.kicad_pcb b/qa/data/tracks_arcs_vias.kicad_pcb new file mode 100644 index 0000000000..70cb6bd73e --- /dev/null +++ b/qa/data/tracks_arcs_vias.kicad_pcb @@ -0,0 +1,162 @@ +(kicad_pcb (version 20210126) (generator pcbnew) + + (general + (thickness 1.6) + ) + + (paper "A4") + (layers + (0 "F.Cu" signal) + (31 "B.Cu" signal) + (32 "B.Adhes" user "B.Adhesive") + (33 "F.Adhes" user "F.Adhesive") + (34 "B.Paste" user) + (35 "F.Paste" user) + (36 "B.SilkS" user "B.Silkscreen") + (37 "F.SilkS" user "F.Silkscreen") + (38 "B.Mask" user) + (39 "F.Mask" user) + (40 "Dwgs.User" user "User.Drawings") + (41 "Cmts.User" user "User.Comments") + (42 "Eco1.User" user "User.Eco1") + (43 "Eco2.User" user "User.Eco2") + (44 "Edge.Cuts" user) + (45 "Margin" user) + (46 "B.CrtYd" user "B.Courtyard") + (47 "F.CrtYd" user "F.Courtyard") + (48 "B.Fab" user) + (49 "F.Fab" user) + (50 "User.1" user) + (51 "User.2" user) + (52 "User.3" user) + (53 "User.4" user) + (54 "User.5" user) + (55 "User.6" user) + (56 "User.7" user) + (57 "User.8" user) + (58 "User.9" user) + ) + + (setup + (pcbplotparams + (layerselection 0x00010fc_ffffffff) + (disableapertmacros false) + (usegerberextensions false) + (usegerberattributes true) + (usegerberadvancedattributes true) + (creategerberjobfile true) + (svguseinch false) + (svgprecision 6) + (excludeedgelayer true) + (plotframeref false) + (viasonmask false) + (mode 1) + (useauxorigin false) + (hpglpennumber 1) + (hpglpenspeed 20) + (hpglpendiameter 15.000000) + (dxfpolygonmode true) + (dxfimperialunits true) + (dxfusepcbnewfont true) + (psnegative false) + (psa4output false) + (plotreference true) + (plotvalue true) + (plotinvisibletext false) + (sketchpadsonfab false) + (subtractmaskfromsilk false) + (outputformat 1) + (mirror false) + (drillshape 1) + (scaleselection 1) + (outputdirectory "") + ) + ) + + + (net 0 "") + (net 1 "McNetty") + + (footprint "Package_SO:SOP-8_3.76x4.96mm_P1.27mm" (layer "F.Cu") + (tedit 5D9F72B1) (tstamp 58309f6f-ebc9-414d-b266-9e4aa4940358) + (at 35.5 33) + (descr "SOP, 8 Pin (https://ww2.minicircuits.com/case_style/XX211.pdf), generated with kicad-footprint-generator ipc_gullwing_generator.py") + (tags "SOP SO") + (attr smd) + (fp_text reference "REF**" (at 0 -3.43) (layer "F.SilkS") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 1b65467e-c11c-47fa-a54b-a7c92d06a5e8) + ) + (fp_text value "SOP-8_3.76x4.96mm_P1.27mm" (at 0 3.43) (layer "F.Fab") + (effects (font (size 1 1) (thickness 0.15))) + (tstamp 5e08ca10-0de1-444e-90e3-089867279474) + ) + (fp_text user "${REFERENCE}" (at 0 0) (layer "F.Fab") + (effects (font (size 0.94 0.94) (thickness 0.14))) + (tstamp a51694be-6253-4c97-b997-e8da5eecbb0e) + ) + (fp_line (start 0 -2.59) (end 1.88 -2.59) (layer "F.SilkS") (width 0.12) (tstamp 422b8774-ff83-447b-8875-c48eb0f4e99d)) + (fp_line (start 0 2.59) (end 1.88 2.59) (layer "F.SilkS") (width 0.12) (tstamp 6b30b508-bb7b-4201-8ed1-ace5e22ae055)) + (fp_line (start 0 2.59) (end -1.88 2.59) (layer "F.SilkS") (width 0.12) (tstamp 8a960c65-6e9c-43db-95b5-244cfe50a460)) + (fp_line (start 0 -2.59) (end -3.525 -2.59) (layer "F.SilkS") (width 0.12) (tstamp be9e236a-c4ef-49d1-9722-193215303b0a)) + (fp_line (start -3.78 -2.73) (end -3.78 2.73) (layer "F.CrtYd") (width 0.05) (tstamp 5508a189-7818-4f39-9c80-d64946a20f5e)) + (fp_line (start 3.78 -2.73) (end -3.78 -2.73) (layer "F.CrtYd") (width 0.05) (tstamp 74759c83-4571-4db9-a730-7d1996fdadf3)) + (fp_line (start 3.78 2.73) (end 3.78 -2.73) (layer "F.CrtYd") (width 0.05) (tstamp c49c5543-47d3-49b7-8bbe-327acf2c99c3)) + (fp_line (start -3.78 2.73) (end 3.78 2.73) (layer "F.CrtYd") (width 0.05) (tstamp f544c2d8-b15f-48f1-bfe0-5aaa296ace0e)) + (fp_line (start -1.88 -1.54) (end -0.94 -2.48) (layer "F.Fab") (width 0.1) (tstamp 22951f42-4851-4921-acfe-9dc069c645c5)) + (fp_line (start 1.88 2.48) (end -1.88 2.48) (layer "F.Fab") (width 0.1) (tstamp 88bb9294-967e-47e9-bb31-5f8c851b0e21)) + (fp_line (start 1.88 -2.48) (end 1.88 2.48) (layer "F.Fab") (width 0.1) (tstamp aafce5d0-596c-4ee9-b35a-0001d3650fb8)) + (fp_line (start -0.94 -2.48) (end 1.88 -2.48) (layer "F.Fab") (width 0.1) (tstamp e687c865-92e7-431f-a080-dc6cccc884f5)) + (fp_line (start -1.88 2.48) (end -1.88 -1.54) (layer "F.Fab") (width 0.1) (tstamp e723b8b9-b3ce-44fa-a388-e006d727c019)) + (pad "1" smd roundrect (at -2.5375 -1.905) (locked) (size 1.975 0.65) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) + (net 1 "McNetty") (tstamp b14792b9-a081-42df-8ab3-8cf0f1ee2010)) + (pad "2" smd roundrect (at -2.5375 -0.635) (locked) (size 1.975 0.65) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp d1292c72-59fc-4daf-8a1f-b49ec2eb2b6b)) + (pad "3" smd roundrect (at -2.5375 0.635) (locked) (size 1.975 0.65) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 87a9e845-8d9d-475e-8a7e-258c0e1ddeb1)) + (pad "4" smd roundrect (at -2.5375 1.905) (locked) (size 1.975 0.65) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp ed097c33-0e1b-4e59-8531-6894e8b5b91a)) + (pad "5" smd roundrect (at 2.5375 1.905) (locked) (size 1.975 0.65) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 9ace56d1-f273-466f-ad46-2d68d6c4b40a)) + (pad "6" smd roundrect (at 2.5375 0.635) (locked) (size 1.975 0.65) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) + (net 1 "McNetty") (tstamp e68b73ec-e76e-4512-8745-2dc383bd16d7)) + (pad "7" smd roundrect (at 2.5375 -0.635) (locked) (size 1.975 0.65) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 3a0195b5-271e-4051-aa7a-54237a29500d)) + (pad "8" smd roundrect (at 2.5375 -1.905) (locked) (size 1.975 0.65) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 4c171eb1-cec7-4313-981a-3985c738b1ad)) + (model "${KISYS3DMOD}/Package_SO.3dshapes/SOP-8_3.76x4.96mm_P1.27mm.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (gr_rect (start 17 16.5) (end 56 51) (layer "Edge.Cuts") (width 0.1) (fill none) (tstamp e3f08f54-b98f-4d4e-8bf5-3552f64c718f)) + + (segment (start 29.381843 35.118156) (end 29 35.5) (width 0.25) (layer "F.Cu") (net 0) (tstamp 3b5d67ef-2181-444a-b3d4-ffb387b384f4)) + (segment (start 28 37.914213) (end 28 39) (width 0.25) (layer "F.Cu") (net 0) (tstamp 5b12cfbe-66bd-4c13-ab5c-9ba796d7a78e)) + (segment (start 35.5 32.5) (end 35.635 32.365) (width 0.25) (layer "F.Cu") (net 0) (tstamp 7c0cb8dd-5fa9-4105-a133-e818c51ff27b)) + (segment (start 28.707107 40.707107) (end 29 41) (width 0.25) (layer "F.Cu") (net 0) (tstamp a37ea611-411a-4068-b4fe-e6c0513cdcd5)) + (segment (start 35.635 32.365) (end 38.0375 32.365) (width 0.25) (layer "F.Cu") (net 0) (tstamp b3d4fe9c-0354-4101-9923-bb4c27387bb8)) + (via (at 35.5 32.5) (size 0.8) (drill 0.4) (layers "F.Cu" "B.Cu") (net 0) (tstamp c3885fb5-6987-48b8-b7db-b6f503d67175)) + (via (at 29 41) (size 0.8) (drill 0.4) (layers "F.Cu" "B.Cu") (net 0) (tstamp f28f5f88-9f3a-4fe2-8d1a-0babec8fe5d2)) + (arc (start 29 35.5) (mid 28.259892 36.60765) (end 28 37.914213) (width 0.25) (layer "F.Cu") (net 0) (tstamp 6f36121a-dffc-4c29-8105-42f651bbab96)) + (arc (start 28 39) (mid 28.183771 39.92388) (end 28.707107 40.707107) (width 0.25) (layer "F.Cu") (net 0) (tstamp 8108710e-231b-4e6a-80d0-440fa9f48521)) + (arc (start 32.9625 33.635) (mid 31.024663 34.02046) (end 29.381843 35.118156) (width 0.25) (layer "F.Cu") (net 0) (tstamp 8389b74e-f6e7-4c8a-9824-41098548832a)) + (segment (start 35.5 37.085787) (end 35.5 32.5) (width 0.25) (layer "B.Cu") (net 0) (tstamp 38c52582-abda-4278-8b98-6af91cf553d4)) + (segment (start 29 41) (end 30.87868 41) (width 0.25) (layer "B.Cu") (net 0) (tstamp f0bf4a85-e807-4677-9e8a-00577e1137b4)) + (arc (start 34.5 39.5) (mid 35.240108 38.39235) (end 35.5 37.085787) (width 0.25) (layer "B.Cu") (net 0) (tstamp 825f1da2-6652-47c5-bf42-9dddc8293a36)) + (arc (start 30.87868 41) (mid 32.838524 40.610163) (end 34.5 39.5) (width 0.25) (layer "B.Cu") (net 0) (tstamp e5273671-3aaa-4947-bdfd-49bb1c112cf7)) + (segment (start 42.340283 24.843644) (end 42.5 25) (width 0.25) (layer "F.Cu") (net 1) (tstamp 3548c1d0-b54d-42f8-a856-3a63a6d65fcb)) + (segment (start 40.966975 33.635) (end 38.0375 33.635) (width 0.25) (layer "F.Cu") (net 1) (tstamp 49102581-8aff-4334-a69a-10e5e98c9e76)) + (segment (start 27 27.585787) (end 27 26.5) (width 0.25) (layer "F.Cu") (net 1) (tstamp 5d61f1c1-b5e5-4b52-98e1-cc149d9498a4)) + (segment (start 27.707107 24.792893) (end 28 24.5) (width 0.25) (layer "F.Cu") (net 1) (tstamp 639d51d3-270a-4c4e-a91b-f334ef31fa4b)) + (segment (start 42.93934 32.56066) (end 42.5 33) (width 0.25) (layer "F.Cu") (net 1) (tstamp 903d46c6-6a93-4262-9402-0df9b257439d)) + (segment (start 32.9625 31.095) (end 30.643563 31.095) (width 0.25) (layer "F.Cu") (net 1) (tstamp 92042dc3-6ea5-4329-9faa-8e27721114af)) + (segment (start 44 28.62132) (end 44 30) (width 0.25) (layer "F.Cu") (net 1) (tstamp 98bdb7bb-500d-4ad5-af4c-47f43ad873c8)) + (segment (start 30.414213 23.5) (end 38.87868 23.5) (width 0.5) (layer "F.Cu") (net 1) (tstamp ae2386da-5d7b-450d-b289-db8ed22fef26)) + (segment (start 28.131219 30.128382) (end 28 30) (width 0.25) (layer "F.Cu") (net 1) (tstamp c23a80a7-5bfc-4b61-99b8-5197ce24db86)) + (arc (start 44 30) (mid 43.724343 31.385819) (end 42.93934 32.56066) (width 0.25) (layer "F.Cu") (net 1) (tstamp 44781cdf-da73-4be3-a07f-9982ac604288)) + (arc (start 38.87868 23.5) (mid 40.838524 23.889837) (end 42.5 25) (width 0.25) (layer "F.Cu") (net 1) (tstamp 5a5e48fd-e572-44d2-9daf-bfb80a0236c7)) + (arc (start 28 24.5) (mid 29.10765 23.759892) (end 30.414213 23.5) (width 0.25) (layer "F.Cu") (net 1) (tstamp 5a89c2f4-8e99-4560-9ae7-f6b71e05c612)) + (arc (start 42.5 25) (mid 43.610163 26.661476) (end 44 28.62132) (width 0.25) (layer "F.Cu") (net 1) (tstamp 68bb9197-0a77-47aa-92fd-cc6756859074)) + (arc (start 42.5 33) (mid 41.796643 33.469969) (end 40.966975 33.635) (width 0.25) (layer "F.Cu") (net 1) (tstamp bf406f8f-78e6-48b8-9e55-98983db24164)) + (arc (start 30.643563 31.095) (mid 29.212877 30.810419) (end 28 30) (width 0.25) (layer "F.Cu") (net 1) (tstamp cfb37722-e3d9-48ee-a976-00e6d7c02db7)) + (arc (start 28 30) (mid 27.259892 28.89235) (end 27 27.585787) (width 0.25) (layer "F.Cu") (net 1) (tstamp e24967b1-33ba-4bad-9692-af4f89bbda0c)) + (arc (start 27 26.5) (mid 27.183771 25.57612) (end 27.707107 24.792893) (width 0.25) (layer "F.Cu") (net 1) (tstamp f121685b-fe56-4138-9696-f5a078f65a96)) + +) diff --git a/qa/data/tracks_arcs_vias.kicad_pro b/qa/data/tracks_arcs_vias.kicad_pro new file mode 100644 index 0000000000..1cb41f407e --- /dev/null +++ b/qa/data/tracks_arcs_vias.kicad_pro @@ -0,0 +1,175 @@ +{ + "board": { + "design_settings": { + "defaults": { + "board_outline_line_width": 0.09999999999999999, + "copper_line_width": 0.19999999999999998, + "copper_text_italic": false, + "copper_text_size_h": 1.5, + "copper_text_size_v": 1.5, + "copper_text_thickness": 0.3, + "copper_text_upright": false, + "courtyard_line_width": 0.049999999999999996, + "dimension_precision": 4, + "dimension_units": 3, + "dimensions": { + "arrow_length": 1270000, + "extension_offset": 500000, + "keep_text_aligned": true, + "suppress_zeroes": false, + "text_position": 0, + "units_format": 1 + }, + "fab_line_width": 0.09999999999999999, + "fab_text_italic": false, + "fab_text_size_h": 1.0, + "fab_text_size_v": 1.0, + "fab_text_thickness": 0.15, + "fab_text_upright": false, + "other_line_width": 0.15, + "other_text_italic": false, + "other_text_size_h": 1.0, + "other_text_size_v": 1.0, + "other_text_thickness": 0.15, + "other_text_upright": false, + "pads": { + "drill": 0.762, + "height": 1.524, + "width": 1.524 + }, + "silk_line_width": 0.15, + "silk_text_italic": false, + "silk_text_size_h": 1.0, + "silk_text_size_v": 1.0, + "silk_text_thickness": 0.15, + "silk_text_upright": false, + "zones": { + "45_degree_only": false, + "min_clearance": 0.508 + } + }, + "diff_pair_dimensions": [], + "drc_exclusions": [], + "meta": { + "version": 1 + }, + "rule_severities": { + "annular_width": "error", + "clearance": "error", + "copper_edge_clearance": "error", + "courtyards_overlap": "error", + "diff_pair_gap_out_of_range": "error", + "diff_pair_uncoupled_length_too_long": "error", + "drill_out_of_range": "error", + "duplicate_footprints": "warning", + "extra_footprint": "warning", + "hole_clearance": "error", + "hole_near_hole": "error", + "invalid_outline": "error", + "item_on_disabled_layer": "error", + "items_not_allowed": "error", + "length_out_of_range": "error", + "malformed_courtyard": "error", + "microvia_drill_out_of_range": "error", + "missing_courtyard": "ignore", + "missing_footprint": "warning", + "net_conflict": "warning", + "npth_inside_courtyard": "ignore", + "padstack": "error", + "pth_inside_courtyard": "ignore", + "shorting_items": "error", + "silk_over_copper": "error", + "silk_overlap": "error", + "skew_out_of_range": "error", + "too_many_vias": "error", + "track_dangling": "warning", + "track_width": "error", + "tracks_crossing": "error", + "unconnected_items": "error", + "unresolved_variable": "error", + "via_dangling": "warning", + "zone_has_empty_net": "error", + "zones_intersect": "error" + }, + "rules": { + "allow_blind_buried_vias": false, + "allow_microvias": false, + "max_error": 0.005, + "min_clearance": 0.0, + "min_copper_edge_clearance": 0.0, + "min_hole_clearance": 0.0, + "min_hole_to_hole": 0.25, + "min_microvia_diameter": 0.19999999999999998, + "min_microvia_drill": 0.09999999999999999, + "min_silk_clearance": 0.0, + "min_through_hole_diameter": 0.3, + "min_track_width": 0.19999999999999998, + "min_via_annular_width": 0.049999999999999996, + "min_via_diameter": 0.39999999999999997, + "solder_mask_clearance": 0.0, + "solder_mask_min_width": 0.0, + "solder_paste_clearance": 0.0, + "solder_paste_margin_ratio": 0.0 + }, + "track_widths": [], + "via_dimensions": [], + "zones_allow_external_fillets": false, + "zones_use_no_outline": true + }, + "layer_presets": [] + }, + "boards": [], + "cvpcb": { + "equivalence_files": [] + }, + "libraries": { + "pinned_footprint_libs": [], + "pinned_symbol_libs": [] + }, + "meta": { + "filename": "tracks_arcs_vias.kicad_pro", + "version": 1 + }, + "net_settings": { + "classes": [ + { + "bus_width": 6.0, + "clearance": 0.2, + "diff_pair_gap": 0.25, + "diff_pair_via_gap": 0.25, + "diff_pair_width": 0.2, + "line_style": 0, + "microvia_diameter": 0.3, + "microvia_drill": 0.1, + "name": "Default", + "pcb_color": "rgba(0, 0, 0, 0.000)", + "schematic_color": "rgba(0, 0, 0, 0.000)", + "track_width": 0.25, + "via_diameter": 0.8, + "via_drill": 0.4, + "wire_width": 6.0 + } + ], + "meta": { + "version": 0 + }, + "net_colors": null + }, + "pcbnew": { + "last_paths": { + "gencad": "", + "idf": "", + "netlist": "", + "specctra_dsn": "", + "step": "", + "vrml": "" + }, + "page_layout_descr_file": "" + }, + "schematic": { + "legacy_lib_dir": "", + "legacy_lib_list": [] + }, + "sheets": [], + "text_variables": {} +} diff --git a/qa/data/tracks_arcs_vias.kicad_sch b/qa/data/tracks_arcs_vias.kicad_sch new file mode 100644 index 0000000000..178c9332b4 --- /dev/null +++ b/qa/data/tracks_arcs_vias.kicad_sch @@ -0,0 +1,5 @@ +(kicad_sch (version 20210126) (generator eeschema) + (paper "A4") + (lib_symbols) + (symbol_instances) +) diff --git a/qa/testcases/test_004_tracks.py b/qa/testcases/test_004_tracks.py new file mode 100644 index 0000000000..6e7a2b0f56 --- /dev/null +++ b/qa/testcases/test_004_tracks.py @@ -0,0 +1,31 @@ +import unittest +import pcbnew + +class TestTracks(unittest.TestCase): + + def setUp(self): + self.pcb = pcbnew.LoadBoard("data/tracks_arcs_vias.kicad_pcb") + + def test_tracks(self): + tracks = [t for t in self.pcb.Tracks() if t.GetClass() == 'TRACK'] + self.assertEqual(16, len(tracks)) + track = sorted(tracks, key=lambda t: [t.GetStart()[0], t.GetStart()[1]])[0] + self.assertEqual([27000000, 27585787], [track.GetStart()[0], track.GetStart()[1]]) + self.assertEqual([27000000, 26500000], [track.GetEnd()[0], track.GetEnd()[1]]) + self.assertEqual(250000, track.GetWidth()) + self.assertEqual('McNetty', track.GetNetname()) + + def test_arcs(self): + arcs = [t for t in self.pcb.Tracks() if t.GetClass() == 'ARC'] + self.assertEqual(13, len(arcs)) + arc = sorted(arcs, key=lambda t: [t.GetStart()[0], t.GetStart()[1]])[0] + self.assertEqual([29414211, 26499999], [arc.GetCenter()[0], arc.GetCenter()[1]]) + self.assertEqual([1800, 2250], [round(arc.GetArcAngleStart()), round(arc.GetArcAngleEnd())]) + self.assertEqual(2414211, round(arc.GetRadius())) + + def test_vias(self): + vias = [t for t in self.pcb.Tracks() if t.GetClass() == 'VIA'] + self.assertEqual(2, len(vias)) + via = sorted(vias, key=lambda t: [t.GetStart()[0], t.GetStart()[1]])[0] + self.assertEqual([29000000, 41000000], [via.GetStart()[0], via.GetStart()[1]]) + self.assertEqual(400000, via.GetDrillValue())