ADDED: Run PCB DRC via cli

This commit is contained in:
Marek Roszko 2023-08-09 19:38:43 -04:00
parent e2cc35db65
commit 812143ac69
18 changed files with 514 additions and 100 deletions

View File

@ -37,7 +37,7 @@ public:
m_excellonCombinePTHNPTH( true ),
m_excellonOvalDrillRoute( false ),
m_format( DRILL_FORMAT::EXCELLON ),
m_drillOrigin( DRILL_ORIGIN::ABSOLUTE ),
m_drillOrigin( DRILL_ORIGIN::ABS ),
m_drillUnits( DRILL_UNITS::INCHES ),
m_zeroFormat( ZEROS_FORMAT::DECIMAL ),
m_mapFormat( MAP_FORMAT::PDF ),
@ -64,7 +64,7 @@ public:
enum class DRILL_ORIGIN
{
ABSOLUTE,
ABS,
PLOT
};

70
common/jobs/job_pcb_drc.h Normal file
View File

@ -0,0 +1,70 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-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 JOB_PCB_DRC_H
#define JOB_PCB_DRC_H
#include <layer_ids.h>
#include <wx/string.h>
#include <widgets/report_severity.h>
#include "job.h"
class JOB_PCB_DRC : public JOB
{
public:
JOB_PCB_DRC( bool aIsCli ) :
JOB( "drc", aIsCli ),
m_filename(),
m_reportAllTrackErrors( false ),
m_units( JOB_PCB_DRC::UNITS::MILLIMETERS ),
m_severity( RPT_SEVERITY_ERROR | RPT_SEVERITY_WARNING ),
m_format( OUTPUT_FORMAT::REPORT ),
m_exitCodeViolations( false )
{
}
wxString m_filename;
wxString m_outputFile;
bool m_reportAllTrackErrors;
enum class UNITS
{
INCHES,
MILLIMETERS,
MILS
};
UNITS m_units;
int m_severity;
enum class OUTPUT_FORMAT
{
REPORT,
JSON
};
OUTPUT_FORMAT m_format;
bool m_exitCodeViolations;
};
#endif

View File

@ -26,12 +26,13 @@ namespace CLI
namespace EXIT_CODES
{
static const int AVOID_CLOSING = -1;
static const int SUCCESS = 0;
static const int SUCCESS = 0;
static const int OK = 0;
static const int ERR_ARGS = 1;
static const int ERR_UNKNOWN = 2;
static const int ERR_ARGS = 1;
static const int ERR_UNKNOWN = 2;
static const int ERR_INVALID_INPUT_FILE = 3;
static const int ERR_INVALID_OUTPUT_CONFLICT = 4;
static const int ERR_DRC_VIOLATIONS = 5;
};
}

View File

