20#include <boost/test/unit_test.hpp>
42#include <wx/filename.h>
43#include <wx/tokenzr.h>
49wxFileName MakeTempDir()
51 wxFileName tempDir( wxFileName::GetTempDir(), wxEmptyString );
52 tempDir.AppendDir( wxString::Format(
"kicad-backdrill-%llu",
static_cast<unsigned long long>( wxGetUTCTime() ) ) );
53 BOOST_REQUIRE( tempDir.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) );
62 wxFileName tempDir = MakeTempDir();
63 wxFileName boardFile( tempDir.GetFullPath(), wxT(
"backdrill_board.kicad_pcb" ) );
76 via->SetSecondaryDrillStartLayer(
F_Cu );
81 via->SetFrontPostMachiningAngle( 900 );
89 wxFileName excellonFile( tempDir.GetFullPath(), wxT(
"backdrill_board_Backdrills_Drill_1_4.drl" ) );
92 wxFFile excellonStream( excellonFile.GetFullPath(), wxT(
"rb" ) );
93 wxString excellonContents;
95 BOOST_CHECK( excellonContents.Contains( wxT(
"TF.FileFunction,NonPlated,1,4,Blind" ) ) );
96 BOOST_CHECK( excellonContents.Contains( wxT(
"; Backdrill" ) ) );
97 BOOST_CHECK( excellonContents.Contains( wxT(
"post-machining" ) ) );
99 wxFileName layerPairFile( tempDir.GetFullPath(), wxT(
"backdrill_board-front-in3-backdrill.drl" ) );
102 wxFFile layerPairStream( layerPairFile.GetFullPath(), wxT(
"rb" ) );
103 wxString layerPairContents;
104 BOOST_REQUIRE( layerPairStream.ReadAll( &layerPairContents ) );
105 BOOST_CHECK( layerPairContents.Contains( wxT(
"; backdrill" ) ) );
107 wxFileName pthFile( tempDir.GetFullPath(), wxT(
"backdrill_board-PTH.drl" ) );
110 wxFFile pthStream( pthFile.GetFullPath(), wxT(
"rb" ) );
111 wxString pthContents;
113 BOOST_CHECK( pthContents.Contains( wxT(
"; Post-machining front countersink dia 0.600mm depth 0.150mm angle 90deg" ) ) );
120 wxFileName gerberFile( tempDir.GetFullPath(), wxT(
"backdrill_board_Backdrills_Drill_1_4-drl.gbr" ) );
123 wxFFile gerberStream( gerberFile.GetFullPath(), wxT(
"rb" ) );
124 wxString gerberContents;
126 BOOST_CHECK( gerberContents.Contains( wxT(
"%TA.AperFunction,BackDrill*%" ) ) );
127 BOOST_CHECK( gerberContents.Contains( wxT(
"%TF.FileFunction,NonPlated,1,4,Blind,Drill*%" ) ) );
129 wxFileName gerberLayerPairFile( tempDir.GetFullPath(),
130 wxT(
"backdrill_board-front-in3-backdrill-drl.gbr" ) );
133 wxFFile gerberLayerPairStream( gerberLayerPairFile.GetFullPath(), wxT(
"rb" ) );
134 wxString gerberLayerPairContents;
135 BOOST_REQUIRE( gerberLayerPairStream.ReadAll( &gerberLayerPairContents ) );
136 BOOST_CHECK( gerberLayerPairContents.Contains( wxT(
"%TF.FileFunction,NonPlated,1,4,Blind,Drill*%" ) ) );
137 BOOST_CHECK( gerberLayerPairContents.Contains( wxT(
"%TA.AperFunction,BackDrill*%" ) ) );
139 wxFileName odbRoot( tempDir.GetFullPath(), wxEmptyString );
140 odbRoot.AppendDir( wxT(
"odb_out" ) );
141 BOOST_REQUIRE( odbRoot.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) );
144 std::map<std::string, UTF8> props;
145 props[
"units"] =
"mm";
146 props[
"sigfig"] =
"4";
147 BOOST_REQUIRE_NO_THROW( odbExporter.
SaveBoard( odbRoot.GetFullPath(), board, &props ) );
149 wxFileName drill1Dir( odbRoot.GetFullPath(), wxEmptyString );
150 drill1Dir.AppendDir( wxT(
"steps" ) );
151 drill1Dir.AppendDir( wxT(
"pcb" ) );
152 drill1Dir.AppendDir( wxT(
"layers" ) );
153 drill1Dir.AppendDir( wxT(
"drill1" ) );
156 wxFileName toolsFile( drill1Dir.GetFullPath(), wxT(
"tools" ) );
159 wxFFile toolsStream( toolsFile.GetFullPath(), wxT(
"rb" ) );
160 wxString toolsContents;
162 BOOST_CHECK( toolsContents.Contains( wxT(
"TYPE=NON_PLATED" ) ) );
163 BOOST_CHECK( toolsContents.Contains( wxT(
"TYPE2=BLIND" ) ) );
165 wxFileName matrixFile( odbRoot.GetFullPath(), wxEmptyString );
166 matrixFile.AppendDir( wxT(
"matrix" ) );
167 matrixFile.SetFullName( wxT(
"matrix" ) );
170 wxFFile matrixStream( matrixFile.GetFullPath(), wxT(
"rb" ) );
171 wxString matrixContents;
173 BOOST_CHECK( matrixContents.Contains( wxT(
"ADD_TYPE=BACKDRILL" ) ) );
175 matrixStream.Close();
177 gerberStream.Close();
178 gerberLayerPairStream.Close();
179 excellonStream.Close();
180 layerPairStream.Close();
183 wxFileName::Rmdir( odbRoot.GetFullPath(), wxPATH_RMDIR_RECURSIVE );
184 wxFileName::Rmdir( tempDir.GetFullPath(), wxPATH_RMDIR_RECURSIVE );
193 wxFileName tempDir = MakeTempDir();
194 wxFileName boardFile( tempDir.GetFullPath(), wxT(
"backdrill_pair_board.kicad_pcb" ) );
220 board.
Add( bottomVia );
227 wxFileName topBackdrillFile( tempDir.GetFullPath(),
228 wxT(
"backdrill_pair_board_Backdrills_Drill_1_2.drl" ) );
229 BOOST_CHECK_MESSAGE( topBackdrillFile.FileExists(),
230 "Front-side backdrill drill file should be produced" );
233 wxFileName bottomBackdrillFile( tempDir.GetFullPath(),
234 wxT(
"backdrill_pair_board_Backdrills_Drill_6_4.drl" ) );
235 BOOST_CHECK_MESSAGE( bottomBackdrillFile.FileExists(),
236 "Back-side (tertiary) backdrill drill file should be produced" );
238 if( bottomBackdrillFile.FileExists() )
240 wxFFile stream( bottomBackdrillFile.GetFullPath(), wxT(
"rb" ) );
243 BOOST_CHECK( contents.Contains( wxT(
"; Backdrill" ) ) );
247 wxFileName::Rmdir( tempDir.GetFullPath(), wxPATH_RMDIR_RECURSIVE );
256 wxFileName tempDir = MakeTempDir();
257 wxFileName boardFile( tempDir.GetFullPath(), wxT(
"dual_backdrill_board.kicad_pcb" ) );
270 via->SetSecondaryDrillStartLayer(
F_Cu );
271 via->SetSecondaryDrillEndLayer(
In1_Cu );
273 via->SetTertiaryDrillStartLayer(
B_Cu );
283 wxFileName topBackdrillFile( tempDir.GetFullPath(),
284 wxT(
"dual_backdrill_board_Backdrills_Drill_1_2.drl" ) );
285 BOOST_CHECK( topBackdrillFile.FileExists() );
287 wxFileName bottomBackdrillFile( tempDir.GetFullPath(),
288 wxT(
"dual_backdrill_board_Backdrills_Drill_6_4.drl" ) );
289 BOOST_CHECK( bottomBackdrillFile.FileExists() );
291 wxFileName::Rmdir( tempDir.GetFullPath(), wxPATH_RMDIR_RECURSIVE );
299 wxFileName tempDir = MakeTempDir();
300 wxFileName boardFile( tempDir.GetFullPath(), wxT(
"precision_board.kicad_pcb" ) );
320 wxFileName gerberFile5( tempDir.GetFullPath(), wxT(
"precision_board-PTH-drl.gbr" ) );
323 wxFFile gerberStream5( gerberFile5.GetFullPath(), wxT(
"rb" ) );
324 wxString gerberContents5;
326 BOOST_CHECK_MESSAGE( gerberContents5.Contains( wxT(
"Fmt 4.5" ) ),
327 "Expected 'Fmt 4.5' in gerber header with precision=5" );
328 BOOST_CHECK( !gerberContents5.Contains( wxT(
"Fmt 4.6" ) ) );
329 gerberStream5.Close();
337 wxFFile gerberStream6( gerberFile5.GetFullPath(), wxT(
"rb" ) );
338 wxString gerberContents6;
340 BOOST_CHECK_MESSAGE( gerberContents6.Contains( wxT(
"Fmt 4.6" ) ),
341 "Expected 'Fmt 4.6' in gerber header with precision=6" );
342 BOOST_CHECK( !gerberContents6.Contains( wxT(
"Fmt 4.5" ) ) );
343 gerberStream6.Close();
345 wxFileName::Rmdir( tempDir.GetFullPath(), wxPATH_RMDIR_RECURSIVE );
354 wxFileName tempDir = MakeTempDir();
355 wxFileName boardFile( tempDir.GetFullPath(), wxT(
"layer_order_board.kicad_pcb" ) );
377 wxFileName correctFile( tempDir.GetFullPath(), wxT(
"layer_order_board-in2-back.drl" ) );
378 wxFileName reversedFile( tempDir.GetFullPath(), wxT(
"layer_order_board-back-in2.drl" ) );
379 BOOST_CHECK_MESSAGE( correctFile.FileExists(),
"Expected drill file 'in2-back' not found" );
380 BOOST_CHECK_MESSAGE( !reversedFile.FileExists(),
"Incorrectly named drill file 'back-in2' found" );
382 wxFileName::Rmdir( tempDir.GetFullPath(), wxPATH_RMDIR_RECURSIVE );
390 wxFileName tempDir = MakeTempDir();
391 wxFileName boardFile( tempDir.GetFullPath(), wxT(
"test_board.kicad_pcb" ) );
397 wxFileName reportFile( tempDir.GetFullPath(), wxT(
"test_board-drl.rpt" ) );
402 BOOST_CHECK( reportFile.FileExists() );
409 BOOST_CHECK( !excellon2.
GenDrillReportFile( wxT(
"/nonexistent/path/report.rpt" ) ) );
414 wxFileName::Rmdir( tempDir.GetFullPath(), wxPATH_RMDIR_RECURSIVE );
423 wxFileName tempDir = MakeTempDir();
424 wxFileName boardFile( tempDir.GetFullPath(), wxT(
"test_board_with_drills.kicad_pcb" ) );
438 wxFileName reportFile( tempDir.GetFullPath(), wxT(
"test_board_with_drills-drl.rpt" ) );
444 BOOST_CHECK( reportFile.FileExists() );
446 wxFFile reportStream( reportFile.GetFullPath(), wxT(
"rb" ) );
447 wxString reportContents;
449 BOOST_CHECK( reportContents.Contains( wxT(
"T1" ) ) );
450 BOOST_CHECK( reportContents.Contains( wxT(
"0.300mm" ) ) );
451 reportStream.Close();
453 wxFileName::Rmdir( tempDir.GetFullPath(), wxPATH_RMDIR_RECURSIVE );
465 wxFileName tempDir = MakeTempDir();
466 wxFileName boardFile( tempDir.GetFullPath(), wxT(
"silk_rect_board.kicad_pcb" ) );
481 wxFileName odbRoot( tempDir.GetFullPath(), wxEmptyString );
482 odbRoot.AppendDir( wxT(
"odb_out" ) );
483 BOOST_REQUIRE( odbRoot.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) );
486 std::map<std::string, UTF8> props;
487 props[
"units"] =
"mm";
488 props[
"sigfig"] =
"4";
489 BOOST_REQUIRE_NO_THROW( odbExporter.
SaveBoard( odbRoot.GetFullPath(), board, &props ) );
491 wxFileName silkFeatures( odbRoot.GetFullPath(), wxT(
"features" ) );
492 silkFeatures.AppendDir( wxT(
"steps" ) );
493 silkFeatures.AppendDir( wxT(
"pcb" ) );
494 silkFeatures.AppendDir( wxT(
"layers" ) );
495 silkFeatures.AppendDir( wxT(
"f.silkscreen" ) );
498 wxFFile silkStream( silkFeatures.GetFullPath(), wxT(
"rb" ) );
499 wxString silkContents;
505 wxStringTokenizer lines( silkContents, wxT(
"\n" ) );
507 while( lines.HasMoreTokens() )
509 if( lines.GetNextToken().StartsWith( wxT(
"L " ) ) )
516 BOOST_CHECK( !silkContents.Contains( wxT(
"donut_rc" ) ) );
518 wxFileName::Rmdir( odbRoot.GetFullPath(), wxPATH_RMDIR_RECURSIVE );
519 wxFileName::Rmdir( tempDir.GetFullPath(), wxPATH_RMDIR_RECURSIVE );
525 wxFileName tempDir = MakeTempDir();
543 wxFileName odbRoot( tempDir.GetFullPath(), wxEmptyString );
544 odbRoot.AppendDir( wxT(
"odb_out" ) );
545 BOOST_REQUIRE( odbRoot.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) );
548 std::map<std::string, UTF8> props;
549 props[
"units"] =
"mm";
550 props[
"sigfig"] =
"4";
551 BOOST_REQUIRE_NO_THROW( odbExporter.
SaveBoard( odbRoot.GetFullPath(), board, &props ) );
553 wxFileName copperFeatures( odbRoot.GetFullPath(), wxT(
"features" ) );
554 copperFeatures.AppendDir( wxT(
"steps" ) );
555 copperFeatures.AppendDir( wxT(
"pcb" ) );
556 copperFeatures.AppendDir( wxT(
"layers" ) );
557 copperFeatures.AppendDir( wxT(
"f.cu" ) );
560 wxFFile copperStream( copperFeatures.GetFullPath(), wxT(
"rb" ) );
561 wxString copperContents;
563 copperStream.Close();
567 wxStringTokenizer lines( copperContents, wxT(
"\n" ) );
569 while( lines.HasMoreTokens() )
571 wxString line = lines.GetNextToken();
573 if( line.StartsWith( wxT(
"L " ) ) )
575 else if( line.StartsWith( wxT(
"A " ) ) )
582 wxFileName::Rmdir( odbRoot.GetFullPath(), wxPATH_RMDIR_RECURSIVE );
583 wxFileName::Rmdir( tempDir.GetFullPath(), wxPATH_RMDIR_RECURSIVE );
591 wxFileName odbRoot( aTempDir.GetFullPath(), 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(), *aBoard, &props ) );
607 wxFileName features( aOdbRoot.GetFullPath(), wxT(
"features" ) );
608 features.AppendDir( wxT(
"steps" ) );
609 features.AppendDir( wxT(
"pcb" ) );
610 features.AppendDir( wxT(
"layers" ) );
611 features.AppendDir( aLayerDir );
614 wxFFile stream( features.GetFullPath(), wxT(
"rb" ) );
630 std::unique_ptr<BOARD> board;
635 wxFileName tempDir = MakeTempDir();
640 for(
const wxString& layerDir : { wxString( wxT(
"f.cu" ) ), wxString( wxT(
"edge.cuts" ) ) } )
644 BOOST_CHECK_MESSAGE( contents.Contains( wxT(
"donut_r2100.0x1900.0" ) ),
645 "Wrong annulus on " + layerDir +
", features file holds:\n"
649 wxFileName::Rmdir( odbRoot.GetFullPath(), wxPATH_RMDIR_RECURSIVE );
650 wxFileName::Rmdir( tempDir.GetFullPath(), wxPATH_RMDIR_RECURSIVE );
661 std::unique_ptr<BOARD> board;
663 KI_TEST::LoadBoard( settingsManager, wxT(
"issue25089/odb_circle_edge_cases" ), board );
666 wxFileName tempDir = MakeTempDir();
671 BOOST_CHECK_MESSAGE( frontContents.Contains( wxT(
"r400.0" ) )
672 && !frontContents.Contains( wxT(
"donut" ) ),
673 "Circle with a hole-closing stroke should export as a solid pad, "
674 "features file holds:\n"
679 wxStringTokenizer backLines( backContents, wxT(
"\n" ) );
681 while( backLines.HasMoreTokens() )
683 wxString line = backLines.GetNextToken();
685 if( line.StartsWith( wxT(
"$" ) ) )
687 BOOST_CHECK_MESSAGE( !line.Contains( wxT(
"-" ) ),
688 "Oversized circle overflowed to a negative symbol dimension: "
693 wxFileName::Rmdir( odbRoot.GetFullPath(), wxPATH_RMDIR_RECURSIVE );
694 wxFileName::Rmdir( tempDir.GetFullPath(), wxPATH_RMDIR_RECURSIVE );
704 pad->SetAttribute( aAttribute );
707 pad->SetPosition( aPos );
726 wxFileName tempDir = MakeTempDir();
727 wxFileName boardFile( tempDir.GetFullPath(), wxT(
"plated_slot_board.kicad_pcb" ) );
743 wxFileName odbRoot( tempDir.GetFullPath(), wxEmptyString );
744 odbRoot.AppendDir( wxT(
"odb_out" ) );
745 BOOST_REQUIRE( odbRoot.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) );
748 std::map<std::string, UTF8> props;
749 props[
"units"] =
"mm";
750 props[
"sigfig"] =
"4";
751 BOOST_REQUIRE_NO_THROW( odbExporter.
SaveBoard( odbRoot.GetFullPath(), board, &props ) );
753 auto layerDir = [&](
const wxString& aLayer )
755 wxFileName dir( odbRoot.GetFullPath(), wxEmptyString );
756 dir.AppendDir( wxT(
"steps" ) );
757 dir.AppendDir( wxT(
"pcb" ) );
758 dir.AppendDir( wxT(
"layers" ) );
759 dir.AppendDir( aLayer );
764 auto readFile = [](
const wxFileName& aFile )
766 wxFFile stream( aFile.GetFullPath(), wxT(
"rb" ) );
775 auto countLinesStartingWith = [](
const wxString& aContents,
const wxString& aPrefix )
778 wxStringTokenizer lines( aContents, wxT(
"\n" ) );
780 while( lines.HasMoreTokens() )
782 wxString line = lines.GetNextToken();
785 if( line.StartsWith( aPrefix ) )
792 auto containsOvalSymbol = [](
const wxString& aContents )
794 wxStringTokenizer lines( aContents, wxT(
"\n" ) );
796 while( lines.HasMoreTokens() )
798 wxString line = lines.GetNextToken();
801 if( line.StartsWith( wxT(
"$" ) ) && line.Contains( wxT(
"oval" ) ) )
810 wxFileName platedDir = layerDir( wxT(
"drill_plated_f.cu-b.cu" ) );
811 BOOST_REQUIRE_MESSAGE( platedDir.DirExists(),
"Plated drill layer should exist" );
813 wxFileName platedFeatures( platedDir.GetFullPath(), wxT(
"features" ) );
815 wxString platedContents =
readFile( platedFeatures );
818 BOOST_CHECK_MESSAGE( containsOvalSymbol( platedContents ),
819 "Plated slot should use an oval symbol" );
821 wxFileName platedTools( platedDir.GetFullPath(), wxT(
"tools" ) );
823 wxString platedToolsContents =
readFile( platedTools );
824 BOOST_CHECK_EQUAL( countLinesStartingWith( platedToolsContents, wxT(
"TYPE=PLATED" ) ), 1 );
825 BOOST_CHECK_EQUAL( countLinesStartingWith( platedToolsContents, wxT(
"TYPE=NON_PLATED" ) ), 0 );
829 wxFileName nonPlatedDir = layerDir( wxT(
"drill_non-plated_f.cu-b.cu" ) );
830 BOOST_REQUIRE_MESSAGE( nonPlatedDir.DirExists(),
"Non-plated drill layer should exist" );
832 wxFileName nonPlatedFeatures( nonPlatedDir.GetFullPath(), wxT(
"features" ) );
834 wxString nonPlatedContents =
readFile( nonPlatedFeatures );
836 BOOST_CHECK_EQUAL( countLinesStartingWith( nonPlatedContents, wxT(
"P " ) ), 1 );
837 BOOST_CHECK_MESSAGE( containsOvalSymbol( nonPlatedContents ),
838 "Non-plated slot should still export an oval symbol" );
840 wxFileName nonPlatedTools( nonPlatedDir.GetFullPath(), wxT(
"tools" ) );
842 wxString nonPlatedToolsContents =
readFile( nonPlatedTools );
843 BOOST_CHECK_EQUAL( countLinesStartingWith( nonPlatedToolsContents, wxT(
"TYPE=NON_PLATED" ) ),
845 BOOST_CHECK_EQUAL( countLinesStartingWith( nonPlatedToolsContents, wxT(
"TYPE=PLATED" ) ), 0 );
847 wxFileName::Rmdir( odbRoot.GetFullPath(), wxPATH_RMDIR_RECURSIVE );
848 wxFileName::Rmdir( tempDir.GetFullPath(), wxPATH_RMDIR_RECURSIVE );
859 std::unique_ptr<BOARD> board;
864 wxFileName tempDir = MakeTempDir();
865 wxFileName boardFile( tempDir.GetFullPath(), wxT(
"backdrill.kicad_pcb" ) );
868 board->SetFileName( boardFile.GetFullPath() );
870 wxFileName reportFile( tempDir.GetFullPath(), wxT(
"backdrill-drl.rpt" ) );
877 wxFFile reportStream( reportFile.GetFullPath(), wxT(
"rb" ) );
878 wxString reportContents;
880 reportStream.Close();
882 struct BACKDRILL_SECTION
888 std::map<wxString, BACKDRILL_SECTION> sections;
889 wxString currentFile;
890 wxStringTokenizer lines( reportContents, wxT(
"\n" ) );
892 while( lines.HasMoreTokens() )
894 wxString line = lines.GetNextToken();
895 line.Trim(
true ).Trim(
false );
897 if( line.StartsWith( wxT(
"Drill file '" ) ) )
898 currentFile = line.AfterFirst(
'\'' ).BeforeFirst(
'\'' );
900 if( line.StartsWith( wxT(
"T" ) ) && line.Contains( wxT(
"0.330mm" ) ) )
901 sections[currentFile].toolLines++;
905 if( line.StartsWith( wxT(
"Total backdrilled holes count " ), &count ) )
909 sections[currentFile].holes = value;
915 const std::map<wxString, long>
expected = {
916 { wxT(
"backdrill_Backdrills_Drill_1_4.drl" ), 2 },
917 { wxT(
"backdrill_Backdrills_Drill_10_4.drl" ), 1 },
918 { wxT(
"backdrill_Backdrills_Drill_10_7.drl" ), 1 }
924 for(
const auto& [file, holes] :
expected )
926 auto section = sections.find( file );
928 if( section == sections.end() )
930 BOOST_ERROR(
"No backdrill section for " << file );
941 BOOST_CHECK( reportContents.Contains( wxT(
"Total plated holes count 4" ) ) );
942 BOOST_CHECK( reportContents.Contains( wxT(
"Total unplated holes count 0" ) ) );
944 wxFileName::Rmdir( tempDir.GetFullPath(), wxPATH_RMDIR_RECURSIVE );
constexpr EDA_IU_SCALE pcbIUScale
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.
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
@ 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.
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.
static wxString ReadOdbLayerFeatures(const wxFileName &aOdbRoot, const wxString &aLayerDir)
static wxFileName ExportOdbTree(BOARD *aBoard, const wxFileName &aTempDir)
BOOST_AUTO_TEST_CASE(BackdrillCamOutputs)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
VECTOR3I expected(15, 30, 45)
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I