15 changed files with 599 additions and 102 deletions
-
4common/notifications_manager.cpp
-
80common/rc_item.cpp
-
1common/wildcards_and_files_ext.cpp
-
18include/rc_item.h
-
103include/rc_json_schema.h
-
1include/wildcards_and_files_ext.h
-
6kicad/cli/command_pcb_drc.cpp
-
1pcbnew/CMakeLists.txt
-
6pcbnew/dialogs/dialog_drc.cpp
-
172pcbnew/drc/drc_report.cpp
-
51pcbnew/drc/drc_report.h
-
24pcbnew/pcbnew_jobs_handler.cpp
-
73pcbnew/tools/drc_tool.cpp
-
11pcbnew/tools/drc_tool.h
-
144resources/schemas/drc.v1.json
@ -0,0 +1,103 @@ |
|||||
|
/* |
||||
|
* This program source code file is part of KiCad, a free EDA CAD application. |
||||
|
* |
||||
|
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors. |
||||
|
* |
||||
|
* This program is free software: you can redistribute it and/or modify it |
||||
|
* under the terms of the GNU General Public License as published by the |
||||
|
* Free Software Foundation, either version 3 of the License, or (at your |
||||
|
* option) any later version. |
||||
|
* |
||||
|
* This program is distributed in the hope that it will be useful, but |
||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
|
* General Public License for more details. |
||||
|
* |
||||
|
* You should have received a copy of the GNU General Public License along |
||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
*/ |
||||
|
|
||||
|
#ifndef RC_JSON_SCHEMA_H |
||||
|
#define RC_JSON_SCHEMA_H |
||||
|
|
||||
|
#include <nlohmann/json.hpp> |
||||
|
#include <wx/string.h> |
||||
|
#include <vector> |
||||
|
|
||||
|
/** |
||||
|
* Contains the json serialization structs for DRC and ERC reports |
||||
|
* If you are trying to change the output schema |
||||
|
* Please update the schemas located in /resources/schemas/ as both documentation |
||||
|
* and use by end user implementations |
||||
|
*/ |
||||
|
namespace RC_JSON |
||||
|
{ |
||||
|
struct COORDINATE |
||||
|
{ |
||||
|
double x; |
||||
|
double y; |
||||
|
}; |
||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE( COORDINATE, x, y ) |
||||
|
|
||||
|
struct AFFECTED_ITEM |
||||
|
{ |
||||
|
wxString uuid; |
||||
|
wxString description; |
||||
|
COORDINATE pos; |
||||
|
}; |
||||
|
|
||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE( AFFECTED_ITEM, uuid, description, pos ) |
||||
|
|
||||
|
struct VIOLATION |
||||
|
{ |
||||
|
wxString type; |
||||
|
wxString description; |
||||
|
wxString severity; |
||||
|
std::vector<AFFECTED_ITEM> items; |
||||
|
}; |
||||
|
|
||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE( VIOLATION, type, description, severity, items ) |
||||
|
|
||||
|
struct REPORT_BASE |
||||
|
{ |
||||
|
wxString source; |
||||
|
wxString date; |
||||
|
wxString kicad_version; |
||||
|
wxString type; |
||||
|
wxString coordinate_units; |
||||
|
}; |
||||
|
|
||||
|
struct DRC_REPORT : REPORT_BASE |
||||
|
{ |
||||
|
DRC_REPORT() { type = wxS( "drc" ); } |
||||
|
|
||||
|
std::vector<VIOLATION> violations; |
||||
|
std::vector<VIOLATION> unconnected_items; |
||||
|
std::vector<VIOLATION> schematic_parity; |
||||
|
}; |
||||
|
|
||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE( DRC_REPORT, source, date, kicad_version, violations, |
||||
|
unconnected_items, schematic_parity, coordinate_units ) |
||||
|
|
||||
|
struct ERC_SHEET |
||||
|
{ |
||||
|
wxString uuid; |
||||
|
wxString path; |
||||
|
std::vector<VIOLATION> violations; |
||||
|
}; |
||||
|
|
||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE( ERC_SHEET, uuid, path, violations ) |
||||
|
|
||||
|
struct ERC_REPORT : REPORT_BASE |
||||
|
{ |
||||
|
ERC_REPORT() { type = wxS( "erc" ); } |
||||
|
|
||||
|
std::vector<ERC_SHEET> sheets; |
||||
|
}; |
||||
|
|
||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE( ERC_REPORT, source, date, kicad_version, sheets, |
||||
|
coordinate_units ) |
||||
|
|
||||
|
} // namespace RC_JSON |
||||
|
|
||||
|
#endif |
@ -0,0 +1,172 @@ |
|||||
|
/*
|
||||
|
* This program source code file is part of KiCad, a free EDA CAD application. |
||||
|
* |
||||
|
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors. |
||||
|
* |
||||
|
* This program is free software: you can redistribute it and/or modify it |
||||
|
* under the terms of the GNU General Public License as published by the |
||||
|
* Free Software Foundation, either version 3 of the License, or (at your |
||||
|
* option) any later version. |
||||
|
* |
||||
|
* This program is distributed in the hope that it will be useful, but |
||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
|
* General Public License for more details. |
||||
|
* |
||||
|
* You should have received a copy of the GNU General Public License along |
||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
|
||||
|
#include <wx/string.h>
|
||||
|
|
||||
|
#include <board.h>
|
||||
|
#include <board_design_settings.h>
|
||||
|
#include <build_version.h>
|
||||
|
#include "drc_report.h"
|
||||
|
#include <drc/drc_item.h>
|
||||
|
#include <fstream>
|
||||
|
#include <macros.h>
|
||||
|
#include <nlohmann/json.hpp>
|
||||
|
#include <rc_json_schema.h>
|
||||
|
|
||||
|
|
||||
|
DRC_REPORT::DRC_REPORT(BOARD* aBoard, EDA_UNITS aReportUnits, |
||||
|
std::shared_ptr<RC_ITEMS_PROVIDER> aMarkersProvider, |
||||
|
std::shared_ptr<RC_ITEMS_PROVIDER> aRatsnestProvider, |
||||
|
std::shared_ptr<RC_ITEMS_PROVIDER> aFpWarningsProvider) : |
||||
|
m_board( aBoard ), |
||||
|
m_reportUnits( aReportUnits ), |
||||
|
m_markersProvider( aMarkersProvider ), |
||||
|
m_ratsnestProvider( aRatsnestProvider ), |
||||
|
m_fpWarningsProvider( aFpWarningsProvider ) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
bool DRC_REPORT::WriteTextReport( const wxString& aFullFileName ) |
||||
|
{ |
||||
|
FILE* fp = wxFopen( aFullFileName, wxT( "w" ) ); |
||||
|
|
||||
|
if( fp == nullptr ) |
||||
|
return false; |
||||
|
|
||||
|
std::map<KIID, EDA_ITEM*> itemMap; |
||||
|
m_board->FillItemMap( itemMap ); |
||||
|
|
||||
|
UNITS_PROVIDER unitsProvider( pcbIUScale, m_reportUnits ); |
||||
|
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); |
||||
|
int count; |
||||
|
|
||||
|
fprintf( fp, "** Drc report for %s **\n", TO_UTF8( m_board->GetFileName() ) ); |
||||
|
|
||||
|
fprintf( fp, "** Created on %s **\n", TO_UTF8( GetISO8601CurrentDateTime() ) ); |
||||
|
|
||||
|
count = m_markersProvider->GetCount(); |
||||
|
|
||||
|
fprintf( fp, "\n** Found %d DRC violations **\n", count ); |
||||
|
|
||||
|
for( int i = 0; i < count; ++i ) |
||||
|
{ |
||||
|
const std::shared_ptr<RC_ITEM>& item = m_markersProvider->GetItem( i ); |
||||
|
SEVERITY severity = item->GetParent()->GetSeverity(); |
||||
|
|
||||
|
if( severity == RPT_SEVERITY_EXCLUSION ) |
||||
|
severity = bds.GetSeverity( item->GetErrorCode() ); |
||||
|
|
||||
|
fprintf( fp, "%s", TO_UTF8( item->ShowReport( &unitsProvider, severity, itemMap ) ) ); |
||||
|
} |
||||
|
|
||||
|
count = m_ratsnestProvider->GetCount(); |
||||
|
|
||||
|
fprintf( fp, "\n** Found %d unconnected pads **\n", count ); |
||||
|
|
||||
|
for( int i = 0; i < count; ++i ) |
||||
|
{ |
||||
|
const std::shared_ptr<RC_ITEM>& item = m_ratsnestProvider->GetItem( i ); |
||||
|
SEVERITY severity = bds.GetSeverity( item->GetErrorCode() ); |
||||
|
|
||||
|
fprintf( fp, "%s", TO_UTF8( item->ShowReport( &unitsProvider, severity, itemMap ) ) ); |
||||
|
} |
||||
|
|
||||
|
count = m_fpWarningsProvider->GetCount(); |
||||
|
|
||||
|
fprintf( fp, "\n** Found %d Footprint errors **\n", count ); |
||||
|
|
||||
|
for( int i = 0; i < count; ++i ) |
||||
|
{ |
||||
|
const std::shared_ptr<RC_ITEM>& item = m_fpWarningsProvider->GetItem( i ); |
||||
|
SEVERITY severity = bds.GetSeverity( item->GetErrorCode() ); |
||||
|
|
||||
|
fprintf( fp, "%s", TO_UTF8( item->ShowReport( &unitsProvider, severity, itemMap ) ) ); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
fprintf( fp, "\n** End of Report **\n" ); |
||||
|
|
||||
|
fclose( fp ); |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
bool DRC_REPORT::WriteJsonReport( const wxString& aFullFileName ) |
||||
|
{ |
||||
|
std::ofstream jsonFileStream( aFullFileName.fn_str() ); |
||||
|
|
||||
|
UNITS_PROVIDER unitsProvider( pcbIUScale, m_reportUnits ); |
||||
|
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); |
||||
|
std::map<KIID, EDA_ITEM*> itemMap; |
||||
|
m_board->FillItemMap( itemMap ); |
||||
|
|
||||
|
RC_JSON::DRC_REPORT reportHead; |
||||
|
reportHead.source = m_board->GetFileName(); |
||||
|
reportHead.date = GetISO8601CurrentDateTime(); |
||||
|
reportHead.kicad_version = GetMajorMinorPatchVersion(); |
||||
|
reportHead.coordinate_units = EDA_UNIT_UTILS::GetLabel( m_reportUnits ); |
||||
|
|
||||
|
for( int i = 0; i < m_markersProvider->GetCount(); ++i ) |
||||
|
{ |
||||
|
const std::shared_ptr<RC_ITEM>& item = m_markersProvider->GetItem( i ); |
||||
|
SEVERITY severity = item->GetParent()->GetSeverity(); |
||||
|
|
||||
|
if( severity == RPT_SEVERITY_EXCLUSION ) |
||||
|
severity = bds.GetSeverity( item->GetErrorCode() ); |
||||
|
|
||||
|
RC_JSON::VIOLATION violation; |
||||
|
item->GetJsonViolation( violation, &unitsProvider, severity, itemMap ); |
||||
|
|
||||
|
reportHead.violations.push_back( violation ); |
||||
|
} |
||||
|
|
||||
|
for( int i = 0; i < m_ratsnestProvider->GetCount(); ++i ) |
||||
|
{ |
||||
|
const std::shared_ptr<RC_ITEM>& item = m_ratsnestProvider->GetItem( i ); |
||||
|
SEVERITY severity = bds.GetSeverity( item->GetErrorCode() ); |
||||
|
|
||||
|
RC_JSON::VIOLATION violation; |
||||
|
item->GetJsonViolation( violation, &unitsProvider, severity, itemMap ); |
||||
|
|
||||
|
reportHead.unconnected_items.push_back( violation ); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
for( int i = 0; i < m_fpWarningsProvider->GetCount(); ++i ) |
||||
|
{ |
||||
|
const std::shared_ptr<RC_ITEM>& item = m_ratsnestProvider->GetItem( i ); |
||||
|
SEVERITY severity = bds.GetSeverity( item->GetErrorCode() ); |
||||
|
|
||||
|
RC_JSON::VIOLATION violation; |
||||
|
item->GetJsonViolation( violation, &unitsProvider, severity, itemMap ); |
||||
|
|
||||
|
reportHead.schematic_parity.push_back( violation ); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
nlohmann::json saveJson = nlohmann::json( reportHead ); |
||||
|
jsonFileStream << std::setw( 4 ) << saveJson << std::endl; |
||||
|
jsonFileStream.flush(); |
||||
|
jsonFileStream.close(); |
||||
|
|
||||
|
return true; |
||||
|
} |
@ -0,0 +1,51 @@ |
|||||
|
/* |
||||
|
* This program source code file is part of KiCad, a free EDA CAD application. |
||||
|
* |
||||
|
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors. |
||||
|
* |
||||
|
* This program is free software: you can redistribute it and/or modify it |
||||
|
* under the terms of the GNU General Public License as published by the |
||||
|
* Free Software Foundation, either version 3 of the License, or (at your |
||||
|
* option) any later version. |
||||
|
* |
||||
|
* This program is distributed in the hope that it will be useful, but |
||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
|
* General Public License for more details. |
||||
|
* |
||||
|
* You should have received a copy of the GNU General Public License along |
||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
*/ |
||||
|
|
||||
|
#ifndef DRC_REPORT_H |
||||
|
#define DRC_REPORT_H |
||||
|
|
||||
|
#include <memory> |
||||
|
#include <eda_units.h> |
||||
|
#include <wx/string.h> |
||||
|
|
||||
|
class BOARD; |
||||
|
class RC_ITEMS_PROVIDER; |
||||
|
|
||||
|
class DRC_REPORT |
||||
|
{ |
||||
|
public: |
||||
|
DRC_REPORT( BOARD* aBoard, |
||||
|
EDA_UNITS aReportUnits, |
||||
|
std::shared_ptr<RC_ITEMS_PROVIDER> aMarkersProvider, |
||||
|
std::shared_ptr<RC_ITEMS_PROVIDER> aRatsnestProvider, |
||||
|
std::shared_ptr<RC_ITEMS_PROVIDER> aFpWarningsProvider ); |
||||
|
|
||||
|
bool WriteTextReport( const wxString& aFullFileName ); |
||||
|
bool WriteJsonReport( const wxString& aFullFileName ); |
||||
|
|
||||
|
private: |
||||
|
BOARD* m_board; |
||||
|
EDA_UNITS m_reportUnits; |
||||
|
std::shared_ptr<RC_ITEMS_PROVIDER> m_markersProvider; |
||||
|
std::shared_ptr<RC_ITEMS_PROVIDER> m_ratsnestProvider; |
||||
|
std::shared_ptr<RC_ITEMS_PROVIDER> m_fpWarningsProvider; |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
#endif |
@ -0,0 +1,144 @@ |
|||||
|
{ |
||||
|
"$schema": "http://json-schema.org/draft-07/schema#", |
||||
|
"$id": "https://schemas.kicad.org/drc.v1.json", |
||||
|
"title": "KiCad DRC Report Schema", |
||||
|
"description": "KiCad Plugin and Content Manager repository and package metadata schema", |
||||
|
"type": "object", |
||||
|
"additionalProperties": false, |
||||
|
"properties": { |
||||
|
"source": { |
||||
|
"type": "string", |
||||
|
"description": "Source file path" |
||||
|
}, |
||||
|
"date": { |
||||
|
"type": "string", |
||||
|
"description": "Time at generation of report", |
||||
|
"format": "date-time" |
||||
|
}, |
||||
|
"kicad_version": { |
||||
|
"type": "string", |
||||
|
"description": "KiCad version used to generate the report", |
||||
|
"pattern": "^\\d{1,2}(\\.\\d{1,2}(\\.\\d{1,2})?)?$" |
||||
|
}, |
||||
|
"violations": { |
||||
|
"type": "array", |
||||
|
"items": { |
||||
|
"$ref": "#/definitions/Violation" |
||||
|
} |
||||
|
}, |
||||
|
"unconnected_items": { |
||||
|
"type": "array", |
||||
|
"items": { |
||||
|
"$ref": "#/definitions/Violation" |
||||
|
} |
||||
|
}, |
||||
|
"schematic_parity": { |
||||
|
"type": "array", |
||||
|
"items": { |
||||
|
"$ref": "#/definitions/Violation" |
||||
|
} |
||||
|
}, |
||||
|
"coordinate_units": { |
||||
|
"type": "string", |
||||
|
"description": "Units that all coordinates in this report are encoded in", |
||||
|
"enum": [ |
||||
|
"mm", |
||||
|
"mils", |
||||
|
"in" |
||||
|
] |
||||
|
} |
||||
|
}, |
||||
|
"required": [ |
||||
|
"source", |
||||
|
"date", |
||||
|
"kicad_version", |
||||
|
"violations", |
||||
|
"unconnected_items", |
||||
|
"schematic_parity", |
||||
|
"coordinate_units", |
||||
|
], |
||||
|
"definitions": { |
||||
|
"Violation": { |
||||
|
"type": "object", |
||||
|
"additionalProperties": false, |
||||
|
"properties": { |
||||
|
"type": { |
||||
|
"type": "string", |
||||
|
"description": "KiCad type name for the violation" |
||||
|
}, |
||||
|
"description": { |
||||
|
"type": "string", |
||||
|
"description": "Description of the violation" |
||||
|
}, |
||||
|
"severity": { |
||||
|
"$ref": "#/definitions/Severity" |
||||
|
}, |
||||
|
"items": { |
||||
|
"type": "array", |
||||
|
"items": { |
||||
|
"$ref": "#/definitions/AffectedItem" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"required": [ |
||||
|
"type", |
||||
|
"description", |
||||
|
"severity", |
||||
|
"items" |
||||
|
] |
||||
|
}, |
||||
|
"AffectedItem": { |
||||
|
"type": "object", |
||||
|
"additionalProperties": false, |
||||
|
"properties": { |
||||
|
"uuid": { |
||||
|
"$ref": "#/definitions/Uuid" |
||||
|
}, |
||||
|
"description": { |
||||
|
"type": "string", |
||||
|
"description": "Description of the item" |
||||
|
}, |
||||
|
"pos": { |
||||
|
"$ref": "#/definitions/Coordinate" |
||||
|
} |
||||
|
}, |
||||
|
"required": [ |
||||
|
"uuid", |
||||
|
"description", |
||||
|
"pos" |
||||
|
] |
||||
|
}, |
||||
|
"Uuid": { |
||||
|
"type": "string", |
||||
|
"description": "Unique identifier of the item", |
||||
|
"pattern": "^[0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12}$" |
||||
|
}, |
||||
|
"Severity": { |
||||
|
"type": "string", |
||||
|
"description": "Severity of the violation", |
||||
|
"enum": [ |
||||
|
"error", |
||||
|
"warning", |
||||
|
"ignore" |
||||
|
] |
||||
|
}, |
||||
|
"Coordinate": { |
||||
|
"type": "object", |
||||
|
"additionalProperties": false, |
||||
|
"properties": { |
||||
|
"x": { |
||||
|
"type": "number", |
||||
|
"description": "x coordinate" |
||||
|
}, |
||||
|
"y": { |
||||
|
"type": "number", |
||||
|
"description": "y coordinate" |
||||
|
} |
||||
|
}, |
||||
|
"required": [ |
||||
|
"x", |
||||
|
"y" |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue