56 BOOST_CHECK_EQUAL( aFp.GetTransform().GetRotate().AsDegrees(), aFp.GetOrientation().AsDegrees() );
112 const BOX2I bboxBefore = shapeBefore->BBox();
122 const BOX2I bboxAfter = shapeAfter->BBox();
141 BOX2I before =
pad->GetBoundingBox();
146 BOX2I after =
pad->GetBoundingBox();
162 BOX2I before =
pad->GetBoundingBox();
168 BOX2I after =
pad->GetBoundingBox();
205 BOOST_CHECK(
copy.IsFlipped() );
220 <<
" actual ( " <<
actual.x <<
", " <<
actual.y <<
" )" );
233 BOOST_CHECK_MESSAGE(
std::abs( derived.
x - stored.
x ) <= 1 &&
std::abs( derived.
y - stored.
y ) <= 1,
234 "pad " <<
pad->GetNumber() <<
" m_libPos ( " << stored.
x <<
", " << stored.
y <<
" )"
235 <<
" != GetFPRelativePosition ( " << derived.
x <<
", " << derived.
y <<
" )" );
251 for(
const FOOTPRINT* fp : m_board->Footprints() )
260 for(
FOOTPRINT* fp : m_board->Footprints() )
278 for(
const FOOTPRINT* fp : m_board->Footprints() )
287 for(
FOOTPRINT* fp : m_board->Footprints() )
305 FOOTPRINT* fp = *m_board->Footprints().begin();
312 std::map<wxString, VECTOR2I> origPadByNumber;
314 origPadByNumber[
pad->GetNumber()] =
pad->GetPosition();
316 std::unique_ptr<FOOTPRINT> snapshot(
static_cast<FOOTPRINT*
>( fp->
Clone() ) );
336 "pad " <<
pad->GetNumber() <<
" after undo at ( " << p.
x <<
", " << p.
y <<
" )"
337 <<
" expected ( " << orig.
x <<
", " << orig.
y <<
" )" );
349 for(
FOOTPRINT* fp : m_board->Footprints() )
351 std::unique_ptr<FOOTPRINT> libCopy(
static_cast<FOOTPRINT*
>( fp->Clone() ) );
354 "footprint " << fp->GetReference() <<
" differs from its own clone" );
359 "footprint " << fp->GetReference()
360 <<
" flipped top-bottom reported as differing from library" );
366 "footprint " << fp->GetReference()
367 <<
" flipped left-right reported as differing from library" );
391 BOOST_CHECK_MESSAGE(
std::abs( libStartFromShape.
x - libStartStored.
x ) <= 1
392 &&
std::abs( libStartFromShape.
y - libStartStored.
y ) <= 1,
393 "shape m_libStart ( " << libStartStored.
x <<
", " << libStartStored.
y <<
" ) "
394 <<
"!= GetFPRelativePosition ( " << libStartFromShape.
x <<
", "
395 << libStartFromShape.
y <<
" )" );
404 for(
const FOOTPRINT* fp : m_board->Footprints() )
413 for(
FOOTPRINT* fp : m_board->Footprints() )
431 FOOTPRINT* fp = *m_board->Footprints().begin();
435 std::map<wxString, VECTOR2I> origOffsets;
439 origOffsets[
pad->GetNumber()] =
pad->GetPosition() -
anchor;
456 BOOST_CHECK_MESSAGE(
std::abs( offset.
x - 2 * orig.
x ) <= 1 &&
std::abs( offset.
y - 2 * orig.
y ) <= 1,
457 "pad " <<
pad->GetNumber() <<
" offset ( " << offset.
x <<
", " << offset.
y <<
" ) "
458 <<
"expected ( " << 2 * orig.
x <<
", " << 2 * orig.
y <<
" )" );
467 FOOTPRINT* fp = *m_board->Footprints().begin();
473 std::vector<VECTOR2I> origStartOffsets;
502 VECTOR2I orig = origStartOffsets[i++];
504 BOOST_CHECK_MESSAGE(
std::abs( offset.
x - 2 * orig.
x ) <= 1 &&
std::abs( offset.
y - 2 * orig.
y ) <= 1,
505 "shape start offset ( " << offset.
x <<
", " << offset.
y <<
" ) "
506 <<
"expected ( " << 2 * orig.
x <<
", " << 2 * orig.
y <<
" )" );
515 FOOTPRINT* fp = *m_board->Footprints().begin();
521 std::map<wxString, VECTOR2I> origPadPositions;
523 origPadPositions[
pad->GetNumber()] =
pad->GetPosition();
525 const std::filesystem::path savePath = std::filesystem::temp_directory_path() /
"scale_roundtrip.kicad_pcb";
532 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
543 VECTOR2I orig = origPadPositions[
pad->GetNumber()];
546 "pad " <<
pad->GetNumber() <<
" after reload at ( " << p.
x <<
", " << p.
y
547 <<
" ) expected ( " << orig.
x <<
", " << orig.
y <<
" )" );
556 FOOTPRINT* fp = *m_board->Footprints().begin();
559 std::map<wxString, VECTOR2I> origPadPositions;
561 origPadPositions[
pad->GetNumber()] =
pad->GetPosition();
563 std::unique_ptr<FOOTPRINT> snapshot(
static_cast<FOOTPRINT*
>( fp->
Clone() ) );
577 VECTOR2I orig = origPadPositions[
pad->GetNumber()];
580 "pad " <<
pad->GetNumber() <<
" after undo at ( " << p.
x <<
", " << p.
y <<
" ) expected ( "
581 << orig.
x <<
", " << orig.
y <<
" )" );
608 std::vector<VECTOR2I> origOffsets;
615 BOOST_REQUIRE_EQUAL( scaledBoard.
TotalVertices(), (
int) origOffsets.size() );
620 BOOST_CHECK_MESSAGE(
std::abs( offset.
x - 2 * origOffsets[i].x ) <= 1
621 &&
std::abs( offset.
y - 2 * origOffsets[i].y ) <= 1,
622 "vertex " << i <<
" offset ( " << offset.
x <<
", " << offset.
y <<
" ) expected ( "
623 << 2 * origOffsets[i].x <<
", " << 2 * origOffsets[i].y <<
" )" );
632 FOOTPRINT* fp = *m_board->Footprints().begin();
635 std::map<wxString, VECTOR2I> origSizes;
636 std::map<wxString, VECTOR2I> origDrills;
641 origDrills[
pad->GetNumber()] =
pad->GetDrillSize();
665 FOOTPRINT* fp = *m_board->Footprints().begin();
688 FOOTPRINT* fp = *m_board->Footprints().begin();
706 BOOST_CHECK_CLOSE( (
double) scaledBox.
GetWidth(), 2.0 * origBox.
GetWidth(), 10.0 );
715 FOOTPRINT* fp = *m_board->Footprints().begin();
743 FOOTPRINT* fp = *m_board->Footprints().begin();
760 std::vector<int> violations;
763 [&](
const std::shared_ptr<DRC_ITEM>& aItem,
const VECTOR2I& aPos,
int aLayer,
764 const std::function<
void(
PCB_MARKER* )>& aPathGenerator )
766 violations.push_back( aItem->GetErrorCode() );
772 for(
int code : violations )
781 BOOST_CHECK_MESSAGE( found,
"expected DRCE_FOOTPRINT_SCALED_WITH_PADS for a 2x scaled "
782 "footprint with pads; got "
783 << violations.size() <<
" violations" );
801 int scaledFlagged = 0;
804 [&](
const std::shared_ptr<DRC_ITEM>& aItem,
const VECTOR2I& aPos,
int aLayer,
805 const std::function<
void(
PCB_MARKER* )>& aPathGenerator )
821 FOOTPRINT* fp = *m_board->Footprints().begin();
845 FOOTPRINT* fp = *m_board->Footprints().begin();
868 FOOTPRINT* fp = *m_board->Footprints().begin();
885 <<
" ) expected ( " << origAnchor.
x <<
", " << origAnchor.
y <<
" )" );
895 std::shared_ptr<CONNECTIVITY_DATA> conn = m_board->GetConnectivity();
898 conn->RecalculateRatsnest();
901 PAD* targetPad =
nullptr;
904 for(
FOOTPRINT* fp : m_board->Footprints() )
906 for(
PAD*
pad : fp->Pads() )
908 if( !conn->GetRatsnestForPad(
pad ).empty() )
927 conn->RecalculateRatsnest();
930 std::vector<CN_EDGE> edges = conn->GetRatsnestForPad( targetPad );
936 for(
const CN_EDGE& e : edges )
938 if( e.GetSourcePos() == newPadPos || e.GetTargetPos() == newPadPos )
945 BOOST_CHECK_MESSAGE( found,
"no ratsnest edge originates at the scaled pad position ( " << newPadPos.
x <<
", "
946 << newPadPos.
y <<
" )" );
956 FOOTPRINT* fp = *m_board->Footprints().begin();
971 BOOST_CHECK_CLOSE( (
double) after.
GetWidth(), 2.0 * origWidth, 5.0 );
972 BOOST_CHECK_CLOSE( (
double) after.
GetHeight(), 2.0 * origHeight, 5.0 );
987 for(
FOOTPRINT* candidate : m_board->Footprints() )
989 if( !candidate->GetCourtyard(
F_CrtYd ).IsEmpty() )
996 BOOST_REQUIRE_MESSAGE( fp,
"no footprint with a front courtyard in issue18" );
999 double areaBefore = before.
Area();
1005 double areaAfter = after.
Area();
1008 BOOST_CHECK_CLOSE( areaAfter, 4.0 * areaBefore, 1.0 );
1093 auto applyOnSelection =
1094 [&](
double sx,
double sy )
1105 applyOnSelection( 2.0, 2.0 );
1112 BOOST_CHECK_CLOSE( a.
GetScaleX(), 2.0, 1e-9 );
1113 BOOST_CHECK_CLOSE( a.
GetScaleY(), 2.0, 1e-9 );
1114 BOOST_CHECK_CLOSE( b.
GetScaleX(), 2.0, 1e-9 );
1115 BOOST_CHECK_CLOSE( b.
GetScaleY(), 2.0, 1e-9 );
1123 FOOTPRINT* fp = *m_board->Footprints().begin();
1130 BOOST_CHECK_CLOSE( fp->
GetScaleX(), 3.0, 1e-9 );
1131 BOOST_CHECK_CLOSE( fp->
GetScaleY(), 0.75, 1e-9 );
1140 FOOTPRINT* fp = *m_board->Footprints().begin();
1147 BOOST_CHECK_CLOSE( fp->
GetScaleX(), 1.5, 1e-9 );
1148 BOOST_CHECK_CLOSE( fp->
GetScaleY(), 4.0, 1e-9 );
1158 FOOTPRINT* fp = *m_board->Footprints().begin();
1172 const std::filesystem::path savePath = std::filesystem::temp_directory_path() /
"promoted_arc_roundtrip.kicad_pcb";
1179 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
1182 bool foundArc =
false;
1198 BOOST_CHECK_MESSAGE( foundArc,
"promoted arc did not round-trip as a lib-frame arc" );
1208 FOOTPRINT* fp = *m_board->Footprints().begin();
1220 const std::filesystem::path savePath =
1221 std::filesystem::temp_directory_path() /
"promoted_circle_roundtrip.kicad_pcb";
1228 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
1231 bool foundCircle =
false;
1247 BOOST_CHECK_MESSAGE( foundCircle,
"promoted circle did not round-trip as a lib-frame circle" );
1256 FOOTPRINT* fp = *m_board->Footprints().begin();
1278 BOOST_CHECK_CLOSE( libRotation.
AsDegrees(), 30.0, 0.01 );
1288 const std::filesystem::path savePath =
1289 std::filesystem::temp_directory_path() /
"native_ellipse_rotated_roundtrip.kicad_pcb";
1296 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
1315 BOOST_REQUIRE_MESSAGE( ellipse2,
"native ellipse not found after reload" );
1356 FOOTPRINT* fp = *m_board->Footprints().begin();
1368 const std::filesystem::path savePath = std::filesystem::temp_directory_path() /
"scale_size_roundtrip_a.kicad_pcb";
1374 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
1376 PAD* pad2 = *fp2->
Pads().begin();
1380 const std::filesystem::path savePath2 = std::filesystem::temp_directory_path() /
"scale_size_roundtrip_b.kicad_pcb";
1386 FOOTPRINT* fp3 = *reloaded2->Footprints().begin();
1388 PAD* pad3 = *fp3->
Pads().begin();
1475 maxX = std::max( maxX, p.x );
1477 BOOST_CHECK_GT( maxX, 3000000 );
1566 const VECTOR2I rotCenter( 150000000, 100000000 );
1590 const VECTOR2I rotCenter( 105000000, 80000000 );
1603 const std::filesystem::path savePath =
1604 std::filesystem::temp_directory_path() /
"normalized_rect_roundtrip.kicad_pcb";
1613 for(
BOARD_ITEM* item : reloaded->Drawings() )
1617 loaded =
static_cast<PCB_SHAPE*
>( item );
1626 BOOST_CHECK_MESSAGE( onDisk == onBoard,
"saved at ( " << onDisk.
GetOrigin().
x <<
", " << onDisk.
GetOrigin().
y
1628 <<
", expected ( " << onBoard.
GetOrigin().
x <<
", "
1638 FOOTPRINT* fp = *m_board->Footprints().begin();
1730 while( rotDeg > 90.0 ) rotDeg -= 180.0;
1731 while( rotDeg <= -90.0 ) rotDeg += 180.0;
1732 BOOST_CHECK_CLOSE( rotDeg, -30.0, 0.1 );
1761 BOOST_CHECK_CLOSE( major_n, major_u, 1.0 );
1762 BOOST_CHECK_CLOSE( minor_n, minor_u, 6.0 );
1764 double diffDeg = rot_n - rot_u;
1765 while( diffDeg > 90.0 ) diffDeg -= 180.0;
1766 while( diffDeg <= -90.0 ) diffDeg += 180.0;
1767 BOOST_CHECK_SMALL( diffDeg, 1.0 );
1796 BOOST_CHECK_CLOSE(
static_cast<double>( bbox.
GetWidth() ), 3162277.0, 1.0 );
1797 BOOST_CHECK_CLOSE(
static_cast<double>( bbox.
GetHeight() ), 1581139.0, 1.0 );
1953 FOOTPRINT* fp = *m_board->Footprints().begin();
1967 pad->SetNumber( wxT(
"88" ) );
1972 const std::filesystem::path savePath = std::filesystem::temp_directory_path() /
"circle_pad_roundtrip.kicad_pcb";
1979 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
1982 PAD* pad2 =
nullptr;
1986 if( p->GetNumber() == wxT(
"88" ) )
1993 BOOST_REQUIRE_MESSAGE( pad2,
"circle pad not found after reload" );
2012 FOOTPRINT* fp = *m_board->Footprints().begin();
2025 pad->SetNumber( wxT(
"99" ) );
2041 const std::filesystem::path savePath = std::filesystem::temp_directory_path() /
"pad_prim_roundtrip.kicad_pcb";
2048 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
2051 PAD* pad2 =
nullptr;
2055 if( p->GetNumber() == wxT(
"99" ) )
2062 BOOST_REQUIRE_MESSAGE( pad2,
"custom pad not found after reload" );
2072 const VECTOR2I libDelta = prim2->GetLibraryEnd() - prim2->GetLibraryStart();
2093 std::vector<VECTOR2I> poly = {
2094 { -1000000, -1000000 }, { 1000000, -1000000 }, { 1000000, 1000000 }, { -1000000, 1000000 }
2100 const BOX2I libBefore = prim->GetLibraryPolyShape().BBox();
2107 const BOX2I libAfter = prim->GetLibraryPolyShape().BBox();
2120 FOOTPRINT* fp = *m_board->Footprints().begin();
2133 pad->SetNumber( wxT(
"77" ) );
2136 std::vector<VECTOR2I> poly = {
2137 { -1000000, -1000000 }, { 1000000, -1000000 }, { 1000000, 1000000 }, { -1000000, 1000000 }
2143 const BOX2I before =
pad->GetBoundingBox();
2145 const std::filesystem::path savePath = std::filesystem::temp_directory_path() /
"pad_poly_prim_roundtrip.kicad_pcb";
2152 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
2155 PAD* pad2 =
nullptr;
2159 if( p->GetNumber() == wxT(
"77" ) )
2166 BOOST_REQUIRE_MESSAGE( pad2,
"custom poly pad not found after reload" );
2212 BOOST_CHECK_CLOSE(
circle->GetEllipseRotation().AsDegrees(), -30.0, 0.001 );
2332 "vertex " << i <<
" expected ( " <<
expected.x <<
", " <<
expected.y <<
" ) actual ( "
2352 std::vector<VECTOR2I> beforeVerts;
2354 beforeVerts.push_back( before.
CVertex( i ) );
2360 BOOST_REQUIRE_EQUAL( after.
TotalVertices(), (
int) beforeVerts.size() );
2368 "vertex " << i <<
" expected ( " <<
expected.x <<
", " <<
expected.y <<
" ) actual ( "
2411 std::vector<VECTOR2I> beforeVerts;
2413 beforeVerts.push_back( before.
CVertex( i ) );
2415 const VECTOR2I offset( 500000, 250000 );
2416 zone->
Move( offset );
2419 BOOST_REQUIRE_EQUAL( after.
TotalVertices(), (
int) beforeVerts.size() );
2427 "vertex " << i <<
" expected ( " <<
expected.x <<
", " <<
expected.y <<
" ) actual ( "
2445 std::vector<VECTOR2I> beforeVerts;
2447 beforeVerts.push_back( before.
CVertex( i ) );
2451 zone->
Rotate( centre, angle );
2454 BOOST_REQUIRE_EQUAL( after.
TotalVertices(), (
int) beforeVerts.size() );
2463 "vertex " << i <<
" expected ( " <<
expected.x <<
", " <<
expected.y <<
" ) actual ( "
2484 <<
" ) expected near board ( 50000000, 30000000 )" );
2508 <<
" ) expected near board ( 50000000, 30000000 )" );
2530 <<
" ) expected near board ( 50000000, 30000000 )" );
2548 BOX2I bbox = shape->BBox();
2552 <<
" ) expected near board ( 50000000, 30000000 )" );
2577 "lib coords did not change after one flip" );
2609 "lib coords did not change after one flip" );
2640 BOOST_CHECK_MESSAGE(
circle->GetLibraryStart() != libStartBefore ||
circle->GetLibraryEnd() != libEndBefore,
2641 "lib coords did not change after one flip" );
2674 "lib coords did not change after one flip" );
2696 text->SetText( wxT(
"X" ) );
2705 BOOST_CHECK_MESSAGE(
text->GetTextPos() != boardPosBefore,
"text position did not change after one flip" );
2718 FOOTPRINT* fp = *m_board->Footprints().begin();
2722 table->SetColCount( 2 );
2726 table->SetColWidth( 0, colW );
2727 table->SetColWidth( 1, colW );
2728 table->SetRowHeight( 0, rowH );
2729 table->SetRowHeight( 1, rowH );
2731 for(
int i = 0; i < 4; ++i )
2735 cell->
SetEnd(
VECTOR2I( ( i % 2 + 1 ) * colW, ( i / 2 + 1 ) * rowH ) );
2736 cell->
SetText( wxString::Format(
"c%d", i ) );
2737 table->AddCell( cell );
2744 const double angles[] = { 90.0, 180.0, 270.0 };
2746 for(
double deg : angles )
2752 std::vector<VECTOR2I> startsBefore, endsBefore;
2755 startsBefore.push_back( cell->GetStart() );
2756 endsBefore.push_back( cell->GetEnd() );
2759 const std::filesystem::path savePath =
2760 std::filesystem::temp_directory_path() /
"table_in_rotated_fp.kicad_pcb";
2766 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
2780 BOOST_REQUIRE_EQUAL( (
int) table2->
GetCells().size(), 4 );
2782 for(
int i = 0; i < 4; ++i )
2788 <<
" ) expected ( " << startsBefore[i].x <<
", " << startsBefore[i].y
2790 BOOST_CHECK_MESSAGE(
std::abs( cell->
GetEnd().
x - endsBefore[i].x ) <= 1
2792 "cell " << i <<
" end ( " << cell->
GetEnd().
x <<
", " << cell->
GetEnd().
y
2793 <<
" ) expected ( " << endsBefore[i].x <<
", " << endsBefore[i].y
2809 const std::vector<Case> cases = {
2810 {
VECTOR2I( 12345678, -7654321 ), 0.0 }, {
VECTOR2I( 12345678, -7654321 ), 90.0 },
2811 {
VECTOR2I( 12345678, -7654321 ), 180.0 }, {
VECTOR2I( 12345678, -7654321 ), 270.0 },
2812 {
VECTOR2I( -12345678, -7654321 ), 90.0 }, {
VECTOR2I( -12345678, 7654321 ), 90.0 },
2813 {
VECTOR2I( 12345678, 7654321 ), 90.0 }, {
VECTOR2I( 12345678, 7654321 ), 270.0 },
2814 {
VECTOR2I( -12345678, -7654321 ), 270.0 },
2817 for(
const Case& tc : cases )
2819 BOOST_TEST_CONTEXT(
"fp pos ( " << tc.pos.x <<
", " << tc.pos.y <<
" ) orient " << tc.angle )
2821 const double fpAngle = tc.angle;
2824 FOOTPRINT* fp = *m_board->Footprints().begin();
2831 table->SetColCount( 2 );
2835 table->SetColWidth( 0, colW );
2836 table->SetColWidth( 1, colW );
2837 table->SetRowHeight( 0, rowH );
2838 table->SetRowHeight( 1, rowH );
2840 for(
int i = 0; i < 4; ++i )
2844 cell->
SetEnd(
VECTOR2I( ( i % 2 + 1 ) * colW, ( i / 2 + 1 ) * rowH ) );
2845 cell->
SetText( wxString::Format(
"c%d", i ) );
2846 table->AddCell( cell );
2856 std::vector<VECTOR2I> startsBefore, endsBefore;
2857 std::vector<double> anglesBefore;
2860 startsBefore.push_back( cell->GetStart() );
2861 endsBefore.push_back( cell->GetEnd() );
2862 anglesBefore.push_back( cell->GetTextAngle().AsDegrees() );
2865 const std::filesystem::path savePath =
2866 std::filesystem::temp_directory_path() /
"table_rotated_in_fp_then_fp_rotated.kicad_pcb";
2872 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
2886 BOOST_REQUIRE_EQUAL( (
int) table2->
GetCells().size(), 4 );
2888 for(
int i = 0; i < 4; ++i )
2894 <<
" ) expected ( " << startsBefore[i].x <<
", " << startsBefore[i].y
2896 BOOST_CHECK_MESSAGE(
std::abs( cell->
GetEnd().
x - endsBefore[i].x ) <= 1
2898 "cell " << i <<
" end ( " << cell->
GetEnd().
x <<
", " << cell->
GetEnd().
y
2899 <<
" ) expected ( " << endsBefore[i].x <<
", " << endsBefore[i].y
2916 table->SetColCount( 2 );
2920 table->SetColWidth( 0, colW );
2921 table->SetColWidth( 1, colW );
2922 table->SetRowHeight( 0, rowH );
2923 table->SetRowHeight( 1, rowH );
2925 for(
int i = 0; i < 4; ++i )
2929 cell->
SetEnd(
VECTOR2I( ( i % 2 + 1 ) * colW, ( i / 2 + 1 ) * rowH ) );
2930 table->AddCell( cell );
2940 std::vector<VECTOR2I> corners = cell->GetCorners();
2941 BOOST_REQUIRE_EQUAL( corners.size(), 4u );
2948 "visual width " << visual.
GetWidth() <<
" expected " << rowH );
2950 "visual height " << visual.
GetHeight() <<
" expected " << colW );
2973 for(
int row = 0; row < 2; ++row )
2978 cell->
SetText( row == 0 ? wxT(
"PCB1234" ) : wxT(
"Rev A00" ) );
2999 box.
Merge( cell->GetStart() );
3000 box.
Merge( cell->GetEnd() );
3010 std::vector<VECTOR2I> starts;
3011 std::vector<VECTOR2I> ends;
3015 starts.push_back( cell->GetStart() );
3016 ends.push_back( cell->GetEnd() );
3021 for(
size_t ii = 0; ii < aTable->
GetCells().size(); ++ii )
3025 BOOST_CHECK_MESSAGE( ( cell->
GetStart() - starts[ii] ).EuclideanNorm() <= 1,
3026 "cell " << ii <<
" start moved to ( " << cell->
GetStart().
x <<
", " << cell->
GetStart().
y
3027 <<
" ) from ( " << starts[ii].x <<
", " << starts[ii].y <<
" )" );
3028 BOOST_CHECK_MESSAGE( ( cell->
GetEnd() - ends[ii] ).EuclideanNorm() <= 1,
3029 "cell " << ii <<
" end moved to ( " << cell->
GetEnd().
x <<
", " << cell->
GetEnd().
y
3030 <<
" ) from ( " << ends[ii].x <<
", " << ends[ii].y <<
" )" );
3059 "table box ( " << after.
GetLeft() <<
", " << after.
GetTop() <<
" ) - ( "
3126 table->SetColCount( 3 );
3128 for(
int col = 0; col < 3; ++col )
3129 table->SetColWidth( col, colWidths[col] );
3131 for(
int row = 0; row < 2; ++row )
3132 table->SetRowHeight( row, rowHeights[row] );
3137 for(
int row = 0; row < 2; ++row )
3141 for(
int col = 0; col < 3; ++col )
3146 cell->
SetText( wxString::Format( wxT(
"%c%d" ),
'A' + col, row + 1 ) );
3147 table->AddCell( cell );
3148 x += colWidths[col];
3151 y += rowHeights[row];
3158 for(
int row = 0; row < 2; ++row )
3160 for(
int col = 0; col < 3; ++col )
3162 wxString
expected = wxString::Format( wxT(
"%c%d" ),
'A' + 2 - col, row + 1 );
3183 table->SetColCount( 2 );
3187 table->SetColWidth( 0, colW );
3188 table->SetColWidth( 1, colW );
3189 table->SetRowHeight( 0, rowH );
3190 table->SetRowHeight( 1, rowH );
3192 for(
int i = 0; i < 4; ++i )
3196 cell->
SetEnd(
VECTOR2I( ( i % 2 + 1 ) * colW, ( i / 2 + 1 ) * rowH ) );
3197 table->AddCell( cell );
3205 std::set<std::pair<int, int>> centers;
3208 int w =
std::abs( cell->GetEnd().x - cell->GetStart().x );
3209 int h =
std::abs( cell->GetEnd().y - cell->GetStart().y );
3211 BOOST_CHECK_MESSAGE( ( w == colW && h == rowH ) || ( w == rowH && h == colW ),
3212 "cell dims " << w <<
" x " << h <<
" expected " << colW <<
"x" << rowH <<
" or rotated" );
3214 std::vector<VECTOR2I> corners = cell->GetCorners();
3215 BOOST_REQUIRE_EQUAL( corners.size(), 4u );
3222 "visual width " << visual.
GetWidth() <<
" expected " << rowH );
3224 "visual height " << visual.
GetHeight() <<
" expected " << colW );
3227 centers.insert( { vc.
x, vc.
y } );
3230 BOOST_CHECK_MESSAGE( centers.size() == 4,
"cells overlapped, got " << centers.size() <<
" unique centers" );
3242 tb->
SetText( wxT(
"Hello" ) );
3253 "lib shape changed to " <<
static_cast<int>( tb->
GetLibraryShape() ) );
3255 "runtime shape changed to " <<
static_cast<int>( tb->
GetShape() ) );
3260 BOOST_CHECK_MESSAGE( newWidth == origWidth,
"width changed from " << origWidth <<
" to " << newWidth );
3261 BOOST_CHECK_MESSAGE( newHeight == origHeight,
"height changed from " << origHeight <<
" to " << newHeight );
3269 FOOTPRINT* fp = *m_board->Footprints().begin();
3276 text->SetText( wxT(
"drift probe" ) );
3288 FOOTPRINT* fp = *aBoard.Footprints().begin();
3293 if( t->GetText() == wxT(
"drift probe" ) )
3300 BOARD* currentBoard = m_board.get();
3301 std::unique_ptr<BOARD> reloadedHolder;
3302 const std::filesystem::path savePathA =
3303 std::filesystem::temp_directory_path() /
"pcb_text_in_rotated_fp_a.kicad_pcb";
3304 const std::filesystem::path savePathB =
3305 std::filesystem::temp_directory_path() /
"pcb_text_in_rotated_fp_b.kicad_pcb";
3307 for(
int cycle = 0; cycle < 3; ++cycle )
3309 const std::filesystem::path&
path = ( cycle % 2 == 0 ) ? savePathA : savePathB;
3314 currentBoard = reloadedHolder.get();
3316 PCB_TEXT* probe = findProbe( *currentBoard );
3321 "cycle " << cycle <<
" text pos ( " << probe->
GetTextPos().
x <<
", "
3322 << probe->
GetTextPos().
y <<
" ) expected ( " << posBefore.
x <<
", " << posBefore.
y
3333 FOOTPRINT* fp = *m_board->Footprints().begin();
3346 const std::filesystem::path savePath = std::filesystem::temp_directory_path() /
"pcb_field_in_rotated_fp.kicad_pcb";
3352 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
3360 <<
" ) expected ( " << refPosBefore.
x <<
", " << refPosBefore.
y
3370 FOOTPRINT* fp = *m_board->Footprints().begin();
3386 text->SetText( wxT(
"scale probe" ) );
3392 tb->
SetText( wxT(
"scale probe box" ) );
3407 const std::filesystem::path savePath =
3408 std::filesystem::temp_directory_path() /
"dim_barcode_in_scaled_fp.kicad_pcb";
3414 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
3431 if( t->GetText() == wxT(
"scale probe" ) )
3444 <<
" ) expected ( " << dimStartBefore.
x <<
", " << dimStartBefore.
y
3448 "dim end after reload ( " << dim2->
GetEnd().
x <<
", " << dim2->
GetEnd().
y <<
" ) expected ( "
3449 << dimEndBefore.
x <<
", " << dimEndBefore.
y <<
" )" );
3453 <<
" ) expected ( " << bcPosBefore.
x <<
", " << bcPosBefore.
y
3458 <<
" ) expected ( " << textPosBefore.
x <<
", " << textPosBefore.
y
3463 <<
" ) expected ( " << tbStartBefore.
x <<
", "
3464 << tbStartBefore.
y <<
" )" );
3467 "textbox end after reload ( " << tb2->
GetEnd().
x <<
", " << tb2->
GetEnd().
y <<
" ) expected ( "
3468 << tbEndBefore.
x <<
", " << tbEndBefore.
y <<
" )" );
3479 text->SetText( wxT(
"X" ) );
3600 bool anyVertexChanged =
false;
3605 anyVertexChanged =
true;
3608 BOOST_CHECK_MESSAGE( anyVertexChanged,
"polygon vertices did not change after one flip" );
3620 BOOST_CHECK_MESSAGE(
std::abs( before.
x - after.
x ) <= 1 &&
std::abs( before.
y - after.
y ) <= 1,
3621 "vertex " << i <<
" before ( " << before.
x <<
", " << before.
y <<
" ) after ( " << after.
x
3622 <<
", " << after.
y <<
" )" );
3654 "lib coords did not change after one flip" );
3687 BOOST_CHECK_MESSAGE( point->
GetPosition() != boardPosBefore,
"board position did not change after one flip" );
3721 "lib coords did not change after one flip" );
3779 BOOST_CHECK_MESSAGE( bezier->
GetBezierC1() != c1Before,
"C1 did not follow rotation" );
3780 BOOST_CHECK_MESSAGE( bezier->
GetBezierC2() != c2Before,
"C2 did not follow rotation" );
3810 "C1 expected ( " << expectedC1.
x <<
", " << expectedC1.
y <<
" ) actual ( "
3814 "C2 expected ( " << expectedC2.
x <<
", " << expectedC2.
y <<
" ) actual ( "
3832 const VECTOR2I libStart( 1000000, 1000000 );
3833 const VECTOR2I libC1( 2000000, 4000000 );
3834 const VECTOR2I libC2( 4000000, 0 );
3835 const VECTOR2I libEnd( 5000000, 3000000 );
3840 bezier->
SetEnd( libEnd );
3857 << board.x <<
", " << board.y <<
" )" );
3860 checkBoard(
"start", libStart, bezier->
GetStart() );
3863 checkBoard(
"end", libEnd, bezier->
GetEnd() );
3878 std::vector<VECTOR2I> libVerts = {
3886 for(
const VECTOR2I& v : libVerts )
3900 BOOST_REQUIRE_EQUAL(
result.TotalVertices(), (
int) libVerts.size() );
3902 for(
int i = 0; i < (int) libVerts.size(); ++i )
3908 "vertex " << i <<
" expected ( " <<
expected.x <<
", " <<
expected.y <<
" ) actual ( "
3938 bool anyMoved =
false;
3945 BOOST_CHECK_MESSAGE( anyMoved,
"polygon vertices did not move after rotation" );
3959 "vertex " << i <<
" before ( " << b.
x <<
", " << b.
y <<
" ) restored ( " << r.
x <<
", "
3996 "vertex " << i <<
" expected ( " <<
expected.x <<
", " <<
expected.y <<
" ) actual ( "
4020 BOOST_CHECK_CLOSE(
pad->GetOrientation().AsDegrees(), 45.0, 1e-6 );
4021 BOOST_CHECK_CLOSE(
pad->GetFPRelativeOrientation().AsDegrees(), 45.0, 1e-6 );
4026 BOOST_CHECK_CLOSE(
pad->GetOrientation().AsDegrees(), 135.0, 1e-6 );
4028 BOOST_CHECK_CLOSE(
pad->GetFPRelativeOrientation().AsDegrees(), 45.0, 1e-6 );
4031 BOOST_CHECK_CLOSE(
pad->GetOrientation().AsDegrees(), 45.0, 1e-6 );
4032 BOOST_CHECK_CLOSE(
pad->GetFPRelativeOrientation().AsDegrees(), 45.0, 1e-6 );
4046 text->SetText( wxT(
"X" ) );
4051 BOOST_CHECK_CLOSE(
text->GetTextAngle().AsDegrees(), 45.0, 1e-6 );
4055 BOOST_CHECK_CLOSE(
text->GetTextAngle().AsDegrees(), 135.0, 1e-6 );
4058 BOOST_CHECK_CLOSE(
text->GetTextAngle().AsDegrees(), 45.0, 1e-6 );
4111 BOOST_CHECK_MESSAGE( tb->
GetTextAngle() != absBefore,
"text angle did not change after one flip" );
4249 [&](
double aFpOrientDeg,
FLIP_DIRECTION aDir,
double aExpectedDelta )
4270 BOOST_CHECK_CLOSE(
actual.AsDegrees(),
expected.AsDegrees(), 1e-6 );
4301 BOOST_CHECK_MESSAGE( bc->
GetPosition() != posBefore,
"barcode pos did not move on first flip" );
4338 BOOST_CHECK_MESSAGE( dim->
GetStart() != startBefore,
"dim start did not move on first flip" );
4376 std::vector<VECTOR2I> savedCorners;
4378 savedCorners.emplace_back( p );
4380 const std::filesystem::path savePath =
4381 std::filesystem::temp_directory_path() /
"rect_noncardinal_roundtrip.kicad_pcb";
4388 for(
BOARD_ITEM* item : reloaded->Drawings() )
4404 BOOST_REQUIRE_EQUAL( (
int) reloadedPoints.size(), (
int) savedCorners.size() );
4406 for(
size_t i = 0; i < savedCorners.size(); ++i )
4452 const VECTOR2I coincident( 53000000, 51000000 );
4459 pad->SetPosition( coincident );
4469 BOOST_REQUIRE_EQUAL(
pad->GetPosition().x, seg->
GetStart().
x );
4470 BOOST_REQUIRE_EQUAL(
pad->GetPosition().y, seg->
GetStart().
y );
4548 aPad =
new PAD( fp );
4580 BOOST_CHECK_MESSAGE( aTxt->
GetTextPos() == aSeg->
GetStart(), aWhen <<
": text vs seg" );
4587 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
4600 std::filesystem::path tmp = std::filesystem::temp_directory_path() /
"kicad_qa_xform_roundtrip.kicad_pcb";
4604 std::filesystem::remove( tmp, ec );
4607 FOOTPRINT* r = reloaded->Footprints().front();
4617 rtxt =
static_cast<PCB_TEXT*
>( it );
4623 BOOST_CHECK( r->
Pads().front()->GetPosition() == padPos );
4624 BOOST_CHECK( rseg->
GetStart() == segStart );
4626 BOOST_CHECK( r->
Points().front()->GetPosition() == ptPos );
4638 VECTOR2I( 53000000, 51000000 ),
pad, seg, txt, pt );
4658 VECTOR2I( 53000000, 51000000 ),
pad, seg, txt, pt );
4674 VECTOR2I( 53000000, 51000000 ),
pad, seg, txt, pt );
4678 std::unique_ptr<FOOTPRINT> clone(
static_cast<FOOTPRINT*
>( fp->
Clone() ) );
4680 BOOST_REQUIRE( !clone->Pads().empty() && !clone->Points().empty() );
4684 for(
BOARD_ITEM* it : clone->GraphicalItems() )
4689 ctxt =
static_cast<PCB_TEXT*
>( it );
4695 BOOST_CHECK( clone->Pads().front()->GetPosition() == ref );
4696 BOOST_CHECK( cseg->
GetStart() == ref );
4698 BOOST_CHECK( clone->Points().front()->GetPosition() == ref );
4712 VECTOR2I( 53000000, 51000000 ),
pad, seg, txt, pt );
4722 BOOST_CHECK(
pad->GetPosition() == padPos );
4723 BOOST_CHECK( seg->
GetStart() == segStart );
4733 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
4739 pad, seg, txt, pt );
4748 std::filesystem::path tmp = std::filesystem::temp_directory_path() /
"kicad_qa_scalar_roundtrip.kicad_pcb";
4752 std::filesystem::remove( tmp, ec );
4755 FOOTPRINT* r = reloaded->Footprints().front();
4764 rtxt =
static_cast<PCB_TEXT*
>( it );
4779 [](
double aScaleX,
double aScaleY )
4805 runCase( 2.0, 2.0 );
4806 runCase( 2.0, 1.0 );
4825 const int maxError =
pcbIUScale.mmToIU( 0.01 );
4837 BOOST_CHECK_GT( height2x, height1x * 3 / 2 );
4844 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
4866 std::filesystem::path tmp = std::filesystem::temp_directory_path() /
"kicad_qa_textbox_roundtrip.kicad_pcb";
4870 std::filesystem::remove( tmp, ec );
4873 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
4896 table->SetColCount( 2 );
4897 table->SetColWidth( 0, 16000000 );
4898 table->SetColWidth( 1, 18000000 );
4899 table->SetRowHeight( 0, 5000000 );
4900 table->SetRowHeight( 1, 5000000 );
4903 { -4000000, 6000000 }, { 12000000, 6000000 }, { -4000000, 11000000 }, { 12000000, 11000000 }
4906 { 12000000, 11000000 }, { 30000000, 11000000 }, { 12000000, 16000000 }, { 30000000, 16000000 }
4909 for(
int ii = 0; ii < 4; ++ii )
4916 cell->
SetEnd( ends[ii] );
4917 table->AddCell( cell );
4931 "table bbox size out of range ( " << bbox.
GetWidth() <<
", " << bbox.
GetHeight() <<
" )" );
4935 "table bbox center ( " <<
center.x <<
", " <<
center.y <<
" ) far from footprint ( "
4936 << aNearPos.
x <<
", " << aNearPos.
y <<
" )" );
4939 BOOST_CHECK( aTable->
GetCells()[0]->GetBoundingBox().GetCenter()
4940 != aTable->
GetCells()[3]->GetBoundingBox().GetCenter() );
4979 for(
double angle : { 0.0, 90.0, 33.0, 217.5 } )
5001 for(
double angle : { 0.0, 90.0, 180.0, 270.0, 33.0, 217.5 } )
5025 FOOTPRINT* fp = *m_board->Footprints().begin();
5039 const std::filesystem::path savePath =
5040 std::filesystem::temp_directory_path() /
"table_in_rotated_scaled_fp.kicad_pcb";
5046 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
5054 table2 =
static_cast<PCB_TABLE*
>( item );
5062 const int tol = 300000;
5068 "table bbox after reload o( "
5080 KI_TEST::LoadBoard( m_settingsManager,
"embedded_table_rotated_legacy_v10", m_board );
5084 for(
FOOTPRINT* fp : m_board->Footprints() )
5086 for(
BOARD_ITEM* item : fp->GraphicalItems() )
5121 BOOST_CHECK_MESSAGE( wRatio > 1.9 && wRatio < 2.1,
"table width ratio " << wRatio <<
" expected ~2.0" );
5122 BOOST_CHECK_MESSAGE( hRatio > 1.4 && hRatio < 1.6,
"table height ratio " << hRatio <<
" expected ~1.5" );
5141 std::vector<VECTOR2I> poly = {
5142 { -1000000, -1000000 }, { 1000000, -1000000 }, { 1000000, 1000000 }, { -1000000, 1000000 }
5147 BOX2I before =
pad->GetBoundingBox();
5151 BOX2I after =
pad->GetBoundingBox();
5156 BOOST_CHECK_MESSAGE( wRatio > 1.9 && wRatio < 2.1,
"custom pad width ratio " << wRatio <<
" expected ~2.0" );
5157 BOOST_CHECK_MESSAGE( hRatio > 1.4 && hRatio < 1.6,
"custom pad height ratio " << hRatio <<
" expected ~1.5" );
5166 for(
FOOTPRINT* fp : m_board->Footprints() )
5170 auto primeAndTransform =
5171 [&](
const std::function<void()>& aTransform )
5173 for(
ZONE* zone : fp->Zones() )
5174 zone->CacheBoundingBox();
5178 for(
ZONE* zone : fp->Zones() )
5180 BOOST_CHECK_MESSAGE( zone->GetBoundingBox() == zone->GetBoardOutline().BBox(),
5181 fp->GetReference() <<
" keepout bbox is stale after transform" );
5185 primeAndTransform( [&]() { fp->SetOrientation( fp->GetOrientation() +
ANGLE_90 ); } );
5186 primeAndTransform( [&]() { fp->SetPosition( fp->GetPosition() +
VECTOR2I( 1234567, 7654321 ) ); } );
constexpr int ARC_HIGH_DEF
constexpr EDA_IU_SCALE pcbIUScale
General utilities for PCB file IO for QA programs.
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Container for design settings for a BOARD object.
std::map< int, SEVERITY > m_DRCSeverities
std::shared_ptr< DRC_ENGINE > m_DRCEngine
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
void SwapItemData(BOARD_ITEM *aImage)
Swap data between aItem and aImage.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
VECTOR2I GetFPRelativePosition() const
Information pertinent to a Pcbnew printed circuit board.
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
constexpr const Vec GetEnd() const
constexpr size_type GetWidth() const
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
constexpr const Vec GetCenter() const
constexpr size_type GetHeight() const
constexpr coord_type GetLeft() const
constexpr const Vec & GetOrigin() const
constexpr coord_type GetRight() const
constexpr const SizeVec & GetSize() const
constexpr coord_type GetTop() const
constexpr coord_type GetBottom() const
CN_EDGE represents a point-to-point connection, whether realized or unrealized (ie: tracks etc.
void RunTests(EDA_UNITS aUnits, bool aReportAllTrackErrors, bool aTestFootprints, BOARD_COMMIT *aCommit=nullptr)
Run the DRC tests.
void SetViolationHandler(DRC_VIOLATION_HANDLER aHandler)
Set an optional DRC violation handler (receives DRC_ITEMs and positions).
int GetEllipseMinorRadius() const
const VECTOR2I & GetBezierC2() const
const VECTOR2I & GetEllipseCenter() const
EDA_ANGLE GetEllipseEndAngle() const
int GetEllipseMajorRadius() const
SHAPE_POLY_SET & GetPolyShape()
EDA_ANGLE GetEllipseRotation() const
virtual void SetFilled(bool aFlag)
void RebuildBezierToSegmentsPointsList(int aMaxError)
Rebuild the m_bezierPoints vertex list that approximate the Bezier curve by a list of segments.
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
EDA_ANGLE GetEllipseStartAngle() const
const std::vector< VECTOR2I > & GetBezierPoints() const
const VECTOR2I & GetBezierC1() const
bool IsPolyShapeValid() const
virtual const wxString & GetText() const
Return the string associated with the text object.
virtual void SetTextPos(const VECTOR2I &aPoint)
BOX2I GetTextBox(const RENDER_SETTINGS *aSettings, int aLine=-1) const
Useful in multiline texts to calculate the full text or a line area (for zones filling,...
virtual void SetText(const wxString &aText)
@ NORMAL
Shape is the same on all layers.
static constexpr PCB_LAYER_ID ALL_LAYERS
! The layer identifier to use for the single defintion on normal padstacks
void SetAttribute(PAD_ATTRIB aAttribute)
const std::vector< std::shared_ptr< PCB_SHAPE > > & GetPrimitives(PCB_LAYER_ID aLayer) const
Accessor to the basic shape list for custom-shaped pads.
void SetPadstackMode(PADSTACK::MODE aMode)
const BOX2I GetBoundingBox() const override
The bounding box is cached, so this will be efficient most of the time.
static LSET PTHMask()
layer set for a through hole pad
VECTOR2I GetPosition() const override
VECTOR2I GetDrillSize() const
VECTOR2I GetSize(PCB_LAYER_ID aLayer) const
void SetPosition(const VECTOR2I &aPos) override
void SetSize(PCB_LAYER_ID aLayer, const VECTOR2I &aSize)
static LSET SMDMask()
layer set for a SMD pad on Front layer
void SetLayerSet(const LSET &aLayers) override
void SetTextSize(int aTextSize)
Change the height of the human-readable text displayed below the barcode.
double GetOrientation() const
const VECTOR2I & GetLibraryPos() const
EDA_ANGLE GetLibraryAngle() const
void SetWidth(int aWidth)
void AssembleBarcode() const
Assemble the barcode polygon and text polygons into a single polygonal representation.
void SetHeight(int aHeight)
VECTOR2I GetPosition() const override
Get the position (center) of the barcode in internal units.
void SetPosition(const VECTOR2I &aPos) override
void SetOrientation(double aDegrees)
void SetLayer(PCB_LAYER_ID aLayer) override
Set the drawing layer for the barcode and its text.
EDA_ANGLE GetAngle() const
void SetText(const wxString &aText)
Set the barcode content text to encode.
virtual void SetEnd(const VECTOR2I &aPoint)
virtual void SetStart(const VECTOR2I &aPoint)
const VECTOR2I & GetLibraryStart() const
virtual VECTOR2I GetEnd() const
const VECTOR2I & GetLibraryEnd() const
virtual VECTOR2I GetStart() const
The dimension's origin is the first feature point for the dimension.
void SetKeepTextAligned(bool aKeepAligned)
For better understanding of the points that make a dimension:
A PCB_POINT is a 0-dimensional point that is used to mark a position on a PCB, or more usually a foot...
void SetPosition(const VECTOR2I &aPos) override
VECTOR2I GetPosition() const override
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
void SetEllipseCenter(const VECTOR2I &aPt) override
EDA_ANGLE GetLibraryEllipseEndAngle() const
void SetBezierC1(const VECTOR2I &aPt) override
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
VECTOR2I GetLibraryBezierC1() const
void SetWidth(int aWidth) override
void OverrideLibPoly(const SHAPE_POLY_SET &aPoly)
void OverrideLibBezier(const VECTOR2I &aC1, const VECTOR2I &aC2)
int GetLibraryEllipseMinorRadius() const
void SetEllipseStartAngle(const EDA_ANGLE &aA) override
EDA_ANGLE GetLibraryEllipseStartAngle() const
int GetLibraryEllipseMajorRadius() const
EDA_ANGLE GetLibraryEllipseRotation() const
SHAPE_T GetLibraryShape() const
void SetEllipseEndAngle(const EDA_ANGLE &aA) override
VECTOR2I GetLibraryEllipseCenter() const
void SetEnd(const VECTOR2I &aEnd) override
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
VECTOR2I GetLibraryEnd() const
void SetPolyShape(const SHAPE_POLY_SET &aShape) override
void SetEllipseRotation(const EDA_ANGLE &aA) override
VECTOR2I GetLibraryStart() const
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
void OverrideLibCoords(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aArcMid=VECTOR2I(0, 0))
void SetEllipseMinorRadius(int aR) override
STROKE_PARAMS GetStroke() const override
void SetStart(const VECTOR2I &aStart) override
void SetBezierC2(const VECTOR2I &aPt) override
void Normalize() override
Perform any normalization required after a user rotate and/or flip.
VECTOR2I GetLibraryBezierC2() const
void SetArcGeometry(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd) override
Set the three controlling points for an arc.
VECTOR2I GetLibraryArcMid() const
void SetEllipseMajorRadius(int aR) override
void SetRowSpan(int aSpan)
void SetColSpan(int aSpan)
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
PCB_TABLECELL * GetCell(int aRow, int aCol) const
std::vector< PCB_TABLECELL * > GetCells() const
void Normalize() override
Perform any normalization required after a user rotate and/or flip.
VECTOR2I GetPosition() const override
EDA_ANGLE GetTextAngle() const override
int GetTextThickness() const override
void SetBorderEnabled(bool enabled)
Disables the border, this is done by changing the stroke internally.
VECTOR2I GetTextSize() const override
void SetShape(SHAPE_T aShape) override
void SetTextAngle(const EDA_ANGLE &aAngle) override
void SetTextThickness(int aWidth) override
The TextThickness is that set by the user.
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true) override
EDA_ANGLE GetTextAngle() const override
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true) override
VECTOR2I GetTextPos() const override
void TransformTextToPolySet(SHAPE_POLY_SET &aBuffer, int aClearance, int aMaxError, ERROR_LOC aErrorLoc) const
Convert the text to a polygonSet describing the actual character strokes (one per segment).
int GetTextThickness() const override
void SetTextAngle(const EDA_ANGLE &aAngle) override
VECTOR2I GetTextSize() const override
int PointCount() const
Return the number of points (vertices) in this line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
const std::vector< VECTOR2I > & CPoints() const
Represent a set of closed polygons.
ITERATOR IterateWithHoles(int aOutline)
double Area()
Return the area of this poly set.
void SetVertex(const VERTEX_INDEX &aIndex, const VECTOR2I &aPos)
Accessor function to set the position of a specific point.
int TotalVertices() const
Return total number of vertices stored in the set.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int NewOutline()
Creates a new empty polygon in the set and returns its index.
const VECTOR2I & CVertex(int aIndex, int aOutline, int aHole) const
Return the index-th vertex in a given hole outline within a given outline.
int OutlineCount() const
Return the number of outlines in the set.
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Handle a list of polygons defining a copper zone.
void SetNeedRefill(bool aNeedRefill)
void TransformSmoothedOutlineToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, SHAPE_POLY_SET *aBoardOutline) const
Convert the outlines shape to a polygon with no holes inflated (optional) by max( aClearanceValue,...
const BOX2I GetBoundingBox() const override
bool HitTestForCorner(const VECTOR2I &refPos, int aAccuracy, SHAPE_POLY_SET::VERTEX_INDEX *aCornerHit=nullptr) const
Test if the given VECTOR2I is near a corner.
SHAPE_POLY_SET * Outline()
void Move(const VECTOR2I &offset) override
Move the outlines.
void SetIsRuleArea(bool aEnable)
void CacheBoundingBox()
Used to preload the zone bounding box cache so we don't have to worry about mutex-locking it each tim...
SHAPE_POLY_SET GetBoardOutline() const
void Rotate(const VECTOR2I &aCentre, const EDA_ANGLE &aAngle) override
Rotate the outlines.
bool HitTestFilledArea(PCB_LAYER_ID aLayer, const VECTOR2I &aRefPos, int aAccuracy=0) const
Test if the given VECTOR2I is within the bounds of a filled area of this zone.
void SetIsFilled(bool isFilled)
std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT, DRC_CONSTRAINT_T aUsage=NULL_CONSTRAINT) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
SHAPE_POLY_SET GetLibraryOutline() const
PCB_LAYER_ID GetFirstLayer() const
@ DRCE_FOOTPRINT_SCALED_WITH_PADS
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_90
static constexpr EDA_ANGLE ANGLE_180
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
@ ALWAYS_FLASHED
Always flashed for connectivity.
PCB_LAYER_ID
A quick note on layer IDs:
@ LEFT_RIGHT
Flip left to right (around the Y axis)
@ TOP_BOTTOM
Flip top to bottom (around the X axis)
void LoadBoard(SETTINGS_MANAGER &aSettingsManager, const wxString &aRelPath, std::unique_ptr< BOARD > &aBoard)
std::unique_ptr< BOARD > ReadBoardFromFileOrStream(const std::string &aFilename, std::istream &aFallback)
Read a board from a file, or another stream, as appropriate.
void DumpBoardToFile(BOARD &board, const std::filesystem::path &aFilename)
Utility function to simply write a Board out to a file.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
@ SMD
Smd pad, appears on the solder paste layer (default)
BARCODE class definition.
SETTINGS_MANAGER m_settingsManager
std::unique_ptr< BOARD > m_board
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
VECTOR3I expected(15, 30, 45)
BOOST_TEST_CONTEXT("Test Clearance")
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
BOOST_TEST_MESSAGE("Polyline has "<< chain.PointCount()<< " points")
wxString result
Test unit parsing edge cases and error handling.
BOOST_CHECK_EQUAL(result, "25.4")
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
@ PCB_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
VECTOR2< int32_t > VECTOR2I