31#include <nlohmann/json.hpp> 
   38#include <wx/datetime.h> 
  166                switch( footprint->GetSide() )
 
  189        auto         trackShapeA = track->GetEffectiveShape( layer );
 
  193            if( layer != otherTrack->GetLayer() )
 
  196            if( track->GetNetCode() == otherTrack->GetNetCode() )
 
  203            auto trackShapeB = otherTrack->GetEffectiveShape( layer );
 
  226        std::vector<DRILL_LINE_ITEM> drills;
 
  257                for( 
int j = 0; j < polySet.
HoleCount( i ); ++j )
 
  262                    for( 
PAD* 
pad : footprint->Pads() )
 
  264                        if( !
pad->HasHole() )
 
  267                        std::shared_ptr<SHAPE_SEGMENT> hole = 
pad->GetEffectiveHoleShape();
 
  272                        const SEG& seg = hole->GetSeg();
 
  273                        double     width = hole->GetWidth();
 
  274                        double     area = seg.
Length() * width;
 
  276                        area += 
M_PI * 0.25 * width * width;
 
  286                        double   drill = 
via->GetDrillValue();
 
 
  359    return wxString::Format( wxT( 
"%i" ), aCount );
 
 
  363static void appendTable( 
const std::vector<std::vector<wxString>>& aRows, 
bool aUseFirstColAsLabel, wxString& aOut )
 
  368    size_t columnCount = 0;
 
  370    for( 
const std::vector<wxString>& row : aRows )
 
  372        if( row.size() > columnCount )
 
  373            columnCount = row.size();
 
  376    if( columnCount == 0 )
 
  379    std::vector<int> widths( columnCount, 0 );
 
  381    for( 
const std::vector<wxString>& row : aRows )
 
  383        for( 
size_t col = 0; col < columnCount; ++col )
 
  385            if( col >= row.size() )
 
  388            int cellWidth = 
static_cast<int>( row[col].length() );
 
  390            if( cellWidth > widths[col] )
 
  391                widths[col] = cellWidth;
 
  396            [&]( 
const std::vector<wxString>& row, 
bool treatFirstAsLabel )
 
  398                if( treatFirstAsLabel && aUseFirstColAsLabel )
 
  401                    wxString firstColumn;
 
  404                        firstColumn = row[0];
 
  406                    formatted.Printf( wxS( 
"|%-*s  |" ), widths[0], firstColumn );
 
  409                    for( 
size_t col = 1; col < columnCount; ++col )
 
  412                        if( col < row.size() )
 
  415                        formatted.Printf( wxS( 
" %*s |" ), widths[col], value );
 
  423                    for( 
size_t col = 0; col < columnCount; ++col )
 
  426                        if( col < row.size() )
 
  430                        formatted.Printf( wxS( 
" %*s |" ), widths[col], value );
 
  438    appendDataRow( aRows.front(), 
false );
 
  442    for( 
size_t col = 0; col < columnCount; ++col )
 
  444        int dashCount = widths[col] + 2;
 
  451        for( 
int i = 0; i < dashCount; ++i )
 
  452            dashes << wxS( 
"-" );
 
  454        aOut << dashes << wxS( 
"|" );
 
  459    for( 
size_t rowIdx = 1; rowIdx < aRows.size(); ++rowIdx )
 
  460        appendDataRow( aRows[rowIdx], 
true );
 
 
  465                                      const UNITS_PROVIDER& aUnitsProvider, 
const wxString& aProjectName,
 
  466                                      const wxString& aBoardName )
 
  470    report << 
_( 
"PCB statistics report\n=====================" ) << wxS( 
"\n" );
 
  471    report << wxS( 
"- " ) << 
_( 
"Date" ) << wxS( 
": " ) << wxDateTime::Now().Format() << wxS( 
"\n" );
 
  472    report << wxS( 
"- " ) << 
_( 
"Project" ) << wxS( 
": " ) << aProjectName << wxS( 
"\n" );
 
  473    report << wxS( 
"- " ) << 
_( 
"Board name" ) << wxS( 
": " ) << aBoardName << wxS( 
"\n\n" );
 
  475    report << 
