20#include <boost/test/unit_test.hpp>
50#include <wx/filename.h>
51#include <wx/tokenzr.h>
59 gerber.SetOptions(
VECTOR2I( 0, 0 ) );
60 gerber.SetFormat( 6 );
62 return gerber.GetCreatedFiles();
66size_t CountContaining(
const std::vector<wxString>& aFiles,
const wxString& aPart )
68 return std::count_if( aFiles.begin(), aFiles.end(), [&](
const wxString& aName )
70 return aName.Contains( aPart );
78 std::unique_ptr<BOARD> board =
84 std::vector<wxString> created = ExportGerberDrill( *board, dir );
85 auto front = std::find_if( created.begin(), created.end(), [](
const wxString& aName )
87 return aName.EndsWith( wxT(
"-tenting-front.gbr" ) );
90 std::ifstream stream( std::filesystem::path( front->ToStdString() ), std::ios::binary );
91 std::string frontTenting( std::istreambuf_iterator<char>{ stream }, std::istreambuf_iterator<char>{} );
96 BOOST_CHECK( frontTenting.find(
"TF,FileFunction,Other,Tenting-Front" ) != std::string::npos );
108 if( !span.m_IsBackdrill )
116 BOOST_CHECK( !op.m_TopTented );
117 BOOST_CHECK( !op.m_BottomTented );
118 BOOST_CHECK( !op.m_TopCovered );
119 BOOST_CHECK( !op.m_BottomCovered );
120 BOOST_CHECK( !op.m_TopPlugged );
121 BOOST_CHECK( !op.m_BottomPlugged );
126 std::vector<wxString> created = ExportGerberDrill( *board, dir );
135 wxFileName boardFile( tempDir.
PathStr(), wxT(
"backdrill_board.kicad_pcb" ) );
148 via->SetSecondaryDrillStartLayer(
F_Cu );
149 via->SetSecondaryDrillEndLayer(
In3_Cu );
152 via->SetFrontPostMachiningDepth(
pcbIUScale.mmToIU( 0.15 ) );
153 via->SetFrontPostMachiningAngle( 900 );
161 wxFileName excellonFile( tempDir.
PathStr(), wxT(
"backdrill_board_Backdrills_Drill_1_4.drl" ) );
164 wxFFile excellonStream( excellonFile.GetFullPath(), wxT(
"rb" ) );
165 wxString excellonContents;
166 BOOST_REQUIRE( excellonStream.ReadAll( &excellonContents ) );
167 BOOST_CHECK( excellonContents.Contains( wxT(
"TF.FileFunction,NonPlated,1,4,Blind" ) ) );
168 BOOST_CHECK( excellonContents.Contains( wxT(
"; Backdrill" ) ) );
169 BOOST_CHECK( excellonContents.Contains( wxT(
"post-machining" ) ) );
171 wxFileName layerPairFile( tempDir.
PathStr(), wxT(
"backdrill_board-front-in3-backdrill.drl" ) );
174 wxFFile layerPairStream( layerPairFile.GetFullPath(), wxT(
"rb" ) );
175 wxString layerPairContents;
176 BOOST_REQUIRE( layerPairStream.ReadAll( &layerPairContents ) );
177 BOOST_CHECK( layerPairContents.Contains( wxT(
"; backdrill" ) ) );
179 wxFileName pthFile( tempDir.
PathStr(), wxT(
"backdrill_board-PTH.drl" ) );
182 wxFFile pthStream( pthFile.GetFullPath(), wxT(
"rb" ) );
183 wxString pthContents;
185 BOOST_CHECK( pthContents.Contains( wxT(
"; Post-machining front countersink dia 0.600mm depth 0.150mm angle 90deg" ) ) );
192 wxFileName gerberFile( tempDir.
PathStr(), wxT(
"backdrill_board_Backdrills_Drill_1_4-drl.gbr" ) );
195 wxFFile gerberStream( gerberFile.GetFullPath(), wxT(
"rb" ) );
196 wxString gerberContents;
198 BOOST_CHECK( gerberContents.Contains( wxT(
"%TA.AperFunction,BackDrill*%" ) ) );
199 BOOST_CHECK( gerberContents.Contains( wxT(
"%TF.FileFunction,NonPlated,1,4,Blind,Drill*%" ) ) );
201 wxFileName gerberLayerPairFile( tempDir.
PathStr(), wxT(
"backdrill_board-front-in3-backdrill-drl.gbr" ) );
204 wxFFile gerberLayerPairStream( gerberLayerPairFile.GetFullPath(), wxT(
"rb" ) );
205 wxString gerberLayerPairContents;
206 BOOST_REQUIRE( gerberLayerPairStream.ReadAll( &gerberLayerPairContents ) );
207 BOOST_CHECK( gerberLayerPairContents.Contains( wxT(
"%TF.FileFunction,NonPlated,1,4,Blind,Drill*%" ) ) );
208 BOOST_CHECK( gerberLayerPairContents.Contains( wxT(
"%TA.AperFunction,BackDrill*%" ) ) );
210 wxFileName odbRoot( tempDir.
PathStr(), wxEmptyString );
211 odbRoot.AppendDir( wxT(
"odb_out" ) );
212 BOOST_REQUIRE( odbRoot.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) );
215 std::map<std::string, UTF8> props;
216 props[
"units"] =
"mm";
217 props[
"sigfig"] =
"4";
218 BOOST_REQUIRE_NO_THROW( odbExporter.
SaveBoard( odbRoot.GetFullPath(), board, &props ) );
220 wxFileName drill1Dir( odbRoot.GetFullPath(), wxEmptyString );
221 drill1Dir.AppendDir( wxT(
"steps" ) );
222 drill1Dir.AppendDir( wxT(
"pcb" ) );
223 drill1Dir.AppendDir( wxT(
"layers" ) );
224 drill1Dir.AppendDir( wxT(
"drill1" ) );
227 wxFileName toolsFile( drill1Dir.GetFullPath(), wxT(
"tools" ) );
230 wxFFile toolsStream( toolsFile.GetFullPath(), wxT(
"rb" ) );
231 wxString toolsContents;
233 BOOST_CHECK( toolsContents.Contains( wxT(
"TYPE=NON_PLATED" ) ) );
234 BOOST_CHECK( toolsContents.Contains( wxT(
"TYPE2=BLIND" ) ) );
236 wxFileName matrixFile( odbRoot.GetFullPath(), wxEmptyString );
237 matrixFile.AppendDir( wxT(
"matrix" ) );
238 matrixFile.SetFullName( wxT(
"matrix" ) );
241 wxFFile matrixStream( matrixFile.GetFullPath(), wxT(
"rb" ) );
242 wxString matrixContents;
244 BOOST_CHECK( matrixContents.Contains( wxT(
"ADD_TYPE=BACKDRILL" ) ) );
246 matrixStream.Close();
248 gerberStream.Close();
249 gerberLayerPairStream.Close();
250 excellonStream.Close();
251 layerPairStream.Close();
262 wxFileName boardFile( tempDir.
PathStr(), wxT(
"backdrill_pair_board.kicad_pcb" ) );
288 board.
Add( bottomVia );
295 wxFileName topBackdrillFile( tempDir.
PathStr(), wxT(
"backdrill_pair_board_Backdrills_Drill_1_2.drl" ) );
296 BOOST_CHECK_MESSAGE( topBackdrillFile.FileExists(),
297 "Front-side backdrill drill file should be produced" );
300 wxFileName bottomBackdrillFile( tempDir.
PathStr(), wxT(
"backdrill_pair_board_Backdrills_Drill_6_4.drl" ) );
301 BOOST_CHECK_MESSAGE( bottomBackdrillFile.FileExists(),
302 "Back-side (tertiary) backdrill drill file should be produced" );
304 if( bottomBackdrillFile.FileExists() )
306 wxFFile stream( bottomBackdrillFile.GetFullPath(), wxT(
"rb" ) );
309 BOOST_CHECK( contents.Contains( wxT(
"; Backdrill" ) ) );
321 wxFileName boardFile( tempDir.
PathStr(), wxT(
"dual_backdrill_board.kicad_pcb" ) );
334 via->SetSecondaryDrillStartLayer(
F_Cu );
335 via->SetSecondaryDrillEndLayer(
In1_Cu );
337 via->SetTertiaryDrillStartLayer(
B_Cu );
346 wxFileName topBackdrillFile( tempDir.
PathStr(), wxT(
"dual_backdrill_board_Backdrills_Drill_1_2.drl" ) );
347 BOOST_CHECK( topBackdrillFile.FileExists() );
349 wxFileName bottomBackdrillFile( tempDir.
PathStr(), wxT(
"dual_backdrill_board_Backdrills_Drill_6_4.drl" ) );
350 BOOST_CHECK( bottomBackdrillFile.FileExists() );
359 wxFileName boardFile( tempDir.
PathStr(), wxT(
"precision_board.kicad_pcb" ) );
379 wxFileName gerberFile5( tempDir.
PathStr(), wxT(
"precision_board-PTH-drl.gbr" ) );
382 wxFFile gerberStream5( gerberFile5.GetFullPath(), wxT(
"rb" ) );
383 wxString gerberContents5;
385 BOOST_CHECK_MESSAGE( gerberContents5.Contains( wxT(
"Fmt 4.5" ) ),
386 "Expected 'Fmt 4.5' in gerber header with precision=5" );
387 BOOST_CHECK( !gerberContents5.Contains( wxT(
"Fmt 4.6" ) ) );
388 gerberStream5.Close();
396 wxFFile gerberStream6( gerberFile5.GetFullPath(), wxT(
"rb" ) );
397 wxString gerberContents6;
399 BOOST_CHECK_MESSAGE( gerberContents6.Contains( wxT(
"Fmt 4.6" ) ),
400 "Expected 'Fmt 4.6' in gerber header with precision=6" );
401 BOOST_CHECK( !gerberContents6.Contains( wxT(
"Fmt 4.5" ) ) );
402 gerberStream6.Close();
412 wxFileName boardFile( tempDir.
PathStr(), wxT(
"layer_order_board.kicad_pcb" ) );
434 wxFileName correctFile( tempDir.
PathStr(), wxT(
"layer_order_board-in2-back.drl" ) );
435 wxFileName reversedFile( tempDir.
PathStr(), wxT(
"layer_order_board-back-in2.drl" ) );
436 BOOST_CHECK_MESSAGE( correctFile.FileExists(),
"Expected drill file 'in2-back' not found" );
437 BOOST_CHECK_MESSAGE( !reversedFile.FileExists(),
"Incorrectly named drill file 'back-in2' found" );
446 wxFileName boardFile( tempDir.
PathStr(), wxT(
"test_board.kicad_pcb" ) );
452 wxFileName reportFile( tempDir.
PathStr(), wxT(
"test_board-drl.rpt" ) );
457 BOOST_CHECK( reportFile.FileExists() );
464 BOOST_CHECK( !excellon2.
GenDrillReportFile( wxT(
"/nonexistent/path/report.rpt" ) ) );
477 wxFileName boardFile( tempDir.
PathStr(), wxT(
"test_board_with_drills.kicad_pcb" ) );
491 wxFileName reportFile( tempDir.
PathStr(), wxT(
"test_board_with_drills-drl.rpt" ) );
497 BOOST_CHECK( reportFile.FileExists() );
499 wxFFile reportStream( reportFile.GetFullPath(), wxT(
"rb" ) );
500 wxString reportContents;
502 BOOST_CHECK( reportContents.Contains( wxT(
"T1" ) ) );
503 BOOST_CHECK( reportContents.Contains( wxT(
"0.300mm" ) ) );
504 reportStream.Close();
517 wxFileName boardFile( tempDir.
PathStr(), wxT(
"silk_rect_board.kicad_pcb" ) );
532 wxFileName odbRoot( tempDir.
PathStr(), wxEmptyString );
533 odbRoot.AppendDir( wxT(
"odb_out" ) );
534 BOOST_REQUIRE( odbRoot.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) );
537 std::map<std::string, UTF8> props;
538 props[
"units"] =
"mm";
539 props[
"sigfig"] =
"4";
540 BOOST_REQUIRE_NO_THROW( odbExporter.
SaveBoard( odbRoot.GetFullPath(), board, &props ) );
542 wxFileName silkFeatures( odbRoot.GetFullPath(), wxT(
"features" ) );
543 silkFeatures.AppendDir( wxT(
"steps" ) );
544 silkFeatures.AppendDir( wxT(
"pcb" ) );
545 silkFeatures.AppendDir( wxT(
"layers" ) );
546 silkFeatures.AppendDir( wxT(
"f.silkscreen" ) );
549 wxFFile silkStream( silkFeatures.GetFullPath(), wxT(
"rb" ) );
550 wxString silkContents;
556 wxStringTokenizer lines( silkContents, wxT(
"\n" ) );
558 while( lines.HasMoreTokens() )
560 if( lines.GetNextToken().StartsWith( wxT(
"L " ) ) )
567 BOOST_CHECK( !silkContents.Contains( wxT(
"donut_rc" ) ) );
591 wxFileName odbRoot( tempDir.
PathStr(), wxEmptyString );
592 odbRoot.AppendDir( wxT(
"odb_out" ) );
593 BOOST_REQUIRE( odbRoot.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) );
596 std::map<std::string, UTF8> props;
597 props[
"units"] =
"mm";
598 props[
"sigfig"] =
"4";
599 BOOST_REQUIRE_NO_THROW( odbExporter.
SaveBoard( odbRoot.GetFullPath(), board, &props ) );
601 wxFileName copperFeatures( odbRoot.GetFullPath(), wxT(
"features" ) );
602 copperFeatures.AppendDir( wxT(
"steps" ) );
603 copperFeatures.AppendDir( wxT(
"pcb" ) );
604 copperFeatures.AppendDir( wxT(
"layers" ) );
605 copperFeatures.AppendDir( wxT(
"f.cu" ) );
608 wxFFile copperStream( copperFeatures.GetFullPath(), wxT(
"rb" ) );
609 wxString copperContents;
611 copperStream.Close();
615 wxStringTokenizer lines( copperContents, wxT(
"\n" ) );
617 while( lines.HasMoreTokens() )
619 wxString line = lines.GetNextToken();
621 if( line.StartsWith( wxT(
"L " ) ) )
623 else if( line.StartsWith( wxT(
"A " ) ) )
636 wxFileName odbRoot( wxString::FromUTF8( aParentDir.string() ), wxEmptyString );
637 odbRoot.AppendDir( wxT(
"odb_out" ) );
638 BOOST_REQUIRE( odbRoot.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) );
641 std::map<std::string, UTF8> props;
642 props[
"units"] =
"mm";
643 props[
"sigfig"] =
"4";
644 BOOST_REQUIRE_NO_THROW( odbExporter.
SaveBoard( odbRoot.GetFullPath(), *aBoard, &props ) );
652 wxFileName features( aOdbRoot.GetFullPath(), wxT(
"features" ) );
653 features.AppendDir( wxT(
"steps" ) );
654 features.AppendDir( wxT(
"pcb" ) );
655 features.AppendDir( wxT(
"layers" ) );
656 features.AppendDir( aLayerDir );
659 wxFFile stream( features.GetFullPath(), wxT(
"rb" ) );
675 std::unique_ptr<BOARD> board;
686 BOOST_CHECK_MESSAGE( contents.Contains( wxT(
"donut_r2100.0x1900.0" ) ),
687 "Wrong copper annulus, features file holds:\n" + contents );
698 std::unique_ptr<BOARD> board;
700 KI_TEST::LoadBoard( settingsManager, wxT(
"issue25089/odb_circle_edge_cases" ), board );
708 BOOST_CHECK_MESSAGE( frontContents.Contains( wxT(
"r400.0" ) )
709 && !frontContents.Contains( wxT(
"donut" ) ),
710 "Circle with a hole-closing stroke should export as a solid pad, "
711 "features file holds:\n"
716 wxStringTokenizer backLines( backContents, wxT(
"\n" ) );
718 while( backLines.HasMoreTokens() )
720 wxString line = backLines.GetNextToken();
722 if( line.StartsWith( wxT(
"$" ) ) )
724 BOOST_CHECK_MESSAGE( !line.Contains( wxT(
"-" ) ),
725 "Oversized circle overflowed to a negative symbol dimension: "
738 pad->SetAttribute( aAttribute );
741 pad->SetPosition( aPos );
761 wxFileName boardFile( tempDir.
PathStr(), wxT(
"plated_slot_board.kicad_pcb" ) );
777 wxFileName odbRoot( tempDir.
PathStr(), wxEmptyString );
778 odbRoot.AppendDir( wxT(
"odb_out" ) );
779 BOOST_REQUIRE( odbRoot.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) );
782 std::map<std::string, UTF8> props;
783 props[
"units"] =
"mm";
784 props[
"sigfig"] =
"4";
785 BOOST_REQUIRE_NO_THROW( odbExporter.
SaveBoard( odbRoot.GetFullPath(), board, &props ) );
787 auto layerDir = [&](
const wxString& aLayer )
789 wxFileName dir( odbRoot.GetFullPath(), wxEmptyString );
790 dir.AppendDir( wxT(
"steps" ) );
791 dir.AppendDir( wxT(
"pcb" ) );
792 dir.AppendDir( wxT(
"layers" ) );
793 dir.AppendDir( aLayer );
798 auto readFile = [](
const wxFileName& aFile )
800 wxFFile stream( aFile.GetFullPath(), wxT(
"rb" ) );
809 auto countLinesStartingWith = [](
const wxString& aContents,
const wxString& aPrefix )
812 wxStringTokenizer lines( aContents, wxT(
"\n" ) );
814 while( lines.HasMoreTokens() )
816 wxString line = lines.GetNextToken();
819 if( line.StartsWith( aPrefix ) )
826 auto containsOvalSymbol = [](
const wxString& aContents )
828 wxStringTokenizer lines( aContents, wxT(
"\n" ) );
830 while( lines.HasMoreTokens() )
832 wxString line = lines.GetNextToken();
835 if( line.StartsWith( wxT(
"$" ) ) && line.Contains( wxT(
"oval" ) ) )
845 wxFileName platedDir = layerDir( wxT(
"drill_plated_f.cu-b.cu" ) );
846 BOOST_REQUIRE_MESSAGE( platedDir.DirExists(),
"Plated drill layer should exist" );
848 wxFileName platedFeatures( platedDir.GetFullPath(), wxT(
"features" ) );
850 wxString platedContents =
readFile( platedFeatures );
853 BOOST_CHECK_MESSAGE( !containsOvalSymbol( platedContents ),
854 "Plated slot should be a line, not an oval pad" );
856 wxFileName platedTools( platedDir.GetFullPath(), wxT(
"tools" ) );
858 wxString platedToolsContents =
readFile( platedTools );
859 BOOST_CHECK_EQUAL( countLinesStartingWith( platedToolsContents, wxT(
"TYPE=PLATED" ) ), 1 );
860 BOOST_CHECK_EQUAL( countLinesStartingWith( platedToolsContents, wxT(
"TYPE=NON_PLATED" ) ), 0 );
864 wxFileName nonPlatedDir = layerDir( wxT(
"drill_non-plated_f.cu-b.cu" ) );
865 BOOST_REQUIRE_MESSAGE( nonPlatedDir.DirExists(),
"Non-plated drill layer should exist" );
867 wxFileName nonPlatedFeatures( nonPlatedDir.GetFullPath(), wxT(
"features" ) );
869 wxString nonPlatedContents =
readFile( nonPlatedFeatures );
871 BOOST_CHECK_EQUAL( countLinesStartingWith( nonPlatedContents, wxT(
"L " ) ), 1 );
872 BOOST_CHECK_MESSAGE( !containsOvalSymbol( nonPlatedContents ),
873 "Non-plated slot should be a line, not an oval pad" );
875 wxFileName nonPlatedTools( nonPlatedDir.GetFullPath(), wxT(
"tools" ) );
877 wxString nonPlatedToolsContents =
readFile( nonPlatedTools );
878 BOOST_CHECK_EQUAL( countLinesStartingWith( nonPlatedToolsContents, wxT(
"TYPE=NON_PLATED" ) ),
880 BOOST_CHECK_EQUAL( countLinesStartingWith( nonPlatedToolsContents, wxT(
"TYPE=PLATED" ) ), 0 );
891 std::unique_ptr<BOARD> board;
897 wxFileName boardFile( tempDir.
PathStr(), wxT(
"backdrill.kicad_pcb" ) );
900 board->SetFileName( boardFile.GetFullPath() );
902 wxFileName reportFile( tempDir.
PathStr(), wxT(
"backdrill-drl.rpt" ) );
909 wxFFile reportStream( reportFile.GetFullPath(), wxT(
"rb" ) );
910 wxString reportContents;
912 reportStream.Close();
914 struct BACKDRILL_SECTION
920 std::map<wxString, BACKDRILL_SECTION> sections;
921 wxString currentFile;
922 wxStringTokenizer lines( reportContents, wxT(
"\n" ) );
924 while( lines.HasMoreTokens() )
926 wxString line = lines.GetNextToken();
927 line.Trim(
true ).Trim(
false );
929 if( line.StartsWith( wxT(
"Drill file '" ) ) )
930 currentFile = line.AfterFirst(
'\'' ).BeforeFirst(
'\'' );
932 if( line.StartsWith( wxT(
"T" ) ) && line.Contains( wxT(
"0.330mm" ) ) )
933 sections[currentFile].toolLines++;
937 if( line.StartsWith( wxT(
"Total backdrilled holes count " ), &count ) )
941 sections[currentFile].holes = value;
947 const std::map<wxString, long>
expected = {
948 { wxT(
"backdrill_Backdrills_Drill_1_4.drl" ), 2 },
949 { wxT(
"backdrill_Backdrills_Drill_10_4.drl" ), 1 },
950 { wxT(
"backdrill_Backdrills_Drill_10_7.drl" ), 1 }
956 for(
const auto& [file, holes] :
expected )
958 auto section = sections.find( file );
960 if( section == sections.end() )
962 BOOST_ERROR(
"No backdrill section for " << file );
973 BOOST_CHECK( reportContents.Contains( wxT(
"Total plated holes count 4" ) ) );
974 BOOST_CHECK( reportContents.Contains( wxT(
"Total unplated holes count 0" ) ) );
constexpr EDA_IU_SCALE pcbIUScale
General utilities for PCB file IO for QA programs.
virtual void SetNet(NETINFO_ITEM *aNetInfo)
Set a NET_INFO object for the item.
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
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.
void SetFileName(const wxString &aFileName)
void SetCopperLayerCount(int aCount)
virtual void SetFilled(bool aFlag)
Create Excellon drill, drill map, and drill report files.
void SetFormat(bool aMetric, ZEROS_FMT aZerosFmt=DECIMAL_FORMAT, int aLeftDigits=0, int aRightDigits=0)
Initialize internal parameters to match the given format.
bool CreateDrillandMapFilesSet(const wxString &aPlotDirectory, bool aGenDrill, bool aGenMap, REPORTER *aReporter=nullptr)
Create the full set of Excellon drill file for the board.
void SetOptions(bool aMirror, bool aMinimalHeader, const VECTOR2I &aOffset, bool aMerge_PTH_NPTH)
Initialize internal parameters to match drill options.
bool GenDrillReportFile(const wxString &aFullFileName, REPORTER *aReporter=nullptr)
Create a plain text report file giving a list of drill values and drill count for through holes,...
Used to create Gerber drill files.
bool CreateDrillandMapFilesSet(const wxString &aPlotDirectory, bool aGenDrill, bool aGenMap, bool aGenTenting, REPORTER *aReporter=nullptr)
Create the full set of Excellon drill file for the board filenames are computed from the board name,...
void SetOptions(const VECTOR2I &aOffset)
Initialize internal parameters to match drill options.
void SetFormat(int aRightDigits=6)
Initialize internal parameters to match the given format.
wxString PathStr() const
Get the path to the temporary directory as a wxString.
const std::filesystem::path & Path() const
Get the path to the temporary directory as a std::filesystem::path.
Handle the data for a net.
@ 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
static LSET PTHMask()
layer set for a through hole pad
static LSET UnplatedHoleMask()
layer set for a mechanical unplated through hole pad
void SetMid(const VECTOR2I &aMid)
void SaveBoard(const wxString &aFileName, BOARD &aBoard, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Write aBoard to a storage file in a format that this PCB_IO implementation knows about or it can be u...
void SetWidth(int aWidth) override
void SetEnd(const VECTOR2I &aEnd) override
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
void SetStart(const VECTOR2I &aStart) override
void SetEnd(const VECTOR2I &aEnd)
void SetStart(const VECTOR2I &aStart)
virtual void SetWidth(int aWidth)
void SetSecondaryDrillStartLayer(PCB_LAYER_ID aLayer)
void SetTertiaryDrillEndLayer(PCB_LAYER_ID aLayer)
void SetDrill(int aDrill)
void SetPadstackMode(PADSTACK::MODE aMode)
void SetSecondaryDrillEndLayer(PCB_LAYER_ID aLayer)
void SetPosition(const VECTOR2I &aPoint) override
void SetLayerPair(PCB_LAYER_ID aTopLayer, PCB_LAYER_ID aBottomLayer)
For a via m_layer contains the top layer, the other layer is in m_bottomLayer/.
void SetTertiaryDrillStartLayer(PCB_LAYER_ID aLayer)
void SetTertiaryDrillSize(const VECTOR2I &aSize)
void SetSecondaryDrillSize(const VECTOR2I &aSize)
void SetWidth(int aWidth) override
std::vector< DRILL_SPAN > EnumerateDrillSpans(const BOARD &aBoard, bool aPadBackdrills)
Every drill span present on the board, through-holes first.
std::vector< DRILL_OPERATION > EnumerateDrillOperations(const BOARD &aBoard, const DRILL_QUERY &aQuery)
The one place that decides what the board's holes are.
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
Classes used in drill files, map files and report files generation.
Classes used in drill files, map files and report files generation.
std::unique_ptr< BOARD > RequireBoardFromPcbnewQAData(const std::filesystem::path &aFilename)
Require a board from the path relative to the pcbnew QA data directory.
void LoadBoard(SETTINGS_MANAGER &aSettingsManager, const wxString &aRelPath, std::unique_ptr< BOARD > &aBoard)
PAD_ATTRIB
The set of pad shapes, used with PAD::{Set,Get}Attribute().
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
@ PTH
Plated through hole pad.
static bool readFile(const wxString &aFileName, wxString &aOut, size_t aLimit=0)
Read a file into aOut.
One machining action, which is also one NC hit and one tool assignment.
Selects which operations EnumerateDrillOperations() returns.
static wxString ReadOdbLayerFeatures(const wxFileName &aOdbRoot, const wxString &aLayerDir)
static wxFileName ExportOdbTree(BOARD *aBoard, const std::filesystem::path &aParentDir)
BOOST_AUTO_TEST_CASE(GerberDrillBoardDefaultsCreateProtectionFiles)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
VECTOR3I expected(15, 30, 45)
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I