55 BOOST_CHECK_EQUAL( aFp.GetTransform().GetRotate().AsDegrees(), aFp.GetOrientation().AsDegrees() );
110 const BOX2I bboxBefore = shapeBefore->BBox();
120 const BOX2I bboxAfter = shapeAfter->BBox();
138 BOX2I before =
pad->GetBoundingBox();
143 BOX2I after =
pad->GetBoundingBox();
158 BOX2I before =
pad->GetBoundingBox();
164 BOX2I after =
pad->GetBoundingBox();
201 BOOST_CHECK(
copy.IsFlipped() );
216 <<
" actual ( " <<
actual.x <<
", " <<
actual.y <<
" )" );
230 "pad " <<
pad->GetNumber() <<
" m_libPos ( " << stored.
x <<
", " << stored.
y <<
" )"
231 <<
" != GetFPRelativePosition ( " << derived.
x <<
", " << derived.
y <<
" )" );
247 for(
const FOOTPRINT* fp : m_board->Footprints() )
256 for(
FOOTPRINT* fp : m_board->Footprints() )
274 for(
const FOOTPRINT* fp : m_board->Footprints() )
283 for(
FOOTPRINT* fp : m_board->Footprints() )
301 FOOTPRINT* fp = *m_board->Footprints().begin();
308 std::map<wxString, VECTOR2I> origPadByNumber;
310 origPadByNumber[
pad->GetNumber()] =
pad->GetPosition();
312 std::unique_ptr<FOOTPRINT> snapshot(
static_cast<FOOTPRINT*
>( fp->
Clone() ) );
332 "pad " <<
pad->GetNumber() <<
" after undo at ( " << p.
x <<
", " << p.
y <<
" )"
333 <<
" expected ( " << orig.
x <<
", " << orig.
y <<
" )" );
361 &&
std::abs( libStartFromShape.
y - libStartStored.
y ) <= 1,
362 "shape m_libStart ( " << libStartStored.
x <<
", " << libStartStored.
y <<
" ) "
363 <<
"!= GetFPRelativePosition ( " << libStartFromShape.
x <<
", "
364 << libStartFromShape.
y <<
" )" );
373 for(
const FOOTPRINT* fp : m_board->Footprints() )
382 for(
FOOTPRINT* fp : m_board->Footprints() )
400 FOOTPRINT* fp = *m_board->Footprints().begin();
404 std::map<wxString, VECTOR2I> origOffsets;
408 origOffsets[
pad->GetNumber()] =
pad->GetPosition() -
anchor;
426 "pad " <<
pad->GetNumber() <<
" offset ( " << offset.
x <<
", " << offset.
y <<
" ) "
427 <<
"expected ( " << 2 * orig.
x <<
", " << 2 * orig.
y <<
" )" );
436 FOOTPRINT* fp = *m_board->Footprints().begin();
442 std::vector<VECTOR2I> origStartOffsets;
471 VECTOR2I orig = origStartOffsets[i++];
474 "shape start offset ( " << offset.
x <<
", " << offset.
y <<
" ) "
475 <<
"expected ( " << 2 * orig.
x <<
", " << 2 * orig.
y <<
" )" );
484 FOOTPRINT* fp = *m_board->Footprints().begin();
490 std::map<wxString, VECTOR2I> origPadPositions;
492 origPadPositions[
pad->GetNumber()] =
pad->GetPosition();
494 const std::filesystem::path savePath = std::filesystem::temp_directory_path() /
"scale_roundtrip.kicad_pcb";
501 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
512 VECTOR2I orig = origPadPositions[
pad->GetNumber()];
515 "pad " <<
pad->GetNumber() <<
" after reload at ( " << p.
x <<
", " << p.
y
516 <<
" ) expected ( " << orig.
x <<
", " << orig.
y <<
" )" );
525 FOOTPRINT* fp = *m_board->Footprints().begin();
528 std::map<wxString, VECTOR2I> origPadPositions;
530 origPadPositions[
pad->GetNumber()] =
pad->GetPosition();
532 std::unique_ptr<FOOTPRINT> snapshot(
static_cast<FOOTPRINT*
>( fp->
Clone() ) );
546 VECTOR2I orig = origPadPositions[
pad->GetNumber()];
549 "pad " <<
pad->GetNumber() <<
" after undo at ( " << p.
x <<
", " << p.
y <<
" ) expected ( "
550 << orig.
x <<
", " << orig.
y <<
" )" );
577 std::vector<VECTOR2I> origOffsets;
584 BOOST_REQUIRE_EQUAL( scaledBoard.
TotalVertices(), (
int) origOffsets.size() );
590 &&
std::abs( offset.
y - 2 * origOffsets[i].y ) <= 1,
591 "vertex " << i <<
" offset ( " << offset.
x <<
", " << offset.
y <<
" ) expected ( "
592 << 2 * origOffsets[i].x <<
", " << 2 * origOffsets[i].y <<
" )" );
601 FOOTPRINT* fp = *m_board->Footprints().begin();
604 std::map<wxString, VECTOR2I> origSizes;
605 std::map<wxString, VECTOR2I> origDrills;
609 origDrills[
pad->GetNumber()] =
pad->GetDrillSize();
633 FOOTPRINT* fp = *m_board->Footprints().begin();
656 FOOTPRINT* fp = *m_board->Footprints().begin();
674 BOOST_CHECK_CLOSE( (
double) scaledBox.
GetWidth(), 2.0 * origBox.
GetWidth(), 10.0 );
683 FOOTPRINT* fp = *m_board->Footprints().begin();
711 FOOTPRINT* fp = *m_board->Footprints().begin();
728 std::vector<int> violations;
731 [&](
const std::shared_ptr<DRC_ITEM>& aItem,
const VECTOR2I& aPos,
int aLayer,
732 const std::function<
void(
PCB_MARKER* )>& aPathGenerator )
734 violations.push_back( aItem->GetErrorCode() );
740 for(
int code : violations )
750 "footprint with pads; got "
751 << violations.size() <<
" violations" );
769 int scaledFlagged = 0;
772 [&](
const std::shared_ptr<DRC_ITEM>& aItem,
const VECTOR2I& aPos,
int aLayer,
773 const std::function<
void(
PCB_MARKER* )>& aPathGenerator )
789 FOOTPRINT* fp = *m_board->Footprints().begin();
813 FOOTPRINT* fp = *m_board->Footprints().begin();
836 FOOTPRINT* fp = *m_board->Footprints().begin();
853 <<
" ) expected ( " << origAnchor.
x <<
", " << origAnchor.
y <<
" )" );
863 std::shared_ptr<CONNECTIVITY_DATA> conn = m_board->GetConnectivity();
866 conn->RecalculateRatsnest();
869 PAD* targetPad =
nullptr;
872 for(
FOOTPRINT* fp : m_board->Footprints() )
874 for(
PAD*
pad : fp->Pads() )
876 if( !conn->GetRatsnestForPad(
pad ).empty() )
895 conn->RecalculateRatsnest();
898 auto edges = conn->GetRatsnestForPad( targetPad );
904 for(
const CN_EDGE& e : edges )
906 if( e.GetSourcePos() == newPadPos || e.GetTargetPos() == newPadPos )
913 BOOST_CHECK_MESSAGE( found,
"no ratsnest edge originates at the scaled pad position ( " << newPadPos.
x <<
", "
914 << newPadPos.
y <<
" )" );
924 FOOTPRINT* fp = *m_board->Footprints().begin();
939 BOOST_CHECK_CLOSE( (
double) after.
GetWidth(), 2.0 * origWidth, 5.0 );
940 BOOST_CHECK_CLOSE( (
double) after.
GetHeight(), 2.0 * origHeight, 5.0 );
955 for(
FOOTPRINT* candidate : m_board->Footprints() )
957 if( !candidate->GetCourtyard(
F_CrtYd ).IsEmpty() )
964 BOOST_REQUIRE_MESSAGE( fp,
"no footprint with a front courtyard in issue18" );
967 double areaBefore = before.
Area();
973 double areaAfter = after.
Area();
976 BOOST_CHECK_CLOSE( areaAfter, 4.0 * areaBefore, 1.0 );
1061 auto applyOnSelection = [&](
double sx,
double sy )
1072 applyOnSelection( 2.0, 2.0 );
1079 BOOST_CHECK_CLOSE( a.
GetScaleX(), 2.0, 1e-9 );
1080 BOOST_CHECK_CLOSE( a.
GetScaleY(), 2.0, 1e-9 );
1081 BOOST_CHECK_CLOSE( b.
GetScaleX(), 2.0, 1e-9 );
1082 BOOST_CHECK_CLOSE( b.
GetScaleY(), 2.0, 1e-9 );
1090 FOOTPRINT* fp = *m_board->Footprints().begin();
1097 BOOST_CHECK_CLOSE( fp->
GetScaleX(), 3.0, 1e-9 );
1098 BOOST_CHECK_CLOSE( fp->
GetScaleY(), 0.75, 1e-9 );
1107 FOOTPRINT* fp = *m_board->Footprints().begin();
1114 BOOST_CHECK_CLOSE( fp->
GetScaleX(), 1.5, 1e-9 );
1115 BOOST_CHECK_CLOSE( fp->
GetScaleY(), 4.0, 1e-9 );
1125 FOOTPRINT* fp = *m_board->Footprints().begin();
1139 const std::filesystem::path savePath = std::filesystem::temp_directory_path() /
"promoted_arc_roundtrip.kicad_pcb";
1146 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
1149 bool foundArc =
false;
1175 FOOTPRINT* fp = *m_board->Footprints().begin();
1187 const std::filesystem::path savePath =
1188 std::filesystem::temp_directory_path() /
"promoted_circle_roundtrip.kicad_pcb";
1195 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
1198 bool foundCircle =
false;
1214 BOOST_CHECK_MESSAGE( foundCircle,
"promoted circle did not round-trip as a lib-frame circle" );
1223 FOOTPRINT* fp = *m_board->Footprints().begin();
1245 BOOST_CHECK_CLOSE( libRotation.
AsDegrees(), 30.0, 0.01 );
1256 const std::filesystem::path savePath =
1257 std::filesystem::temp_directory_path() /
"native_ellipse_rotated_roundtrip.kicad_pcb";
1264 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
1283 BOOST_REQUIRE_MESSAGE( ellipse2,
"native ellipse not found after reload" );
1325 FOOTPRINT* fp = *m_board->Footprints().begin();
1337 const std::filesystem::path savePath = std::filesystem::temp_directory_path() /
"scale_size_roundtrip_a.kicad_pcb";
1343 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
1345 PAD* pad2 = *fp2->
Pads().begin();
1349 const std::filesystem::path savePath2 = std::filesystem::temp_directory_path() /
"scale_size_roundtrip_b.kicad_pcb";
1355 FOOTPRINT* fp3 = *reloaded2->Footprints().begin();
1357 PAD* pad3 = *fp3->
Pads().begin();
1444 maxX = std::max( maxX, p.x );
1446 BOOST_CHECK_GT( maxX, 3000000 );
1535 const VECTOR2I rotCenter( 150000000, 100000000 );
1550 FOOTPRINT* fp = *m_board->Footprints().begin();
1642 while( rotDeg > 90.0 ) rotDeg -= 180.0;
1643 while( rotDeg <= -90.0 ) rotDeg += 180.0;
1644 BOOST_CHECK_CLOSE( rotDeg, -30.0, 0.1 );
1673 BOOST_CHECK_CLOSE( major_n, major_u, 1.0 );
1674 BOOST_CHECK_CLOSE( minor_n, minor_u, 6.0 );
1676 double diffDeg = rot_n - rot_u;
1677 while( diffDeg > 90.0 ) diffDeg -= 180.0;
1678 while( diffDeg <= -90.0 ) diffDeg += 180.0;
1679 BOOST_CHECK_SMALL( diffDeg, 1.0 );
1709 BOOST_CHECK_CLOSE(
static_cast<double>( bbox.
GetWidth() ), 3162277.0, 1.0 );
1710 BOOST_CHECK_CLOSE(
static_cast<double>( bbox.
GetHeight() ), 1581139.0, 1.0 );
1829 FOOTPRINT* fp = *m_board->Footprints().begin();
1842 pad->SetNumber( wxT(
"88" ) );
1847 const std::filesystem::path savePath = std::filesystem::temp_directory_path() /
"circle_pad_roundtrip.kicad_pcb";
1854 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
1857 PAD* pad2 =
nullptr;
1861 if( p->GetNumber() == wxT(
"88" ) )
1868 BOOST_REQUIRE_MESSAGE( pad2,
"circle pad not found after reload" );
1887 FOOTPRINT* fp = *m_board->Footprints().begin();
1899 pad->SetNumber( wxT(
"99" ) );
1915 const std::filesystem::path savePath = std::filesystem::temp_directory_path() /
"pad_prim_roundtrip.kicad_pcb";
1922 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
1925 PAD* pad2 =
nullptr;
1929 if( p->GetNumber() == wxT(
"99" ) )
1936 BOOST_REQUIRE_MESSAGE( pad2,
"custom pad not found after reload" );
1946 const VECTOR2I libDelta = prim2->GetLibraryEnd() - prim2->GetLibraryStart();
1966 std::vector<VECTOR2I> poly = {
1967 { -1000000, -1000000 }, { 1000000, -1000000 }, { 1000000, 1000000 }, { -1000000, 1000000 }
1973 const BOX2I libBefore = prim->GetLibraryPolyShape().BBox();
1980 const BOX2I libAfter = prim->GetLibraryPolyShape().BBox();
1993 FOOTPRINT* fp = *m_board->Footprints().begin();
2005 pad->SetNumber( wxT(
"77" ) );
2008 std::vector<VECTOR2I> poly = {
2009 { -1000000, -1000000 }, { 1000000, -1000000 }, { 1000000, 1000000 }, { -1000000, 1000000 }
2015 const BOX2I before =
pad->GetBoundingBox();
2017 const std::filesystem::path savePath = std::filesystem::temp_directory_path() /
"pad_poly_prim_roundtrip.kicad_pcb";
2024 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
2027 PAD* pad2 =
nullptr;
2031 if( p->GetNumber() == wxT(
"77" ) )
2038 BOOST_REQUIRE_MESSAGE( pad2,
"custom poly pad not found after reload" );
2084 BOOST_CHECK_CLOSE(
circle->GetEllipseRotation().AsDegrees(), -30.0, 0.001 );
2204 "vertex " << i <<
" expected ( " <<
expected.x <<
", " <<
expected.y <<
" ) actual ( "
2224 std::vector<VECTOR2I> beforeVerts;
2226 beforeVerts.push_back( before.
CVertex( i ) );
2232 BOOST_REQUIRE_EQUAL( after.
TotalVertices(), (
int) beforeVerts.size() );
2240 "vertex " << i <<
" expected ( " <<
expected.x <<
", " <<
expected.y <<
" ) actual ( "
2283 std::vector<VECTOR2I> beforeVerts;
2285 beforeVerts.push_back( before.
CVertex( i ) );
2287 const VECTOR2I offset( 500000, 250000 );
2288 zone->
Move( offset );
2291 BOOST_REQUIRE_EQUAL( after.
TotalVertices(), (
int) beforeVerts.size() );
2299 "vertex " << i <<
" expected ( " <<
expected.x <<
", " <<
expected.y <<
" ) actual ( "
2317 std::vector<VECTOR2I> beforeVerts;
2319 beforeVerts.push_back( before.
CVertex( i ) );
2323 zone->
Rotate( centre, angle );
2326 BOOST_REQUIRE_EQUAL( after.
TotalVertices(), (
int) beforeVerts.size() );
2335 "vertex " << i <<
" expected ( " <<
expected.x <<
", " <<
expected.y <<
" ) actual ( "
2356 <<
" ) expected near board ( 50000000, 30000000 )" );
2378 <<
" ) expected near board ( 50000000, 30000000 )" );
2396 BOX2I bbox = shape->BBox();
2400 <<
" ) expected near board ( 50000000, 30000000 )" );
2425 "lib coords did not change after one flip" );
2457 "lib coords did not change after one flip" );
2489 "lib coords did not change after one flip" );
2522 "lib coords did not change after one flip" );
2544 text->SetText( wxT(
"X" ) );
2566 FOOTPRINT* fp = *m_board->Footprints().begin();
2570 table->SetColCount( 2 );
2574 table->SetColWidth( 0, colW );
2575 table->SetColWidth( 1, colW );
2576 table->SetRowHeight( 0, rowH );
2577 table->SetRowHeight( 1, rowH );
2579 for(
int i = 0; i < 4; ++i )
2583 cell->
SetEnd(
VECTOR2I( ( i % 2 + 1 ) * colW, ( i / 2 + 1 ) * rowH ) );
2584 cell->
SetText( wxString::Format(
"c%d", i ) );
2585 table->AddCell( cell );
2592 const double angles[] = { 90.0, 180.0, 270.0 };
2594 for(
double deg : angles )
2600 std::vector<VECTOR2I> startsBefore, endsBefore;
2603 startsBefore.push_back( cell->GetStart() );
2604 endsBefore.push_back( cell->GetEnd() );
2607 const std::filesystem::path savePath =
2608 std::filesystem::temp_directory_path() /
"table_in_rotated_fp.kicad_pcb";
2614 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
2628 BOOST_REQUIRE_EQUAL( (
int) table2->
GetCells().size(), 4 );
2630 for(
int i = 0; i < 4; ++i )
2636 <<
" ) expected ( " << startsBefore[i].x <<
", " << startsBefore[i].y
2640 "cell " << i <<
" end ( " << cell->
GetEnd().
x <<
", " << cell->
GetEnd().
y
2641 <<
" ) expected ( " << endsBefore[i].x <<
", " << endsBefore[i].y
2657 const std::vector<Case> cases = {
2658 {
VECTOR2I( 12345678, -7654321 ), 0.0 }, {
VECTOR2I( 12345678, -7654321 ), 90.0 },
2659 {
VECTOR2I( 12345678, -7654321 ), 180.0 }, {
VECTOR2I( 12345678, -7654321 ), 270.0 },
2660 {
VECTOR2I( -12345678, -7654321 ), 90.0 }, {
VECTOR2I( -12345678, 7654321 ), 90.0 },
2661 {
VECTOR2I( 12345678, 7654321 ), 90.0 }, {
VECTOR2I( 12345678, 7654321 ), 270.0 },
2662 {
VECTOR2I( -12345678, -7654321 ), 270.0 },
2665 for(
const Case& tc : cases )
2667 BOOST_TEST_CONTEXT(
"fp pos ( " << tc.pos.x <<
", " << tc.pos.y <<
" ) orient " << tc.angle )
2669 const double fpAngle = tc.angle;
2672 FOOTPRINT* fp = *m_board->Footprints().begin();
2679 table->SetColCount( 2 );
2683 table->SetColWidth( 0, colW );
2684 table->SetColWidth( 1, colW );
2685 table->SetRowHeight( 0, rowH );
2686 table->SetRowHeight( 1, rowH );
2688 for(
int i = 0; i < 4; ++i )
2692 cell->
SetEnd(
VECTOR2I( ( i % 2 + 1 ) * colW, ( i / 2 + 1 ) * rowH ) );
2693 cell->
SetText( wxString::Format(
"c%d", i ) );
2694 table->AddCell( cell );
2704 std::vector<VECTOR2I> startsBefore, endsBefore;
2705 std::vector<double> anglesBefore;
2708 startsBefore.push_back( cell->GetStart() );
2709 endsBefore.push_back( cell->GetEnd() );
2710 anglesBefore.push_back( cell->GetTextAngle().AsDegrees() );
2713 const std::filesystem::path savePath =
2714 std::filesystem::temp_directory_path() /
"table_rotated_in_fp_then_fp_rotated.kicad_pcb";
2720 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
2734 BOOST_REQUIRE_EQUAL( (
int) table2->
GetCells().size(), 4 );
2736 for(
int i = 0; i < 4; ++i )
2742 <<
" ) expected ( " << startsBefore[i].x <<
", " << startsBefore[i].y
2746 "cell " << i <<
" end ( " << cell->
GetEnd().
x <<
", " << cell->
GetEnd().
y
2747 <<
" ) expected ( " << endsBefore[i].x <<
", " << endsBefore[i].y
2764 table->SetColCount( 2 );
2768 table->SetColWidth( 0, colW );
2769 table->SetColWidth( 1, colW );
2770 table->SetRowHeight( 0, rowH );
2771 table->SetRowHeight( 1, rowH );
2773 for(
int i = 0; i < 4; ++i )
2777 cell->
SetEnd(
VECTOR2I( ( i % 2 + 1 ) * colW, ( i / 2 + 1 ) * rowH ) );
2778 table->AddCell( cell );
2788 std::vector<VECTOR2I> corners = cell->GetCorners();
2789 BOOST_REQUIRE_EQUAL( corners.size(), 4u );
2796 "visual width " << visual.
GetWidth() <<
" expected " << rowH );
2798 "visual height " << visual.
GetHeight() <<
" expected " << colW );
2807 table->SetColCount( 2 );
2811 table->SetColWidth( 0, colW );
2812 table->SetColWidth( 1, colW );
2813 table->SetRowHeight( 0, rowH );
2814 table->SetRowHeight( 1, rowH );
2816 for(
int i = 0; i < 4; ++i )
2820 cell->
SetEnd(
VECTOR2I( ( i % 2 + 1 ) * colW, ( i / 2 + 1 ) * rowH ) );
2821 table->AddCell( cell );
2829 std::set<std::pair<int, int>> centers;
2832 int w =
std::abs( cell->GetEnd().x - cell->GetStart().x );
2833 int h =
std::abs( cell->GetEnd().y - cell->GetStart().y );
2836 "cell dims " << w <<
" x " << h <<
" expected " << colW <<
"x" << rowH <<
" or rotated" );
2838 std::vector<VECTOR2I> corners = cell->GetCorners();
2839 BOOST_REQUIRE_EQUAL( corners.size(), 4u );
2846 "visual width " << visual.
GetWidth() <<
" expected " << rowH );
2848 "visual height " << visual.
GetHeight() <<
" expected " << colW );
2851 centers.insert( { vc.
x, vc.
y } );
2854 BOOST_CHECK_MESSAGE( centers.size() == 4,
"cells overlapped, got " << centers.size() <<
" unique centers" );
2866 tb->
SetText( wxT(
"Hello" ) );
2877 "lib shape changed to " <<
static_cast<int>( tb->
GetLibraryShape() ) );
2879 "runtime shape changed to " <<
static_cast<int>( tb->
GetShape() ) );
2884 BOOST_CHECK_MESSAGE( newWidth == origWidth,
"width changed from " << origWidth <<
" to " << newWidth );
2885 BOOST_CHECK_MESSAGE( newHeight == origHeight,
"height changed from " << origHeight <<
" to " << newHeight );
2893 FOOTPRINT* fp = *m_board->Footprints().begin();
2900 text->SetText( wxT(
"drift probe" ) );
2911 FOOTPRINT* fp = *aBoard.Footprints().begin();
2916 if( t->GetText() == wxT(
"drift probe" ) )
2923 BOARD* currentBoard = m_board.get();
2924 std::unique_ptr<BOARD> reloadedHolder;
2925 const std::filesystem::path savePathA =
2926 std::filesystem::temp_directory_path() /
"pcb_text_in_rotated_fp_a.kicad_pcb";
2927 const std::filesystem::path savePathB =
2928 std::filesystem::temp_directory_path() /
"pcb_text_in_rotated_fp_b.kicad_pcb";
2930 for(
int cycle = 0; cycle < 3; ++cycle )
2932 const std::filesystem::path&
path = ( cycle % 2 == 0 ) ? savePathA : savePathB;
2937 currentBoard = reloadedHolder.get();
2939 PCB_TEXT* probe = findProbe( *currentBoard );
2944 "cycle " << cycle <<
" text pos ( " << probe->
GetTextPos().
x <<
", "
2945 << probe->
GetTextPos().
y <<
" ) expected ( " << posBefore.
x <<
", " << posBefore.
y
2956 FOOTPRINT* fp = *m_board->Footprints().begin();
2969 const std::filesystem::path savePath = std::filesystem::temp_directory_path() /
"pcb_field_in_rotated_fp.kicad_pcb";
2975 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
2983 <<
" ) expected ( " << refPosBefore.
x <<
", " << refPosBefore.
y
2993 FOOTPRINT* fp = *m_board->Footprints().begin();
3009 text->SetText( wxT(
"scale probe" ) );
3015 tb->
SetText( wxT(
"scale probe box" ) );
3030 const std::filesystem::path savePath =
3031 std::filesystem::temp_directory_path() /
"dim_barcode_in_scaled_fp.kicad_pcb";
3037 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
3054 if( t->GetText() == wxT(
"scale probe" ) )
3067 <<
" ) expected ( " << dimStartBefore.
x <<
", " << dimStartBefore.
y
3071 "dim end after reload ( " << dim2->
GetEnd().
x <<
", " << dim2->
GetEnd().
y <<
" ) expected ( "
3072 << dimEndBefore.
x <<
", " << dimEndBefore.
y <<
" )" );
3076 <<
" ) expected ( " << bcPosBefore.
x <<
", " << bcPosBefore.
y
3081 <<
" ) expected ( " << textPosBefore.
x <<
", " << textPosBefore.
y
3086 <<
" ) expected ( " << tbStartBefore.
x <<
", "
3087 << tbStartBefore.
y <<
" )" );
3090 "textbox end after reload ( " << tb2->
GetEnd().
x <<
", " << tb2->
GetEnd().
y <<
" ) expected ( "
3091 << tbEndBefore.
x <<
", " << tbEndBefore.
y <<
" )" );
3102 text->SetText( wxT(
"X" ) );
3223 bool anyVertexChanged =
false;
3228 anyVertexChanged =
true;
3231 BOOST_CHECK_MESSAGE( anyVertexChanged,
"polygon vertices did not change after one flip" );
3244 "vertex " << i <<
" before ( " << before.
x <<
", " << before.
y <<
" ) after ( " << after.
x
3245 <<
", " << after.
y <<
" )" );
3277 "lib coords did not change after one flip" );
3344 "lib coords did not change after one flip" );
3433 "C1 expected ( " << expectedC1.
x <<
", " << expectedC1.
y <<
" ) actual ( "
3437 "C2 expected ( " << expectedC2.
x <<
", " << expectedC2.
y <<
" ) actual ( "
3455 const VECTOR2I libStart( 1000000, 1000000 );
3456 const VECTOR2I libC1( 2000000, 4000000 );
3457 const VECTOR2I libC2( 4000000, 0 );
3458 const VECTOR2I libEnd( 5000000, 3000000 );
3463 bezier->
SetEnd( libEnd );
3479 <<
", " << board.y <<
" )" );
3482 checkBoard(
"start", libStart, bezier->
GetStart() );
3485 checkBoard(
"end", libEnd, bezier->
GetEnd() );
3500 std::vector<VECTOR2I> libVerts = {
3508 for(
const VECTOR2I& v : libVerts )
3522 BOOST_REQUIRE_EQUAL(
result.TotalVertices(), (
int) libVerts.size() );
3524 for(
int i = 0; i < (int) libVerts.size(); ++i )
3530 "vertex " << i <<
" expected ( " <<
expected.x <<
", " <<
expected.y <<
" ) actual ( "
3560 bool anyMoved =
false;
3581 "vertex " << i <<
" before ( " << b.
x <<
", " << b.
y <<
" ) restored ( " << r.
x <<
", "
3618 "vertex " << i <<
" expected ( " <<
expected.x <<
", " <<
expected.y <<
" ) actual ( "
3641 BOOST_CHECK_CLOSE(
pad->GetOrientation().AsDegrees(), 45.0, 1e-6 );
3642 BOOST_CHECK_CLOSE(
pad->GetFPRelativeOrientation().AsDegrees(), 45.0, 1e-6 );
3647 BOOST_CHECK_CLOSE(
pad->GetOrientation().AsDegrees(), 135.0, 1e-6 );
3649 BOOST_CHECK_CLOSE(
pad->GetFPRelativeOrientation().AsDegrees(), 45.0, 1e-6 );
3652 BOOST_CHECK_CLOSE(
pad->GetOrientation().AsDegrees(), 45.0, 1e-6 );
3653 BOOST_CHECK_CLOSE(
pad->GetFPRelativeOrientation().AsDegrees(), 45.0, 1e-6 );
3667 text->SetText( wxT(
"X" ) );
3672 BOOST_CHECK_CLOSE(
text->GetTextAngle().AsDegrees(), 45.0, 1e-6 );
3676 BOOST_CHECK_CLOSE(
text->GetTextAngle().AsDegrees(), 135.0, 1e-6 );
3679 BOOST_CHECK_CLOSE(
text->GetTextAngle().AsDegrees(), 45.0, 1e-6 );
3869 auto checkFlip = [&](
double aFpOrientDeg,
FLIP_DIRECTION aDir,
double aExpectedDelta )
3890 BOOST_CHECK_CLOSE(
actual.AsDegrees(),
expected.AsDegrees(), 1e-6 );
3996 std::vector<VECTOR2I> savedCorners;
3998 savedCorners.emplace_back( p );
4000 const std::filesystem::path savePath =
4001 std::filesystem::temp_directory_path() /
"rect_noncardinal_roundtrip.kicad_pcb";
4008 for(
BOARD_ITEM* item : reloaded->Drawings() )
4024 BOOST_REQUIRE_EQUAL( (
int) reloadedPoints.size(), (
int) savedCorners.size() );
4026 for(
size_t i = 0; i < savedCorners.size(); ++i )
4071 const VECTOR2I coincident( 53000000, 51000000 );
4077 pad->SetPosition( coincident );
4087 BOOST_REQUIRE_EQUAL(
pad->GetPosition().x, seg->
GetStart().
x );
4088 BOOST_REQUIRE_EQUAL(
pad->GetPosition().y, seg->
GetStart().
y );
4166 aPad =
new PAD( fp );
4204 auto board = std::make_unique<BOARD>();
4217 std::filesystem::path tmp = std::filesystem::temp_directory_path() /
"kicad_qa_xform_roundtrip.kicad_pcb";
4221 std::filesystem::remove( tmp, ec );
4224 FOOTPRINT* r = reloaded->Footprints().front();
4234 rtxt =
static_cast<PCB_TEXT*
>( it );
4240 BOOST_CHECK( r->
Pads().front()->GetPosition() == padPos );
4241 BOOST_CHECK( rseg->
GetStart() == segStart );
4243 BOOST_CHECK( r->
Points().front()->GetPosition() == ptPos );
4255 VECTOR2I( 53000000, 51000000 ),
pad, seg, txt, pt );
4275 VECTOR2I( 53000000, 51000000 ),
pad, seg, txt, pt );
4291 VECTOR2I( 53000000, 51000000 ),
pad, seg, txt, pt );
4295 std::unique_ptr<FOOTPRINT> clone(
static_cast<FOOTPRINT*
>( fp->
Clone() ) );
4297 BOOST_REQUIRE( !clone->Pads().empty() && !clone->Points().empty() );
4301 for(
BOARD_ITEM* it : clone->GraphicalItems() )
4306 ctxt =
static_cast<PCB_TEXT*
>( it );
4312 BOOST_CHECK( clone->Pads().front()->GetPosition() == ref );
4313 BOOST_CHECK( cseg->
GetStart() == ref );
4315 BOOST_CHECK( clone->Points().front()->GetPosition() == ref );
4329 VECTOR2I( 53000000, 51000000 ),
pad, seg, txt, pt );
4339 BOOST_CHECK(
pad->GetPosition() == padPos );
4340 BOOST_CHECK( seg->
GetStart() == segStart );
4350 auto board = std::make_unique<BOARD>();
4365 std::filesystem::path tmp = std::filesystem::temp_directory_path() /
"kicad_qa_scalar_roundtrip.kicad_pcb";
4369 std::filesystem::remove( tmp, ec );
4372 FOOTPRINT* r = reloaded->Footprints().front();
4381 rtxt =
static_cast<PCB_TEXT*
>( it );
4395 auto runCase = [](
double aScaleX,
double aScaleY )
4421 runCase( 2.0, 2.0 );
4422 runCase( 2.0, 1.0 );
4441 const int maxError =
pcbIUScale.mmToIU( 0.01 );
4453 BOOST_CHECK_GT( height2x, height1x * 3 / 2 );
4460 auto board = std::make_unique<BOARD>();
4482 std::filesystem::path tmp = std::filesystem::temp_directory_path() /
"kicad_qa_textbox_roundtrip.kicad_pcb";
4486 std::filesystem::remove( tmp, ec );
4489 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
4512 table->SetColCount( 2 );
4513 table->SetColWidth( 0, 16000000 );
4514 table->SetColWidth( 1, 18000000 );
4515 table->SetRowHeight( 0, 5000000 );
4516 table->SetRowHeight( 1, 5000000 );
4519 { -4000000, 6000000 }, { 12000000, 6000000 }, { -4000000, 11000000 }, { 12000000, 11000000 }
4522 { 12000000, 11000000 }, { 30000000, 11000000 }, { 12000000, 16000000 }, { 30000000, 16000000 }
4525 for(
int ii = 0; ii < 4; ++ii )
4532 cell->
SetEnd( ends[ii] );
4533 table->AddCell( cell );
4547 "table bbox size out of range ( " << bbox.
GetWidth() <<
", " << bbox.
GetHeight() <<
" )" );
4551 "table bbox center ( " <<
center.x <<
", " <<
center.y <<
" ) far from footprint ( "
4552 << aNearPos.
x <<
", " << aNearPos.
y <<
" )" );
4555 BOOST_CHECK( aTable->
GetCells()[0]->GetBoundingBox().GetCenter()
4556 != aTable->
GetCells()[3]->GetBoundingBox().GetCenter() );
4595 for(
double angle : { 0.0, 90.0, 33.0, 217.5 } )
4617 for(
double angle : { 0.0, 90.0, 180.0, 270.0, 33.0, 217.5 } )
4641 FOOTPRINT* fp = *m_board->Footprints().begin();
4655 const std::filesystem::path savePath =
4656 std::filesystem::temp_directory_path() /
"table_in_rotated_scaled_fp.kicad_pcb";
4662 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
4670 table2 =
static_cast<PCB_TABLE*
>( item );
4678 const int tol = 300000;
4684 "table bbox after reload o( "
4696 KI_TEST::LoadBoard( m_settingsManager,
"embedded_table_rotated_legacy_v10", m_board );
4700 for(
FOOTPRINT* fp : m_board->Footprints() )
4702 for(
BOARD_ITEM* item : fp->GraphicalItems() )
4737 BOOST_CHECK_MESSAGE( wRatio > 1.9 && wRatio < 2.1,
"table width ratio " << wRatio <<
" expected ~2.0" );
4738 BOOST_CHECK_MESSAGE( hRatio > 1.4 && hRatio < 1.6,
"table height ratio " << hRatio <<
" expected ~1.5" );
4756 std::vector<VECTOR2I> poly = {
4757 { -1000000, -1000000 }, { 1000000, -1000000 }, { 1000000, 1000000 }, { -1000000, 1000000 }
4762 BOX2I before =
pad->GetBoundingBox();
4766 BOX2I after =
pad->GetBoundingBox();
4771 BOOST_CHECK_MESSAGE( wRatio > 1.9 && wRatio < 2.1,
"custom pad width ratio " << wRatio <<
" expected ~2.0" );
4772 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 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 const Vec & GetOrigin() const
constexpr const SizeVec & GetSize() 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 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)
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
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.
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
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
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.
std::vector< PCB_TABLECELL * > GetCells() const
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, 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)
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)
SHAPE_POLY_SET GetLibraryOutline() const
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
@ 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::string &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_CHECK_MESSAGE(totalMismatches==0, std::to_string(totalMismatches)+" board(s) with strategy disagreements")
BOOST_TEST_MESSAGE("\n=== Real-World Polygon PIP Benchmark ===\n"<< formatTable(table))
std::vector< std::vector< std::string > > table
BOOST_TEST_CONTEXT("Test Clearance")
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
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