50 {
"ClaySight_MK1",
"ClaySight_MK1.asc" },
51 {
"TMS1mmX19",
"TMS1mmX19.asc" },
52 {
"MC4_PLUS_CSHAPE",
"MC4_PLUS_CSHAPE.asc" },
53 {
"MC2_PLUS_REV1",
"MC2_PLUS_REV1.asc" },
54 {
"Ems4_Rev2",
"Ems4_Rev2.asc" },
55 {
"LCORE_4",
"LCORE_4.asc" },
56 {
"LCORE_2",
"LCORE_2.asc" },
57 {
"Dexter_MotorCtrl",
"Dexter_MotorCtrl.asc" },
58 {
"MAIS_FC",
"MAIS_FC.asc" },
59 {
"ClaySight_MK2",
"ClaySight_MK2.asc" },
79 aBoard.
dir <<
" should be a readable PADS file" );
81 std::unique_ptr<BOARD> board;
85 board.reset( plugin.
LoadBoard( filename,
nullptr,
nullptr,
nullptr ) );
87 catch(
const std::exception& e )
89 BOOST_WARN_MESSAGE(
false,
90 aBoard.
dir <<
" threw exception during load: " << e.what() );
94 BOOST_REQUIRE_MESSAGE( board !=
nullptr, aBoard.
dir <<
" failed to load" );
96 aBoard.
dir <<
" should have footprints" );
116 BOOST_WARN_MESSAGE( board->Tracks().size() > 0,
117 aBoard.
dir <<
" has no tracks (parser may not support this format version)" );
119 if( board->Tracks().size() > 0 && board->Footprints().size() > 0 )
124 for(
FOOTPRINT* fp : board->Footprints() )
125 fpBbox.
Merge( fp->GetBoundingBox() );
131 trackBbox.
Merge( trk->GetBoundingBox() );
134 aBoard.
dir <<
" footprint and track bounding boxes should overlap" );
138 std::set<std::pair<int, int>> viaPositions;
139 bool hasDuplicate =
false;
148 auto key = std::make_pair(
via->GetPosition().x,
via->GetPosition().y );
150 if( viaPositions.count( key ) )
156 viaPositions.insert( key );
160 aBoard.
dir <<
" should have no duplicate through-hole vias" );
168 aBoard.
dir <<
" track on non-copper layer " << trk->GetLayer() );
173 for(
FOOTPRINT* fp : board->Footprints() )
175 for(
PAD*
pad : fp->Pads() )
179 aBoard.
dir <<
" " << fp->GetReference() <<
" pad has zero size" );
184 for(
ZONE* zone : board->Zones() )
187 BOOST_REQUIRE_MESSAGE( outline !=
nullptr,
188 aBoard.
dir <<
" zone has null outline" );
193 aBoard.
dir <<
" zone outline " << ii <<
" has "
228 for(
FOOTPRINT* fp : board->Footprints() )
229 totalPads += fp->Pads().size();
254 int edgeCutsCount = 0;
272 if(
dynamic_cast<PCB_TEXT*
>( item ) )
279 std::set<wxString> trackNets;
298 "trace on unexpected layer " << layer );
359 std::unique_ptr<BOARD> board( plugin.
LoadBoard( filename,
nullptr,
nullptr,
nullptr ) );
365 for(
PCB_TRACK* track : board->Tracks() )
374 BOOST_CHECK( track_count > 0 );
385 std::unique_ptr<BOARD> board( plugin.
LoadBoard( filename,
nullptr,
nullptr,
nullptr ) );
389 int silkscreen_count = 0;
390 int comments_count = 0;
391 int copper_count = 0;
405 else if( layer ==
F_Cu )
441 for(
FOOTPRINT* fp : board->Footprints() )
442 totalPads += fp->Pads().size();
462 std::set<wxString> trackNets;
480 "trace on non-copper layer " << trk->GetLayer() );
494 if( shape->GetLayer() ==
F_SilkS )
510 BOOST_CHECK( defaultNc->GetViaDiameter() > 0 );
511 BOOST_CHECK( defaultNc->GetViaDrill() > 0 );
512 BOOST_CHECK( defaultNc->GetViaDiameter() > defaultNc->GetViaDrill() );
519 int edgeCutsCount = 0;
534 wxString textContent;
541 textContent =
text->GetText();
550 BOOST_CHECK( textContent.Contains( wxT(
"\n" ) ) );
551 BOOST_CHECK( !textContent.Contains( wxT(
"_" ) ) );
552 BOOST_CHECK( textContent.Contains( wxT(
"CLAYSIGHT MCU V.2" ) ) );
553 BOOST_CHECK( textContent.Contains( wxT(
"The Ohio State University" ) ) );
574 bool foundCopperThickness =
false;
575 bool foundDielectric =
false;
581 if( item->GetThickness() > 0 )
582 foundCopperThickness =
true;
586 if( item->GetEpsilonR() > 3.0 )
587 foundDielectric =
true;
591 BOOST_CHECK_MESSAGE( foundCopperThickness,
"stackup should have non-zero copper thickness" );
610 +
"plugins/pads/synthetic_degenerate_pour.asc";
612 std::unique_ptr<BOARD> board( plugin.
LoadBoard( filename,
nullptr,
nullptr,
nullptr ) );
622 if( board->Zones().size() == 1 )
624 ZONE* zone = board->Zones()[0];
644 +
"plugins/pads/synthetic_filled_copper.asc";
646 std::unique_ptr<BOARD> board( plugin.
LoadBoard( filename,
nullptr,
nullptr,
nullptr ) );
649 BOOST_REQUIRE_EQUAL( board->Zones().size(), 1 );
651 ZONE* zone = board->Zones()[0];
672 std::unique_ptr<BOARD> board( plugin.
LoadBoard( filename,
nullptr,
nullptr,
nullptr ) );
680 int dwgsUserCount = 0;
692 "graphics on PADS layer 18 (drill drawing) should map to Dwgs_User" );
699 for(
FOOTPRINT* fp : board->Footprints() )
701 if( fp->GetReference() == wxT(
"U1" ) )
708 BOOST_REQUIRE_MESSAGE( u1 !=
nullptr,
"U1 footprint should exist" );
710 bool foundOvalPad =
false;
723 BOOST_CHECK_MESSAGE( foundOvalPad,
"U1 should have oval pads (OF shape, not RT thermal)" );
728 int pourZoneCount = 0;
729 int filledZoneCount = 0;
731 for(
ZONE* zone : board->Zones() )
733 if( !zone->GetIsRuleArea() )
737 if( zone->IsFilled() )
743 "should not have duplicate zones from HATOUT; got " << pourZoneCount );
762 "horizontal dimension endpoints should have equal Y coordinates; "
763 "start.y=" << start.
y <<
" end.y=" <<
end.y );
789 std::unique_ptr<BOARD> board( plugin.
LoadBoard( filename,
nullptr,
nullptr,
nullptr ) );
794 std::map<std::pair<int, int>,
int> viaPositionCount;
796 int throughCount = 0;
802 const int maxExpectedViaWidth = 1200000;
804 int oversizedViaCount = 0;
806 for(
PCB_TRACK* track : board->Tracks() )
814 auto key = std::make_pair( pos.
x, pos.
y );
815 viaPositionCount[key]++;
822 if(
via->GetWidth(
F_Cu ) > maxExpectedViaWidth )
828 "no vias should be blind; STANDARDVIA spans all copper layers; got "
829 << blindCount <<
" blind vias" );
835 "via size should use copper pad, not soldermask opening; got "
836 << oversizedViaCount <<
" oversized vias" );
839 int duplicateCount = 0;
841 for(
const auto& [pos, count] : viaPositionCount )
848 "should not have duplicate vias at the same position; got "
849 << duplicateCount <<
" positions with duplicates" );
854 int backTentedCount = 0;
857 for(
PCB_TRACK* track : board->Tracks() )
871 "vias without soldermask opening should be tented; "
872 << backTentedCount <<
" of " << totalVias <<
" back-tented" );
890 std::unique_ptr<BOARD> board( plugin.
LoadBoard( filename,
nullptr,
nullptr,
nullptr ) );
896 for(
FOOTPRINT* fp : board->Footprints() )
898 if( fp->GetReference() ==
"U1" )
905 BOOST_REQUIRE_MESSAGE( u1,
"U1 not found on board" );
910 const int expectedMajor = 6000000;
911 const int expectedMinor = 1500000;
912 const int tolerance = 10000;
918 wxString padNum =
pad->GetNumber();
920 if( padNum ==
"1" || padNum ==
"2" || padNum ==
"3"
921 || padNum ==
"4" || padNum ==
"5" )
924 "pad " << padNum <<
" should have oblong drill" );
927 int major = std::max( drillSize.
x, drillSize.
y );
928 int minor = std::min( drillSize.
x, drillSize.
y );
931 "pad " << padNum <<
" drill major axis " << major
932 <<
" should be ~" << expectedMajor );
935 "pad " << padNum <<
" drill minor axis " << minor
936 <<
" should be ~" << expectedMinor );
944 "expected 5 pads with oblong drill, got " << oblongCount );
962 std::unique_ptr<BOARD> board( plugin.
LoadBoard( filename,
nullptr,
nullptr,
nullptr ) );
968 for(
FOOTPRINT* fp : board->Footprints() )
970 if( fp->GetReference() ==
"M4" )
977 BOOST_REQUIRE_MESSAGE( m4,
"M4 not found on board" );
981 const int expectedPadSize = 6350000;
982 const int expectedDrill = 3175000;
983 const int tolerance = 10000;
985 BOOST_REQUIRE_MESSAGE( m4->
Pads().size() == 1,
986 "MTHOLEAAAB has 1 terminal; got " << m4->
Pads().size() );
991 "M4 pad 1 drill should be circular" );
994 int padDim = std::max( padSize.
x, padSize.
y );
997 "M4 pad size " << padDim <<
" should be ~" << expectedPadSize
1001 int drillDim = std::max( drillSize.
x, drillSize.
y );
1004 "M4 drill size " << drillDim <<
" should be ~" << expectedDrill
1023 std::unique_ptr<BOARD> board( plugin.
LoadBoard( filename,
nullptr,
nullptr,
nullptr ) );
1031 auto hasTrueCrossing = [](
const SHAPE_POLY_SET& aPoly,
int aIdx ) ->
bool
1033 std::vector<SEG> segs;
1036 segs.emplace_back( *it );
1038 for(
size_t i = 0; i < segs.size(); i++ )
1040 for(
size_t j = i + 1; j < segs.size(); j++ )
1044 if( segs[i].
A == segs[j].
A || segs[i].
A == segs[j].
B
1045 || segs[i].
B == segs[j].
A || segs[i].
B == segs[j].
B )
1050 if( segs[i].Intersects( segs[j] ) )
1058 int zonesChecked = 0;
1060 for(
ZONE* zone : board->Zones() )
1062 if( !zone->IsFilled() )
1067 if( !zone->HasFilledPolysForLayer( layer ) )
1070 std::shared_ptr<SHAPE_POLY_SET> fill = zone->GetFilledPolysList( layer );
1072 if( !fill || fill->OutlineCount() == 0 )
1077 for(
int pi = 0; pi < fill->OutlineCount(); pi++ )
1079 if( fill->Outline( pi ).PointCount() < 3 )
1083 !hasTrueCrossing( *fill, pi ),
1084 "zone \"" << zone->GetNetname() <<
"\" on "
1085 << board->GetLayerName( layer )
1086 <<
" outline " << pi
1087 <<
" has self-intersecting fill polygon" );
1117 std::unique_ptr<BOARD> board( plugin.
LoadBoard( filename,
nullptr,
nullptr,
nullptr ) );
1120 BOOST_REQUIRE_EQUAL( board->Footprints().size(), 5 );
1122 auto findFP = [&](
const wxString& aRef ) ->
FOOTPRINT*
1124 for(
FOOTPRINT* fp : board->Footprints() )
1125 if( fp->GetReference() == aRef )
1133 BOOST_REQUIRE_MESSAGE( u1,
"U1 should exist" );
1134 BOOST_REQUIRE_EQUAL( u1->
Pads().size(), 1 );
1146 BOOST_REQUIRE_MESSAGE( u2,
"U2 should exist" );
1147 BOOST_REQUIRE_EQUAL( u2->
Pads().size(), 1 );
1159 BOOST_REQUIRE_MESSAGE( u3,
"U3 should exist" );
1160 BOOST_REQUIRE_EQUAL( u3->
Pads().size(), 1 );
1173 BOOST_REQUIRE_MESSAGE( u4,
"U4 should exist" );
1174 BOOST_REQUIRE_EQUAL( u4->
Pads().size(), 1 );
1189 BOOST_REQUIRE_MESSAGE( u5,
"U5 should exist" );
1190 BOOST_REQUIRE_EQUAL( u5->
Pads().size(), 1 );
1212 std::unique_ptr<BOARD> board( plugin.
LoadBoard( filename,
nullptr,
nullptr,
nullptr ) );
1216 bool foundSmdWithMask =
false;
1218 for(
FOOTPRINT* fp : board->Footprints() )
1220 for(
PAD*
pad : fp->Pads() )
1225 foundSmdWithMask =
true;
1230 if( foundSmdWithMask )
1235 "At least one SMD pad in issue23254.asc should have F.Mask and F.Paste" );
1248 std::unique_ptr<BOARD> board;
1249 board.reset( plugin.
LoadBoard( filename,
nullptr,
nullptr,
nullptr ) );
1254 bool foundSquarePad =
false;
1256 for(
FOOTPRINT* fp : board->Footprints() )
1258 for(
PAD*
pad : fp->Pads() )
1262 foundSquarePad =
true;
1267 if( foundSquarePad )
1272 "At least one pad should have RECTANGLE shape (square pad import)" );
1276 bool foundZoneWithFull =
false;
1277 bool foundPadWithThermal =
false;
1278 bool foundPadWithoutThermal =
false;
1280 for(
ZONE* zone : board->Zones() )
1284 foundZoneWithFull =
true;
1290 "Zones should default to FULL (solid) connection" );
1292 for(
FOOTPRINT* fp : board->Footprints() )
1294 for(
PAD*
pad : fp->Pads() )
1297 foundPadWithThermal =
true;
1299 foundPadWithoutThermal =
true;
1304 "Pads with RT/ST entries should have per-pad THERMAL connection" );
1306 "Pads without RT/ST entries should not have per-pad THERMAL override" );
1312 auto nc1It = netclasses.find( wxT(
"NETTCLASS1" ) );
1313 auto nc2It = netclasses.find( wxT(
"NETTCLASS2" ) );
1318 if( nc1It != netclasses.end() )
1321 "NETTCLASS1 should have a track width rule" );
1324 if( nc2It != netclasses.end() )
1327 "NETTCLASS2 should have a track width rule" );
1329 "NETTCLASS2 should have a clearance rule" );
1334 std::map<wxString, wxString> netAssignments;
1336 for(
const auto& [matcher, ncName] : patterns )
1337 netAssignments[matcher->GetPattern()] = ncName;
1340 "+24V0 should be assigned to a net class" );
1342 "+24V0_FILTER should be assigned to a net class" );
1344 "+24V0_FILTER_RTN should be assigned to a net class" );
1346 if( netAssignments.count( wxT(
"+24V0" ) ) )
1351 if( netAssignments.count( wxT(
"+24V0_FILTER_RTN" ) ) )
1353 BOOST_CHECK_EQUAL( netAssignments[wxT(
"+24V0_FILTER_RTN" )], wxT(
"NETTCLASS2" ) );
1371 std::unique_ptr<BOARD> board( plugin.
LoadBoard( filename,
nullptr,
nullptr,
nullptr ) );
1378 "NETTCLASS1 should be imported" );
1380 "NETTCLASS2 should be imported" );
1384 std::map<wxString, wxString> netAssignments;
1386 for(
const auto& [matcher, ncName] : patterns )
1387 netAssignments[matcher->GetPattern()] = ncName;
1391 BOOST_CHECK_EQUAL( netAssignments[wxT(
"+24V0_FILTER" )], wxT(
"NETTCLASS1" ) );
1394 BOOST_CHECK_EQUAL( netAssignments[wxT(
"+24V0_FILTER_RTN" )], wxT(
"NETTCLASS2" ) );
1399 auto nc2It = netclasses.find( wxT(
"NETTCLASS2" ) );
1401 if( nc2It != netclasses.end() )
1404 "NETTCLASS2 should have clearance from RULE_SET" );
1406 "NETTCLASS2 should have track width from RULE_SET" );
1423 +
"plugins/pads/issue23540/test_import.asc";
1425 std::unique_ptr<BOARD> board( plugin.
LoadBoard( filename,
nullptr,
nullptr,
nullptr ) );
1443 "route arc angle " << absDeg <<
" should be ~180 degrees (semicircle)" );
1452 int chordY = ( start.
y +
end.y ) / 2;
1455 "arc midpoint Y=" << mid.
y <<
" should be above (less than) "
1456 "chord center Y=" << chordY );
1460 "expected at least 1 PCB_ARC from route CW/CCW arc, got " << arcCount );
1484 +
"plugins/pads/issue23425/controlCARDDockingStation.asc";
1486 std::unique_ptr<BOARD> board( plugin.
LoadBoard( filename,
nullptr,
nullptr,
nullptr ) );
1492 for(
FOOTPRINT* fp : board->Footprints() )
1494 if( fp->GetReference() == wxT(
"J3" ) )
1501 BOOST_REQUIRE_MESSAGE( j3,
"J3 (HSEC8 edge connector) not found on board" );
1504 const int expectedOffset = 762000;
1505 const int tolerance = 1000;
1507 int offsetPadCount = 0;
1520 "J3 pad " <<
pad->GetNumber()
1521 <<
" offset Y should be 0 (unrotated pad-local), got " << offset.
y );
1524 "J3 pad " <<
pad->GetNumber()
1525 <<
" offset X magnitude " <<
std::abs( offset.
x )
1526 <<
" should be ~" << expectedOffset );
1533 "expected the HSEC8 finger pads to carry a finger offset; got "
1534 << offsetPadCount );
1555 std::unique_ptr<BOARD> board( plugin.
LoadBoard( filename,
nullptr,
nullptr,
nullptr ) );
1561 PAD* mtg_top_pad =
nullptr;
1562 PAD* mtg_bot_pad =
nullptr;
1563 PAD* conn_top_pin1 =
nullptr;
1564 PAD* conn_bot_pin1 =
nullptr;
1566 for(
FOOTPRINT* fp : board->Footprints() )
1568 wxString ref = fp->GetReference();
1570 for(
PAD*
pad : fp->Pads() )
1574 else if( ref ==
"E3" )
1576 else if( ref ==
"X1" &&
pad->GetNumber() ==
"1" )
1577 conn_top_pin1 =
pad;
1578 else if( ref ==
"X2" &&
pad->GetNumber() ==
"1" )
1579 conn_bot_pin1 =
pad;
1583 BOOST_REQUIRE_MESSAGE( mtg_top_pad,
"E1 (top mounting hole) not found" );
1584 BOOST_REQUIRE_MESSAGE( mtg_bot_pad,
"E3 (bottom mounting hole) not found" );
1585 BOOST_REQUIRE_MESSAGE( conn_top_pin1,
"X1 pin 1 (top connector square pad) not found" );
1586 BOOST_REQUIRE_MESSAGE( conn_bot_pin1,
"X2 pin 1 (bottom connector square pad) not found" );
1591 "Mounting hole with same shape but different sizes should use NORMAL padstack mode" );
1595 "Bottom-placed mounting hole should also use NORMAL padstack mode" );
1602 top_size == bot_size,
1603 "Top and bottom mounting holes should have equal pad size on F_Cu; "
1604 "top=" << top_size.
x <<
" bot=" << bot_size.
x );
1611 "Mounting hole pad size must be non-zero" );
1616 "Connector pin-1 with square-on-top / round-on-bottom must use FRONT_INNER_BACK" );
1621 "Top connector pin-1 must have RECTANGLE shape on F_Cu" );
1625 "Top connector pin-1 must have CIRCLE shape on B_Cu" );
1630 "Bottom connector pin-1 must have CIRCLE shape on F_Cu after flip" );
1634 "Bottom connector pin-1 must have RECTANGLE shape on B_Cu after flip" );
1661 std::unique_ptr<BOARD> board( plugin.
LoadBoard( filename,
nullptr,
nullptr,
nullptr ) );
1671 for(
FOOTPRINT* fp : board->Footprints() )
1673 if( fp->GetValue() == wxT(
"TP_BOTTOM_SMD" ) )
1675 else if( fp->GetValue() == wxT(
"TP_TOP_SMD" ) )
1680 BOOST_REQUIRE_MESSAGE( tpBottom,
"TP_BOTTOM_SMD test point footprint should exist" );
1683 if( tpBottom->
Pads().size() == 1 )
1687 "TP_BOTTOM_SMD pad should be on B.Cu" );
1689 "TP_BOTTOM_SMD pad should not be on F.Cu" );
1694 "TP_BOTTOM_SMD pad size " << padSize <<
" should be ~800000 nm" );
1698 BOOST_REQUIRE_MESSAGE( tpTop,
"TP_TOP_SMD test point footprint should exist" );
1701 if( tpTop->
Pads().size() == 1 )
1705 "TP_TOP_SMD pad should be on F.Cu" );
1707 "TP_TOP_SMD pad should not be on B.Cu" );
1711 "TP_TOP_SMD pad size " << padSize <<
" should be ~800000 nm" );
1736 "TP_BOTTOM_SMD position should not have a bare PCB_VIA" );
1738 "TP_TOP_SMD position should not have a bare PCB_VIA" );
1758 std::unique_ptr<BOARD> board;
1759 board.reset( plugin.
LoadBoard( filename,
nullptr,
nullptr,
nullptr ) );
1764 int copyrightCount = 0;
1765 bool frontCopyrightNotMirrored =
false;
1766 bool backCopyrightMirrored =
false;
1777 "imported free text should not be empty" );
1779 if( t->
GetText().Contains( wxT(
"TEXMATE" ) ) )
1785 "copyright text should retain the (c) character" );
1790 "front silkscreen text should not be mirrored" );
1791 frontCopyrightNotMirrored =
true;
1796 "back-side text should be mirrored" );
1797 backCopyrightMirrored =
true;
1803 "expected the copyright text on both front and back, got " << copyrightCount );
1804 BOOST_CHECK( frontCopyrightNotMirrored );
1805 BOOST_CHECK( backCopyrightMirrored );
1809 bool foundCN1 =
false;
1811 for(
FOOTPRINT* fp : board->Footprints() )
1813 if( fp->GetReference() != wxT(
"CN1" ) )
1819 "CN1 should have at least 10 pads, got " << fp->Pads().size() );
1821 for(
PAD*
pad : fp->Pads() )
1829 "CN1 finger pad " <<
pad->GetNumber().ToStdString()
1830 <<
" should be oriented 90 degrees, got "
1831 <<
pad->GetOrientation().AsDegrees() );
General utilities for PCB file IO for QA programs.
@ BS_ITEM_TYPE_DIELECTRIC
Container for design settings for a BOARD object.
std::shared_ptr< NET_SETTINGS > m_NetSettings
int m_CopperEdgeClearance
int GetBoardThickness() const
The full thickness of the board including copper and masks.
BOARD_STACKUP & GetStackupDescriptor()
std::vector< VIA_DIMENSION > m_ViasDimensionsList
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Manage one layer needed to make a physical board.
Manage layers needed to make a physical board.
const std::vector< BOARD_STACKUP_ITEM * > & GetList() const
constexpr void SetMaximum()
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
constexpr bool Intersects(const BOX2< Vec > &aRect) const
virtual const wxString & GetText() const
Return the string associated with the text object.
Handle the data for a net.
const wxString & GetNetname() const
const std::map< wxString, std::shared_ptr< NETCLASS > > & GetNetclasses() const
Gets all netclasses.
std::shared_ptr< NETCLASS > GetDefaultNetclass() const
Gets the default netclass for the project.
std::vector< std::pair< std::unique_ptr< EDA_COMBINED_MATCHER >, wxString > > & GetNetclassPatternAssignments()
Gets the netclass pattern assignments.
@ NORMAL
Shape is the same on all layers.
@ FRONT_INNER_BACK
Up to three shapes can be defined (F_Cu, inner copper layers, B_Cu)
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
PAD_SHAPE GetShape(PCB_LAYER_ID aLayer) const
VECTOR2I GetSize(PCB_LAYER_ID aLayer) const
const PADSTACK & Padstack() const
EDA_ANGLE GetAngle() const
const VECTOR2I & GetMid() const
For better understanding of the points that make a dimension:
BOARD * LoadBoard(const wxString &aFileName, BOARD *aAppendToMe, const std::map< std::string, UTF8 > *aProperties, PROJECT *aProject) override
Load information from some input file format that this PCB_IO implementation knows about into either ...
bool CanReadBoard(const wxString &aFileName) const override
Checks if this PCB_IO can read the specified board file.
const VECTOR2I & GetStart() const
const VECTOR2I & GetEnd() const
int PointCount() const
Return the number of points (vertices) in this line chain.
Represent a set of closed polygons.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
CONST_SEGMENT_ITERATOR CIterateSegmentsWithHoles() const
Return an iterator object, for the aOutline-th outline in the set (with holes).
int OutlineCount() const
Return the number of outlines in the set.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
Handle a list of polygons defining a copper zone.
SHAPE_POLY_SET * Outline()
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
PCB_LAYER_ID
A quick note on layer IDs:
std::string GetPcbnewTestDataDir()
Utility which returns a path to the data directory where the test board files are stored.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
@ SMD
Smd pad, appears on the solder paste layer (default)
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
static void RunStructuralChecks(const PADS_BOARD_INFO &aBoard)
Run structural integrity checks on a successfully loaded board.
static wxString GetBoardPath(const PADS_BOARD_INFO &aBoard)
static const PADS_BOARD_INFO PADS_BOARDS[]
static std::unique_ptr< BOARD > LoadAndVerify(const PADS_BOARD_INFO &aBoard)
Verify that the PADS file is recognized and loads without crashing.
BOOST_AUTO_TEST_CASE(ImportClaySight_MK1)
BOOST_CHECK_MESSAGE(totalMismatches==0, std::to_string(totalMismatches)+" board(s) with strategy disagreements")
BOOST_CHECK_EQUAL(result, "25.4")
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
VECTOR2< int32_t > VECTOR2I
@ THERMAL
Use thermal relief for pads.
@ FULL
pads are covered by copper