_( 
"Board" ) << wxS( 
"\n-----\n" );
 
  481        report << wxS( 
"- " ) << 
_( 
"Height" ) << wxS( 
": " )
 
  483        report << wxS( 
"- " ) << 
_( 
"Area" ) << wxS( 
": " )
 
  488        report << wxS( 
"- " ) << 
_( 
"Dimensions" ) << wxS( 
": " ) << 
_( 
"unknown" ) << wxS( 
"\n" );
 
  489        report << wxS( 
"- " ) << 
_( 
"Area" ) << wxS( 
": " ) << 
_( 
"unknown" ) << wxS( 
"\n" );
 
  492    report << wxS( 
"- " ) << 
_( 
"Front copper area" ) << wxS( 
": " )
 
  494    report << wxS( 
"- " ) << 
_( 
"Back copper area" ) << wxS( 
": " )
 
  497    report << wxS( 
"- " ) << 
_( 
"Min track clearance" ) << wxS( 
": " )
 
  501    report << wxS( 
"- " ) << 
_( 
"Min track width" ) << wxS( 
": " )
 
  506    report << wxS( 
"- " ) << 
_( 
"Min drill diameter" ) << wxS( 
": " )
 
  509    report << wxS( 
"- " ) << 
_( 
"Board stackup thickness" ) << wxS( 
": " )
 
  513    report << 
_( 
"Pads" ) << wxS( 
"\n----\n" );
 
  516        report << wxS( 
"- " ) << padEntry.
title << wxS( 
" " ) << padEntry.
quantity << wxS( 
"\n" );
 
  519        report << wxS( 
"- " ) << propEntry.
title << wxS( 
" " ) << propEntry.
quantity << wxS( 
"\n" );
 
  521    report << wxS( 
"\n" );
 
  522    report << 
_( 
"Vias" ) << wxS( 
"\n----\n" );
 
  525        report << wxS( 
"- " ) << viaEntry.
title << wxS( 
" " ) << viaEntry.
quantity << wxS( 
"\n" );
 
  527    report << wxS( 
"\n" );
 
  528    report << 
_( 
"Components" ) << wxS( 
"\n----------\n\n" );
 
  530    std::vector<std::vector<wxString>> componentRows;
 
  531    std::vector<wxString>              header;
 
  532    header.push_back( wxString() );
 
  533    header.push_back( 
_( 
"Front Side" ) );
 
  534    header.push_back( 
_( 
"Back Side" ) );
 
  535    header.push_back( 
_( 
"Total" ) );
 
  536    componentRows.push_back( std::move( header ) );
 
  543        std::vector<wxString> row;
 
  544        row.push_back( fpEntry.
title );
 
  548        componentRows.push_back( std::move( row ) );
 
  554    std::vector<wxString> totalRow;
 
  555    totalRow.push_back( 
_( 
"Total:" ) );
 
  558    totalRow.push_back( 
formatCount( frontTotal + backTotal ) );
 
  559    componentRows.push_back( std::move( totalRow ) );
 
  563    report << wxS( 
"\n" );
 
  564    report << 
_( 
"Drill holes" ) << wxS( 
"\n-----------\n\n" );
 
  566    std::vector<std::vector<wxString>> drillRows;
 
  567    std::vector<wxString>              drillHeader;
 
  568    drillHeader.push_back( 
_( 
"Count" ) );
 
  569    drillHeader.push_back( 
_( 
"Shape" ) );
 
  570    drillHeader.push_back( 
_( 
"X Size" ) );
 
  571    drillHeader.push_back( 
_( 
"Y Size" ) );
 
  572    drillHeader.push_back( 
_( 
"Plated" ) );
 
  573    drillHeader.push_back( 
_( 
"Via/Pad" ) );
 
  574    drillHeader.push_back( 
_( 
"Start Layer" ) );
 
  575    drillHeader.push_back( 
_( 
"Stop Layer" ) );
 
  576    drillRows.push_back( std::move( drillHeader ) );
 
  582        switch( drill.
shape )
 
  586        default: shapeStr = 
_( 
"???" ); 
break;
 
  589        wxString platedStr = drill.
isPlated ? 
_( 
"PTH" ) : 
_( 
"NPTH" );
 
  590        wxString itemStr = drill.
