ADDED: Run PCB DRC via cli
This commit is contained in:
parent
e2cc35db65
commit
812143ac69
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" ) )
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -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() );
|
||||
|
|
|
@ -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() {}
|
||||
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
|
|
Loading…
Reference in New Issue