mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-13 17:53:11 +02:00
Pcbnew: add layer mode/stackup checks to library parity DRC
This commit is contained in:
parent
c9476caebf
commit
262f1fdabb
@ -877,6 +877,7 @@ set( PCB_COMMON_SRCS
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/pcb_marker.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/footprint.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/fix_board_shape.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/layer_utils.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/netinfo_item.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/netinfo_list.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/pad.cpp
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include <footprint_edit_frame.h>
|
||||
#include <footprint_editor_settings.h>
|
||||
#include <grid_layer_box_helpers.h>
|
||||
#include <layer_utils.h>
|
||||
#include <kiplatform/ui.h>
|
||||
#include <panel_embedded_files.h>
|
||||
#include <panel_fp_properties_3d_model.h>
|
||||
@ -575,19 +576,6 @@ static LSET GetAllUsedFootprintLayers( const FOOTPRINT& aFootprint )
|
||||
}
|
||||
|
||||
|
||||
static wxString GetLayerStringList( const BOARD& aBoard, const LSET& layers )
|
||||
{
|
||||
std::vector<wxString> layerNames;
|
||||
|
||||
for( PCB_LAYER_ID layer : layers.UIOrder() )
|
||||
{
|
||||
layerNames.push_back( aBoard.GetLayerName( layer ) );
|
||||
}
|
||||
|
||||
return AccumulateDescriptions( layerNames );
|
||||
}
|
||||
|
||||
|
||||
bool DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::Validate()
|
||||
{
|
||||
if( !m_itemsGrid->CommitPendingChanges() )
|
||||
@ -692,7 +680,7 @@ bool DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::Validate()
|
||||
m_delayedErrorMessage =
|
||||
wxString::Format( _( "You are trying to remove layers that are used by the footprint: %s.\n"
|
||||
"Please remove the objects that use these layers first." ),
|
||||
GetLayerStringList( *m_frame->GetBoard(), usedLayers ) );
|
||||
LAYER_UTILS::AccumulateNames( usedLayers, m_frame->GetBoard() ) );
|
||||
m_delayedFocusGrid = m_customUserLayersGrid;
|
||||
m_delayedFocusColumn = 0;
|
||||
m_delayedFocusRow = 0;
|
||||
|
@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include <layer_range.h>
|
||||
#include <layer_utils.h>
|
||||
#include <kiway.h>
|
||||
#include <macros.h>
|
||||
#include <netlist_reader/pcb_netlist.h>
|
||||
@ -581,6 +582,74 @@ bool zoneNeedsUpdate( const ZONE* a, const ZONE* b, REPORTER* aReporter )
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare the stackup related settings of two footprints.
|
||||
*
|
||||
* Returns true if they differ.
|
||||
*/
|
||||
bool stackupNeedsUpdate( const FOOTPRINT& a, const FOOTPRINT& b, REPORTER* aReporter )
|
||||
{
|
||||
bool diff = false;
|
||||
|
||||
TEST( a.GetStackupMode(), b.GetStackupMode(),
|
||||
wxString::Format( _( "Footprint stackup mode differs." ) ) );
|
||||
|
||||
const LSET& aLayers = a.GetLayerSet();
|
||||
const LSET& bLayers = b.GetLayerSet();
|
||||
|
||||
TEST( aLayers, bLayers,
|
||||
wxString::Format( _( "Footprint layers differ." ) ) );
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Report board->footprint stackup differences.
|
||||
*
|
||||
* This is not necessarily a comparison failure, but may be useful information
|
||||
* for the user to see.
|
||||
*
|
||||
* @return true if there is
|
||||
*/
|
||||
bool footprintVsBoardStackup( const FOOTPRINT& aFp, const BOARD& aBoard, REPORTER* aReporter )
|
||||
{
|
||||
if( aFp.GetStackupMode() == FOOTPRINT_STACKUP::EXPAND_INNER_LAYERS )
|
||||
return false;
|
||||
|
||||
// Filter only layers that can differ between footprint and board
|
||||
const LSET& fpLayers = aFp.GetStackupLayers();
|
||||
const LSET& brdLayers = aBoard.GetEnabledLayers() & ( LSET::AllCuMask() | LSET::UserDefinedLayersMask() );
|
||||
|
||||
bool mismatch = false;
|
||||
|
||||
// Any layer in the FP and not on the board is flagged
|
||||
const LSET onlyInFp = fpLayers & ~brdLayers;
|
||||
|
||||
if( onlyInFp.count() )
|
||||
{
|
||||
mismatch = true;
|
||||
if( aReporter )
|
||||
aReporter->Report( wxString::Format( _( "Footprint has %lu layers not on board: %s" ), onlyInFp.count(),
|
||||
LAYER_UTILS::AccumulateNames( onlyInFp, &aBoard ) ) );
|
||||
}
|
||||
|
||||
// Only look at copper layers here: user layers on the board and not in the FP is normal
|
||||
const LSET cuOnlyInBoard = ( brdLayers & ~fpLayers ) & LSET::AllCuMask();
|
||||
|
||||
if( cuOnlyInBoard.count() )
|
||||
{
|
||||
mismatch = true;
|
||||
if( aReporter )
|
||||
aReporter->Report( wxString::Format( _( "Board has %lu copper layers not in footprint: %s" ),
|
||||
cuOnlyInBoard.count(),
|
||||
LAYER_UTILS::AccumulateNames( cuOnlyInBoard, &aBoard ) ) );
|
||||
}
|
||||
|
||||
return mismatch;
|
||||
}
|
||||
|
||||
|
||||
bool FOOTPRINT::FootprintNeedsUpdate( const FOOTPRINT* aLibFP, int aCompareFlags,
|
||||
REPORTER* aReporter )
|
||||
{
|
||||
@ -617,6 +686,9 @@ bool FOOTPRINT::FootprintNeedsUpdate( const FOOTPRINT* aLibFP, int aCompareFlags
|
||||
|
||||
aLibFP = temp.get();
|
||||
|
||||
// These checks don't set off errors, they're just informational
|
||||
footprintVsBoardStackup( *this, *GetBoard(), aReporter );
|
||||
|
||||
#define TEST_ATTR( a, b, attr, msg ) TEST( ( a & attr ), ( b & attr ), msg )
|
||||
|
||||
TEST_ATTR( GetAttributes(), aLibFP->GetAttributes(), (FP_THROUGH_HOLE | FP_SMD),
|
||||
@ -649,6 +721,12 @@ bool FOOTPRINT::FootprintNeedsUpdate( const FOOTPRINT* aLibFP, int aCompareFlags
|
||||
#define REPORT( msg ) { if( aReporter ) aReporter->Report( msg ); }
|
||||
#define CHECKPOINT { if( diff && !aReporter ) return diff; }
|
||||
|
||||
if( stackupNeedsUpdate( *this, *aLibFP, aReporter ) )
|
||||
{
|
||||
diff = true;
|
||||
REPORT( _( "Footprint stackup differs." ) );
|
||||
}
|
||||
|
||||
// Clearance and zone connection overrides are as likely to be set at the board level as in
|
||||
// the library.
|
||||
//
|
||||
|
40
pcbnew/layer_utils.cpp
Normal file
40
pcbnew/layer_utils.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright The KiCad Developers.
|
||||
*
|
||||
* 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 2
|
||||
* 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, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "layer_utils.h"
|
||||
|
||||
|
||||
wxString LAYER_UTILS::AccumulateNames( const LSEQ& aLayers, const BOARD* aBoard )
|
||||
{
|
||||
wxString result;
|
||||
|
||||
for( const PCB_LAYER_ID layer : aLayers )
|
||||
{
|
||||
if( !result.IsEmpty() )
|
||||
result += ", ";
|
||||
|
||||
result += aBoard ? aBoard->GetLayerName( layer ) : LayerName( layer );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
61
pcbnew/layer_utils.h
Normal file
61
pcbnew/layer_utils.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright The KiCad Developers.
|
||||
*
|
||||
* 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 2
|
||||
* 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, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wx/string.h>
|
||||
|
||||
#include <board.h>
|
||||
#include <lseq.h>
|
||||
#include <lset.h>
|
||||
|
||||
|
||||
/**
|
||||
* Utility functions for dealing with layers in the context of a PCB board.s
|
||||
*
|
||||
* This includes functions that need access to the board to get layer names,
|
||||
* and other more complex, but reusable operations that either shouldn't be in LSET/LSEQ's
|
||||
* interface or need access to Pcbnew types.
|
||||
*/
|
||||
namespace LAYER_UTILS
|
||||
{
|
||||
|
||||
/**
|
||||
* Accumulate layer names from a layer set into a comma separated string.
|
||||
*
|
||||
* @param aLayers is the list of layers to accumulate.
|
||||
* @param aBoard is the board to get layer names from, if null the default names
|
||||
* are used.
|
||||
*/
|
||||
wxString AccumulateNames( const LSEQ& aLayers, const BOARD* aBoard );
|
||||
|
||||
/**
|
||||
* Accumulate layer names from a layer set into a comma separated string,
|
||||
* in UI order.
|
||||
*/
|
||||
inline wxString AccumulateNames( const LSET& aLayers, const BOARD* aBoard )
|
||||
{
|
||||
return AccumulateNames( aLayers.UIOrder(), aBoard );
|
||||
}
|
||||
|
||||
} // namespace LAYER_UTILS
|
Loading…
x
Reference in New Issue
Block a user