@ -36,6 +36,7 @@ set( KICAD_SRCS
set( KICAD_CLI_SRCS
cli/command.cpp
cli/command_export_pcb_base.cpp
cli/command_pcb_drc.cpp
cli/command_export_pcb_drill.cpp
cli/command_export_pcb_dxf.cpp
cli/command_export_pcb_gerber.cpp

View File

@ -192,7 +192,7 @@ int CLI::EXPORT_PCB_DRILL_COMMAND::doPerform( KIWAY& aKiway )
if( origin == wxS( "absolute" ) )
{
drillJob->m_drillOrigin = JOB_EXPORT_PCB_DRILL::DRILL_ORIGIN::ABSOLUTE;
drillJob->m_drillOrigin = JOB_EXPORT_PCB_DRILL::DRILL_ORIGIN::ABS;
}
else if( origin == wxS( "plot" ) )
{

View File

@ -0,0 +1,152 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-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 "command_pcb_drc.h"
#include <cli/exit_codes.h>
#include "jobs/job_pcb_drc.h"
#include <kiface_base.h>
#include <layer_ids.h>
#include <wx/crt.h>
#include <macros.h>
#include <wx/tokenzr.h>
#define ARG_FORMAT "--format"
#define ARG_ALL_TRACK_ERRORS "--all-track-errors"
#define ARG_UNITS "--units"
#define ARG_SEVERITY_ALL "--severity-all"
#define ARG_SEVERITY_ERROR "--severity-error"
#define ARG_SEVERITY_WARNING "--severity-warning"
#define ARG_SEVERITY_EXCLUSIONS "--severity-exclusions"
#define ARG_EXIT_CODE_VIOLATIONS "--exit-code-violations"
CLI::PCB_DRC_COMMAND::PCB_DRC_COMMAND() : EXPORT_PCB_BASE_COMMAND( "drc" )
{
m_argParser.add_argument( ARG_FORMAT )
.default_value( std::string( "report" ) )
.help( UTF8STDSTR( _( "Output file format, options: report" ) ) );
m_argParser.add_argument( ARG_ALL_TRACK_ERRORS )
.help( UTF8STDSTR( _( "Report all errors for each track" ) ) )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( ARG_UNITS )
.default_value( std::string( "mm" ) )
.help( UTF8STDSTR(
_( "Report units; valid options: in, mm, mils" ) ) );
m_argParser.add_argument( ARG_SEVERITY_ALL )
.help( UTF8STDSTR( _( "Report all DRC violations, this is equivalent to including all the other severity arguments" ) ) )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( ARG_SEVERITY_ERROR )
.help( UTF8STDSTR( _( "Report all DRC error level violations, this can be combined with the other severity arguments" ) ) )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( ARG_SEVERITY_WARNING )
.help( UTF8STDSTR( _( "Report all DRC warning level violations, this can be combined with the other severity arguments" ) ) )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( ARG_SEVERITY_EXCLUSIONS )
.help( UTF8STDSTR( _( "Report all excluded DRC violations, this can be combined with the other severity arguments" ) ) )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( ARG_EXIT_CODE_VIOLATIONS )
.help( UTF8STDSTR( _( "Return a exit code depending on whether or not violations exist" ) ) )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( "-o", ARG_OUTPUT )
.default_value( std::string() )
.help( UTF8STDSTR( _( "Output file name" ) ) );
}
int CLI::PCB_DRC_COMMAND::doPerform( KIWAY& aKiway )
{
std::unique_ptr<JOB_PCB_DRC> drcJob( new JOB_PCB_DRC( true ) );
drcJob->m_outputFile = FROM_UTF8( m_argParser.get<std::string>( ARG_OUTPUT ).c_str() );
drcJob->m_filename = FROM_UTF8( m_argParser.get<std::string>( ARG_INPUT ).c_str() );
drcJob->m_reportAllTrackErrors = m_argParser.get<bool>( ARG_ALL_TRACK_ERRORS );
drcJob->m_exitCodeViolations = m_argParser.get<bool>( ARG_EXIT_CODE_VIOLATIONS );
if( m_argParser.get<bool>( ARG_SEVERITY_ALL ) )
{
drcJob->m_severity = RPT_SEVERITY_ERROR | RPT_SEVERITY_WARNING | RPT_SEVERITY_EXCLUSION;
}
if( m_argParser.get<bool>( ARG_SEVERITY_ERROR ) )
{
drcJob->m_severity |= RPT_SEVERITY_ERROR;
}
if( m_argParser.get<bool>( ARG_SEVERITY_WARNING ) )
{
drcJob->m_severity |= RPT_SEVERITY_WARNING;
}
if( m_argParser.get<bool>( ARG_SEVERITY_EXCLUSIONS ) )
{
drcJob->m_severity |= RPT_SEVERITY_EXCLUSION;
}
drcJob->m_reportAllTrackErrors = m_argParser.get<bool>( ARG_ALL_TRACK_ERRORS );
wxString units = FROM_UTF8( m_argParser.get<std::string>( ARG_UNITS ).c_str() );
if( units == wxS( "mm" ) )
{
drcJob->m_units = JOB_PCB_DRC::UNITS::MILLIMETERS;
}
else if( units == wxS( "in" ) )
{
drcJob->m_units = JOB_PCB_DRC::UNITS::INCHES;
}
else if( units == wxS( "mils" ) )
{
drcJob->m_units = JOB_PCB_DRC::UNITS::MILS;
}
else if( !units.IsEmpty() )
{
wxFprintf( stderr, _( "Invalid units specified\n" ) );
return EXIT_CODES::ERR_ARGS;
}
wxString format = FROM_UTF8( m_argParser.get<std::string>( ARG_FORMAT ).c_str() );
if( format == "report" )
{
drcJob->m_format = JOB_PCB_DRC::OUTPUT_FORMAT::REPORT;
}
else
{
wxFprintf( stderr, _( "Invalid report format\n" ) );
return EXIT_CODES::ERR_ARGS;
}
int exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, drcJob.get() );
return exitCode;
}

View File

@ -0,0 +1,38 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 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 COMMAND_EXPORT_PCB_DRC_H
#define COMMAND_EXPORT_PCB_DRC_H
#include "command_export_pcb_base.h"
namespace CLI
{
class PCB_DRC_COMMAND : public EXPORT_PCB_BASE_COMMAND
{
public:
PCB_DRC_COMMAND();
protected:
int doPerform( KIWAY& aKiway ) override;
};
} // namespace CLI
#endif

View File

@ -48,6 +48,7 @@
#include "cli/command_pcb.h"
#include "cli/command_pcb_export.h"
#include "cli/command_pcb_drc.h"
#include "cli/command_export_pcb_drill.h"
#include "cli/command_export_pcb_dxf.h"
#include "cli/command_export_pcb_gerber.h"
@ -124,7 +125,7 @@ struct COMMAND_ENTRY
handler( aHandler ), subCommands( aSub ){};
};
static CLI::PCB_DRC_COMMAND pcbDrcCmd{};
static CLI::EXPORT_PCB_DRILL_COMMAND exportPcbDrillCmd{};
static CLI::EXPORT_PCB_DXF_COMMAND exportPcbDxfCmd{};
static CLI::EXPORT_PCB_STEP_COMMAND exportPcbStepCmd{};
@ -186,6 +187,9 @@ static std::vector<COMMAND_ENTRY> commandStack = {
&exportPcbStepCmd,
&exportPcbSvgCmd
}
},
{
&pcbDrcCmd
}
}
},

View File

@ -58,6 +58,14 @@ BOARD_COMMIT::BOARD_COMMIT( EDA_DRAW_FRAME* aFrame ) :
}
BOARD_COMMIT::BOARD_COMMIT( TOOL_MANAGER* aMgr ) :
m_toolMgr( aMgr ),
m_isBoardEditor( false )
{
}
BOARD* BOARD_COMMIT::GetBoard() const
{
return static_cast<BOARD*>( m_toolMgr->GetModel() );

View File

@ -47,7 +47,8 @@ class BOARD_COMMIT : public COMMIT
{
public:
BOARD_COMMIT( EDA_DRAW_FRAME* aFrame );
BOARD_COMMIT( TOOL_BASE *aTool );
BOARD_COMMIT( TOOL_BASE* aTool );
BOARD_COMMIT( TOOL_MANAGER* aMgr );
virtual ~BOARD_COMMIT() {}

View File

@ -869,7 +869,7 @@ void DIALOG_DRC::OnSaveReport( wxCommandEvent& aEvent )
fn.MakeAbsolute( prj_path );
}
if( writeReport( fn.GetFullPath() ) )
if( DRC_TOOL::WriteReport( fn.GetFullPath(), m_frame->GetBoard(), GetUserUnits(), m_markersProvider, m_ratsnestProvider, m_fpWarningsProvider ) )
{
m_messages->Report( wxString::Format( _( "Report file '%s' created<br>" ),
fn.GetFullPath() ) );
@ -1024,74 +1024,6 @@ void DIALOG_DRC::deleteAllMarkers( bool aIncludeExclusions )
}
bool DIALOG_DRC::writeReport( const wxString& aFullFileName )
{
FILE* fp = wxFopen( aFullFileName, wxT( "w" ) );
if( fp == nullptr )
return false;
std::map<KIID, EDA_ITEM*> itemMap;
m_frame->GetBoard()->FillItemMap( itemMap );
BOARD_DESIGN_SETTINGS& bds = m_frame->GetBoard()->GetDesignSettings();
UNITS_PROVIDER unitsProvider( pcbIUScale, GetUserUnits() );
int count;
fprintf( fp, "** Drc report for %s **\n", TO_UTF8( m_frame->GetBoard()->GetFileName() ) );
wxDateTime now = wxDateTime::Now();
fprintf( fp, "** Created on %s **\n", TO_UTF8( now.Format( wxT( "%F %T" ) ) ) );
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;
}
void DIALOG_DRC::OnDeleteOneClick( wxCommandEvent& aEvent )
{
if( m_Notebook->GetSelection() == 0 )

View File

@ -72,14 +72,6 @@ public:
void ExcludeMarker();
private:
/**
* Function writeReport
* outputs the MARKER items with commentary to an open text file.
* @param aFullFileName The text filename to write the report to.
* @return true if OK, false on error
*/
bool writeReport( const wxString& aFullFileName );
void syncCheckboxes();
void updateDisplayedCounts();

View File

@ -26,7 +26,6 @@
#ifndef EXPORTER_STEP_H
#define EXPORTER_STEP_H
#include "step_pcb_model.h"
#include <geometry/shape_poly_set.h>
#include <gal/color4d.h>
@ -40,6 +39,7 @@ class BOARD_ITEM;
class FOOTPRINT;
class PCB_TRACK;
class FILENAME_RESOLVER;
class STEP_PCB_MODEL;
class EXPORTER_STEP_PARAMS
{

View File

@ -18,7 +18,12 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <wx/dir.h>
#include "pcbnew_jobs_handler.h"
#include <board_commit.h>
#include <board_design_settings.h>
#include <drc/drc_item.h>
#include <drawing_sheet/ds_proxy_view_item.h>
#include <jobs/job_fp_export_svg.h>
#include <jobs/job_fp_upgrade.h>
#include <jobs/job_export_pcb_gerber.h>
@ -29,26 +34,30 @@
#include <jobs/job_export_pcb_pos.h>
#include <jobs/job_export_pcb_svg.h>
#include <jobs/job_export_pcb_step.h>
#include <jobs/job_pcb_drc.h>
#include <cli/exit_codes.h>
#include <exporters/place_file_exporter.h>
#include <exporters/step/exporter_step.h>
#include <plotters/plotter_dxf.h>
#include <plotters/plotter_gerber.h>
#include <plotters/plotters_pslike.h>
#include <exporters/place_file_exporter.h>
#include <exporters/step/exporter_step.h>
#include <tool/tool_manager.h>
#include <tools/drc_tool.h>
#include <gerber_jobfile_writer.h>
#include "gerber_placefile_writer.h"
#include <pgm_base.h>
#include <pcbplot.h>
#include <board_design_settings.h>
#include <pad.h>
#include <pcbnew_settings.h>
#include <wx/dir.h>
#include <pcb_plot_svg.h>
#include <gendrill_Excellon_writer.h>
#include <gendrill_gerber_writer.h>
#include <wildcards_and_files_ext.h>
#include <kiface_base.h>
#include <macros.h>
#include <pad.h>
#include <pcb_marker.h>
#include <pcb_plot_svg.h>
#include <pcbnew_settings.h>
#include <pcbplot.h>
#include <pgm_base.h>
#include <plugins/kicad/pcb_plugin.h>
#include <gerber_jobfile_writer.h>
#include <reporter.h>
#include <wildcards_and_files_ext.h>
#include "pcbnew_scripting_helpers.h"
@ -71,6 +80,8 @@ PCBNEW_JOBS_HANDLER::PCBNEW_JOBS_HANDLER()
std::bind( &PCBNEW_JOBS_HANDLER::JobExportFpUpgrade, this, std::placeholders::_1 ) );
Register( "fpsvg",
std::bind( &PCBNEW_JOBS_HANDLER::JobExportFpSvg, this, std::placeholders::_1 ) );
Register( "drc",
std::bind( &PCBNEW_JOBS_HANDLER::JobExportDrc, this, std::placeholders::_1 ) );
}
@ -481,7 +492,7 @@ int PCBNEW_JOBS_HANDLER::JobExportDrill( JOB* aJob )
VECTOR2I offset;
if( aDrillJob->m_drillOrigin == JOB_EXPORT_PCB_DRILL::DRILL_ORIGIN::ABSOLUTE )
if( aDrillJob->m_drillOrigin == JOB_EXPORT_PCB_DRILL::DRILL_ORIGIN::ABS )
offset = VECTOR2I( 0, 0 );
else
offset = brd->GetDesignSettings().GetAuxOrigin();
@ -838,3 +849,119 @@ int PCBNEW_JOBS_HANDLER::doFpExportSvg( JOB_FP_EXPORT_SVG* aSvgJob, const FOOTPR
return CLI::EXIT_CODES::OK;
}
int PCBNEW_JOBS_HANDLER::JobExportDrc( JOB* aJob )
{
JOB_PCB_DRC* drcJob = dynamic_cast<JOB_PCB_DRC*>( aJob );
if( drcJob == nullptr )
return CLI::EXIT_CODES::ERR_UNKNOWN;
if( aJob->IsCli() )
m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
BOARD* brd = LoadBoard( drcJob->m_filename );
if( drcJob->m_outputFile.IsEmpty() )
{
wxFileName fn = brd->GetFileName();
fn.SetName( fn.GetName() );
fn.SetExt( ReportFileExtension );
drcJob->m_outputFile = fn.GetFullName();
}
EDA_UNITS units;
switch( drcJob->m_units )
{
case JOB_PCB_DRC::UNITS::INCHES:
units = EDA_UNITS::INCHES;
break;
case JOB_PCB_DRC::UNITS::MILS:
units = EDA_UNITS::MILS;
break;
case JOB_PCB_DRC::UNITS::MILLIMETERS:
default:
units = EDA_UNITS::MILLIMETRES; break;
}
std::shared_ptr<DRC_ENGINE> drcEngine = brd->GetDesignSettings().m_DRCEngine;
drcEngine->SetDrawingSheet( getDrawingSheetProxyView( brd ) );
// BOARD_COMMIT uses TOOL_MANAGER to grab the board internally so we must give it one
TOOL_MANAGER* toolManager = new TOOL_MANAGER;
toolManager->SetEnvironment( brd, nullptr, nullptr, Kiface().KifaceSettings(), nullptr );
BOARD_COMMIT commit( toolManager );
m_reporter->Report( _( "Running DRC...\n" ), RPT_SEVERITY_INFO );
drcEngine->SetProgressReporter( nullptr );
drcEngine->SetViolationHandler(
[&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, int aLayer )
{
PCB_MARKER* marker = new PCB_MARKER( aItem, aPos, aLayer );
commit.Add( marker );
} );
drcEngine->RunTests( units, drcJob->m_reportAllTrackErrors, false );
commit.Push( _( "DRC" ), SKIP_UNDO | SKIP_SET_DIRTY );
std::shared_ptr<DRC_ITEMS_PROVIDER> markersProvider = std::make_shared<DRC_ITEMS_PROVIDER>(
brd, MARKER_BASE::MARKER_DRC, MARKER_BASE::MARKER_DRAWING_SHEET );
std::shared_ptr<DRC_ITEMS_PROVIDER> ratsnestProvider =
std::make_shared<DRC_ITEMS_PROVIDER>( brd, MARKER_BASE::MARKER_RATSNEST );
std::shared_ptr<DRC_ITEMS_PROVIDER> fpWarningsProvider =
std::make_shared<DRC_ITEMS_PROVIDER>( brd, MARKER_BASE::MARKER_PARITY );
markersProvider->SetSeverities( drcJob->m_severity );
ratsnestProvider->SetSeverities( drcJob->m_severity );
fpWarningsProvider->SetSeverities( drcJob->m_severity );
bool wroteReport = DRC_TOOL::WriteReport( drcJob->m_outputFile, brd, units, markersProvider,
ratsnestProvider, fpWarningsProvider );
if( !wroteReport )
{
m_reporter->Report( wxString::Format( _( "Unable to save DRC report to %s\n" ), drcJob->m_outputFile ),
RPT_SEVERITY_INFO );
return CLI::EXIT_CODES::ERR_INVALID_OUTPUT_CONFLICT;
}
m_reporter->Report( wxString::Format( _( "Saved DRC Report to %s\n" ), drcJob->m_outputFile ),
RPT_SEVERITY_INFO );
if( drcJob->m_exitCodeViolations )
{
if( markersProvider->GetCount() > 0 || ratsnestProvider->GetCount() > 0
|| fpWarningsProvider->GetCount() > 0 )
{
return CLI::EXIT_CODES::ERR_DRC_VIOLATIONS;
}
}
return CLI::EXIT_CODES::SUCCESS;
}
DS_PROXY_VIEW_ITEM* PCBNEW_JOBS_HANDLER::getDrawingSheetProxyView( BOARD* aBrd )
{
DS_PROXY_VIEW_ITEM* drawingSheet = new DS_PROXY_VIEW_ITEM( pcbIUScale,
&aBrd->GetPageSettings(),
aBrd->GetProject(),
&aBrd->GetTitleBlock(),
&aBrd->GetProperties() );
drawingSheet->SetSheetName( std::string() );
drawingSheet->SetSheetPath( std::string() );
drawingSheet->SetIsFirstPage( true );
if( BOARD* board = GetBoard() )
drawingSheet->SetFileName( TO_UTF8( board->GetFileName() ) );
return drawingSheet;
}

View File

@ -24,9 +24,11 @@
#include <jobs/job_dispatcher.h>
#include <pcb_plot_params.h>
class BOARD;
class DS_PROXY_VIEW_ITEM;
class FOOTPRINT;
class JOB_EXPORT_PCB_GERBER;
class JOB_FP_EXPORT_SVG;
class FOOTPRINT;
class PCBNEW_JOBS_HANDLER : public JOB_DISPATCHER
{
@ -42,11 +44,14 @@ public:
int JobExportPos( JOB* aJob );
int JobExportFpUpgrade( JOB* aJob );
int JobExportFpSvg( JOB* aJob );
int JobExportDrc( JOB* aJob );
private:
void populateGerberPlotOptionsFromJob( PCB_PLOT_PARAMS& aPlotOpts,
JOB_EXPORT_PCB_GERBER* aJob );
int doFpExportSvg( JOB_FP_EXPORT_SVG* aSvgJob, const FOOTPRINT* aFootprint );
DS_PROXY_VIEW_ITEM* getDrawingSheetProxyView( BOARD* aBrd );
};
#endif

View File

@ -36,6 +36,7 @@
#include <drc/drc_engine.h>
#include <drc/drc_item.h>
#include <netlist_reader/pcb_netlist.h>
#include <macros.h>
DRC_TOOL::DRC_TOOL() :
PCB_TOOL_BASE( "pcbnew.DRCTool" ),
@ -296,3 +297,74 @@ void DRC_TOOL::setTransitions()
}
bool DRC_TOOL::WriteReport( const wxString& aFullFileName,
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 )
{
FILE* fp = wxFopen( aFullFileName, wxT( "w" ) );
if( fp == nullptr )
return false;
std::map<KIID, EDA_ITEM*> itemMap;
aBoard->FillItemMap( itemMap );
BOARD_DESIGN_SETTINGS& bds = aBoard->GetDesignSettings();
UNITS_PROVIDER unitsProvider( pcbIUScale, aReportUnits );
int count;
fprintf( fp, "** Drc report for %s **\n", TO_UTF8( aBoard->GetFileName() ) );
wxDateTime now = wxDateTime::Now();
fprintf( fp, "** Created on %s **\n", TO_UTF8( now.Format( wxT( "%F %T" ) ) ) );
count = aMarkersProvider->GetCount();
fprintf( fp, "\n** Found %d DRC violations **\n", count );
for( int i = 0; i < count; ++i )
{
const std::shared_ptr<RC_ITEM>& item = aMarkersProvider->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 = aRatsnestProvider->GetCount();
fprintf( fp, "\n** Found %d unconnected pads **\n", count );
for( int i = 0; i < count; ++i )
{
const std::shared_ptr<RC_ITEM>& item = aRatsnestProvider->GetItem( i );
SEVERITY severity = bds.GetSeverity( item->GetErrorCode() );
fprintf( fp, "%s", TO_UTF8( item->ShowReport( &unitsProvider, severity, itemMap ) ) );
}
count = aFpWarningsProvider->GetCount();
fprintf( fp, "\n** Found %d Footprint errors **\n", count );
for( int i = 0; i < count; ++i )
{
const std::shared_ptr<RC_ITEM>& item = aFpWarningsProvider->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;
}

View File

@ -95,6 +95,17 @@ public:
int ExcludeMarker( const TOOL_EVENT& aEvent );
/**
* Function writeReport
* outputs the MARKER items with commentary to an open text file.
* @param aFullFileName The text filename to write the report to.
* @return true if OK, false on error
*/
static bool WriteReport( const wxString& aFullFileName, 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 );
private:
///< Set up handlers for various events.
void setTransitions() override;

View File

@ -846,7 +846,7 @@ wxString ZONE::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
}
else if( layers.size() > 3 )
{
layerDesc.Printf( _( "on %s, %s and %d more" ),
layerDesc.Printf( _( "on %s, %s and %zu more" ),
GetBoard()->GetLayerName( layers[0] ),
GetBoard()->GetLayerName( layers[1] ),
layers.size() - 2 );