isPad ? 
_( 
"Pad" ) : 
_( 
"Via" );
 
  592        wxString startLayerStr;
 
  593        wxString stopLayerStr;
 
  596            startLayerStr = 
_( 
"N/A" );
 
  600            startLayerStr = 
_( 
"N/A" );
 
  603            stopLayerStr = 
_( 
"N/A" );
 
  607            stopLayerStr = 
_( 
"N/A" );
 
  609        std::vector<wxString> row;
 
  611        row.push_back( shapeStr );
 
  614        row.push_back( platedStr );
 
  615        row.push_back( itemStr );
 
  616        row.push_back( startLayerStr );
 
  617        row.push_back( stopLayerStr );
 
  618        drillRows.push_back( std::move( row ) );
 
 
  628                                    const UNITS_PROVIDER& aUnitsProvider, 
const wxString& aProjectName,
 
  629                                    const wxString& aBoardName )
 
  631    nlohmann::ordered_json root;
 
  633    nlohmann::ordered_json metadata;
 
  636    metadata[
"project"] = aProjectName;
 
  637    metadata[
"board_name"] = aBoardName;
 
  638    root[
"metadata"] = metadata;
 
  640    nlohmann::ordered_json board;
 
  651        board[
"width"] = nlohmann::json();
 
  652        board[
"height"] = nlohmann::json();
 
  653        board[
"area"] = nlohmann::json();
 
  656    board[
"front_copper_area"] =
 
  663    root[
"board"] = board;
 
  668            []( 
const wxString& title, 
bool removeSuffix ) -> wxString
 
  670                wxString 
json = title;
 
  675                if( 
json.EndsWith( wxS( 
":" ) ) )
 
  678                json.Replace( wxS( 
" " ), wxS( 
"_" ) );
 
  679                json.Replace( wxS( 
"-" ), wxS( 
"_" ) );
 
  681                return json.MakeLower();
 
  684    nlohmann::ordered_json pads = nlohmann::ordered_json::object();
 
  690        pads[jsonize( propEntry.
title, 
false )] = propEntry.
quantity;
 
  694    nlohmann::ordered_json vias = nlohmann::ordered_json::object();
 
  703    nlohmann::ordered_json components = nlohmann::ordered_json::object();
 
  707        nlohmann::ordered_json component;
 
  711        components[jsonize( fpEntry.
title, 
false )] = component;
 
  717    nlohmann::ordered_json totals;
 
  718    totals[
"front"] = frontTotal;
 
  719    totals[
"back"] = backTotal;
 
  720    totals[
"total"] = frontTotal + backTotal;
 
  721    components[
"total"] = totals;
 
  723    root[
"components"] = components;
 
  725    nlohmann::ordered_json drillHoles = nlohmann::ordered_json::array();
 
  729        nlohmann::ordered_json drillJson;
 
  733        switch( drill.
shape )
 
  737        default: shapeStr = 
_( 
"???" ); 
break;
 
  740        wxString sourceStr = drill.
isPad ? 
_( 
"Pad" ) : 
_( 
"Via" );
 
  741        wxString startLayerStr = 
_( 
"N/A" );
 
  742        wxString stopLayerStr = 
_( 
"N/A" );
 
  750        drillJson[
"count"] = drill.
m_Qty;
 
  751        drillJson[
"shape"] = shapeStr;
 
  754        drillJson[
"plated"] = drill.
isPlated;
 
  755        drillJson[
"source"] = sourceStr;
 
  756        drillJson[
"start_layer"] = startLayerStr;
 
  757        drillJson[
"stop_layer"] = stopLayerStr;
 
  758        drillHoles.push_back( std::move( drillJson ) );
 
  761    root[
"drill_holes"] = drillHoles;
 
  763    std::string jsonText = root.dump( 2 );
 
  764    return wxString::FromUTF8( jsonText.c_str() );
 
 
constexpr int ARC_LOW_DEF
 
void CollectDrillLineItems(BOARD *board, std::vector< DRILL_LINE_ITEM > &out)
 
static void updatePadCounts(FOOTPRINT *aFootprint, BOARD_STATISTICS_DATA &aData)
 
wxString FormatBoardStatisticsJson(const BOARD_STATISTICS_DATA &aData, BOARD *aBoard, const UNITS_PROVIDER &aUnitsProvider, const wxString &aProjectName, const wxString &aBoardName)
 
