55 BOOST_CHECK_EQUAL( aFp.GetTransform().GetRotate().AsDegrees(), aFp.GetOrientation().AsDegrees() );
111 const BOX2I bboxBefore = shapeBefore->BBox();
121 const BOX2I bboxAfter = shapeAfter->BBox();
140 BOX2I before =
pad->GetBoundingBox();
145 BOX2I after =
pad->GetBoundingBox();
161 BOX2I before =
pad->GetBoundingBox();
167 BOX2I after =
pad->GetBoundingBox();
204 BOOST_CHECK(
copy.IsFlipped() );
219 <<
" actual ( " <<
actual.x <<
", " <<
actual.y <<
" )" );
232 BOOST_CHECK_MESSAGE(
std::abs( derived.
x - stored.
x ) <= 1 &&
std::abs( derived.
y - stored.
y ) <= 1,
233 "pad " <<
pad->GetNumber() <<
" m_libPos ( " << stored.
x <<
", " << stored.
y <<
" )"
234 <<
" != GetFPRelativePosition ( " << derived.
x <<
", " << derived.
y <<
" )" );
250 for(
const FOOTPRINT* fp : m_board->Footprints() )
259 for(
FOOTPRINT* fp : m_board->Footprints() )
277 for(
const FOOTPRINT* fp : m_board->Footprints() )
286 for(
FOOTPRINT* fp : m_board->Footprints() )
304 FOOTPRINT* fp = *m_board->Footprints().begin();
311 std::map<wxString, VECTOR2I> origPadByNumber;
313 origPadByNumber[
pad->GetNumber()] =
pad->GetPosition();
315 std::unique_ptr<FOOTPRINT> snapshot(
static_cast<FOOTPRINT*
>( fp->
Clone() ) );
335 "pad " <<
pad->GetNumber() <<
" after undo at ( " << p.
x <<
", " << p.
y <<
" )"
336 <<
" expected ( " << orig.
x <<
", " << orig.
y <<
" )" );
348 for(
FOOTPRINT* fp : m_board->Footprints() )
350 std::unique_ptr<FOOTPRINT> libCopy(
static_cast<FOOTPRINT*
>( fp->Clone() ) );
353 "footprint " << fp->GetReference() <<
" differs from its own clone" );
358 "footprint " << fp->GetReference()
359 <<
" flipped top-bottom reported as differing from library" );
365 "footprint " << fp->GetReference()
366 <<
" flipped left-right reported as differing from library" );
390 BOOST_CHECK_MESSAGE(
std::abs( libStartFromShape.
x - libStartStored.
x ) <= 1
391 &&
std::abs( libStartFromShape.
y - libStartStored.
y ) <= 1,
392 "shape m_libStart ( " << libStartStored.
x <<
", " << libStartStored.
y <<
" ) "
393 <<
"!= GetFPRelativePosition ( " << libStartFromShape.
x <<
", "
394 << libStartFromShape.
y <<
" )" );
403 for(
const FOOTPRINT* fp : m_board->Footprints() )
412 for(
FOOTPRINT* fp : m_board->Footprints() )
430 FOOTPRINT* fp = *m_board->Footprints().begin();
434 std::map<wxString, VECTOR2I> origOffsets;
438 origOffsets[
pad->GetNumber()] =
pad->GetPosition() -
anchor;
455 BOOST_CHECK_MESSAGE(
std::abs( offset.
x - 2 * orig.
x ) <= 1 &&
std::abs( offset.
y - 2 * orig.
y ) <= 1,
456 "pad " <<
pad->GetNumber() <<
" offset ( " << offset.
x <<
", " << offset.
y <<
" ) "
457 <<
"expected ( " << 2 * orig.
x <<
", " << 2 * orig.
y <<
" )" );
466 FOOTPRINT* fp = *m_board->Footprints().begin();
472 std::vector<VECTOR2I> origStartOffsets;
501 VECTOR2I orig = origStartOffsets[i++];
503 BOOST_CHECK_MESSAGE(
std::abs( offset.
x - 2 * orig.
x ) <= 1 &&
std::abs( offset.
y - 2 * orig.
y ) <= 1,
504 "shape start offset ( " << offset.
x <<
", " << offset.
y <<
" ) "
505 <<
"expected ( " << 2 * orig.
x <<
", " << 2 * orig.
y <<
" )" );
514 FOOTPRINT* fp = *m_board->Footprints().begin();
520 std::map<wxString, VECTOR2I> origPadPositions;
522 origPadPositions[
pad->GetNumber()] =
pad->GetPosition();
524 const std::filesystem::path savePath = std::filesystem::temp_directory_path() /
"scale_roundtrip.kicad_pcb";
531 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
542 VECTOR2I orig = origPadPositions[
pad->GetNumber()];
545 "pad " <<
pad->GetNumber() <<
" after reload at ( " << p.
x <<
", " << p.
y
546 <<
" ) expected ( " << orig.
x <<
", " << orig.
y <<
" )" );
555 FOOTPRINT* fp = *m_board->Footprints().begin();
558 std::map<wxString, VECTOR2I> origPadPositions;
560 origPadPositions[
pad->GetNumber()] =
pad->GetPosition();
562 std::unique_ptr<FOOTPRINT> snapshot(
static_cast<FOOTPRINT*
>( fp->
Clone() ) );
576 VECTOR2I orig = origPadPositions[
pad->GetNumber()];
579 "pad " <<
pad->GetNumber() <<
" after undo at ( " << p.
x <<
", " << p.
y <<
" ) expected ( "
580 << orig.
x <<
", " << orig.
y <<
" )" );
607 std::vector<VECTOR2I> origOffsets;
614 BOOST_REQUIRE_EQUAL( scaledBoard.
TotalVertices(), (
int) origOffsets.size() );
619 BOOST_CHECK_MESSAGE(
std::abs( offset.
x - 2 * origOffsets[i].x ) <= 1
620 &&
std::abs( offset.
y - 2 * origOffsets[i].y ) <= 1,
621 "vertex " << i <<
" offset ( " << offset.
x <<
", " << offset.
y <<
" ) expected ( "
622 << 2 * origOffsets[i].x <<
", " << 2 * origOffsets[i].y <<
" )" );
631 FOOTPRINT* fp = *m_board->Footprints().begin();
634 std::map<wxString, VECTOR2I> origSizes;
635 std::map<wxString, VECTOR2I> origDrills;
640 origDrills[
pad->GetNumber()] =
pad->GetDrillSize();
664 FOOTPRINT* fp = *m_board->Footprints().begin();
687 FOOTPRINT* fp = *m_board->Footprints().begin();
705 BOOST_CHECK_CLOSE( (
double) scaledBox.
GetWidth(), 2.0 * origBox.
GetWidth(), 10.0 );
714 FOOTPRINT* fp = *m_board->Footprints().begin();
742 FOOTPRINT* fp = *m_board->Footprints().begin();
759 std::vector<int> violations;
762 [&](
const std::shared_ptr<DRC_ITEM>& aItem,
const VECTOR2I& aPos,
int aLayer,
763 const std::function<
void(
PCB_MARKER* )>& aPathGenerator )
765 violations.push_back( aItem->GetErrorCode() );
771 for(
int code : violations )
780 BOOST_CHECK_MESSAGE( found,
"expected DRCE_FOOTPRINT_SCALED_WITH_PADS for a 2x scaled "
781 "footprint with pads; got "
782 << violations.size() <<
" violations" );
800 int scaledFlagged = 0;
803 [&](
const std::shared_ptr<DRC_ITEM>& aItem,
const VECTOR2I& aPos,
int aLayer,
804 const std::function<
void(
PCB_MARKER* )>& aPathGenerator )
820 FOOTPRINT* fp = *m_board->Footprints().begin();
844 FOOTPRINT* fp = *m_board->Footprints().begin();
867 FOOTPRINT* fp = *m_board->Footprints().begin();
884 <<
" ) expected ( " << origAnchor.
x <<
", " << origAnchor.
y <<
" )" );
894 std::shared_ptr<CONNECTIVITY_DATA> conn = m_board->GetConnectivity();
897 conn->RecalculateRatsnest();
900 PAD* targetPad =
nullptr;
903 for(
FOOTPRINT* fp : m_board->Footprints() )
905 for(
PAD*
pad : fp->Pads() )
907 if( !conn->GetRatsnestForPad(
pad ).empty() )
926 conn->RecalculateRatsnest();
929 std::vector<CN_EDGE> edges = conn->GetRatsnestForPad( targetPad );
935 for(
const CN_EDGE& e : edges )
937 if( e.GetSourcePos() == newPadPos || e.GetTargetPos() == newPadPos )
944 BOOST_CHECK_MESSAGE( found,
"no ratsnest edge originates at the scaled pad position ( " << newPadPos.
x <<
", "
945 << newPadPos.
y <<
" )" );
955 FOOTPRINT* fp = *m_board->Footprints().begin();
970 BOOST_CHECK_CLOSE( (
double) after.
GetWidth(), 2.0 * origWidth, 5.0 );
971 BOOST_CHECK_CLOSE( (
double) after.
GetHeight(), 2.0 * origHeight, 5.0 );
986 for(
FOOTPRINT* candidate : m_board->Footprints() )
988 if( !candidate->GetCourtyard(
F_CrtYd ).IsEmpty() )
995 BOOST_REQUIRE_MESSAGE( fp,
"no footprint with a front courtyard in issue18" );
998 double areaBefore = before.
Area();
1004 double areaAfter = after.
Area();
1007 BOOST_CHECK_CLOSE( areaAfter, 4.0 * areaBefore, 1.0 );
1092 auto applyOnSelection =
1093 [&](
double sx,
double sy )
1104 applyOnSelection( 2.0, 2.0 );
1111 BOOST_CHECK_CLOSE( a.
GetScaleX(), 2.0, 1e-9 );
1112 BOOST_CHECK_CLOSE( a.
GetScaleY(), 2.0, 1e-9 );
1113 BOOST_CHECK_CLOSE( b.
GetScaleX(), 2.0, 1e-9 );
1114 BOOST_CHECK_CLOSE( b.
GetScaleY(), 2.0, 1e-9 );
1122 FOOTPRINT* fp = *m_board->Footprints().begin();
1129 BOOST_CHECK_CLOSE( fp->
GetScaleX(), 3.0, 1e-9 );
1130 BOOST_CHECK_CLOSE( fp->
GetScaleY(), 0.75, 1e-9 );
1139 FOOTPRINT* fp = *m_board->Footprints().begin();
1146 BOOST_CHECK_CLOSE( fp->
GetScaleX(), 1.5, 1e-9 );
1147 BOOST_CHECK_CLOSE( fp->
GetScaleY(), 4.0, 1e-9 );
1157 FOOTPRINT* fp = *m_board->Footprints().begin();
1171 const std::filesystem::path savePath = std::filesystem::temp_directory_path() /
"promoted_arc_roundtrip.kicad_pcb";
1178 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
1181 bool foundArc =
false;
1197 BOOST_CHECK_MESSAGE( foundArc,
"promoted arc did not round-trip as a lib-frame arc" );
1207 FOOTPRINT* fp = *m_board->Footprints().begin();
1219 const std::filesystem::path savePath =
1220 std::filesystem::temp_directory_path() /
"promoted_circle_roundtrip.kicad_pcb";
1227 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
1230 bool foundCircle =
false;
1246 BOOST_CHECK_MESSAGE( foundCircle,
"promoted circle did not round-trip as a lib-frame circle" );
1255 FOOTPRINT* fp = *m_board->Footprints().begin();
1277 BOOST_CHECK_CLOSE( libRotation.
AsDegrees(), 30.0, 0.01 );
1287 const std::filesystem::path savePath =
1288 std::filesystem::temp_directory_path() /
"native_ellipse_rotated_roundtrip.kicad_pcb";
1295 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
1314 BOOST_REQUIRE_MESSAGE( ellipse2,
"native ellipse not found after reload" );
1355 FOOTPRINT* fp = *m_board->Footprints().begin();
1367 const std::filesystem::path savePath = std::filesystem::temp_directory_path() /
"scale_size_roundtrip_a.kicad_pcb";
1373 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
1375 PAD* pad2 = *fp2->
Pads().begin();
1379 const std::filesystem::path savePath2 = std::filesystem::temp_directory_path() /
"scale_size_roundtrip_b.kicad_pcb";
1385 FOOTPRINT* fp3 = *reloaded2->Footprints().begin();
1387 PAD* pad3 = *fp3->
Pads().begin();
1474 maxX = std::max( maxX, p.x );
1476 BOOST_CHECK_GT( maxX, 3000000 );
1565 const VECTOR2I rotCenter( 150000000, 100000000 );
1589 const VECTOR2I rotCenter( 105000000, 80000000 );
1602 const std::filesystem::path savePath =
1603 std::filesystem::temp_directory_path() /
"normalized_rect_roundtrip.kicad_pcb";
1612 for(
BOARD_ITEM* item : reloaded->Drawings() )
1616 loaded =
static_cast<PCB_SHAPE*
>( item );
1625 BOOST_CHECK_MESSAGE( onDisk == onBoard,
"saved at ( " << onDisk.
GetOrigin().
x <<
", " << onDisk.
GetOrigin().
y
1627 <<
", expected ( " << onBoard.
GetOrigin().
x <<
", "
1637 FOOTPRINT* fp = *m_board->Footprints().begin();
1729 while( rotDeg > 90.0 ) rotDeg -= 180.0;
1730 while( rotDeg <= -90.0 ) rotDeg += 180.0;
1731 BOOST_CHECK_CLOSE( rotDeg, -30.0, 0.1 );
1760 BOOST_CHECK_CLOSE( major_n, major_u, 1.0 );
1761 BOOST_CHECK_CLOSE( minor_n, minor_u, 6.0 );
1763 double diffDeg = rot_n - rot_u;
1764 while( diffDeg > 90.0 ) diffDeg -= 180.0;
1765 while( diffDeg <= -90.0 ) diffDeg += 180.0;
1766 BOOST_CHECK_SMALL( diffDeg, 1.0 );
1795 BOOST_CHECK_CLOSE(
static_cast<double>( bbox.
GetWidth() ), 3162277.0, 1.0 );
1796 BOOST_CHECK_CLOSE(
static_cast<double>( bbox.
GetHeight() ), 1581139.0, 1.0 );
1952 FOOTPRINT* fp = *m_board->Footprints().begin();
1966 pad->SetNumber( wxT(
"88" ) );
1971 const std::filesystem::path savePath = std::filesystem::temp_directory_path() /
"circle_pad_roundtrip.kicad_pcb";
1978 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
1981 PAD* pad2 =
nullptr;
1985 if( p->GetNumber() == wxT(
"88" ) )
1992 BOOST_REQUIRE_MESSAGE( pad2,
"circle pad not found after reload" );
2011 FOOTPRINT* fp = *m_board->Footprints().begin();
2024 pad->SetNumber( wxT(
"99" ) );
2040 const std::filesystem::path savePath = std::filesystem::temp_directory_path() /
"pad_prim_roundtrip.kicad_pcb";
2047 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
2050 PAD* pad2 =
nullptr;
2054 if( p->GetNumber() == wxT(
"99" ) )
2061 BOOST_REQUIRE_MESSAGE( pad2,
"custom pad not found after reload" );
2071 const VECTOR2I libDelta = prim2->GetLibraryEnd() - prim2->GetLibraryStart();
2092 std::vector<VECTOR2I> poly = {
2093 { -1000000, -1000000 }, { 1000000, -1000000 }, { 1000000, 1000000 }, { -1000000, 1000000 }
2099 const BOX2I libBefore = prim->GetLibraryPolyShape().BBox();
2106 const BOX2I libAfter = prim->GetLibraryPolyShape().BBox();
2119 FOOTPRINT* fp = *m_board->Footprints().begin();
2132 pad->SetNumber( wxT(
"77" ) );
2135 std::vector<VECTOR2I> poly = {
2136 { -1000000, -1000000 }, { 1000000, -1000000 }, { 1000000, 1000000 }, { -1000000, 1000000 }
2142 const BOX2I before =
pad->GetBoundingBox();
2144 const std::filesystem::path savePath = std::filesystem::temp_directory_path() /
"pad_poly_prim_roundtrip.kicad_pcb";
2151 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
2154 PAD* pad2 =
nullptr;
2158 if( p->GetNumber() == wxT(
"77" ) )
2165 BOOST_REQUIRE_MESSAGE( pad2,
"custom poly pad not found after reload" );
2211 BOOST_CHECK_CLOSE(
circle->GetEllipseRotation().AsDegrees(), -30.0, 0.001 );
2331 "vertex " << i <<
" expected ( " <<
expected.x <<
", " <<
expected.y <<
" ) actual ( "
2351 std::vector<VECTOR2I> beforeVerts;
2353 beforeVerts.push_back( before.
CVertex( i ) );
2359 BOOST_REQUIRE_EQUAL( after.
TotalVertices(), (
int) beforeVerts.size() );
2367 "vertex " << i <<
" expected ( " <<
expected.x <<
", " <<
expected.y <<
" ) actual ( "
2410 std::vector<VECTOR2I> beforeVerts;
2412 beforeVerts.push_back( before.
CVertex( i ) );
2414 const VECTOR2I offset( 500000, 250000 );
2415 zone->
Move( offset );
2418 BOOST_REQUIRE_EQUAL( after.
TotalVertices(), (
int) beforeVerts.size() );
2426 "vertex " << i <<
" expected ( " <<
expected.x <<
", " <<
expected.y <<
" ) actual ( "
2444 std::vector<VECTOR2I> beforeVerts;
2446 beforeVerts.push_back( before.
CVertex( i ) );
2450 zone->
Rotate( centre, angle );
2453 BOOST_REQUIRE_EQUAL( after.
TotalVertices(), (
int) beforeVerts.size() );
2462 "vertex " << i <<
" expected ( " <<
expected.x <<
", " <<
expected.y <<
" ) actual ( "
2483 <<
" ) expected near board ( 50000000, 30000000 )" );
2507 <<
" ) expected near board ( 50000000, 30000000 )" );
2529 <<
" ) expected near board ( 50000000, 30000000 )" );
2547 BOX2I bbox = shape->BBox();
2551 <<
" ) expected near board ( 50000000, 30000000 )" );
2576 "lib coords did not change after one flip" );
2608 "lib coords did not change after one flip" );
2639 BOOST_CHECK_MESSAGE(
circle->GetLibraryStart() != libStartBefore ||
circle->GetLibraryEnd() != libEndBefore,
2640 "lib coords did not change after one flip" );
2673 "lib coords did not change after one flip" );
2695 text->SetText( wxT(
"X" ) );
2704 BOOST_CHECK_MESSAGE(
text->GetTextPos() != boardPosBefore,
"text position did not change after one flip" );
2717 FOOTPRINT* fp = *m_board->Footprints().begin();
2721 table->SetColCount( 2 );
2725 table->SetColWidth( 0, colW );
2726 table->SetColWidth( 1, colW );
2727 table->SetRowHeight( 0, rowH );
2728 table->SetRowHeight( 1, rowH );
2730 for(
int i = 0; i < 4; ++i )
2734 cell->
SetEnd(
VECTOR2I( ( i % 2 + 1 ) * colW, ( i / 2 + 1 ) * rowH ) );
2735 cell->
SetText( wxString::Format(
"c%d", i ) );
2736 table->AddCell( cell );
2743 const double angles[] = { 90.0, 180.0, 270.0 };
2745 for(
double deg : angles )
2751 std::vector<VECTOR2I> startsBefore, endsBefore;
2754 startsBefore.push_back( cell->GetStart() );
2755 endsBefore.push_back( cell->GetEnd() );
2758 const std::filesystem::path savePath =
2759 std::filesystem::temp_directory_path() /
"table_in_rotated_fp.kicad_pcb";
2765 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
2779 BOOST_REQUIRE_EQUAL( (
int) table2->
GetCells().size(), 4 );
2781 for(
int i = 0; i < 4; ++i )
2787 <<
" ) expected ( " << startsBefore[i].x <<
", " << startsBefore[i].y
2789 BOOST_CHECK_MESSAGE(
std::abs( cell->
GetEnd().
x - endsBefore[i].x ) <= 1
2791 "cell " << i <<
" end ( " << cell->
GetEnd().
x <<
", " << cell->
GetEnd().
y
2792 <<
" ) expected ( " << endsBefore[i].x <<
", " << endsBefore[i].y
2808 const std::vector<Case> cases = {
2809 {
VECTOR2I( 12345678, -7654321 ), 0.0 }, {
VECTOR2I( 12345678, -7654321 ), 90.0 },
2810 {
VECTOR2I( 12345678, -7654321 ), 180.0 }, {
VECTOR2I( 12345678, -7654321 ), 270.0 },
2811 {
VECTOR2I( -12345678, -7654321 ), 90.0 }, {
VECTOR2I( -12345678, 7654321 ), 90.0 },
2812 {
VECTOR2I( 12345678, 7654321 ), 90.0 }, {
VECTOR2I( 12345678, 7654321 ), 270.0 },
2813 {
VECTOR2I( -12345678, -7654321 ), 270.0 },
2816 for(
const Case& tc : cases )
2818 BOOST_TEST_CONTEXT(
"fp pos ( " << tc.pos.x <<
", " << tc.pos.y <<
" ) orient " << tc.angle )
2820 const double fpAngle = tc.angle;
2823 FOOTPRINT* fp = *m_board->Footprints().begin();
2830 table->SetColCount( 2 );
2834 table->SetColWidth( 0, colW );
2835 table->SetColWidth( 1, colW );
2836 table->SetRowHeight( 0, rowH );
2837 table->SetRowHeight( 1, rowH );
2839 for(
int i = 0; i < 4; ++i )
2843 cell->
SetEnd(
VECTOR2I( ( i % 2 + 1 ) * colW, ( i / 2 + 1 ) * rowH ) );
2844 cell->
SetText( wxString::Format(
"c%d", i ) );
2845 table->AddCell( cell );
2855 std::vector<VECTOR2I> startsBefore, endsBefore;
2856 std::vector<double> anglesBefore;
2859 startsBefore.push_back( cell->GetStart() );
2860 endsBefore.push_back( cell->GetEnd() );
2861 anglesBefore.push_back( cell->GetTextAngle().AsDegrees() );
2864 const std::filesystem::path savePath =
2865 std::filesystem::temp_directory_path() /
"table_rotated_in_fp_then_fp_rotated.kicad_pcb";
2871 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
2885 BOOST_REQUIRE_EQUAL( (
int) table2->
GetCells().size(), 4 );
2887 for(
int i = 0; i < 4; ++i )
2893 <<
" ) expected ( " << startsBefore[i].x <<
", " << startsBefore[i].y
2895 BOOST_CHECK_MESSAGE(
std::abs( cell->
GetEnd().
x - endsBefore[i].x ) <= 1
2897 "cell " << i <<
" end ( " << cell->
GetEnd().
x <<
", " << cell->
GetEnd().
y
2898 <<
" ) expected ( " << endsBefore[i].x <<
", " << endsBefore[i].y
2915 table->SetColCount( 2 );
2919 table->SetColWidth( 0, colW );
2920 table->SetColWidth( 1, colW );
2921 table->SetRowHeight( 0, rowH );
2922 table->SetRowHeight( 1, rowH );
2924 for(
int i = 0; i < 4; ++i )
2928 cell->
SetEnd(
VECTOR2I( ( i % 2 + 1 ) * colW, ( i / 2 + 1 ) * rowH ) );
2929 table->AddCell( cell );
2939 std::vector<VECTOR2I> corners = cell->GetCorners();
2940 BOOST_REQUIRE_EQUAL( corners.size(), 4u );
2947 "visual width " << visual.
GetWidth() <<
" expected " << rowH );
2949 "visual height " << visual.
GetHeight() <<
" expected " << colW );
2972 for(
int row = 0; row < 2; ++row )
2977 cell->
SetText( row == 0 ? wxT(
"PCB1234" ) : wxT(
"Rev A00" ) );
2998 box.
Merge( cell->GetStart() );
2999 box.
Merge( cell->GetEnd() );
3009 std::vector<VECTOR2I> starts;
3010 std::vector<VECTOR2I> ends;
3014 starts.push_back( cell->GetStart() );
3015 ends.push_back( cell->GetEnd() );
3020 for(
size_t ii = 0; ii < aTable->
GetCells().size(); ++ii )
3024 BOOST_CHECK_MESSAGE( ( cell->
GetStart() - starts[ii] ).EuclideanNorm() <= 1,
3025 "cell " << ii <<
" start moved to ( " << cell->
GetStart().
x <<
", " << cell->
GetStart().
y
3026 <<
" ) from ( " << starts[ii].x <<
", " << starts[ii].y <<
" )" );
3027 BOOST_CHECK_MESSAGE( ( cell->
GetEnd() - ends[ii] ).EuclideanNorm() <= 1,
3028 "cell " << ii <<
" end moved to ( " << cell->
GetEnd().
x <<
", " << cell->
GetEnd().
y
3029 <<
" ) from ( " << ends[ii].x <<
", " << ends[ii].y <<
" )" );
3058 "table box ( " << after.
GetLeft() <<
", " << after.
GetTop() <<
" ) - ( "
3125 table->SetColCount( 3 );
3127 for(
int col = 0; col < 3; ++col )
3128 table->SetColWidth( col, colWidths[col] );
3130 for(
int row = 0; row < 2; ++row )
3131 table->SetRowHeight( row, rowHeights[row] );
3136 for(
int row = 0; row < 2; ++row )
3140 for(
int col = 0; col < 3; ++col )
3145 cell->
SetText( wxString::Format( wxT(
"%c%d" ),
'A' + col, row + 1 ) );
3146 table->AddCell( cell );
3147 x += colWidths[col];
3150 y += rowHeights[row];
3157 for(
int row = 0; row < 2; ++row )
3159 for(
int col = 0; col < 3; ++col )
3161 wxString
expected = wxString::Format( wxT(
"%c%d" ),
'A' + 2 - col, row + 1 );
3182 table->SetColCount( 2 );
3186 table->SetColWidth( 0, colW );
3187 table->SetColWidth( 1, colW );
3188 table->SetRowHeight( 0, rowH );
3189 table->SetRowHeight( 1, rowH );
3191 for(
int i = 0; i < 4; ++i )
3195 cell->
SetEnd(
VECTOR2I( ( i % 2 + 1 ) * colW, ( i / 2 + 1 ) * rowH ) );
3196 table->AddCell( cell );
3204 std::set<std::pair<int, int>> centers;
3207 int w =
std::abs( cell->GetEnd().x - cell->GetStart().x );
3208 int h =
std::abs( cell->GetEnd().y - cell->GetStart().y );
3210 BOOST_CHECK_MESSAGE( ( w == colW && h == rowH ) || ( w == rowH && h == colW ),
3211 "cell dims " << w <<
" x " << h <<
" expected " << colW <<
"x" << rowH <<
" or rotated" );
3213 std::vector<VECTOR2I> corners = cell->GetCorners();
3214 BOOST_REQUIRE_EQUAL( corners.size(), 4u );
3221 "visual width " << visual.
GetWidth() <<
" expected " << rowH );
3223 "visual height " << visual.
GetHeight() <<
" expected " << colW );
3226 centers.insert( { vc.
x, vc.
y } );
3229 BOOST_CHECK_MESSAGE( centers.size() == 4,
"cells overlapped, got " << centers.size() <<
" unique centers" );
3241 tb->
SetText( wxT(
"Hello" ) );
3252 "lib shape changed to " <<
static_cast<int>( tb->
GetLibraryShape() ) );
3254 "runtime shape changed to " <<
static_cast<int>( tb->
GetShape() ) );
3259 BOOST_CHECK_MESSAGE( newWidth == origWidth,
"width changed from " << origWidth <<
" to " << newWidth );
3260 BOOST_CHECK_MESSAGE( newHeight == origHeight,
"height changed from " << origHeight <<
" to " << newHeight );
3268 FOOTPRINT* fp = *m_board->Footprints().begin();
3275 text->SetText( wxT(
"drift probe" ) );
3287 FOOTPRINT* fp = *aBoard.Footprints().begin();
3292 if( t->GetText() == wxT(
"drift probe" ) )
3299 BOARD* currentBoard = m_board.get();
3300 std::unique_ptr<BOARD> reloadedHolder;
3301 const std::filesystem::path savePathA =
3302 std::filesystem::temp_directory_path() /
"pcb_text_in_rotated_fp_a.kicad_pcb";
3303 const std::filesystem::path savePathB =
3304 std::filesystem::temp_directory_path() /
"pcb_text_in_rotated_fp_b.kicad_pcb";
3306 for(
int cycle = 0; cycle < 3; ++cycle )
3308 const std::filesystem::path&
path = ( cycle % 2 == 0 ) ? savePathA : savePathB;
3313 currentBoard = reloadedHolder.get();
3315 PCB_TEXT* probe = findProbe( *currentBoard );
3320 "cycle " << cycle <<
" text pos ( " << probe->
GetTextPos().
x <<
", "
3321 << probe->
GetTextPos().
y <<
" ) expected ( " << posBefore.
x <<
", " << posBefore.
y
3332 FOOTPRINT* fp = *m_board->Footprints().begin();
3345 const std::filesystem::path savePath = std::filesystem::temp_directory_path() /
"pcb_field_in_rotated_fp.kicad_pcb";
3351 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
3359 <<
" ) expected ( " << refPosBefore.
x <<
", " << refPosBefore.
y
3369 FOOTPRINT* fp = *m_board->Footprints().begin();
3385 text->SetText( wxT(
"scale probe" ) );
3391 tb->
SetText( wxT(
"scale probe box" ) );
3406 const std::filesystem::path savePath =
3407 std::filesystem::temp_directory_path() /
"dim_barcode_in_scaled_fp.kicad_pcb";
3413 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
3430 if( t->GetText() == wxT(
"scale probe" ) )
3443 <<
" ) expected ( " << dimStartBefore.
x <<
", " << dimStartBefore.
y
3447 "dim end after reload ( " << dim2->
GetEnd().
x <<
", " << dim2->
GetEnd().
y <<
" ) expected ( "
3448 << dimEndBefore.
x <<
", " << dimEndBefore.
y <<
" )" );
3452 <<
" ) expected ( " << bcPosBefore.
x <<
", " << bcPosBefore.
y
3457 <<
" ) expected ( " << textPosBefore.
x <<
", " << textPosBefore.
y
3462 <<
" ) expected ( " << tbStartBefore.
x <<
", "
3463 << tbStartBefore.
y <<
" )" );
3466 "textbox end after reload ( " << tb2->
GetEnd().
x <<
", " << tb2->
GetEnd().
y <<
" ) expected ( "
3467 << tbEndBefore.
x <<
", " << tbEndBefore.
y <<
" )" );
3478 text->SetText( wxT(
"X" ) );
3599 bool anyVertexChanged =
false;
3604 anyVertexChanged =
true;
3607 BOOST_CHECK_MESSAGE( anyVertexChanged,
"polygon vertices did not change after one flip" );
3619 BOOST_CHECK_MESSAGE(
std::abs( before.
x - after.
x ) <= 1 &&
std::abs( before.
y - after.
y ) <= 1,
3620 "vertex " << i <<
" before ( " << before.
x <<
", " << before.
y <<
" ) after ( " << after.
x
3621 <<
", " << after.
y <<
" )" );
3653 "lib coords did not change after one flip" );
3686 BOOST_CHECK_MESSAGE( point->
GetPosition() != boardPosBefore,
"board position did not change after one flip" );
3720 "lib coords did not change after one flip" );
3778 BOOST_CHECK_MESSAGE( bezier->
GetBezierC1() != c1Before,
"C1 did not follow rotation" );
3779 BOOST_CHECK_MESSAGE( bezier->
GetBezierC2() != c2Before,
"C2 did not follow rotation" );
3809 "C1 expected ( " << expectedC1.
x <<
", " << expectedC1.
y <<
" ) actual ( "
3813 "C2 expected ( " << expectedC2.
x <<
", " << expectedC2.
y <<
" ) actual ( "
3831 const VECTOR2I libStart( 1000000, 1000000 );
3832 const VECTOR2I libC1( 2000000, 4000000 );
3833 const VECTOR2I libC2( 4000000, 0 );
3834 const VECTOR2I libEnd( 5000000, 3000000 );
3839 bezier->
SetEnd( libEnd );
3856 << board.x <<
", " << board.y <<
" )" );
3859 checkBoard(
"start", libStart, bezier->
GetStart() );
3862 checkBoard(
"end", libEnd, bezier->
GetEnd() );
3877 std::vector<VECTOR2I> libVerts = {
3885 for(
const VECTOR2I& v : libVerts )
3899 BOOST_REQUIRE_EQUAL(
result.TotalVertices(), (
int) libVerts.size() );
3901 for(
int i = 0; i < (int) libVerts.size(); ++i )
3907 "vertex " << i <<
" expected ( " <<
expected.x <<
", " <<
expected.y <<
" ) actual ( "
3937 bool anyMoved =
false;
3944 BOOST_CHECK_MESSAGE( anyMoved,
"polygon vertices did not move after rotation" );
3958 "vertex " << i <<
" before ( " << b.
x <<
", " << b.
y <<
" ) restored ( " << r.
x <<
", "
3995 "vertex " << i <<
" expected ( " <<
expected.x <<
", " <<
expected.y <<
" ) actual ( "
4019 BOOST_CHECK_CLOSE(
pad->GetOrientation().AsDegrees(), 45.0, 1e-6 );
4020 BOOST_CHECK_CLOSE(
pad->GetFPRelativeOrientation().AsDegrees(), 45.0, 1e-6 );
4025 BOOST_CHECK_CLOSE(
pad->GetOrientation().AsDegrees(), 135.0, 1e-6 );
4027 BOOST_CHECK_CLOSE(
pad->GetFPRelativeOrientation().AsDegrees(), 45.0, 1e-6 );
4030 BOOST_CHECK_CLOSE(
pad->GetOrientation().AsDegrees(), 45.0, 1e-6 );
4031 BOOST_CHECK_CLOSE(
pad->GetFPRelativeOrientation().AsDegrees(), 45.0, 1e-6 );
4045 text->SetText( wxT(
"X" ) );
4050 BOOST_CHECK_CLOSE(
text->GetTextAngle().AsDegrees(), 45.0, 1e-6 );
4054 BOOST_CHECK_CLOSE(
text->GetTextAngle().AsDegrees(), 135.0, 1e-6 );
4057 BOOST_CHECK_CLOSE(
text->GetTextAngle().AsDegrees(), 45.0, 1e-6 );
4110 BOOST_CHECK_MESSAGE( tb->
GetTextAngle() != absBefore,
"text angle did not change after one flip" );
4248 [&](
double aFpOrientDeg,
FLIP_DIRECTION aDir,
double aExpectedDelta )
4269 BOOST_CHECK_CLOSE(
actual.AsDegrees(),
expected.AsDegrees(), 1e-6 );
4300 BOOST_CHECK_MESSAGE( bc->
GetPosition() != posBefore,
"barcode pos did not move on first flip" );
4337 BOOST_CHECK_MESSAGE( dim->
GetStart() != startBefore,
"dim start did not move on first flip" );
4375 std::vector<VECTOR2I> savedCorners;
4377 savedCorners.emplace_back( p );
4379 const std::filesystem::path savePath =
4380 std::filesystem::temp_directory_path() /
"rect_noncardinal_roundtrip.kicad_pcb";
4387 for(
BOARD_ITEM* item : reloaded->Drawings() )
4403 BOOST_REQUIRE_EQUAL( (
int) reloadedPoints.size(), (
int) savedCorners.size() );
4405 for(
size_t i = 0; i < savedCorners.size(); ++i )
4451 const VECTOR2I coincident( 53000000, 51000000 );
4458 pad->SetPosition( coincident );
4468 BOOST_REQUIRE_EQUAL(
pad->GetPosition().x, seg->
GetStart().
x );
4469 BOOST_REQUIRE_EQUAL(
pad->GetPosition().y, seg->
GetStart().
y );
4547 aPad =
new PAD( fp );
4579 BOOST_CHECK_MESSAGE( aTxt->
GetTextPos() == aSeg->
GetStart(), aWhen <<
": text vs seg" );
4586 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
4599 std::filesystem::path tmp = std::filesystem::temp_directory_path() /
"kicad_qa_xform_roundtrip.kicad_pcb";
4603 std::filesystem::remove( tmp, ec );
4606 FOOTPRINT* r = reloaded->Footprints().front();
4616 rtxt =
static_cast<PCB_TEXT*
>( it );
4622 BOOST_CHECK( r->
Pads().front()->GetPosition() == padPos );
4623 BOOST_CHECK( rseg->
GetStart() == segStart );
4625 BOOST_CHECK( r->
Points().front()->GetPosition() == ptPos );
4637 VECTOR2I( 53000000, 51000000 ),
pad, seg, txt, pt );
4657 VECTOR2I( 53000000, 51000000 ),
pad, seg, txt, pt );
4673 VECTOR2I( 53000000, 51000000 ),
pad, seg, txt, pt );
4677 std::unique_ptr<FOOTPRINT> clone(
static_cast<FOOTPRINT*
>( fp->
Clone() ) );
4679 BOOST_REQUIRE( !clone->Pads().empty() && !clone->Points().empty() );
4683 for(
BOARD_ITEM* it : clone->GraphicalItems() )
4688 ctxt =
static_cast<PCB_TEXT*
>( it );
4694 BOOST_CHECK( clone->Pads().front()->GetPosition() == ref );
4695 BOOST_CHECK( cseg->
GetStart() == ref );
4697 BOOST_CHECK( clone->Points().front()->GetPosition() == ref );
4711 VECTOR2I( 53000000, 51000000 ),
pad, seg, txt, pt );
4721 BOOST_CHECK(
pad->GetPosition() == padPos );
4722 BOOST_CHECK( seg->
GetStart() == segStart );
4732 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
4738 pad, seg, txt, pt );
4747 std::filesystem::path tmp = std::filesystem::temp_directory_path() /
"kicad_qa_scalar_roundtrip.kicad_pcb";
4751 std::filesystem::remove( tmp, ec );
4754 FOOTPRINT* r = reloaded->Footprints().front();
4763 rtxt =
static_cast<PCB_TEXT*
>( it );
4778 [](
double aScaleX,
double aScaleY )
4804 runCase( 2.0, 2.0 );
4805 runCase( 2.0, 1.0 );
4824 const int maxError =
pcbIUScale.mmToIU( 0.01 );
4836 BOOST_CHECK_GT( height2x, height1x * 3 / 2 );
4843 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
4865 std::filesystem::path tmp = std::filesystem::temp_directory_path() /
"kicad_qa_textbox_roundtrip.kicad_pcb";
4869 std::filesystem::remove( tmp, ec );
4872 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
4895 table->SetColCount( 2 );
4896 table->SetColWidth( 0, 16000000 );
4897 table->SetColWidth( 1, 18000000 );
4898 table->SetRowHeight( 0, 5000000 );
4899 table->SetRowHeight( 1, 5000000 );
4902 { -4000000, 6000000 }, { 12000000, 6000000 }, { -4000000, 11000000 }, { 12000000, 11000000 }
4905 { 12000000, 11000000 }, { 30000000, 11000000 }, { 12000000, 16000000 }, { 30000000, 16000000 }
4908 for(
int ii = 0; ii < 4; ++ii )
4915 cell->
SetEnd( ends[ii] );
4916 table->AddCell( cell );
4930 "table bbox size out of range ( " << bbox.
GetWidth() <<
", " << bbox.
GetHeight() <<
" )" );
4934 "table bbox center ( " <<
center.x <<
", " <<
center.y <<
" ) far from footprint ( "
4935 << aNearPos.
x <<
", " << aNearPos.
y <<
" )" );
4938 BOOST_CHECK( aTable->
GetCells()[0]->GetBoundingBox().GetCenter()
4939 != aTable->
GetCells()[3]->GetBoundingBox().GetCenter() );
4978 for(
double angle : { 0.0, 90.0, 33.0, 217.5 } )
5000 for(
double angle : { 0.0, 90.0, 180.0, 270.0, 33.0, 217.5 } )
5024 FOOTPRINT* fp = *m_board->Footprints().begin();
5038 const std::filesystem::path savePath =
5039 std::filesystem::temp_directory_path() /
"table_in_rotated_scaled_fp.kicad_pcb";
5045 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
5053 table2 =
static_cast<PCB_TABLE*
>( item );
5061 const int tol = 300000;
5067 "table bbox after reload o( "
5079 KI_TEST::LoadBoard( m_settingsManager,
"embedded_table_rotated_legacy_v10", m_board );
5083 for(
FOOTPRINT* fp : m_board->Footprints() )
5085 for(
BOARD_ITEM* item : fp->GraphicalItems() )
5120 BOOST_CHECK_MESSAGE( wRatio > 1.9 && wRatio < 2.1,
"table width ratio " << wRatio <<
" expected ~2.0" );
5121 BOOST_CHECK_MESSAGE( hRatio > 1.4 && hRatio < 1.6,
"table height ratio " << hRatio <<
" expected ~1.5" );
5140 std::vector<VECTOR2I> poly = {
5141 { -1000000, -1000000 }, { 1000000, -1000000 }, { 1000000, 1000000 }, { -1000000, 1000000 }
5146 BOX2I before =
pad->GetBoundingBox();
5150 BOX2I after =
pad->GetBoundingBox();
5155 BOOST_CHECK_MESSAGE( wRatio > 1.9 && wRatio < 2.1,
"custom pad width ratio " << wRatio <<
" expected ~2.0" );
5156 BOOST_CHECK_MESSAGE( hRatio > 1.4 && hRatio < 1.6,
"custom pad height ratio " << hRatio <<
" expected ~1.5" );
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
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 SetArcGeometry(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
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
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)
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
Function TransformTextToPolySet Convert the text to a polygonSet describing the actual character stro...
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_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