15 changed files with 599 additions and 102 deletions
-
4common/notifications_manager.cpp
-
80common/rc_item.cpp
-
1common/wildcards_and_files_ext.cpp
-
22include/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
-
26pcbnew/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