void ComputeBoardStatistics(BOARD *aBoard, const BOARD_STATISTICS_OPTIONS &aOptions, BOARD_STATISTICS_DATA &aData)
 
static wxString formatCount(int aCount)
 
wxString FormatBoardStatisticsReport(const BOARD_STATISTICS_DATA &aData, BOARD *aBoard, const UNITS_PROVIDER &aUnitsProvider, const wxString &aProjectName, const wxString &aBoardName)
 
void InitializeBoardStatisticsData(BOARD_STATISTICS_DATA &aData)
 
static void appendTable(const std::vector< std::vector< wxString > > &aRows, bool aUseFirstColAsLabel, wxString &aOut)
 
wxString GetBuildVersion()
Get the full KiCad version string.
 
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
 
virtual void TransformShapeToPolySet(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc) const
Convert the item shape to a polyset.
 
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
 
int BuildBoardThicknessFromStackup() const
 
Information pertinent to a Pcbnew printed circuit board.
 
BOARD_STACKUP GetStackupOrDefault() const
 
bool GetBoardPolygonOutlines(SHAPE_POLY_SET &aOutlines, OUTLINE_ERROR_HANDLER *aErrorHandler=nullptr, bool aAllowUseArcsInPolygons=false, bool aIncludeNPTHAsOutlines=false)
Extract the board outlines and build a closed polygon from lines, arcs and circle items on edge cut l...
 
const FOOTPRINTS & Footprints() const
 
const TRACKS & Tracks() const
 
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
 
void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction, RECURSE_MODE aMode) const override
Invoke a function on all children.
 
constexpr size_type GetWidth() const
 
constexpr size_type GetHeight() const
 
KICAD_T Type() const
Returns the type of object.
 
int Length() const
Return the length (this).
 
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
 
double Area(bool aAbsolute=true) const
Return the area of this chain.
 
Represent a set of closed polygons.
 
double Area()
Return the area of this poly set.
 
int HoleCount(int aOutline) const
Returns the number of holes in a given outline.
 
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
 
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Return the reference to aHole-th hole in the aIndex-th outline.
 
int OutlineCount() const
Return the number of outlines in the set.
 
void BooleanSubtract(const SHAPE_POLY_SET &b)
Perform boolean polyset difference.
 
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
 
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
 
void TransformCircleToPolygon(SHAPE_LINE_CHAIN &aBuffer, const VECTOR2I &aCenter, int aRadius, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a circle to a polygon, using multiple straight lines.
 
Some functions to handle hotkeys in KiCad.
 
PCB_LAYER_ID
A quick note on layer IDs:
 
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
 
@ SMD
Smd pad, appears on the solder paste layer (default)
 
@ PTH
Plated through hole pad.
 
@ CONN
Like smd, does not appear on the solder paste layer (default) Note: also has a special attribute in G...
 
@ PRESSFIT
a PTH with a hole diameter with tight tolerances for press fit pin
 
@ CASTELLATED
a pad with a castellated through hole
 
bool collide(T aObject, U aAnotherObject, int aLayer, int aMinDistance)
Used by SHAPE_INDEX to implement Query().
 
wxString GetISO8601CurrentDateTime()
 
int minClearanceTrackToTrack
 
std::vector< BOARD_STATISTICS_INFO_ENTRY< PAD_ATTRIB > > padEntries
 
std::vector< BOARD_STATISTICS_FP_ENTRY > footprintEntries
 
std::vector< BOARD_STATISTICS_INFO_ENTRY< VIATYPE > > viaEntries
 
std::vector< BOARD_STATISTICS_INFO_ENTRY< PAD_PROP > > padPropertyEntries
 
std::vector< DRILL_LINE_ITEM > drillEntries
 
bool subtractHolesFromCopperAreas
 
bool subtractHolesFromBoardArea
 
bool excludeFootprintsWithoutPads
 
@ PCB_GENERATOR_T
class PCB_GENERATOR, generator on a layer
 
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
 
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
 
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
 
@ PCB_PAD_T
class PAD, a pad in a footprint
 
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
 
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
 
VECTOR2< int32_t > VECTOR2I