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 )" );
2380 <<
" ) expected near board ( 50000000, 30000000 )" );
2402 <<
" ) expected near board ( 50000000, 30000000 )" );
2420 BOX2I bbox = shape->BBox();
2424 <<
" ) expected near board ( 50000000, 30000000 )" );
2449 "lib coords did not change after one flip" );
2481 "lib coords did not change after one flip" );
2513 "lib coords did not change after one flip" );
2546 "lib coords did not change after one flip" );
2568 text->SetText( wxT(
"X" ) );
2590 FOOTPRINT* fp = *m_board->Footprints().begin();
2594 table->SetColCount( 2 );
2598 table->SetColWidth( 0, colW );
2599 table->SetColWidth( 1, colW );
2600 table->SetRowHeight( 0, rowH );
2601 table->SetRowHeight( 1, rowH );
2603 for(
int i = 0; i < 4; ++i )
2607 cell->
SetEnd(
VECTOR2I( ( i % 2 + 1 ) * colW, ( i / 2 + 1 ) * rowH ) );
2608 cell->
SetText( wxString::Format(
"c%d", i ) );
2609 table->AddCell( cell );
2616 const double angles[] = { 90.0, 180.0, 270.0 };
2618 for(
double deg : angles )
2624 std::vector<VECTOR2I> startsBefore, endsBefore;
2627 startsBefore.push_back( cell->GetStart() );
2628 endsBefore.push_back( cell->GetEnd() );
2631 const std::filesystem::path savePath =
2632 std::filesystem::temp_directory_path() /
"table_in_rotated_fp.kicad_pcb";
2638 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
2652 BOOST_REQUIRE_EQUAL( (
int) table2->
GetCells().size(), 4 );
2654 for(
int i = 0; i < 4; ++i )
2660 <<
" ) expected ( " << startsBefore[i].x <<
", " << startsBefore[i].y
2664 "cell " << i <<
" end ( " << cell->
GetEnd().
x <<
", " << cell->
GetEnd().
y
2665 <<
" ) expected ( " << endsBefore[i].x <<
", " << endsBefore[i].y
2681 const std::vector<Case> cases = {
2682 {
VECTOR2I( 12345678, -7654321 ), 0.0 }, {
VECTOR2I( 12345678, -7654321 ), 90.0 },
2683 {
VECTOR2I( 12345678, -7654321 ), 180.0 }, {
VECTOR2I( 12345678, -7654321 ), 270.0 },
2684 {
VECTOR2I( -12345678, -7654321 ), 90.0 }, {
VECTOR2I( -12345678, 7654321 ), 90.0 },
2685 {
VECTOR2I( 12345678, 7654321 ), 90.0 }, {
VECTOR2I( 12345678, 7654321 ), 270.0 },
2686 {
VECTOR2I( -12345678, -7654321 ), 270.0 },
2689 for(
const Case& tc : cases )
2691 BOOST_TEST_CONTEXT(
"fp pos ( " << tc.pos.x <<
", " << tc.pos.y <<
" ) orient " << tc.angle )
2693 const double fpAngle = tc.angle;
2696 FOOTPRINT* fp = *m_board->Footprints().begin();
2703 table->SetColCount( 2 );
2707 table->SetColWidth( 0, colW );
2708 table->SetColWidth( 1, colW );
2709 table->SetRowHeight( 0, rowH );
2710 table->SetRowHeight( 1, rowH );
2712 for(
int i = 0; i < 4; ++i )
2716 cell->
SetEnd(
VECTOR2I( ( i % 2 + 1 ) * colW, ( i / 2 + 1 ) * rowH ) );
2717 cell->
SetText( wxString::Format(
"c%d", i ) );
2718 table->AddCell( cell );
2728 std::vector<VECTOR2I> startsBefore, endsBefore;
2729 std::vector<double> anglesBefore;
2732 startsBefore.push_back( cell->GetStart() );
2733 endsBefore.push_back( cell->GetEnd() );
2734 anglesBefore.push_back( cell->GetTextAngle().AsDegrees() );
2737 const std::filesystem::path savePath =
2738 std::filesystem::temp_directory_path() /
"table_rotated_in_fp_then_fp_rotated.kicad_pcb";
2744 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
2758 BOOST_REQUIRE_EQUAL( (
int) table2->
GetCells().size(), 4 );
2760 for(
int i = 0; i < 4; ++i )
2766 <<
" ) expected ( " << startsBefore[i].x <<
", " << startsBefore[i].y
2770 "cell " << i <<
" end ( " << cell->
GetEnd().
x <<
", " << cell->
GetEnd().
y
2771 <<
" ) expected ( " << endsBefore[i].x <<
", " << endsBefore[i].y
2788 table->SetColCount( 2 );
2792 table->SetColWidth( 0, colW );
2793 table->SetColWidth( 1, colW );
2794 table->SetRowHeight( 0, rowH );
2795 table->SetRowHeight( 1, rowH );
2797 for(
int i = 0; i < 4; ++i )
2801 cell->
SetEnd(
VECTOR2I( ( i % 2 + 1 ) * colW, ( i / 2 + 1 ) * rowH ) );
2802 table->AddCell( cell );
2812 std::vector<VECTOR2I> corners = cell->GetCorners();
2813 BOOST_REQUIRE_EQUAL( corners.size(), 4u );
2820 "visual width " << visual.
GetWidth() <<
" expected " << rowH );
2822 "visual height " << visual.
GetHeight() <<
" expected " << colW );
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 table->AddCell( cell );
2853 std::set<std::pair<int, int>> centers;
2856 int w =
std::abs( cell->GetEnd().x - cell->GetStart().x );
2857 int h =
std::abs( cell->GetEnd().y - cell->GetStart().y );
2860 "cell dims " << w <<
" x " << h <<
" expected " << colW <<
"x" << rowH <<
" or rotated" );
2862 std::vector<VECTOR2I> corners = cell->GetCorners();
2863 BOOST_REQUIRE_EQUAL( corners.size(), 4u );
2870 "visual width " << visual.
GetWidth() <<
" expected " << rowH );
2872 "visual height " << visual.
GetHeight() <<
" expected " << colW );
2875 centers.insert( { vc.
x, vc.
y } );
2878 BOOST_CHECK_MESSAGE( centers.size() == 4,
"cells overlapped, got " << centers.size() <<
" unique centers" );
2890 tb->
SetText( wxT(
"Hello" ) );
2901 "lib shape changed to " <<
static_cast<int>( tb->
GetLibraryShape() ) );
2903 "runtime shape changed to " <<
static_cast<int>( tb->
GetShape() ) );
2908 BOOST_CHECK_MESSAGE( newWidth == origWidth,
"width changed from " << origWidth <<
" to " << newWidth );
2909 BOOST_CHECK_MESSAGE( newHeight == origHeight,
"height changed from " << origHeight <<
" to " << newHeight );
2917 FOOTPRINT* fp = *m_board->Footprints().begin();
2924 text->SetText( wxT(
"drift probe" ) );
2935 FOOTPRINT* fp = *aBoard.Footprints().begin();
2940 if( t->GetText() == wxT(
"drift probe" ) )
2947 BOARD* currentBoard = m_board.get();
2948 std::unique_ptr<BOARD> reloadedHolder;
2949 const std::filesystem::path savePathA =
2950 std::filesystem::temp_directory_path() /
"pcb_text_in_rotated_fp_a.kicad_pcb";
2951 const std::filesystem::path savePathB =
2952 std::filesystem::temp_directory_path() /
"pcb_text_in_rotated_fp_b.kicad_pcb";
2954 for(
int cycle = 0; cycle < 3; ++cycle )
2956 const std::filesystem::path&
path = ( cycle % 2 == 0 ) ? savePathA : savePathB;
2961 currentBoard = reloadedHolder.get();
2963 PCB_TEXT* probe = findProbe( *currentBoard );
2968 "cycle " << cycle <<
" text pos ( " << probe->
GetTextPos().
x <<
", "
2969 << probe->
GetTextPos().
y <<
" ) expected ( " << posBefore.
x <<
", " << posBefore.
y
2980 FOOTPRINT* fp = *m_board->Footprints().begin();
2993 const std::filesystem::path savePath = std::filesystem::temp_directory_path() /
"pcb_field_in_rotated_fp.kicad_pcb";
2999 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
3007 <<
" ) expected ( " << refPosBefore.
x <<
", " << refPosBefore.
y
3017 FOOTPRINT* fp = *m_board->Footprints().begin();
3033 text->SetText( wxT(
"scale probe" ) );
3039 tb->
SetText( wxT(
"scale probe box" ) );
3054 const std::filesystem::path savePath =
3055 std::filesystem::temp_directory_path() /
"dim_barcode_in_scaled_fp.kicad_pcb";
3061 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
3078 if( t->GetText() == wxT(
"scale probe" ) )
3091 <<
" ) expected ( " << dimStartBefore.
x <<
", " << dimStartBefore.
y
3095 "dim end after reload ( " << dim2->
GetEnd().
x <<
", " << dim2->
GetEnd().
y <<
" ) expected ( "
3096 << dimEndBefore.
x <<
", " << dimEndBefore.
y <<
" )" );
3100 <<
" ) expected ( " << bcPosBefore.
x <<
", " << bcPosBefore.
y
3105 <<
" ) expected ( " << textPosBefore.
x <<
", " << textPosBefore.
y
3110 <<
" ) expected ( " << tbStartBefore.
x <<
", "
3111 << tbStartBefore.
y <<
" )" );
3114 "textbox end after reload ( " << tb2->
GetEnd().
x <<
", " << tb2->
GetEnd().
y <<
" ) expected ( "
3115 << tbEndBefore.
x <<
", " << tbEndBefore.
y <<
" )" );
3126 text->SetText( wxT(
"X" ) );
3247 bool anyVertexChanged =
false;
3252 anyVertexChanged =
true;
3255 BOOST_CHECK_MESSAGE( anyVertexChanged,
"polygon vertices did not change after one flip" );
3268 "vertex " << i <<
" before ( " << before.
x <<
", " << before.
y <<
" ) after ( " << after.
x
3269 <<
", " << after.
y <<
" )" );
3301 "lib coords did not change after one flip" );
3368 "lib coords did not change after one flip" );
3457 "C1 expected ( " << expectedC1.
x <<
", " << expectedC1.
y <<
" ) actual ( "
3461 "C2 expected ( " << expectedC2.
x <<
", " << expectedC2.
y <<
" ) actual ( "
3479 const VECTOR2I libStart( 1000000, 1000000 );
3480 const VECTOR2I libC1( 2000000, 4000000 );
3481 const VECTOR2I libC2( 4000000, 0 );
3482 const VECTOR2I libEnd( 5000000, 3000000 );
3487 bezier->
SetEnd( libEnd );
3503 <<
", " << board.y <<
" )" );
3506 checkBoard(
"start", libStart, bezier->
GetStart() );
3509 checkBoard(
"end", libEnd, bezier->
GetEnd() );
3524 std::vector<VECTOR2I> libVerts = {
3532 for(
const VECTOR2I& v : libVerts )
3546 BOOST_REQUIRE_EQUAL(
result.TotalVertices(), (
int) libVerts.size() );
3548 for(
int i = 0; i < (int) libVerts.size(); ++i )
3554 "vertex " << i <<
" expected ( " <<
expected.x <<
", " <<
expected.y <<
" ) actual ( "
3584 bool anyMoved =
false;
3605 "vertex " << i <<
" before ( " << b.
x <<
", " << b.
y <<
" ) restored ( " << r.
x <<
", "
3642 "vertex " << i <<
" expected ( " <<
expected.x <<
", " <<
expected.y <<
" ) actual ( "
3665 BOOST_CHECK_CLOSE(
pad->GetOrientation().AsDegrees(), 45.0, 1e-6 );
3666 BOOST_CHECK_CLOSE(
pad->GetFPRelativeOrientation().AsDegrees(), 45.0, 1e-6 );
3671 BOOST_CHECK_CLOSE(
pad->GetOrientation().AsDegrees(), 135.0, 1e-6 );
3673 BOOST_CHECK_CLOSE(
pad->GetFPRelativeOrientation().AsDegrees(), 45.0, 1e-6 );
3676 BOOST_CHECK_CLOSE(
pad->GetOrientation().AsDegrees(), 45.0, 1e-6 );
3677 BOOST_CHECK_CLOSE(
pad->GetFPRelativeOrientation().AsDegrees(), 45.0, 1e-6 );
3691 text->SetText( wxT(
"X" ) );
3696 BOOST_CHECK_CLOSE(
text->GetTextAngle().AsDegrees(), 45.0, 1e-6 );
3700 BOOST_CHECK_CLOSE(
text->GetTextAngle().AsDegrees(), 135.0, 1e-6 );
3703 BOOST_CHECK_CLOSE(
text->GetTextAngle().AsDegrees(), 45.0, 1e-6 );
3893 auto checkFlip = [&](
double aFpOrientDeg,
FLIP_DIRECTION aDir,
double aExpectedDelta )
3914 BOOST_CHECK_CLOSE(
actual.AsDegrees(),
expected.AsDegrees(), 1e-6 );
4020 std::vector<VECTOR2I> savedCorners;
4022 savedCorners.emplace_back( p );
4024 const std::filesystem::path savePath =
4025 std::filesystem::temp_directory_path() /
"rect_noncardinal_roundtrip.kicad_pcb";
4032 for(
BOARD_ITEM* item : reloaded->Drawings() )
4048 BOOST_REQUIRE_EQUAL( (
int) reloadedPoints.size(), (
int) savedCorners.size() );
4050 for(
size_t i = 0; i < savedCorners.size(); ++i )
4095 const VECTOR2I coincident( 53000000, 51000000 );
4101 pad->SetPosition( coincident );
4111 BOOST_REQUIRE_EQUAL(
pad->GetPosition().x, seg->
GetStart().
x );
4112 BOOST_REQUIRE_EQUAL(
pad->GetPosition().y, seg->
GetStart().
y );
4190 aPad =
new PAD( fp );
4228 auto board = std::make_unique<BOARD>();
4241 std::filesystem::path tmp = std::filesystem::temp_directory_path() /
"kicad_qa_xform_roundtrip.kicad_pcb";
4245 std::filesystem::remove( tmp, ec );
4248 FOOTPRINT* r = reloaded->Footprints().front();
4258 rtxt =
static_cast<PCB_TEXT*
>( it );
4264 BOOST_CHECK( r->
Pads().front()->GetPosition() == padPos );
4265 BOOST_CHECK( rseg->
GetStart() == segStart );
4267 BOOST_CHECK( r->
Points().front()->GetPosition() == ptPos );
4279 VECTOR2I( 53000000, 51000000 ),
pad, seg, txt, pt );
4299 VECTOR2I( 53000000, 51000000 ),
pad, seg, txt, pt );
4315 VECTOR2I( 53000000, 51000000 ),
pad, seg, txt, pt );
4319 std::unique_ptr<FOOTPRINT> clone(
static_cast<FOOTPRINT*
>( fp->
Clone() ) );
4321 BOOST_REQUIRE( !clone->Pads().empty() && !clone->Points().empty() );
4325 for(
BOARD_ITEM* it : clone->GraphicalItems() )
4330 ctxt =
static_cast<PCB_TEXT*
>( it );
4336 BOOST_CHECK( clone->Pads().front()->GetPosition() == ref );
4337 BOOST_CHECK( cseg->
GetStart() == ref );
4339 BOOST_CHECK( clone->Points().front()->GetPosition() == ref );
4353 VECTOR2I( 53000000, 51000000 ),
pad, seg, txt, pt );
4363 BOOST_CHECK(
pad->GetPosition() == padPos );
4364 BOOST_CHECK( seg->
GetStart() == segStart );
4374 auto board = std::make_unique<BOARD>();
4389 std::filesystem::path tmp = std::filesystem::temp_directory_path() /
"kicad_qa_scalar_roundtrip.kicad_pcb";
4393 std::filesystem::remove( tmp, ec );
4396 FOOTPRINT* r = reloaded->Footprints().front();
4405 rtxt =
static_cast<PCB_TEXT*
>( it );
4419 auto runCase = [](
double aScaleX,
double aScaleY )
4445 runCase( 2.0, 2.0 );
4446 runCase( 2.0, 1.0 );
4465 const int maxError =
pcbIUScale.mmToIU( 0.01 );
4477 BOOST_CHECK_GT( height2x, height1x * 3 / 2 );
4484 auto board = std::make_unique<BOARD>();
4506 std::filesystem::path tmp = std::filesystem::temp_directory_path() /
"kicad_qa_textbox_roundtrip.kicad_pcb";
4510 std::filesystem::remove( tmp, ec );
4513 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
4536 table->SetColCount( 2 );
4537 table->SetColWidth( 0, 16000000 );
4538 table->SetColWidth( 1, 18000000 );
4539 table->SetRowHeight( 0, 5000000 );
4540 table->SetRowHeight( 1, 5000000 );
4543 { -4000000, 6000000 }, { 12000000, 6000000 }, { -4000000, 11000000 }, { 12000000, 11000000 }
4546 { 12000000, 11000000 }, { 30000000, 11000000 }, { 12000000, 16000000 }, { 30000000, 16000000 }
4549 for(
int ii = 0; ii < 4; ++ii )
4556 cell->
SetEnd( ends[ii] );
4557 table->AddCell( cell );
4571 "table bbox size out of range ( " << bbox.
GetWidth() <<
", " << bbox.
GetHeight() <<
" )" );
4575 "table bbox center ( " <<
center.x <<
", " <<
center.y <<
" ) far from footprint ( "
4576 << aNearPos.
x <<
", " << aNearPos.
y <<
" )" );
4579 BOOST_CHECK( aTable->
GetCells()[0]->GetBoundingBox().GetCenter()
4580 != aTable->
GetCells()[3]->GetBoundingBox().GetCenter() );
4619 for(
double angle : { 0.0, 90.0, 33.0, 217.5 } )
4641 for(
double angle : { 0.0, 90.0, 180.0, 270.0, 33.0, 217.5 } )
4665 FOOTPRINT* fp = *m_board->Footprints().begin();
4679 const std::filesystem::path savePath =
4680 std::filesystem::temp_directory_path() /
"table_in_rotated_scaled_fp.kicad_pcb";
4686 FOOTPRINT* fp2 = *reloaded->Footprints().begin();
4694 table2 =
static_cast<PCB_TABLE*
>( item );
4702 const int tol = 300000;
4708 "table bbox after reload o( "
4720 KI_TEST::LoadBoard( m_settingsManager,
"embedded_table_rotated_legacy_v10", m_board );
4724 for(
FOOTPRINT* fp : m_board->Footprints() )
4726 for(
BOARD_ITEM* item : fp->GraphicalItems() )
4761 BOOST_CHECK_MESSAGE( wRatio > 1.9 && wRatio < 2.1,
"table width ratio " << wRatio <<
" expected ~2.0" );
4762 BOOST_CHECK_MESSAGE( hRatio > 1.4 && hRatio < 1.6,
"table height ratio " << hRatio <<
" expected ~1.5" );
4780 std::vector<VECTOR2I> poly = {
4781 { -1000000, -1000000 }, { 1000000, -1000000 }, { 1000000, 1000000 }, { -1000000, 1000000 }
4786 BOX2I before =
pad->GetBoundingBox();
4790 BOX2I after =
pad->GetBoundingBox();
4795 BOOST_CHECK_MESSAGE( wRatio > 1.9 && wRatio < 2.1,
"custom pad width ratio " << wRatio <<
" expected ~2.0" );
4796 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)
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)
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