88 return std::optional<int>();
91 return std::optional<int>( stackup.
GetLayerDistance( aStartLayer, aEndLayer ) );
94 if( !aGenerateNPTH_list )
110 DRILL_SPAN drillSpan( aDrill.start, aDrill.end,
true,
false );
112 if( drillSpan.
Pair() != aSpan.
Pair() )
121 if( aDrill.size.x <= 0 && aDrill.size.y <= 0 )
135 int diameter = aDrill.size.x;
137 if( aDrill.size.y > 0 )
138 diameter = ( diameter > 0 ) ? std::min( diameter, aDrill.size.y )
145 && aDrill.size.x != aDrill.size.y )
175 hole.
m_StubLength = computeStubLength( aDrill.start, aDrill.end );
184 tryEmitBackdrill(
via->Padstack().SecondaryDrill() );
185 tryEmitBackdrill(
via->Padstack().TertiaryDrill() );
189 int hole_sz =
via->GetDrillValue();
196 via->LayerPair( &top_layer, &bottom_layer );
251 for(
PAD*
pad : footprint->Pads() )
262 if(
pad->GetDrillSize().x == 0 )
288 &&
pad->GetDrillSizeX() !=
pad->GetDrillSizeY() )
308 bool last_notplated_opt =
false;
384 std::set<DRILL_SPAN> unique;
386 for(
int i = 0; i < vias.
GetCount(); ++i )
392 via->LayerPair( &top_layer, &bottom_layer );
395 unique.emplace( top_layer, bottom_layer,
false,
false );
402 if( aDrill.size.x <= 0 && aDrill.size.y <= 0 )
405 unique.emplace( aDrill.start, aDrill.end,
true,
false );
408 addBackdrillSpan(
via->Padstack().SecondaryDrill() );
409 addBackdrillSpan(
via->Padstack().TertiaryDrill() );
412 std::vector<DRILL_SPAN> ret;
414 ret.emplace_back(
F_Cu,
B_Cu,
false,
false );
419 ret.push_back( span );
438 int ly_id = ( aLayer -
B_Cu ) / 2;
439 return fmt::format(
"in{}", ly_id );
447 std::string ret =
layerName( aPair.first );
456 bool aMerge_PTH_NPTH )
const
464 int conventional_layer_num = 1;
468 if( layer == aLayer )
469 return conventional_layer_num;
471 conventional_layer_num++;
474 return conventional_layer_num;
479 extend.Printf( wxT(
"_Backdrills_Drill_%d_%d" ),
485 extend = wxT(
"-NPTH" );
489 if( !aMerge_PTH_NPTH )
490 extend = wxT(
"-PTH" );
499 wxFileName fn =
m_pcb->GetFileName();
501 fn.SetName( fn.GetName() + extend );
504 wxString ret = fn.GetFullName();
520 extend << wxT(
"-filling-" );
524 extend << wxT(
"-capping-" );
528 extend << wxT(
"-covering-" );
532 extend << wxT(
"-covering-" );
536 extend << wxT(
"-plugging-" );
540 extend << wxT(
"-plugging-" );
544 extend << wxT(
"-tenting-" );
548 extend << wxT(
"-tenting-" );
553 wxFileName fn =
m_pcb->GetFileName();
555 fn.SetName( fn.GetName() + extend );
558 wxString ret = fn.GetFullName();
572 hole_sets.emplace_back(
F_Cu,
B_Cu,
false,
true );
574 for( std::vector<DRILL_SPAN>::const_iterator it = hole_sets.begin(); it != hole_sets.end(); ++it )
584 fn.SetPath( aPlotDirectory );
586 fn.SetExt( wxEmptyString );
587 wxString fullfilename = fn.GetFullPath() + wxT(
"-drl_map" );
596 msg.Printf(
_(
"Failed to create file '%s'." ), fullfilename );
606 msg.Printf(
_(
"Created file '%s'." ), fullfilename );
619 bool aCompatNCdrill )
const
626 text = wxT(
"; #@! " );
630 text << wxT(
"TF.FileFunction," );
633 text << wxT(
"NonPlated," );
635 text << wxT(
"MixedPlating," );
637 text << wxT(
"Plated," );
639 int layer1 = aSpan.
Pair().first;
640 int layer2 = aSpan.
Pair().second;
650 else if( layer1 ==
B_Cu )
651 layer1 =
m_pcb->GetCopperLayerCount();
653 layer1 = ( ( layer1 -
B_Cu ) / 2 ) + 1;
657 else if( layer2 ==
B_Cu )
658 layer2 =
m_pcb->GetCopperLayerCount();
660 layer2 = ( ( layer2 -
B_Cu ) / 2) + 1;
663 if( layer1 > layer2 )
664 std::swap( layer1, layer2 );
666 text << layer1 << wxT(
"," ) << layer2;
670 int bottomlayer =
m_pcb->GetCopperLayerCount();
673 text << wxT(
",Blind" );
675 text << wxT(
",NPTH" );
678 else if( layer1 == toplayer && layer2 == bottomlayer )
679 text << wxT(
",PTH" );
680 else if( layer1 == toplayer || layer2 == bottomlayer )
681 text << wxT(
",Blind" );
683 text << wxT(
",Buried" );
694 bool hasOblong =
false;
695 bool hasDrill =
false;
707 if( hasOblong && hasDrill )
708 text << wxT(
",Mixed" );
710 text << wxT(
",Drill" );
712 text << wxT(
",Rout" );
740 int bestsize = aMarkerDiameter / 10;
742 const double MIN_SIZE_MM = 0.1;
743 bestsize = std::max( bestsize,
pcbIUScale.mmToIU( MIN_SIZE_MM ) );
752 const double SKETCH_LINE_WIDTH_MM = 0.1;
753 return pcbIUScale.mmToIU( SKETCH_LINE_WIDTH_MM );
760 const double DEFAULT_LINE_WIDTH_MM = 0.2;
761 return pcbIUScale.mmToIU( DEFAULT_LINE_WIDTH_MM );
775 int bottom_limit = 0;
783 LSET visibleLayers =
m_pcb->GetVisibleLayers();
785 BOX2I bbbox =
m_pcb->GetBoardEdgesBoundingBox();
786 m_pcb->SetVisibleLayers( visibleLayers );
816 double Xscale = double( pageSizeIU.
x - ( 2 * margin ) ) / bbbox.
GetWidth();
820 int ypagesize_for_board =
KiROUND( pageSizeIU.
y * 0.6 );
821 double Yscale = double( ypagesize_for_board - margin ) / bbbox.
GetHeight();
823 scale = std::min( Xscale, Yscale );
836 bottom_limit = ( pageSizeIU.
y - margin ) / std::min(
scale, 1.0 );
856 plotter = dxf_plotter;
871 if( !plotter->
OpenFile( aFullFileName ) )
894 text =
"%TF.FileFunction,Drillmap*%";
898 text = wxT(
"%TF.FilePolarity,Positive*%" );
916 switch( item->Type() )
934 for(
BOARD_ITEM* item : footprint->GraphicalItems() )
939 switch( item->Type() )
955 int plotX, plotY, TextWidth;
959 int textmarginaftersymbol =
pcbIUScale.mmToIU( 2 );
975 double charScale = std::min( 1.0, 1.0 /
scale );
977 TextWidth =
KiROUND( ( charSize * charScale ) / 10.0 );
978 intervalle =
KiROUND( charSize * charScale ) + TextWidth;
981 plotX =
KiROUND( bbbox.
GetX() + textmarginaftersymbol * charScale );
985 wxString Text = wxT(
"Drill Map:" );
990 attrs.
m_Size =
KiROUND( charSize * charScale, charSize * charScale );
1001 int max_line_len = 0;
1010 plotY += intervalle;
1013 if( bottom_limit && ( plotY + intervalle > bottom_limit ) )
1016 plotX += max_line_len +
pcbIUScale.mmToIU( 10 );
1023 plot_diam = std::min( plot_diam,
KiROUND( charSize * charScale ) );
1024 int x =
KiROUND( plotX - textmarginaftersymbol * charScale - plot_diam / 2.0 );
1025 int y =
KiROUND( plotY + charSize * charScale );
1039 extraInfo += wxT(
", castellated" );
1041 extraInfo += wxT(
", press-fit" );
1052 extraInfo += wxString::Format( wxT(
", backdrill stub %.3f-%.3fmm" ), minStub, maxStub );
1056 extraInfo += wxString::Format( wxT(
", backdrill stub %.3fmm" ), minStub );
1061 extraInfo += wxT(
", backdrill" );
1066 extraInfo += wxT(
", post-machined" );
1071 counts.Printf( wxT(
"(1 hole%s)" ), extraInfo );
1073 counts.Printf( wxT(
"(1 slot%s)" ), extraInfo );
1075 counts.Printf( wxT(
"(%d holes%s)" ), tool.
m_TotalCount, extraInfo );
1077 counts.Printf( wxT(
"(%d holes + 1 slot%s)" ), tool.
m_TotalCount - 1, extraInfo );
1086 msg += wxT(
" (not plated)" );
1091 intervalle =
KiROUND( ( ( charSize * charScale ) + TextWidth ) * 1.2 );
1093 if( intervalle < ( plot_diam + ( 1 *
pcbIUScale.IU_PER_MM /
scale ) + TextWidth ) )
1094 intervalle = plot_diam + ( 1 *
pcbIUScale.IU_PER_MM /
scale ) + TextWidth;
1098 int text_len = msg.Len() * ( ( charSize * charScale ) + TextWidth );
1099 max_line_len = std::max( max_line_len, text_len + plot_diam );
1111 wxFFile out( aFullFileName,
"wb" );
1113 if( !out.IsOpened() )
1117 wxString msg = wxString::Format(
_(
"Error creating drill report file '%s'" ),
1125 FILE* outFp = out.fp();
1127 static const char separator[] =
1128 " =============================================================\n";
1132 unsigned totalHoleCount;
1133 wxFileName brdFilename(
m_pcb->GetFileName() );
1137 bool writeError =
false;
1141 fmt::print( outFp,
"Drill report for {}\n",
TO_UTF8( brdFilename.GetFullName() ) );
1145 fmt::print( outFp,
"Copper Layer Stackup:\n" );
1146 fmt::print( outFp,
"{}", separator );
1148 int conventional_layer_num = 1;
1152 fmt::print( outFp,
" L{:<2}: {:<25} {}\n", conventional_layer_num++,
1157 fmt::print( outFp,
"\n\n" );
1165 bool buildNPTHlist =
false;
1168 for(
unsigned pair_ndx = 0; pair_ndx < hole_sets.size(); ++pair_ndx )
1170 const DRILL_SPAN& span = hole_sets[pair_ndx];
1176 fmt::print( outFp,
"Drill file '{}' contains\n",
1179 fmt::print( outFp,
" plated through holes:\n" );
1180 fmt::print( outFp,
"{}", separator );
1182 fmt::print( outFp,
" Total plated holes count {}\n", totalHoleCount );
1186 fmt::print( outFp,
"Drill file '{}' contains\n",
1189 fmt::print( outFp,
" backdrill span: '{}' to '{}':\n",
1193 fmt::print( outFp,
"{}", separator );
1195 fmt::print( outFp,
" Total backdrilled holes count {}\n", totalHoleCount );
1199 fmt::print( outFp,
"Drill file '{}' contains\n",
1202 fmt::print( outFp,
" holes connecting layer pair: '{} and {}' ({} vias):\n",
1205 span.
Pair().first ==
F_Cu || span.
Pair().second ==
B_Cu ?
"blind" :
"buried" );
1207 fmt::print( outFp,
"{}", separator );
1209 fmt::print( outFp,
" Total plated holes count {}\n", totalHoleCount );
1212 fmt::print( outFp,
"\n\n" );
1218 buildNPTHlist =
true;
1226 fmt::print( outFp,
"Not plated through holes are merged with plated holes\n" );
1228 fmt::print( outFp,
"Drill file '{}' contains\n",
1231 fmt::print( outFp,
" unplated through holes:\n" );
1232 fmt::print( outFp,
"{}", separator );
1234 fmt::print( outFp,
" Total unplated holes count {}\n", totalHoleCount );
1236 catch(
const std::system_error& )
1240 catch(
const fmt::format_error& )
1245 if( writeError && aReporter )
1247 wxString msg = wxString::Format(
_(
"Error writing drill report file '%s'" ), aFullFileName );
1283 unsigned totalHoleCount = 0;
1294 if( bucket != aSummary )
1298 int tool_number = ii+1;
1299 fmt::print( out,
" T{} {:2.3f}mm {:2.4f}\" ", tool_number,
1305 fmt::print( out,
"(1 hole" );
1307 fmt::print( out,
"(1 hole) (with 1 slot" );
1311 fmt::print( out,
"({} holes) (with 1 slot", tool.
m_TotalCount );
1316 fmt::print( out,
", castellated" );
1319 fmt::print( out,
", press-fit" );
1321 fmt::print( out,
")\n" );
1326 fmt::print( out,
"\n" );
1328 return totalHoleCount;
constexpr EDA_IU_SCALE pcbIUScale
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Manage layers needed to make a physical board.
int GetLayerDistance(PCB_LAYER_ID aFirstLayer, PCB_LAYER_ID aSecondLayer) const
Calculate the distance (height) between the two given copper layers.
constexpr size_type GetWidth() const
constexpr Vec Centre() const
constexpr coord_type GetX() const
constexpr size_type GetHeight() const
constexpr coord_type GetBottom() const
void SetLayerSet(const LSET &aLayerMask)
void PlotShape(const PCB_SHAPE *aShape)
int GetCount() const
Return the number of objects in the list.
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
void SetUnits(DXF_UNITS aUnit)
Set the units to use for plotting the DXF file.
virtual void SetParentGroup(EDA_GROUP *aGroup)
unsigned printToolSummary(FILE *out, TOOL_SUMMARY aSummary) const
Print m_toolListBuffer[] tools to aOut and returns total hole count.
virtual const wxString getProtectionFileName(const DRILL_SPAN &aSpan, IPC4761_FEATURES aFeature) const
const PAGE_INFO * m_pageInfo
wxString m_drillFileExtension
std::vector< HOLE_INFO > m_holeListBuffer
TOOL_SUMMARY
Selects which subset of m_toolListBuffer a summary covers.
@ UNPLATED
Non-plated holes, excluding backdrills.
@ BACKDRILL
Backdrills, which are non-plated by construction.
void buildHolesList(const DRILL_SPAN &aSpan, bool aGenerateNPTH_list)
Create the list of holes and tools for a given board.
bool genDrillMapFile(const wxString &aFullFileName, PLOT_FORMAT aFormat)
Plot a map of drill marks for holes.
VECTOR2I GetOffset()
Return the plot offset (usually the position of the drill/place origin).
std::vector< DRILL_SPAN > getUniqueLayerPairs() const
Get unique layer pairs by examining the micro and blind_buried vias.
std::vector< DRILL_TOOL > m_toolListBuffer
const std::string layerPairName(DRILL_LAYER_PAIR aPair) const
bool CreateMapFilesSet(const wxString &aPlotDirectory, REPORTER *aReporter=nullptr)
Create the full set of map files for the board, in PS, PDF ... format (use SetMapFileFormat() to sele...
const std::string layerName(PCB_LAYER_ID aLayer) const
int getHolesCount() const
virtual const wxString getDrillFileName(const DRILL_SPAN &aSpan, bool aNPTH, bool aMerge_PTH_NPTH) const
bool plotDrillMarks(PLOTTER *aPlotter)
Write the drill marks in PDF, POSTSCRIPT or other supported formats/.
const wxString BuildFileFunctionAttributeString(const DRILL_SPAN &aSpan, TYPE_FILE aHoleType, bool aCompatNCdrill=false) const
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,...
void UseX2format(bool aEnable)
void UseX2NetAttributes(bool aEnable)
void DisableApertMacros(bool aDisable)
Disable Aperture Macro (AM) command, only for broken Gerber Readers.
Handle hole which must be drilled (diameter, position and layers).
int m_FrontPostMachiningDepth
PAD_DRILL_POST_MACHINING_MODE m_FrontPostMachining
PCB_LAYER_ID m_Hole_Bottom_Layer
std::optional< int > m_StubLength
PCB_LAYER_ID m_Hole_Top_Layer
HOLE_ATTRIBUTE m_HoleAttribute
int m_FrontPostMachiningAngle
PCB_LAYER_ID m_DrillStart
BOARD_ITEM * m_ItemParent
int m_BackPostMachiningDepth
int m_BackPostMachiningSize
PAD_DRILL_POST_MACHINING_MODE m_BackPostMachining
int m_FrontPostMachiningSize
int m_BackPostMachiningAngle
static const METRICS & Default()
PCB specific render settings.
void SetDefaultPenWidth(int aWidth)
LSET is a set of PCB_LAYER_IDs.
static LSET AllCuMask(int aCuLayerCount)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Describe the page size and margins of a paper page on which to eventually print or plot.
const VECTOR2D GetSizeIU(double aIUScale) const
Gets the page size in internal units.
Parameters and options when plotting/printing a board.
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Collect all BOARD_ITEM objects of a given set of KICAD_T type(s).
void Collect(BOARD_ITEM *aBoard, const std::vector< KICAD_T > &aTypes)
Collect BOARD_ITEM objects using this class's Inspector method, which does the collection.
Base plotter engine class.
virtual bool OpenFile(const wxString &aFullFilename)
Open or create the plot file aFullFilename.
virtual void SetPageSettings(const PAGE_INFO &aPageSettings)
void SetRenderSettings(RENDER_SETTINGS *aSettings)
static const int USE_DEFAULT_LINE_WIDTH
virtual void ThickOval(const VECTOR2I &aPos, const VECTOR2I &aSize, const EDA_ANGLE &aOrient, int aWidth, void *aData)
virtual bool StartPlot(const wxString &aPageNumber)=0
virtual void SetGerberCoordinatesFormat(int aResolution, bool aUseInches=false)
virtual PLOT_FORMAT GetPlotterType() const =0
Return the effective plot engine in use.
void Marker(const VECTOR2I &position, int diametre, unsigned aShapeId)
Draw a pattern shape number aShapeId, to coord position.
virtual void SetCreator(const wxString &aCreator)
void ClearHeaderLinesList()
Remove all lines from the list of free lines to print at the beginning of the file.
virtual void SetViewport(const VECTOR2I &aOffset, double aIusPerDecimil, double aScale, bool aMirror)=0
Set the plot offset and scaling for the current plot.
void AddLineToHeader(const wxString &aExtraString)
Add a line to the list of free lines to print at the beginning of the file.
virtual void SetColorMode(bool aColorMode)
Plot in B/W or color.
virtual void SetCurrentLineWidth(int width, void *aData=nullptr)=0
Set the line width for the next drawing.
virtual void PlotText(const VECTOR2I &aPos, const COLOR4D &aColor, const wxString &aText, const TEXT_ATTRIBUTES &aAttributes, KIFONT::FONT *aFont=nullptr, const KIFONT::METRICS &aFontMetrics=KIFONT::METRICS::Default(), void *aData=nullptr)
A pure virtual class used to derive REPORTER objects from.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
GR_TEXT_H_ALIGN_T m_Halign
GR_TEXT_V_ALIGN_T m_Valign
wxString GetDefaultPlotExtension(PLOT_FORMAT aFormat)
Return the default plot extension for a format.
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
double diameter_in_mm(double ius)
double diameter_in_inches(double ius)
static bool cmpHoleSorting(const HOLE_INFO &a, const HOLE_INFO &b)
static int getMarkerBestPenSize(int aMarkerDiameter)
int getSketchOvalBestPenSize()
helper classes to handle hole info for drill files generators.
#define USE_ATTRIB_FOR_HOLES
std::pair< PCB_LAYER_ID, PCB_LAYER_ID > DRILL_LAYER_PAIR
bool IsCopperLayerLowerThan(PCB_LAYER_ID aLayerA, PCB_LAYER_ID aLayerB)
Return true if copper aLayerA is placed lower than aLayerB, false otherwise.
PCB_LAYER_ID
A quick note on layer IDs:
PCB_LAYER_ID ToLAYER_ID(int aLayer)
This file contains miscellaneous commonly used macros and functions.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
@ PRESSFIT
a PTH with a hole diameter with tight tolerances for press fit pin
@ CASTELLATED
a pad with a castellated through hole
void AddGerberX2Header(PLOTTER *aPlotter, const BOARD *aBoard, bool aUseX1CompatibilityMode)
Calculate some X2 attributes as defined in the Gerber file format specification J4 (chapter 5) and ad...
PLOT_FORMAT
The set of supported output plot formats.
Plotting engines similar to ps (PostScript, Gerber, svg)
std::vector< FAB_LAYER_COLOR > dummy
wxString From_UTF8(const char *cstring)
wxString GetISO8601CurrentDateTime()
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
DRILL_LAYER_PAIR Pair() const
PCB_LAYER_ID DrillEndLayer() const
PCB_LAYER_ID TopLayer() const
PCB_LAYER_ID DrillStartLayer() const
PCB_LAYER_ID BottomLayer() const
! The properties of a padstack drill. Drill position is always the pad position (origin).
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
VECTOR2< int32_t > VECTOR2I