mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 02:03:12 +02:00
Reorganize layer numbering
F_Cu = 0 B_Cu = 2 Remaining internal copper layers are even and incrementing Non-copper layers are odd and incrementing. This means that we can no longer do things like: for( PCB_LAYER_ID layer = F_Cu; layer <= B_Cu; ++layer) Instead, we have the class LAYER_RANGE: for( PCB_LAYER_ID layer : LAYER_RANGE( F_Cu, B_Cu) ) Similarly, gt/lt tests should not refer to the integer value of the layer. We have functions such as IsCopperLayer to test whether a layer is copper or not. When using the connectivity RTree, the third dimension is layer, so we provide B_Cu with the special INT_MAX value, ensuring that elements between F_Cu and B_Cu will be identified. There is a new, special function GetBoardLayer() for interfacing with CN_ITEMS Similarly, PNS layers remain unchanged and sequential. A set of interface functions is provided to map PNS layers to Board layers and back. This allows the PNS_LAYER_RANGE to function as expected
This commit is contained in:
parent
b99a43bec2
commit
5e0abadb23
@ -31,6 +31,7 @@
|
||||
#include <3d_rendering/raytracing/shapes2D/polygon_2d.h>
|
||||
#include <board.h>
|
||||
#include <dialogs/dialog_color_picker.h>
|
||||
#include <layer_range.h>
|
||||
#include <3d_math.h>
|
||||
#include "3d_fastmath.h"
|
||||
#include <geometry/geometry_utils.h>
|
||||
@ -434,14 +435,16 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
|
||||
// Top = Bottom - m_copperThickness
|
||||
|
||||
unsigned int layer;
|
||||
LSET copperLayers = LSET::AllCuMask();
|
||||
|
||||
for( layer = 0; layer < m_copperLayersCount; ++layer )
|
||||
for( auto layer : LAYER_RANGE( F_Cu, B_Cu, m_copperLayersCount ) )
|
||||
{
|
||||
// This approximates internal layer positions (because we're treating all the dielectric
|
||||
// layers as having the same thickness). But we don't render them anyway so it doesn't
|
||||
// really matter.
|
||||
m_layerZcoordBottom[layer] = m_boardBodyThickness3DU / 2.0f -
|
||||
(m_boardBodyThickness3DU * layer / (m_copperLayersCount - 1) );
|
||||
m_layerZcoordBottom[layer] = m_boardBodyThickness3DU / 2.0f
|
||||
- ( m_boardBodyThickness3DU * static_cast<int>( layer )
|
||||
/ ( 2 * ( m_copperLayersCount - 1 ) ) );
|
||||
|
||||
if( layer < (m_copperLayersCount / 2) )
|
||||
m_layerZcoordTop[layer] = m_layerZcoordBottom[layer] + m_frontCopperThickness3DU;
|
||||
@ -452,20 +455,13 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
|
||||
#define layerThicknessMargin 1.1
|
||||
const float zpos_offset = m_nonCopperLayerThickness3DU * layerThicknessMargin;
|
||||
|
||||
// Fill remaining unused copper layers and back layer zpos with -m_boardBodyThickness / 2.0
|
||||
for( ; layer < MAX_CU_LAYERS; layer++ )
|
||||
{
|
||||
m_layerZcoordBottom[layer] = -( m_boardBodyThickness3DU / 2.0f );
|
||||
m_layerZcoordTop[layer] = m_layerZcoordBottom[layer] - m_backCopperThickness3DU;
|
||||
}
|
||||
|
||||
// This is the top of the copper layer thickness.
|
||||
const float zpos_copperTop_back = m_layerZcoordTop[B_Cu];
|
||||
const float zpos_copperTop_front = m_layerZcoordTop[F_Cu];
|
||||
|
||||
// calculate z position for each non copper layer
|
||||
// Solder mask and Solder paste have the same Z position
|
||||
for( int layer_id = MAX_CU_LAYERS; layer_id < PCB_LAYER_ID_COUNT; ++layer_id )
|
||||
for( PCB_LAYER_ID layer_id : { B_Adhes, B_Mask, B_Paste, F_Adhes, F_Mask, F_Paste, B_SilkS, F_SilkS } )
|
||||
{
|
||||
float zposTop;
|
||||
float zposBottom;
|
||||
@ -513,12 +509,10 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
|
||||
break;
|
||||
|
||||
default:
|
||||
zposTop = zpos_copperTop_front + (layer_id - MAX_CU_LAYERS + 3.0f) * zpos_offset;
|
||||
zposBottom = zposTop - m_nonCopperLayerThickness3DU;
|
||||
break;
|
||||
}
|
||||
|
||||
m_layerZcoordTop[layer_id] = zposTop;
|
||||
m_layerZcoordTop[layer_id] = zposTop;
|
||||
m_layerZcoordBottom[layer_id] = zposBottom;
|
||||
}
|
||||
|
||||
@ -957,9 +951,17 @@ bool BOARD_ADAPTER::createBoardPolygon( wxString* aErrorMsg )
|
||||
float BOARD_ADAPTER::GetFootprintZPos( bool aIsFlipped ) const
|
||||
{
|
||||
if( aIsFlipped )
|
||||
return m_layerZcoordBottom[B_Paste];
|
||||
{
|
||||
if( auto it = m_layerZcoordBottom.find( B_Paste ); it != m_layerZcoordBottom.end() )
|
||||
return it->second;
|
||||
}
|
||||
else
|
||||
return m_layerZcoordTop[F_Paste];
|
||||
{
|
||||
if( auto it = m_layerZcoordTop.find( F_Paste ); it != m_layerZcoordTop.end() )
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -236,7 +236,12 @@ public:
|
||||
*/
|
||||
float GetLayerTopZPos( PCB_LAYER_ID aLayerId ) const noexcept
|
||||
{
|
||||
return m_layerZcoordTop[aLayerId];
|
||||
auto it = m_layerZcoordTop.find( aLayerId );
|
||||
|
||||
if( it != m_layerZcoordTop.end() )
|
||||
return it->second;
|
||||
else
|
||||
return -( m_boardBodyThickness3DU / 2.0f );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -247,7 +252,12 @@ public:
|
||||
*/
|
||||
float GetLayerBottomZPos( PCB_LAYER_ID aLayerId ) const noexcept
|
||||
{
|
||||
return m_layerZcoordBottom[aLayerId];
|
||||
auto it = m_layerZcoordBottom.find( aLayerId );
|
||||
|
||||
if( it != m_layerZcoordBottom.end() )
|
||||
return it->second;
|
||||
else
|
||||
return -( m_boardBodyThickness3DU / 2.0f ) - m_backCopperThickness3DU;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -488,11 +498,11 @@ private:
|
||||
double m_biuTo3Dunits; ///< Scale factor to convert board internal units
|
||||
///< to 3D units normalized between -1.0 and 1.0.
|
||||
|
||||
std::array<float, PCB_LAYER_ID_COUNT> m_layerZcoordTop; ///< Top (End) Z position of each
|
||||
///< layer in 3D units.
|
||||
std::map<PCB_LAYER_ID, float> m_layerZcoordTop; ///< Top (End) Z position of each
|
||||
///< layer in 3D units.
|
||||
|
||||
std::array<float, PCB_LAYER_ID_COUNT> m_layerZcoordBottom; ///< Bottom (Start) Z position of
|
||||
///< each layer in 3D units.
|
||||
std::map<PCB_LAYER_ID, float> m_layerZcoordBottom; ///< Bottom (Start) Z position of
|
||||
///< each layer in 3D units.
|
||||
|
||||
float m_frontCopperThickness3DU;
|
||||
float m_backCopperThickness3DU;
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include <board_design_settings.h>
|
||||
#include <board.h>
|
||||
#include <footprint.h>
|
||||
#include <layer_range.h>
|
||||
#include <lset.h>
|
||||
#include <pad.h>
|
||||
#include <pcb_text.h>
|
||||
@ -162,9 +163,6 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
int64_t start_Time = stats_startCopperLayersTime;
|
||||
#endif
|
||||
|
||||
PCB_LAYER_ID cu_seq[MAX_CU_LAYERS];
|
||||
LSET cu_set = LSET::AllCuMask( m_copperLayersCount );
|
||||
|
||||
EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS& cfg = m_Cfg->m_Render;
|
||||
|
||||
std::bitset<LAYER_3D_END> visibilityFlags = GetVisibleLayers();
|
||||
@ -220,10 +218,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
layer_ids.clear();
|
||||
layer_ids.reserve( m_copperLayersCount );
|
||||
|
||||
for( unsigned i = 0; i < arrayDim( cu_seq ); ++i )
|
||||
cu_seq[i] = ToLAYER_ID( B_Cu - i );
|
||||
|
||||
for( PCB_LAYER_ID layer : cu_set.Seq( cu_seq, arrayDim( cu_seq ) ) )
|
||||
for( PCB_LAYER_ID layer : LAYER_RANGE( B_Cu, F_Cu, m_copperLayersCount ) )
|
||||
{
|
||||
if( !Is3dLayerEnabled( layer, visibilityFlags ) ) // Skip non enabled layers
|
||||
continue;
|
||||
@ -795,7 +790,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
|
||||
// draw graphic items, on technical layers
|
||||
|
||||
static const PCB_LAYER_ID techLayerList[] = {
|
||||
LSEQ techLayerList = LSET::AllNonCuMask().Seq( {
|
||||
B_Adhes,
|
||||
F_Adhes,
|
||||
B_Paste,
|
||||
@ -810,7 +805,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
Cmts_User,
|
||||
Eco1_User,
|
||||
Eco2_User
|
||||
};
|
||||
} );
|
||||
|
||||
std::bitset<LAYER_3D_END> enabledFlags = visibilityFlags;
|
||||
|
||||
@ -820,7 +815,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
enabledFlags.set( LAYER_3D_SOLDERMASK_BOTTOM );
|
||||
}
|
||||
|
||||
for( PCB_LAYER_ID layer : LSET::AllNonCuMask().Seq( techLayerList, arrayDim( techLayerList ) ) )
|
||||
for( PCB_LAYER_ID layer : techLayerList )
|
||||
{
|
||||
if( aStatusReporter )
|
||||
aStatusReporter->Report( wxString::Format( _( "Build Tech layer %d" ), (int) layer ) );
|
||||
|
@ -604,7 +604,8 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
|
||||
|
||||
if( layerFlags.test( LAYER_3D_BOARD ) && m_boardAdapter.m_BoardBodyColor.a > opacity_min )
|
||||
{
|
||||
if( layer > F_Cu && layer < B_Cu )
|
||||
// B_Cu is layer 2 and all inner layers are higher values
|
||||
if( layer > B_Cu )
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -280,6 +280,7 @@ target_include_directories( kicommon
|
||||
PUBLIC
|
||||
.
|
||||
${CMAKE_BINARY_DIR}
|
||||
$<TARGET_PROPERTY:dynamic_bitset,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<TARGET_PROPERTY:magic_enum,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<TARGET_PROPERTY:pegtl,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<TARGET_PROPERTY:expected,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
|
@ -102,6 +102,10 @@ wxString LayerName( int aLayer )
|
||||
case PCB_LAYER_ID::User_7: return wxT( "User.7" );
|
||||
case PCB_LAYER_ID::User_8: return wxT( "User.8" );
|
||||
case PCB_LAYER_ID::User_9: return wxT( "User.9" );
|
||||
case 57: return wxT( "User.10" );
|
||||
case 59: return wxT( "User.11" );
|
||||
case 61: return wxT( "User.12" );
|
||||
case 63: return wxT( "User.13" );
|
||||
|
||||
// Rescue
|
||||
case PCB_LAYER_ID::Rescue: return _( "Rescue" );
|
||||
|
689
common/lset.cpp
689
common/lset.cpp
@ -28,9 +28,11 @@
|
||||
#include <cstdarg>
|
||||
#include <iostream> // for string, endl, basic_ost...
|
||||
#include <cstddef> // for size_t
|
||||
#include <map>
|
||||
|
||||
#include <core/arraydim.h>
|
||||
#include <layer_ids.h> // for PCB_LAYER_ID
|
||||
#include <layer_range.h>
|
||||
#include <lseq.h>
|
||||
#include <macros.h> // for arrayDim
|
||||
#include <wx/debug.h> // for wxASSERT, wxASSERT_MSG
|
||||
@ -55,49 +57,128 @@ LSET::LSET( const LSEQ& aSeq ) :
|
||||
}
|
||||
|
||||
|
||||
LSET::LSET( const LAYER_RANGE& aRange )
|
||||
{
|
||||
for( PCB_LAYER_ID layer : aRange )
|
||||
set( layer );
|
||||
}
|
||||
|
||||
|
||||
int LSET::LayerCount( PCB_LAYER_ID aStart, PCB_LAYER_ID aEnd, int aCopperLayerCount )
|
||||
{
|
||||
int start = aStart;
|
||||
int end = aEnd;
|
||||
|
||||
// Both layers need to be copper
|
||||
wxCHECK( IsCopperLayer( aStart ) && IsCopperLayer( aEnd ), aCopperLayerCount );
|
||||
|
||||
if( aStart == B_Cu )
|
||||
std::swap( start, end );
|
||||
|
||||
if( aStart == aEnd )
|
||||
return 1;
|
||||
|
||||
if( aStart == F_Cu )
|
||||
{
|
||||
if ( aEnd == B_Cu )
|
||||
return aCopperLayerCount;
|
||||
else
|
||||
return ( end - start ) / 2 - 1;
|
||||
}
|
||||
else if ( aEnd == B_Cu )
|
||||
{
|
||||
// Add 1 for the B_Cu layer
|
||||
return aCopperLayerCount - start / 2 + 1;
|
||||
}
|
||||
|
||||
return ( end - start ) / 2;
|
||||
}
|
||||
|
||||
|
||||
int LSET::NameToLayer( wxString& aName )
|
||||
{
|
||||
std::map<wxString, PCB_LAYER_ID> layerMap = {
|
||||
{ "F.Cu", F_Cu },
|
||||
{ "B.Cu", B_Cu },
|
||||
{ "F.Adhes", F_Adhes },
|
||||
{ "B.Adhes", B_Adhes },
|
||||
{ "F.Paste", F_Paste },
|
||||
{ "B.Paste", B_Paste },
|
||||
{ "F.SilkS", F_SilkS },
|
||||
{ "B.SilkS", B_SilkS },
|
||||
{ "F.Mask", F_Mask },
|
||||
{ "B.Mask", B_Mask },
|
||||
{ "Dwgs.User", Dwgs_User },
|
||||
{ "Cmts.User", Cmts_User },
|
||||
{ "Eco1.User", Eco1_User },
|
||||
{ "Eco2.User", Eco2_User },
|
||||
{ "Edge.Cuts", Edge_Cuts },
|
||||
{ "Margin", Margin },
|
||||
{ "F.CrtYd", F_CrtYd },
|
||||
{ "B.CrtYd", B_CrtYd },
|
||||
{ "F.Fab", F_Fab },
|
||||
{ "B.Fab", B_Fab },
|
||||
{ "Rescue", Rescue },
|
||||
{ "B.Cu", B_Cu },
|
||||
};
|
||||
|
||||
if( auto it = layerMap.find( aName ); it != layerMap.end() )
|
||||
return static_cast<int>( it->second );
|
||||
|
||||
if( aName.StartsWith( "User." ) )
|
||||
{
|
||||
long offset;
|
||||
|
||||
if( aName.Mid( 5 ).ToLong( &offset ) && offset > 0 )
|
||||
return static_cast<int>( User_1 ) + ( offset - 1 ) * 2;
|
||||
}
|
||||
|
||||
if( aName.StartsWith( "In" ) )
|
||||
{
|
||||
long offset;
|
||||
wxString str_num = aName.Mid( 2 );
|
||||
str_num.RemoveLast( 3 ); // Removes .Cu
|
||||
|
||||
if( str_num.ToLong( &offset ) && offset > 0 )
|
||||
return static_cast<int>( In1_Cu ) + ( offset - 1 ) * 2;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
bool LSET::IsBetween( PCB_LAYER_ID aStart, PCB_LAYER_ID aEnd, PCB_LAYER_ID aLayer )
|
||||
{
|
||||
if( aLayer == aStart || aLayer == aEnd )
|
||||
return true;
|
||||
|
||||
int start = std::min( aStart, aEnd );
|
||||
int end = std::max( aStart, aEnd );
|
||||
int layer = aLayer;
|
||||
|
||||
if( end == B_Cu )
|
||||
{
|
||||
//Reassign the end layer to the largest possible positive even number
|
||||
end = std::numeric_limits<PCB_LAYER_ID>::max() & ~1;
|
||||
}
|
||||
|
||||
return !( layer & 1 ) && ( layer >= start ) && ( layer <= end );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* NOTE: These names must not be translated or changed. They are used as tokens in the board
|
||||
* file format because the ordinal value of the PCB_LAYER_ID enum was not stable over time.
|
||||
* @see LayerName() for what should be used to display the default name of a layer in the GUI.
|
||||
*/
|
||||
const wxChar* LSET::Name( PCB_LAYER_ID aLayerId )
|
||||
wxString LSET::Name( PCB_LAYER_ID aLayerId )
|
||||
{
|
||||
const wxChar* txt;
|
||||
wxString txt;
|
||||
|
||||
// using a switch to explicitly show the mapping more clearly
|
||||
switch( aLayerId )
|
||||
{
|
||||
case F_Cu: txt = wxT( "F.Cu" ); break;
|
||||
case In1_Cu: txt = wxT( "In1.Cu" ); break;
|
||||
case In2_Cu: txt = wxT( "In2.Cu" ); break;
|
||||
case In3_Cu: txt = wxT( "In3.Cu" ); break;
|
||||
case In4_Cu: txt = wxT( "In4.Cu" ); break;
|
||||
case In5_Cu: txt = wxT( "In5.Cu" ); break;
|
||||
case In6_Cu: txt = wxT( "In6.Cu" ); break;
|
||||
case In7_Cu: txt = wxT( "In7.Cu" ); break;
|
||||
case In8_Cu: txt = wxT( "In8.Cu" ); break;
|
||||
case In9_Cu: txt = wxT( "In9.Cu" ); break;
|
||||
case In10_Cu: txt = wxT( "In10.Cu" ); break;
|
||||
case In11_Cu: txt = wxT( "In11.Cu" ); break;
|
||||
case In12_Cu: txt = wxT( "In12.Cu" ); break;
|
||||
case In13_Cu: txt = wxT( "In13.Cu" ); break;
|
||||
case In14_Cu: txt = wxT( "In14.Cu" ); break;
|
||||
case In15_Cu: txt = wxT( "In15.Cu" ); break;
|
||||
case In16_Cu: txt = wxT( "In16.Cu" ); break;
|
||||
case In17_Cu: txt = wxT( "In17.Cu" ); break;
|
||||
case In18_Cu: txt = wxT( "In18.Cu" ); break;
|
||||
case In19_Cu: txt = wxT( "In19.Cu" ); break;
|
||||
case In20_Cu: txt = wxT( "In20.Cu" ); break;
|
||||
case In21_Cu: txt = wxT( "In21.Cu" ); break;
|
||||
case In22_Cu: txt = wxT( "In22.Cu" ); break;
|
||||
case In23_Cu: txt = wxT( "In23.Cu" ); break;
|
||||
case In24_Cu: txt = wxT( "In24.Cu" ); break;
|
||||
case In25_Cu: txt = wxT( "In25.Cu" ); break;
|
||||
case In26_Cu: txt = wxT( "In26.Cu" ); break;
|
||||
case In27_Cu: txt = wxT( "In27.Cu" ); break;
|
||||
case In28_Cu: txt = wxT( "In28.Cu" ); break;
|
||||
case In29_Cu: txt = wxT( "In29.Cu" ); break;
|
||||
case In30_Cu: txt = wxT( "In30.Cu" ); break;
|
||||
case B_Cu: txt = wxT( "B.Cu" ); break;
|
||||
|
||||
// Technicals
|
||||
@ -124,24 +205,23 @@ const wxChar* LSET::Name( PCB_LAYER_ID aLayerId )
|
||||
case F_Fab: txt = wxT( "F.Fab" ); break;
|
||||
case B_Fab: txt = wxT( "B.Fab" ); break;
|
||||
|
||||
// User definable layers.
|
||||
case User_1: txt = wxT( "User.1" ); break;
|
||||
case User_2: txt = wxT( "User.2" ); break;
|
||||
case User_3: txt = wxT( "User.3" ); break;
|
||||
case User_4: txt = wxT( "User.4" ); break;
|
||||
case User_5: txt = wxT( "User.5" ); break;
|
||||
case User_6: txt = wxT( "User.6" ); break;
|
||||
case User_7: txt = wxT( "User.7" ); break;
|
||||
case User_8: txt = wxT( "User.8" ); break;
|
||||
case User_9: txt = wxT( "User.9" ); break;
|
||||
|
||||
// Rescue
|
||||
case Rescue: txt = wxT( "Rescue" ); break;
|
||||
|
||||
default:
|
||||
std::cout << aLayerId << std::endl;
|
||||
wxASSERT_MSG( 0, wxT( "aLayerId out of range" ) );
|
||||
txt = wxT( "BAD INDEX!" ); break;
|
||||
|
||||
if( static_cast<int>( aLayerId ) & 1 )
|
||||
{
|
||||
int offset = ( aLayerId - Rescue ) / 2;
|
||||
txt = wxString::Format( wxT( "User.%d" ), offset );
|
||||
}
|
||||
else
|
||||
{
|
||||
int offset = ( aLayerId - B_Cu ) / 2;
|
||||
txt = wxString::Format( wxT( "In%d.Cu" ), offset );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return txt;
|
||||
@ -150,98 +230,24 @@ const wxChar* LSET::Name( PCB_LAYER_ID aLayerId )
|
||||
|
||||
LSEQ LSET::CuStack() const
|
||||
{
|
||||
// desired sequence
|
||||
static const PCB_LAYER_ID sequence[] = {
|
||||
F_Cu,
|
||||
In1_Cu,
|
||||
In2_Cu,
|
||||
In3_Cu,
|
||||
In4_Cu,
|
||||
In5_Cu,
|
||||
In6_Cu,
|
||||
In7_Cu,
|
||||
In8_Cu,
|
||||
In9_Cu,
|
||||
In10_Cu,
|
||||
In11_Cu,
|
||||
In12_Cu,
|
||||
In13_Cu,
|
||||
In14_Cu,
|
||||
In15_Cu,
|
||||
In16_Cu,
|
||||
In17_Cu,
|
||||
In18_Cu,
|
||||
In19_Cu,
|
||||
In20_Cu,
|
||||
In21_Cu,
|
||||
In22_Cu,
|
||||
In23_Cu,
|
||||
In24_Cu,
|
||||
In25_Cu,
|
||||
In26_Cu,
|
||||
In27_Cu,
|
||||
In28_Cu,
|
||||
In29_Cu,
|
||||
In30_Cu,
|
||||
B_Cu, // 31
|
||||
};
|
||||
LSEQ ret;
|
||||
|
||||
return Seq( sequence, arrayDim( sequence ) );
|
||||
}
|
||||
ret.reserve( 32 );
|
||||
|
||||
for( auto it = copper_layers_begin(); it != copper_layers_end(); ++it )
|
||||
ret.push_back( *it );
|
||||
|
||||
LSEQ LSET::Technicals( LSET aSetToOmit ) const
|
||||
{
|
||||
// desired sequence
|
||||
static const PCB_LAYER_ID sequence[] = {
|
||||
F_Adhes,
|
||||
B_Adhes,
|
||||
F_Paste,
|
||||
B_Paste,
|
||||
F_SilkS,
|
||||
B_SilkS,
|
||||
F_Mask,
|
||||
B_Mask,
|
||||
F_CrtYd,
|
||||
B_CrtYd,
|
||||
F_Fab,
|
||||
B_Fab,
|
||||
};
|
||||
|
||||
LSET subset = ~aSetToOmit & *this;
|
||||
|
||||
return subset.Seq( sequence, arrayDim( sequence ) );
|
||||
}
|
||||
|
||||
|
||||
LSEQ LSET::Users() const
|
||||
{
|
||||
// desired
|
||||
static const PCB_LAYER_ID sequence[] = {
|
||||
Dwgs_User,
|
||||
Cmts_User,
|
||||
Eco1_User,
|
||||
Eco2_User,
|
||||
Edge_Cuts,
|
||||
Margin,
|
||||
User_1,
|
||||
User_2,
|
||||
User_3,
|
||||
User_4,
|
||||
User_5,
|
||||
User_6,
|
||||
User_7,
|
||||
User_8,
|
||||
User_9
|
||||
};
|
||||
|
||||
return Seq( sequence, arrayDim( sequence ) );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
LSEQ LSET::TechAndUserUIOrder() const
|
||||
{
|
||||
static const PCB_LAYER_ID sequence[] = {
|
||||
LSEQ ret;
|
||||
|
||||
ret.reserve( 32 );
|
||||
|
||||
ret = Seq( {
|
||||
F_Adhes,
|
||||
B_Adhes,
|
||||
F_Paste,
|
||||
@ -259,19 +265,16 @@ LSEQ LSET::TechAndUserUIOrder() const
|
||||
F_CrtYd,
|
||||
B_CrtYd,
|
||||
F_Fab,
|
||||
B_Fab,
|
||||
User_1,
|
||||
User_2,
|
||||
User_3,
|
||||
User_4,
|
||||
User_5,
|
||||
User_6,
|
||||
User_7,
|
||||
User_8,
|
||||
User_9
|
||||
};
|
||||
B_Fab
|
||||
} );
|
||||
|
||||
return Seq( sequence, arrayDim( sequence ) );
|
||||
for( auto it = non_copper_layers_begin(); it != non_copper_layers_end(); ++it )
|
||||
{
|
||||
if( *it >= User_1 )
|
||||
ret.push_back( *it );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -389,40 +392,6 @@ int LSET::ParseHex( const char* aStart, int aCount )
|
||||
}
|
||||
|
||||
|
||||
LSEQ LSET::Seq( const PCB_LAYER_ID* aWishListSequence, unsigned aCount ) const
|
||||
{
|
||||
LSEQ ret;
|
||||
|
||||
#if defined(DEBUG) && 0
|
||||
LSET dup_detector;
|
||||
|
||||
for( unsigned i=0; i<aCount; ++i )
|
||||
{
|
||||
PCB_LAYER_ID id = aWishListSequence[i];
|
||||
|
||||
if( test( id ) )
|
||||
{
|
||||
wxASSERT_MSG( !dup_detector[id], wxT( "Duplicate in aWishListSequence" ) );
|
||||
dup_detector[id] = true;
|
||||
|
||||
ret.push_back( id );
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
for( unsigned i=0; i<aCount; ++i )
|
||||
{
|
||||
PCB_LAYER_ID id = aWishListSequence[i];
|
||||
|
||||
if( test( id ) )
|
||||
ret.push_back( id );
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
LSEQ LSET::Seq( const LSEQ& aSequence ) const
|
||||
{
|
||||
LSEQ ret;
|
||||
@ -455,69 +424,48 @@ LSEQ LSET::Seq() const
|
||||
|
||||
LSEQ LSET::SeqStackupTop2Bottom( PCB_LAYER_ID aSelectedLayer ) const
|
||||
{
|
||||
static const PCB_LAYER_ID sequence[] = {
|
||||
LSEQ base_sequence = Seq( {
|
||||
Edge_Cuts,
|
||||
Margin,
|
||||
Dwgs_User,
|
||||
Cmts_User,
|
||||
Eco1_User,
|
||||
Eco2_User,
|
||||
User_1,
|
||||
User_2,
|
||||
User_3,
|
||||
User_4,
|
||||
User_5,
|
||||
User_6,
|
||||
User_7,
|
||||
User_8,
|
||||
User_9,
|
||||
Eco2_User
|
||||
} );
|
||||
|
||||
LSEQ top_tech_sequence = Seq( {
|
||||
F_Fab,
|
||||
F_SilkS,
|
||||
F_Paste,
|
||||
F_Adhes,
|
||||
F_Mask,
|
||||
F_CrtYd,
|
||||
F_Cu,
|
||||
In1_Cu,
|
||||
In2_Cu,
|
||||
In3_Cu,
|
||||
In4_Cu,
|
||||
In5_Cu,
|
||||
In6_Cu,
|
||||
In7_Cu,
|
||||
In8_Cu,
|
||||
In9_Cu,
|
||||
In10_Cu,
|
||||
In11_Cu,
|
||||
In12_Cu,
|
||||
In13_Cu,
|
||||
In14_Cu,
|
||||
In15_Cu,
|
||||
In16_Cu,
|
||||
In17_Cu,
|
||||
In18_Cu,
|
||||
In19_Cu,
|
||||
In20_Cu,
|
||||
In21_Cu,
|
||||
In22_Cu,
|
||||
In23_Cu,
|
||||
In24_Cu,
|
||||
In25_Cu,
|
||||
In26_Cu,
|
||||
In27_Cu,
|
||||
In28_Cu,
|
||||
In29_Cu,
|
||||
In30_Cu,
|
||||
B_Cu,
|
||||
} );
|
||||
|
||||
LSEQ bottom_tech_sequence = Seq( {
|
||||
B_CrtYd,
|
||||
B_Mask,
|
||||
B_Adhes,
|
||||
B_Paste,
|
||||
B_SilkS,
|
||||
B_Fab,
|
||||
};
|
||||
} );
|
||||
|
||||
LSEQ seq = Seq( sequence, arrayDim( sequence ) );
|
||||
|
||||
LSEQ seq = Seq( base_sequence );
|
||||
|
||||
for( auto it = non_copper_layers_begin(); it != non_copper_layers_end(); ++it )
|
||||
{
|
||||
if( *it >= User_1 )
|
||||
seq.push_back( *it );
|
||||
}
|
||||
|
||||
std::copy( top_tech_sequence.begin(), top_tech_sequence.end(), std::back_inserter( seq ) );
|
||||
|
||||
for( auto it = copper_layers_begin(); it != copper_layers_end(); ++it )
|
||||
seq.push_back( *it );
|
||||
|
||||
std::copy( bottom_tech_sequence.begin(), bottom_tech_sequence.end(), std::back_inserter( seq ) );
|
||||
|
||||
if( aSelectedLayer != UNDEFINED_LAYER )
|
||||
{
|
||||
@ -539,7 +487,7 @@ LSEQ LSET::SeqStackupForPlotting() const
|
||||
// bottom-to-top stack-up layers
|
||||
// Note that the bottom technical layers are flipped so that when plotting a bottom-side view,
|
||||
// they appear in the correct sequence.
|
||||
static const PCB_LAYER_ID sequence[] = {
|
||||
LSEQ bottom_tech_sequence = Seq( {
|
||||
B_Cu,
|
||||
B_Mask,
|
||||
B_Paste,
|
||||
@ -547,61 +495,71 @@ LSEQ LSET::SeqStackupForPlotting() const
|
||||
B_Adhes,
|
||||
B_CrtYd,
|
||||
B_Fab,
|
||||
In30_Cu,
|
||||
In29_Cu,
|
||||
In28_Cu,
|
||||
In27_Cu,
|
||||
In26_Cu,
|
||||
In25_Cu,
|
||||
In24_Cu,
|
||||
In23_Cu,
|
||||
In22_Cu,
|
||||
In21_Cu,
|
||||
In20_Cu,
|
||||
In19_Cu,
|
||||
In18_Cu,
|
||||
In17_Cu,
|
||||
In16_Cu,
|
||||
In15_Cu,
|
||||
In14_Cu,
|
||||
In13_Cu,
|
||||
In12_Cu,
|
||||
In11_Cu,
|
||||
In10_Cu,
|
||||
In9_Cu,
|
||||
In8_Cu,
|
||||
In7_Cu,
|
||||
In6_Cu,
|
||||
In5_Cu,
|
||||
In4_Cu,
|
||||
In3_Cu,
|
||||
In2_Cu,
|
||||
In1_Cu,
|
||||
F_Cu,
|
||||
} );
|
||||
|
||||
// Copper layers go here
|
||||
|
||||
LSEQ top_tech_sequence = Seq( {
|
||||
F_Mask,
|
||||
F_Paste,
|
||||
F_SilkS,
|
||||
F_Adhes,
|
||||
F_CrtYd,
|
||||
F_Fab,
|
||||
} );
|
||||
|
||||
LSEQ user_sequence = Seq( {
|
||||
Dwgs_User,
|
||||
Cmts_User,
|
||||
Eco1_User,
|
||||
Eco2_User,
|
||||
User_1,
|
||||
User_2,
|
||||
User_3,
|
||||
User_4,
|
||||
User_5,
|
||||
User_6,
|
||||
User_7,
|
||||
User_8,
|
||||
User_9,
|
||||
} );
|
||||
|
||||
// User layers go here
|
||||
|
||||
LSEQ base_sequence = Seq( {
|
||||
Margin,
|
||||
Edge_Cuts,
|
||||
};
|
||||
} );
|
||||
|
||||
return Seq( sequence, arrayDim( sequence ) );
|
||||
|
||||
|
||||
LSEQ seq = Seq( bottom_tech_sequence );
|
||||
|
||||
std::vector<PCB_LAYER_ID> temp_layers;
|
||||
|
||||
// We are going to reverse the copper layers and then add them to the sequence
|
||||
// because the plotting order is bottom-to-top
|
||||
for( auto it = copper_layers_begin(); it != copper_layers_end(); ++it )
|
||||
{
|
||||
// Skip B_Cu because it is already in the sequence (if it exists)
|
||||
if( *it != B_Cu )
|
||||
temp_layers.push_back( *it );
|
||||
}
|
||||
|
||||
for( auto it = temp_layers.rbegin(); it != temp_layers.rend(); ++it )
|
||||
seq.push_back( *it );
|
||||
|
||||
std::copy( top_tech_sequence.begin(), top_tech_sequence.end(), std::back_inserter( seq ) );
|
||||
|
||||
std::copy( user_sequence.begin(), user_sequence.end(), std::back_inserter( seq ) );
|
||||
|
||||
temp_layers.clear();
|
||||
|
||||
for( auto it = non_copper_layers_begin(); it != non_copper_layers_end(); ++it )
|
||||
{
|
||||
if( *it >= User_1 )
|
||||
temp_layers.push_back( *it );
|
||||
}
|
||||
|
||||
for( auto it = temp_layers.rbegin(); it != temp_layers.rend(); ++it )
|
||||
{
|
||||
seq.push_back( *it );
|
||||
}
|
||||
|
||||
std::copy( base_sequence.begin(), base_sequence.end(), std::back_inserter( seq ) );
|
||||
|
||||
return seq;
|
||||
}
|
||||
|
||||
|
||||
@ -611,70 +569,41 @@ LSET& LSET::Flip( int aCopperLayersCount )
|
||||
|
||||
reset();
|
||||
|
||||
if( oldMask.test( B_Cu ) )
|
||||
set( F_Cu );
|
||||
// Mapping for Copper and Non-Copper layers
|
||||
const std::map<PCB_LAYER_ID, PCB_LAYER_ID> flip_map =
|
||||
{
|
||||
{F_Cu, B_Cu},
|
||||
{B_Cu, F_Cu},
|
||||
{F_SilkS, B_SilkS},
|
||||
{B_SilkS, F_SilkS},
|
||||
{F_Adhes, B_Adhes},
|
||||
{B_Adhes, F_Adhes},
|
||||
{F_Mask, B_Mask},
|
||||
{B_Mask, F_Mask},
|
||||
{F_Paste, B_Paste},
|
||||
{B_Paste, F_Paste},
|
||||
{F_CrtYd, B_CrtYd},
|
||||
{B_CrtYd, F_CrtYd},
|
||||
{F_Fab, B_Fab},
|
||||
{B_Fab, F_Fab}
|
||||
};
|
||||
|
||||
if( oldMask.test( F_Cu ) )
|
||||
set( B_Cu );
|
||||
for( const auto& pair : flip_map )
|
||||
{
|
||||
if( oldMask.test( pair.first ) )
|
||||
set( pair.second );
|
||||
}
|
||||
|
||||
if( oldMask.test( B_SilkS ) )
|
||||
set( F_SilkS );
|
||||
|
||||
if( oldMask.test( F_SilkS ) )
|
||||
set( B_SilkS );
|
||||
|
||||
if( oldMask.test( B_Adhes ) )
|
||||
set( F_Adhes );
|
||||
|
||||
if( oldMask.test( F_Adhes ) )
|
||||
set( B_Adhes );
|
||||
|
||||
if( oldMask.test( B_Mask ) )
|
||||
set( F_Mask );
|
||||
|
||||
if( oldMask.test( F_Mask ) )
|
||||
set( B_Mask );
|
||||
|
||||
if( oldMask.test( B_Paste ) )
|
||||
set( F_Paste );
|
||||
|
||||
if( oldMask.test( F_Paste ) )
|
||||
set( B_Paste );
|
||||
|
||||
if( oldMask.test( B_Adhes ) )
|
||||
set( F_Adhes );
|
||||
|
||||
if( oldMask.test( F_Adhes ) )
|
||||
set( B_Adhes );
|
||||
|
||||
if( oldMask.test( B_CrtYd ) )
|
||||
set( F_CrtYd );
|
||||
|
||||
if( oldMask.test( F_CrtYd ) )
|
||||
set( B_CrtYd );
|
||||
|
||||
if( oldMask.test( B_Fab ) )
|
||||
set( F_Fab );
|
||||
|
||||
if( oldMask.test( F_Fab ) )
|
||||
set( B_Fab );
|
||||
|
||||
if( aCopperLayersCount >= 4 ) // Internal layers exist
|
||||
if( aCopperLayersCount >= 4 )
|
||||
{
|
||||
LSET internalMask = oldMask & InternalCuMask();
|
||||
int innerLayerCnt = aCopperLayersCount - 2;
|
||||
int innerLayerCount = aCopperLayersCount - 2;
|
||||
|
||||
// the flipped mask is the innerLayerCnt bits rewritten in reverse order
|
||||
// ( bits innerLayerCnt to 1 rewritten in bits 1 to innerLayerCnt )
|
||||
for( int ii = 0; ii < innerLayerCnt; ii++ )
|
||||
for( int ii = 0; ii < innerLayerCount; ii++ )
|
||||
{
|
||||
if( internalMask[innerLayerCnt - ii] )
|
||||
if( internalMask.test( innerLayerCount - ii * 2 + In1_Cu ) )
|
||||
{
|
||||
set( ii + In1_Cu );
|
||||
}
|
||||
else
|
||||
{
|
||||
reset( ii + In1_Cu );
|
||||
set( ii * 2 + In1_Cu );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -731,20 +660,10 @@ LSET LSET::InternalCuMask()
|
||||
|
||||
LSET LSET::AllCuMask( int aCuLayerCount )
|
||||
{
|
||||
// retain all in static as the full set, which is a common case.
|
||||
static const LSET all = InternalCuMask().set( F_Cu ).set( B_Cu );
|
||||
LSET ret;
|
||||
|
||||
if( aCuLayerCount == MAX_CU_LAYERS )
|
||||
return all;
|
||||
|
||||
// subtract out some Cu layers not wanted in the mask.
|
||||
LSET ret = all;
|
||||
int clear_count = MAX_CU_LAYERS - aCuLayerCount;
|
||||
|
||||
clear_count = std::clamp( clear_count, 0, MAX_CU_LAYERS - 2 );
|
||||
|
||||
for( int elem = In30_Cu; clear_count; --elem, --clear_count )
|
||||
ret.set( elem, false );
|
||||
for( PCB_LAYER_ID layer : LAYER_RANGE( F_Cu, B_Cu, aCuLayerCount ) )
|
||||
ret.set( layer );
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -866,6 +785,7 @@ LSEQ LSET::UIOrder() const
|
||||
{
|
||||
LSEQ order = CuStack();
|
||||
LSEQ techuser = TechAndUserUIOrder();
|
||||
|
||||
order.insert( order.end(), techuser.begin(), techuser.end() );
|
||||
|
||||
return order;
|
||||
@ -874,6 +794,10 @@ LSEQ LSET::UIOrder() const
|
||||
|
||||
PCB_LAYER_ID ToLAYER_ID( int aLayer )
|
||||
{
|
||||
// We use std::numeric_limits<int>::max() to represent B_Cu for the connectivity_rtree
|
||||
if( aLayer == std::numeric_limits<int>::max() )
|
||||
return B_Cu;
|
||||
|
||||
wxASSERT( aLayer < GAL_LAYER_ID_END );
|
||||
return PCB_LAYER_ID( aLayer );
|
||||
}
|
||||
@ -946,3 +870,100 @@ GAL_SET GAL_SET::DefaultVisible()
|
||||
static const GAL_SET saved( visible, arrayDim( visible ) );
|
||||
return saved;
|
||||
}
|
||||
|
||||
#ifndef SWIG // Skip SWIG generators for the iterators because it requires a default constructor
|
||||
// Custom iterators for Copper and Non-Copper layers
|
||||
|
||||
LSET::copper_layers_iterator::copper_layers_iterator( const BASE_SET& set, size_t index ) :
|
||||
BASE_SET::set_bits_iterator( set, index )
|
||||
{
|
||||
m_index = ( index + 1 ) & ~1;
|
||||
advance_to_next_set_copper_bit();
|
||||
}
|
||||
|
||||
PCB_LAYER_ID LSET::copper_layers_iterator::operator*() const
|
||||
{
|
||||
return static_cast<PCB_LAYER_ID>( m_index );
|
||||
}
|
||||
|
||||
LSET::copper_layers_iterator& LSET::copper_layers_iterator::operator++()
|
||||
{
|
||||
next_copper_layer();
|
||||
advance_to_next_set_copper_bit();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void LSET::copper_layers_iterator::next_copper_layer()
|
||||
{
|
||||
if( m_index == F_Cu )
|
||||
{
|
||||
m_index += 4;
|
||||
}
|
||||
else if( m_index == B_Cu )
|
||||
{
|
||||
m_index = m_baseSet.size();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_index += 2;
|
||||
|
||||
if( m_index >= m_baseSet.size() )
|
||||
m_index = B_Cu;
|
||||
}
|
||||
}
|
||||
|
||||
void LSET::copper_layers_iterator::advance_to_next_set_copper_bit()
|
||||
{
|
||||
while( m_index < m_baseSet.size() && !m_baseSet.test( m_index ) )
|
||||
next_copper_layer();
|
||||
}
|
||||
|
||||
LSET::non_copper_layers_iterator::non_copper_layers_iterator( const BASE_SET& set, size_t index ) :
|
||||
BASE_SET::set_bits_iterator( set, index )
|
||||
{
|
||||
advance_to_next_set_non_copper_bit();
|
||||
}
|
||||
|
||||
PCB_LAYER_ID LSET::non_copper_layers_iterator::operator*() const
|
||||
{
|
||||
return static_cast<PCB_LAYER_ID>( m_index );
|
||||
}
|
||||
|
||||
LSET::non_copper_layers_iterator& LSET::non_copper_layers_iterator::operator++()
|
||||
{
|
||||
++m_index;
|
||||
advance_to_next_set_non_copper_bit();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void LSET::non_copper_layers_iterator::advance_to_next_set_non_copper_bit()
|
||||
{
|
||||
while( m_index < m_baseSet.size() && ( m_index % 2 != 1 || !m_baseSet.test( m_index ) ) )
|
||||
{
|
||||
++m_index;
|
||||
}
|
||||
}
|
||||
|
||||
LSET::copper_layers_iterator LSET::copper_layers_begin() const
|
||||
{
|
||||
return copper_layers_iterator( *this, 0 );
|
||||
}
|
||||
|
||||
LSET::copper_layers_iterator LSET::copper_layers_end() const
|
||||
{
|
||||
return copper_layers_iterator( *this, size() );
|
||||
}
|
||||
|
||||
LSET::non_copper_layers_iterator LSET::non_copper_layers_begin() const
|
||||
{
|
||||
return non_copper_layers_iterator( *this, 0 );
|
||||
}
|
||||
|
||||
LSET::non_copper_layers_iterator LSET::non_copper_layers_end() const
|
||||
{
|
||||
return non_copper_layers_iterator( *this, size() );
|
||||
}
|
||||
|
||||
|
||||
#endif
|
@ -147,6 +147,10 @@ static const std::map<int, COLOR4D> s_defaultTheme =
|
||||
{ GERBVIEW_LAYER_ID_START + 57, CSS_COLOR( 127, 200, 127, 1 ) },
|
||||
{ GERBVIEW_LAYER_ID_START + 58, CSS_COLOR( 206, 125, 44, 1 ) },
|
||||
{ GERBVIEW_LAYER_ID_START + 59, CSS_COLOR( 79, 203, 203, 1 ) },
|
||||
{ GERBVIEW_LAYER_ID_START + 60, CSS_COLOR( 219, 98, 139, 1 ) },
|
||||
{ GERBVIEW_LAYER_ID_START + 61, CSS_COLOR( 167, 165, 198, 1 ) },
|
||||
{ GERBVIEW_LAYER_ID_START + 62, CSS_COLOR( 40, 204, 217, 1 ) },
|
||||
{ GERBVIEW_LAYER_ID_START + 63, CSS_COLOR( 232, 178, 167, 1 ) },
|
||||
|
||||
{ LAYER_ANCHOR, CSS_COLOR( 255, 38, 226, 1 ) },
|
||||
{ LAYER_LOCKED_ITEM_SHADOW, CSS_COLOR( 255, 38, 226, 0.5 ) },
|
||||
|
@ -59,7 +59,7 @@ bool GERBVIEW_PRINTOUT::OnPrintPage( int aPage )
|
||||
// objects when using only one page is tricky
|
||||
|
||||
// Enable only one layer to create a printout
|
||||
m_settings.m_LayerSet = LSET( layerId );
|
||||
m_settings.m_LayerSet = LSET( { layerId } );
|
||||
|
||||
GERBER_FILE_IMAGE_LIST& gbrImgList = GERBER_FILE_IMAGE_LIST::GetImagesList();
|
||||
GERBER_FILE_IMAGE* gbrImage = gbrImgList.GetGbrImage( layerId );
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include <limits>
|
||||
#include <ostream>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <dynamic_bitset.h>
|
||||
|
||||
#include <core/kicad_algo.h>
|
||||
#include <import_export.h>
|
||||
@ -37,176 +37,182 @@
|
||||
typedef SSIZE_T ssize_t;
|
||||
#endif
|
||||
|
||||
class APIEXPORT BASE_SET
|
||||
class APIEXPORT BASE_SET : public sul::dynamic_bitset<uint64_t>
|
||||
{
|
||||
public:
|
||||
using iterator = std::vector<int>::iterator;
|
||||
using const_iterator = std::vector<int>::const_iterator;
|
||||
|
||||
BASE_SET( size_t size ) : m_bits( size, 0 ) {}
|
||||
|
||||
bool test( size_t pos ) const
|
||||
class iterator
|
||||
{
|
||||
if( pos >= m_bits.size() )
|
||||
return false;
|
||||
public:
|
||||
using iterator_category = std::random_access_iterator_tag;
|
||||
using value_type = bool;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = void;
|
||||
using reference = bool;
|
||||
|
||||
return m_bits[pos] == 1;
|
||||
}
|
||||
|
||||
bool any() const { return std::any_of( m_bits.begin(), m_bits.end(), []( int bit ) { return bit == 1; } ); }
|
||||
|
||||
bool all() const { return std::all_of( m_bits.begin(), m_bits.end(), []( int bit ) { return bit == 1; } ); }
|
||||
|
||||
bool none() const { return std::none_of( m_bits.begin(), m_bits.end(), []( int bit ) { return bit == 1; } ); }
|
||||
|
||||
BASE_SET& set( size_t pos = std::numeric_limits<size_t>::max(), bool value = true )
|
||||
{
|
||||
if( pos == std::numeric_limits<size_t>::max() )
|
||||
iterator( BASE_SET* set, size_t pos ) : m_set( set ), m_pos( pos ) {}
|
||||
bool operator*() const { return m_set->test( m_pos ); }
|
||||
iterator& operator++()
|
||||
{
|
||||
std::fill( m_bits.begin(), m_bits.end(), value ? 1 : 0 );
|
||||
++m_pos;
|
||||
return *this;
|
||||
}
|
||||
iterator operator+( difference_type n ) const
|
||||
{
|
||||
return iterator( m_set, m_pos + n );
|
||||
}
|
||||
difference_type operator-( const iterator& other ) const
|
||||
{
|
||||
return static_cast<difference_type>(m_pos) - static_cast<difference_type>(other.m_pos);
|
||||
}
|
||||
auto operator<=>( const iterator& ) const = default;
|
||||
|
||||
if( pos >= m_bits.size() )
|
||||
m_bits.resize( pos + 1, 0 );
|
||||
private:
|
||||
BASE_SET* m_set;
|
||||
size_t m_pos;
|
||||
};
|
||||
|
||||
m_bits[pos] = value ? 1 : 0;
|
||||
class const_iterator
|
||||
{
|
||||
public:
|
||||
using iterator_category = std::random_access_iterator_tag;
|
||||
using value_type = bool;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = void;
|
||||
using reference = bool;
|
||||
|
||||
const_iterator( const BASE_SET* set, size_t pos ) : m_set( set ), m_pos( pos ) {}
|
||||
bool operator*() const { return m_set->test( m_pos ); }
|
||||
const_iterator& operator++()
|
||||
{
|
||||
++m_pos;
|
||||
return *this;
|
||||
}
|
||||
const_iterator operator+( difference_type n ) const
|
||||
{
|
||||
return const_iterator( m_set, m_pos + n );
|
||||
}
|
||||
difference_type operator-( const const_iterator& other ) const
|
||||
{
|
||||
return static_cast<difference_type>(m_pos) - static_cast<difference_type>(other.m_pos);
|
||||
}
|
||||
auto operator<=>( const const_iterator& ) const = default;
|
||||
|
||||
private:
|
||||
const BASE_SET* m_set;
|
||||
size_t m_pos;
|
||||
};
|
||||
|
||||
iterator begin() { return iterator(this, 0); }
|
||||
iterator end() { return iterator(this, size()); }
|
||||
const_iterator begin() const { return const_iterator(this, 0); }
|
||||
const_iterator end() const { return const_iterator(this, size()); }
|
||||
|
||||
BASE_SET( size_t size = 64 ) : sul::dynamic_bitset<uint64_t>( size ) {}
|
||||
|
||||
// Overloads for set, reset, and flip operations
|
||||
|
||||
// Set a bit at the specified position
|
||||
BASE_SET& set(size_t pos)
|
||||
{
|
||||
if( pos >= size() )
|
||||
sul::dynamic_bitset<uint64_t>::resize( pos + 1 );
|
||||
|
||||
sul::dynamic_bitset<uint64_t>::set(pos);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BASE_SET& reset( size_t pos = std::numeric_limits<size_t>::max() )
|
||||
// Set a bit at the specified position to a given value
|
||||
BASE_SET& set(size_t pos, bool value)
|
||||
{
|
||||
if( pos == std::numeric_limits<size_t>::max() )
|
||||
{
|
||||
std::fill( m_bits.begin(), m_bits.end(), 0 );
|
||||
return *this;
|
||||
}
|
||||
if( pos >= size() )
|
||||
sul::dynamic_bitset<uint64_t>::resize( pos + 1 );
|
||||
|
||||
if( pos >= m_bits.size() )
|
||||
m_bits.resize( pos + 1, 0 );
|
||||
|
||||
m_bits[pos] = 0;
|
||||
sul::dynamic_bitset<uint64_t>::set(pos, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BASE_SET& flip( size_t pos = std::numeric_limits<size_t>::max() )
|
||||
// Set all bits to 1
|
||||
BASE_SET& set()
|
||||
{
|
||||
if( pos == std::numeric_limits<size_t>::max() )
|
||||
{
|
||||
std::transform( m_bits.begin(), m_bits.end(), m_bits.begin(), []( int bit ) { return bit ^ 1; } );
|
||||
return *this;
|
||||
}
|
||||
|
||||
if( pos >= m_bits.size() )
|
||||
m_bits.resize( pos + 1, 0 );
|
||||
|
||||
m_bits[pos] ^= 1;
|
||||
sul::dynamic_bitset<uint64_t>::set();
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_t count() const { return std::count( m_bits.begin(), m_bits.end(), 1 ); }
|
||||
// Reset (clear) a bit at the specified position
|
||||
BASE_SET& reset(size_t pos)
|
||||
{
|
||||
if( pos >= size() )
|
||||
sul::dynamic_bitset<uint64_t>::resize( pos + 1 );
|
||||
|
||||
size_t size() const { return m_bits.size(); }
|
||||
sul::dynamic_bitset<uint64_t>::reset(pos);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void resize( size_t newSize ) { m_bits.resize( newSize, 0 ); }
|
||||
// Reset (clear) all bits
|
||||
BASE_SET& reset()
|
||||
{
|
||||
sul::dynamic_bitset<uint64_t>::reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
int& operator[]( size_t pos ) { return m_bits[pos]; }
|
||||
// Flip a bit at the specified position
|
||||
BASE_SET& flip(size_t pos)
|
||||
{
|
||||
if( pos >= size() )
|
||||
sul::dynamic_bitset<uint64_t>::resize( pos + 1 );
|
||||
|
||||
const int& operator[]( size_t pos ) const { return m_bits[pos]; }
|
||||
sul::dynamic_bitset<uint64_t>::flip(pos);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Flip all bits
|
||||
BASE_SET& flip()
|
||||
{
|
||||
sul::dynamic_bitset<uint64_t>::flip();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Overloads for boolean operators
|
||||
|
||||
// Bitwise NOT operator
|
||||
BASE_SET operator~() const
|
||||
{
|
||||
BASE_SET result(*this);
|
||||
result.flip();
|
||||
return result;
|
||||
}
|
||||
|
||||
// Compound assignment AND operator
|
||||
BASE_SET& operator&=(const BASE_SET& other)
|
||||
{
|
||||
sul::dynamic_bitset<uint64_t>::operator&=(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Compound assignment OR operator
|
||||
BASE_SET& operator|=(const BASE_SET& other)
|
||||
{
|
||||
sul::dynamic_bitset<uint64_t>::operator|=(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Compound assignment XOR operator
|
||||
BASE_SET& operator^=(const BASE_SET& other)
|
||||
{
|
||||
sul::dynamic_bitset<uint64_t>::operator^=(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
int compare( const BASE_SET& other ) const
|
||||
{
|
||||
return alg::lexicographical_compare_3way( m_bits, other.m_bits );
|
||||
}
|
||||
|
||||
iterator begin() { return m_bits.begin(); }
|
||||
iterator end() { return m_bits.end(); }
|
||||
const_iterator begin() const { return m_bits.begin(); }
|
||||
const_iterator end() const { return m_bits.end(); }
|
||||
|
||||
// Define equality operator
|
||||
bool operator==( const BASE_SET& other ) const
|
||||
{
|
||||
std::size_t minSize = std::min( size(), other.size() );
|
||||
if( !std::equal( m_bits.begin(), m_bits.begin() + minSize, other.m_bits.begin() ) )
|
||||
return false;
|
||||
|
||||
if( std::any_of( m_bits.begin() + minSize, m_bits.end(), []( int bit ) { return bit != 0; } ) )
|
||||
return false;
|
||||
|
||||
if( std::any_of( other.m_bits.begin() + minSize, other.m_bits.end(), []( int bit ) { return bit != 0; } ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
auto result = std::lexicographical_compare_three_way( begin(), end(), other.begin(), other.end() );
|
||||
return result == std::strong_ordering::equal ? 0 : ( result == std::strong_ordering::less ? -1 : 1 );
|
||||
}
|
||||
|
||||
// Define less-than operator for comparison
|
||||
bool operator<( const BASE_SET& other ) const
|
||||
{
|
||||
return std::lexicographical_compare( m_bits.begin(), m_bits.end(), other.m_bits.begin(), other.m_bits.end() );
|
||||
}
|
||||
|
||||
// Define output operator
|
||||
friend std::ostream& operator<<( std::ostream& os, const BASE_SET& set )
|
||||
{
|
||||
return os << set.to_string();
|
||||
}
|
||||
|
||||
// to_string method
|
||||
template <typename CharT = char>
|
||||
std::basic_string<CharT> to_string( CharT zero = CharT( '0' ), CharT one = CharT( '1' ) ) const
|
||||
{
|
||||
std::basic_string<CharT> result( size(), zero );
|
||||
|
||||
for( size_t i = 0; i < size(); ++i )
|
||||
{
|
||||
if( test( i ) )
|
||||
{
|
||||
result[size() - 1 - i] = one; // Reverse order to match std::bitset behavior
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Boolean operators
|
||||
BASE_SET& operator&=( const BASE_SET& rhs )
|
||||
{
|
||||
assert( m_bits.size() == rhs.m_bits.size() );
|
||||
|
||||
for( size_t i = 0; i < m_bits.size(); ++i )
|
||||
m_bits[i] &= rhs.m_bits[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BASE_SET& operator|=( const BASE_SET& rhs )
|
||||
{
|
||||
assert( m_bits.size() == rhs.m_bits.size() );
|
||||
|
||||
for( size_t i = 0; i < m_bits.size(); ++i )
|
||||
m_bits[i] |= rhs.m_bits[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BASE_SET& operator^=( const BASE_SET& rhs )
|
||||
{
|
||||
assert( m_bits.size() == rhs.m_bits.size() );
|
||||
|
||||
for( size_t i = 0; i < m_bits.size(); ++i )
|
||||
m_bits[i] ^= rhs.m_bits[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BASE_SET operator~() const
|
||||
{
|
||||
BASE_SET result = *this;
|
||||
for( size_t i = 0; i < m_bits.size(); ++i )
|
||||
result.m_bits[i] = !m_bits[i];
|
||||
|
||||
return result;
|
||||
return std::lexicographical_compare( begin(), end(), other.begin(), other.end() );
|
||||
}
|
||||
|
||||
// Custom iterator to iterate over set bits
|
||||
@ -238,7 +244,7 @@ public:
|
||||
|
||||
bool operator==( const set_bits_iterator& other ) const { return m_index == other.m_index; }
|
||||
|
||||
private:
|
||||
protected:
|
||||
void advance_to_next_set_bit()
|
||||
{
|
||||
while( m_index < m_baseSet.size() && !m_baseSet.test( m_index ) )
|
||||
@ -284,7 +290,7 @@ public:
|
||||
return m_index == other.m_index;
|
||||
}
|
||||
|
||||
private:
|
||||
protected:
|
||||
void advance_to_previous_set_bit()
|
||||
{
|
||||
while( m_index >= 0 && !m_baseSet.test( m_index ) )
|
||||
@ -298,19 +304,17 @@ public:
|
||||
};
|
||||
|
||||
set_bits_iterator set_bits_begin() const { return set_bits_iterator( *this, 0 ); }
|
||||
set_bits_iterator set_bits_end() const { return set_bits_iterator( *this, m_bits.size() ); }
|
||||
set_bits_iterator set_bits_end() const { return set_bits_iterator( *this, size() ); }
|
||||
|
||||
set_bits_reverse_iterator set_bits_rbegin() const
|
||||
{
|
||||
return set_bits_reverse_iterator( *this, m_bits.size() - 1 );
|
||||
return set_bits_reverse_iterator( *this, size() - 1 );
|
||||
}
|
||||
set_bits_reverse_iterator set_bits_rend() const
|
||||
{
|
||||
return set_bits_reverse_iterator( *this, -1 );
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<int> m_bits;
|
||||
};
|
||||
|
||||
inline BASE_SET operator&( const BASE_SET& lhs, const BASE_SET& rhs )
|
||||
|
@ -239,6 +239,21 @@ public:
|
||||
*/
|
||||
virtual PCB_LAYER_ID GetLayer() const { return m_layer; }
|
||||
|
||||
/**
|
||||
* Return the total number of layers for the board that this item resides on.
|
||||
*/
|
||||
virtual int BoardLayerCount() const;
|
||||
|
||||
/**
|
||||
* Return the total number of copper layers for the board that this item resides on.
|
||||
*/
|
||||
virtual int BoardCopperLayerCount() const;
|
||||
|
||||
/**
|
||||
* Return the LSET for the board that this item resides on.
|
||||
*/
|
||||
virtual LSET BoardLayerSet() const;
|
||||
|
||||
/**
|
||||
* Return a std::bitset of all layers on which the item physically resides.
|
||||
*/
|
||||
@ -247,7 +262,7 @@ public:
|
||||
if( m_layer == UNDEFINED_LAYER )
|
||||
return LSET();
|
||||
else
|
||||
return LSET( m_layer );
|
||||
return LSET( { m_layer } );
|
||||
}
|
||||
|
||||
virtual void SetLayerSet( const LSET& aLayers )
|
||||
|
@ -62,84 +62,82 @@ enum PCB_LAYER_ID: int
|
||||
UNSELECTED_LAYER = -2,
|
||||
|
||||
F_Cu = 0,
|
||||
In1_Cu,
|
||||
In2_Cu,
|
||||
In3_Cu,
|
||||
In4_Cu,
|
||||
In5_Cu,
|
||||
In6_Cu,
|
||||
In7_Cu,
|
||||
In8_Cu,
|
||||
In9_Cu,
|
||||
In10_Cu,
|
||||
In11_Cu,
|
||||
In12_Cu,
|
||||
In13_Cu,
|
||||
In14_Cu,
|
||||
In15_Cu,
|
||||
In16_Cu,
|
||||
In17_Cu,
|
||||
In18_Cu,
|
||||
In19_Cu,
|
||||
In20_Cu,
|
||||
In21_Cu,
|
||||
In22_Cu,
|
||||
In23_Cu,
|
||||
In24_Cu,
|
||||
In25_Cu,
|
||||
In26_Cu,
|
||||
In27_Cu,
|
||||
In28_Cu,
|
||||
In29_Cu,
|
||||
In30_Cu,
|
||||
B_Cu, // 31
|
||||
B_Cu = 2,
|
||||
In1_Cu = 4,
|
||||
In2_Cu = 6,
|
||||
In3_Cu = 8,
|
||||
In4_Cu = 10,
|
||||
In5_Cu = 12,
|
||||
In6_Cu = 14,
|
||||
In7_Cu = 16,
|
||||
In8_Cu = 18,
|
||||
In9_Cu = 20,
|
||||
In10_Cu = 22,
|
||||
In11_Cu = 24,
|
||||
In12_Cu = 26,
|
||||
In13_Cu = 28,
|
||||
In14_Cu = 30,
|
||||
In15_Cu = 32,
|
||||
In16_Cu = 34,
|
||||
In17_Cu = 36,
|
||||
In18_Cu = 38,
|
||||
In19_Cu = 40,
|
||||
In20_Cu = 42,
|
||||
In21_Cu = 44,
|
||||
In22_Cu = 46,
|
||||
In23_Cu = 48,
|
||||
In24_Cu = 50,
|
||||
In25_Cu = 52,
|
||||
In26_Cu = 54,
|
||||
In27_Cu = 56,
|
||||
In28_Cu = 58,
|
||||
In29_Cu = 60,
|
||||
In30_Cu = 62,
|
||||
|
||||
B_Adhes,
|
||||
F_Adhes,
|
||||
F_Mask = 1,
|
||||
B_Mask = 3,
|
||||
|
||||
B_Paste,
|
||||
F_Paste,
|
||||
F_SilkS = 5,
|
||||
B_SilkS = 7,
|
||||
F_Adhes = 9,
|
||||
B_Adhes = 11,
|
||||
F_Paste = 13,
|
||||
B_Paste = 15,
|
||||
|
||||
B_SilkS,
|
||||
F_SilkS,
|
||||
Dwgs_User = 17,
|
||||
Cmts_User = 19,
|
||||
Eco1_User = 21,
|
||||
Eco2_User = 23,
|
||||
|
||||
B_Mask,
|
||||
F_Mask, // 39
|
||||
Edge_Cuts = 25,
|
||||
Margin = 27,
|
||||
|
||||
Dwgs_User,
|
||||
Cmts_User,
|
||||
Eco1_User,
|
||||
Eco2_User,
|
||||
Edge_Cuts,
|
||||
Margin, // 45
|
||||
B_CrtYd = 29,
|
||||
F_CrtYd = 31,
|
||||
|
||||
B_CrtYd,
|
||||
F_CrtYd,
|
||||
B_Fab = 33,
|
||||
F_Fab = 35,
|
||||
|
||||
B_Fab,
|
||||
F_Fab, // 49
|
||||
Rescue = 37,
|
||||
|
||||
// User definable layers.
|
||||
User_1,
|
||||
User_2,
|
||||
User_3,
|
||||
User_4,
|
||||
User_5,
|
||||
User_6,
|
||||
User_7,
|
||||
User_8,
|
||||
User_9,
|
||||
User_1 = 39,
|
||||
User_2 = 41,
|
||||
User_3 = 43,
|
||||
User_4 = 45,
|
||||
User_5 = 47,
|
||||
User_6 = 49,
|
||||
User_7 = 51,
|
||||
User_8 = 53,
|
||||
User_9 = 55,
|
||||
|
||||
Rescue, // 59
|
||||
|
||||
// Four reserved layers (60 - 63) for future expansion within the 64 bit integer limit.
|
||||
|
||||
PCB_LAYER_ID_COUNT
|
||||
PCB_LAYER_ID_COUNT = 64
|
||||
};
|
||||
|
||||
constexpr PCB_LAYER_ID PCBNEW_LAYER_ID_START = F_Cu;
|
||||
|
||||
#define MAX_CU_LAYERS (B_Cu - F_Cu + 1)
|
||||
#define MAX_CU_LAYERS 32
|
||||
|
||||
/**
|
||||
* Enum used during connectivity building to ensure we do not query connectivity while building
|
||||
@ -531,7 +529,7 @@ inline bool IsPcbLayer( int aLayer )
|
||||
*/
|
||||
inline bool IsCopperLayer( int aLayerId )
|
||||
{
|
||||
return aLayerId >= F_Cu && aLayerId <= B_Cu;
|
||||
return !( aLayerId & 1 ) && aLayerId <= PCB_LAYER_ID_COUNT;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -542,7 +540,7 @@ inline bool IsCopperLayer( int aLayerId )
|
||||
*/
|
||||
inline bool IsNonCopperLayer( int aLayerId )
|
||||
{
|
||||
return aLayerId > B_Cu && aLayerId <= PCB_LAYER_ID_COUNT;
|
||||
return ( aLayerId & 1 ) && aLayerId <= PCB_LAYER_ID_COUNT;
|
||||
}
|
||||
|
||||
/**
|
||||
|
143
include/layer_range.h
Normal file
143
include/layer_range.h
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2024 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 <layer_ids.h>
|
||||
|
||||
#ifndef LAYER_RANGE_H
|
||||
#define LAYER_RANGE_H
|
||||
|
||||
|
||||
class LAYER_RANGE
|
||||
{
|
||||
private:
|
||||
PCB_LAYER_ID m_start;
|
||||
PCB_LAYER_ID m_stop;
|
||||
int m_layer_count;
|
||||
|
||||
class LAYER_RANGE_ITERATOR
|
||||
{
|
||||
private:
|
||||
int m_current;
|
||||
int m_stop;
|
||||
int m_layer_count;
|
||||
bool m_reverse;
|
||||
|
||||
int next_layer( int aLayer )
|
||||
{
|
||||
if( m_reverse )
|
||||
{
|
||||
if( aLayer == B_Cu )
|
||||
aLayer = m_layer_count == 2 ? F_Cu : static_cast<int>( F_Cu ) + 2 * ( m_layer_count - 2 ) + 2;
|
||||
else if( aLayer == m_stop || aLayer == UNDEFINED_LAYER )
|
||||
aLayer = UNDEFINED_LAYER;
|
||||
else if( aLayer == In1_Cu )
|
||||
aLayer = F_Cu;
|
||||
else
|
||||
aLayer = static_cast<int>( aLayer ) - 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( aLayer == F_Cu && m_layer_count == 2 )
|
||||
aLayer = B_Cu;
|
||||
else if( aLayer == m_stop || aLayer == UNDEFINED_LAYER )
|
||||
aLayer = UNDEFINED_LAYER;
|
||||
else if( aLayer == static_cast<int>( F_Cu ) + 2 * ( m_layer_count - 2 ) + 2)
|
||||
aLayer = B_Cu;
|
||||
else if( aLayer == F_Cu )
|
||||
aLayer = In1_Cu;
|
||||
else
|
||||
aLayer = static_cast<int>( aLayer ) + 2;
|
||||
}
|
||||
|
||||
return aLayer;
|
||||
}
|
||||
|
||||
public:
|
||||
using iterator_category = std::bidirectional_iterator_tag;
|
||||
using value_type = PCB_LAYER_ID;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = PCB_LAYER_ID*;
|
||||
using reference = PCB_LAYER_ID&;
|
||||
|
||||
LAYER_RANGE_ITERATOR( PCB_LAYER_ID start, PCB_LAYER_ID stop, int layer_count ) :
|
||||
m_current( start ), m_stop( stop ), m_layer_count( layer_count )
|
||||
{
|
||||
if( start & 1 || stop & 1 )
|
||||
throw std::invalid_argument( "Only works for copper layers" );
|
||||
|
||||
m_layer_count = m_layer_count & ~1;
|
||||
|
||||
if( stop == B_Cu || m_stop >= m_current )
|
||||
m_reverse = false;
|
||||
else
|
||||
m_reverse = true;
|
||||
}
|
||||
|
||||
PCB_LAYER_ID operator*() const { return static_cast<PCB_LAYER_ID>( m_current ); }
|
||||
|
||||
LAYER_RANGE_ITERATOR& operator++()
|
||||
{
|
||||
m_current = next_layer( m_current );
|
||||
return *this;
|
||||
}
|
||||
|
||||
LAYER_RANGE_ITERATOR operator++( int )
|
||||
{
|
||||
LAYER_RANGE_ITERATOR tmp = *this;
|
||||
++( *this );
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool operator==( const LAYER_RANGE_ITERATOR& other ) const
|
||||
{
|
||||
return m_current == other.m_current;
|
||||
}
|
||||
|
||||
bool operator!=( const LAYER_RANGE_ITERATOR& other ) const { return !( *this == other ); }
|
||||
};
|
||||
|
||||
public:
|
||||
LAYER_RANGE( PCB_LAYER_ID start, PCB_LAYER_ID stop, int layer_count ) :
|
||||
m_start( start ), m_stop( stop ), m_layer_count( layer_count )
|
||||
{
|
||||
if( start & 1 || stop & 1 )
|
||||
throw std::invalid_argument( "Only works for copper layers" );
|
||||
}
|
||||
|
||||
LAYER_RANGE_ITERATOR begin() const { return LAYER_RANGE_ITERATOR( m_start, m_stop, m_layer_count ); }
|
||||
LAYER_RANGE_ITERATOR end() const { auto it = LAYER_RANGE_ITERATOR( m_stop, m_stop, m_layer_count ); return ++it; }
|
||||
|
||||
static bool Contains( int aStart_layer, int aEnd_layer, int aTest_layer )
|
||||
{
|
||||
if( aStart_layer == B_Cu )
|
||||
aStart_layer = INT_MAX;
|
||||
|
||||
if( aEnd_layer == B_Cu )
|
||||
aEnd_layer = INT_MAX;
|
||||
|
||||
return aTest_layer >= aStart_layer && aTest_layer <= aEnd_layer;
|
||||
}
|
||||
|
||||
bool Contains( int aTest_layer )
|
||||
{
|
||||
return Contains( m_start, m_stop, aTest_layer );
|
||||
}
|
||||
};
|
||||
|
||||
#endif // LAYER_RANGE_H
|
119
include/lset.h
119
include/lset.h
@ -24,6 +24,7 @@
|
||||
#include <base_set.h>
|
||||
|
||||
class LSEQ;
|
||||
class LAYER_RANGE;
|
||||
|
||||
/**
|
||||
* LSET is a set of PCB_LAYER_IDs. It can be converted to numerous purpose LSEQs using
|
||||
@ -35,39 +36,19 @@ class KICOMMON_API LSET : public BASE_SET
|
||||
{
|
||||
public:
|
||||
|
||||
// The constructor flavors are carefully chosen to prevent LSET( int ) from compiling.
|
||||
// That excludes "LSET s = 0;" and excludes "LSET s = -1;", etc.
|
||||
// LSET s = 0; needs to be removed from the code, this accomplishes that.
|
||||
// Remember LSET( PCB_LAYER_ID(0) ) sets bit 0, so "LSET s = 0;" is illegal
|
||||
// to prevent that surprise. Therefore LSET's constructor suite is significantly
|
||||
// different than the base class from which it is derived.
|
||||
|
||||
// Other member functions (non-constructor functions) are identical to the base
|
||||
// class's and therefore are re-used from the base class.
|
||||
|
||||
/**
|
||||
* Create an empty (cleared) set.
|
||||
*/
|
||||
LSET() :
|
||||
BASE_SET( PCB_LAYER_ID_COUNT ) // all bits are set to zero in BASE_SET()
|
||||
{
|
||||
}
|
||||
LSET() : BASE_SET( PCB_LAYER_ID_COUNT ) {} // all bits are set to zero in BASE_SET()
|
||||
|
||||
LSET( const BASE_SET& aOther ) :
|
||||
BASE_SET( aOther )
|
||||
{
|
||||
}
|
||||
|
||||
LSET( PCB_LAYER_ID aLayer ) :
|
||||
BASE_SET( PCB_LAYER_ID_COUNT )
|
||||
{
|
||||
set( aLayer );
|
||||
}
|
||||
LSET( const BASE_SET& aOther ) : BASE_SET( aOther ) {}
|
||||
|
||||
LSET( std::initializer_list<PCB_LAYER_ID> aList );
|
||||
|
||||
LSET( const LSEQ& aSeq );
|
||||
|
||||
LSET( const LAYER_RANGE& aRange );
|
||||
|
||||
LSET( unsigned long __val ) = delete;
|
||||
|
||||
/**
|
||||
@ -91,7 +72,18 @@ public:
|
||||
/**
|
||||
* Return the fixed name association with aLayerId.
|
||||
*/
|
||||
static const wxChar* Name( PCB_LAYER_ID aLayerId );
|
||||
static wxString Name( PCB_LAYER_ID aLayerId );
|
||||
|
||||
/**
|
||||
* Return the layer number from a layer name.
|
||||
*/
|
||||
static int NameToLayer( wxString& aName );
|
||||
|
||||
/**
|
||||
* Return true if aLayer is between aStart and aEnd, inclusive. Takes into
|
||||
* account the direction of the layers and the fact that B_Cu comes before In*_Cu
|
||||
*/
|
||||
static bool IsBetween( PCB_LAYER_ID aStart, PCB_LAYER_ID aEnd, PCB_LAYER_ID aLayer );
|
||||
|
||||
/**
|
||||
* Return a complete set of internal copper layers which is all Cu layers
|
||||
@ -192,24 +184,20 @@ public:
|
||||
|
||||
/**
|
||||
* Return a sequence of copper layers in starting from the front/top
|
||||
* and extending to the back/bottom. This specific sequence is depended upon
|
||||
* in numerous places.
|
||||
* and extending to the back/bottom.
|
||||
*/
|
||||
LSEQ CuStack() const;
|
||||
|
||||
/**
|
||||
* Return a sequence of technical layers. A sequence provides a certain order.
|
||||
* Returns the technical and user layers in the order shown in layer widget
|
||||
*
|
||||
* @param aSubToOmit is the subset of the technical layers to omit, defaults to none.
|
||||
*/
|
||||
LSEQ Technicals( LSET aSubToOmit = LSET() ) const;
|
||||
|
||||
/// *_User layers.
|
||||
LSEQ Users() const;
|
||||
|
||||
/// Returns the technical and user layers in the order shown in layer widget
|
||||
LSEQ TechAndUserUIOrder() const;
|
||||
|
||||
/**
|
||||
* Returns the copper, technical and user layers in the order shown in layer widget
|
||||
*
|
||||
*/
|
||||
LSEQ UIOrder() const;
|
||||
|
||||
/**
|
||||
@ -217,10 +205,7 @@ public:
|
||||
* element will be in the same sequence as aWishListSequence if they are present.
|
||||
* @param aWishListSequence establishes the order of the returned LSEQ, and the LSEQ will only
|
||||
* contain PCB_LAYER_IDs which are present in this set.
|
||||
* @param aCount is the length of aWishListSequence array.
|
||||
*/
|
||||
LSEQ Seq( const PCB_LAYER_ID* aWishListSequence, unsigned aCount ) const;
|
||||
|
||||
LSEQ Seq( const LSEQ& aSequence ) const;
|
||||
|
||||
/**
|
||||
@ -295,5 +280,63 @@ public:
|
||||
*/
|
||||
LSET& Flip( int aCopperLayersCount = 0 );
|
||||
|
||||
/**
|
||||
* Return the number of layers between aStart and aEnd, inclusive.
|
||||
*/
|
||||
static int LayerCount( PCB_LAYER_ID aStart, PCB_LAYER_ID aEnd, int aCopperLayerCount );
|
||||
|
||||
#ifndef SWIG
|
||||
// Custom iterator to iterate over all set bits
|
||||
class all_set_layers_iterator : public BASE_SET::set_bits_iterator
|
||||
{
|
||||
public:
|
||||
all_set_layers_iterator( const BASE_SET& set, size_t index ) :
|
||||
BASE_SET::set_bits_iterator( set, index )
|
||||
{
|
||||
}
|
||||
|
||||
PCB_LAYER_ID operator*() const { return PCB_LAYER_ID( BASE_SET::set_bits_iterator::operator*() ); }
|
||||
|
||||
all_set_layers_iterator& operator++()
|
||||
{
|
||||
BASE_SET::set_bits_iterator::operator++();
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
all_set_layers_iterator begin() const { return all_set_layers_iterator( *this, 0 ); }
|
||||
all_set_layers_iterator end() const { return all_set_layers_iterator( *this, size() ); }
|
||||
|
||||
// Custom iterators for Copper and Non-Copper layers
|
||||
class copper_layers_iterator : public BASE_SET::set_bits_iterator
|
||||
{
|
||||
public:
|
||||
copper_layers_iterator( const BASE_SET& set, size_t index );
|
||||
PCB_LAYER_ID operator*() const;
|
||||
copper_layers_iterator& operator++();
|
||||
|
||||
private:
|
||||
void advance_to_next_set_copper_bit();
|
||||
void next_copper_layer();
|
||||
};
|
||||
|
||||
class non_copper_layers_iterator : public BASE_SET::set_bits_iterator
|
||||
{
|
||||
public:
|
||||
non_copper_layers_iterator( const BASE_SET& set, size_t index );
|
||||
PCB_LAYER_ID operator*() const;
|
||||
non_copper_layers_iterator& operator++();
|
||||
|
||||
private:
|
||||
void advance_to_next_set_non_copper_bit();
|
||||
};
|
||||
|
||||
copper_layers_iterator copper_layers_begin() const;
|
||||
copper_layers_iterator copper_layers_end() const;
|
||||
non_copper_layers_iterator non_copper_layers_begin() const;
|
||||
non_copper_layers_iterator non_copper_layers_end() const;
|
||||
|
||||
#endif
|
||||
|
||||
};
|
||||
#endif // LSET_H
|
||||
|
@ -50,9 +50,9 @@ CLI::PCB_EXPORT_BASE_COMMAND::PCB_EXPORT_BASE_COMMAND( const std::string& aName,
|
||||
//m_layerIndices[untranslated] = PCB_LAYER_ID( layer );
|
||||
|
||||
// Add layer name used in pcb files
|
||||
m_layerMasks[untranslated] = LSET( PCB_LAYER_ID( layer ) );
|
||||
m_layerMasks[untranslated] = LSET( { PCB_LAYER_ID( layer ) } );
|
||||
// Add layer name using GUI canonical layer name
|
||||
m_layerGuiMasks[ TO_UTF8(LayerName( layer ) ) ] = LSET( PCB_LAYER_ID( layer ) );
|
||||
m_layerGuiMasks[ TO_UTF8(LayerName( layer ) ) ] = LSET( { PCB_LAYER_ID( layer ) } );
|
||||
}
|
||||
|
||||
// Add list of grouped layer names used in pcb files
|
||||
|
@ -571,7 +571,7 @@ int AR_AUTOPLACER::getOptimalFPPlacement( FOOTPRINT* aFootprint )
|
||||
|
||||
if( m_matrix.m_RoutingLayersCount > 1 )
|
||||
{
|
||||
LSET other( aFootprint->GetLayer() == B_Cu ? F_Cu : B_Cu );
|
||||
LSET other( { aFootprint->GetLayer() == B_Cu ? F_Cu : B_Cu } );
|
||||
|
||||
for( PAD* pad : aFootprint->Pads() )
|
||||
{
|
||||
|
@ -2121,7 +2121,7 @@ PAD* BOARD::GetPad( const PCB_TRACK* aTrace, ENDPOINT_T aEndPoint ) const
|
||||
{
|
||||
const VECTOR2I& aPosition = aTrace->GetEndPoint( aEndPoint );
|
||||
|
||||
LSET lset( aTrace->GetLayer() );
|
||||
LSET lset( { aTrace->GetLayer() } );
|
||||
|
||||
return GetPad( aPosition, lset );
|
||||
}
|
||||
|
@ -103,6 +103,39 @@ const KIFONT::METRICS& BOARD_ITEM::GetFontMetrics() const
|
||||
}
|
||||
|
||||
|
||||
int BOARD_ITEM::BoardLayerCount() const
|
||||
{
|
||||
const BOARD* board = GetBoard();
|
||||
|
||||
if( board )
|
||||
return board->GetLayerSet().count();
|
||||
|
||||
return 64;
|
||||
}
|
||||
|
||||
|
||||
int BOARD_ITEM::BoardCopperLayerCount() const
|
||||
{
|
||||
const BOARD* board = GetBoard();
|
||||
|
||||
if( board )
|
||||
return board->GetCopperLayerCount();
|
||||
|
||||
return 32;
|
||||
}
|
||||
|
||||
|
||||
LSET BOARD_ITEM::BoardLayerSet() const
|
||||
{
|
||||
const BOARD* board = GetBoard();
|
||||
|
||||
if( board )
|
||||
return board->GetLayerSet();
|
||||
|
||||
return LSET::AllLayersMask();
|
||||
}
|
||||
|
||||
|
||||
wxString BOARD_ITEM::GetLayerName() const
|
||||
{
|
||||
if( const BOARD* board = GetBoard() )
|
||||
|
@ -703,7 +703,7 @@ void CN_CONNECTIVITY_ALGO::FillIsolatedIslandsMap(
|
||||
{
|
||||
for( CN_ITEM* item : *cluster )
|
||||
{
|
||||
if( item->Parent() == zone && item->Layer() == layer )
|
||||
if( item->Parent() == zone && item->GetBoardLayer() == layer )
|
||||
{
|
||||
CN_ZONE_LAYER* z = static_cast<CN_ZONE_LAYER*>( item );
|
||||
|
||||
|
@ -447,7 +447,7 @@ bool CONNECTIVITY_DATA::IsConnectedOnLayer( const BOARD_CONNECTED_ITEM *aItem, i
|
||||
CN_ZONE_LAYER* zoneLayer = dynamic_cast<CN_ZONE_LAYER*>( connected );
|
||||
|
||||
if( connected->Valid()
|
||||
&& connected->Layers().Overlaps( aLayer )
|
||||
&& connected->StartLayer() <= aLayer && connected->EndLayer() >= aLayer
|
||||
&& matchType( connected->Parent()->Type() )
|
||||
&& connected->Net() == aItem->GetNetCode() )
|
||||
{
|
||||
|
@ -152,7 +152,7 @@ CN_ITEM* CN_LIST::Add( PAD* pad )
|
||||
|
||||
auto item = new CN_ITEM( pad, false, 1 );
|
||||
item->AddAnchor( pad->ShapePos() );
|
||||
item->SetLayers( LAYER_RANGE( F_Cu, B_Cu ) );
|
||||
item->SetLayers( F_Cu, B_Cu );
|
||||
|
||||
switch( pad->GetAttribute() )
|
||||
{
|
||||
@ -160,16 +160,11 @@ CN_ITEM* CN_LIST::Add( PAD* pad )
|
||||
case PAD_ATTRIB::NPTH:
|
||||
case PAD_ATTRIB::CONN:
|
||||
{
|
||||
LSET lmsk = pad->GetLayerSet();
|
||||
LSEQ lmsk = pad->GetLayerSet().CuStack();
|
||||
|
||||
if( !lmsk.empty() )
|
||||
item->SetLayer( lmsk.front() );
|
||||
|
||||
for( int i = 0; i <= MAX_CU_LAYERS; i++ )
|
||||
{
|
||||
if( lmsk[i] )
|
||||
{
|
||||
item->SetLayer( i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -216,7 +211,7 @@ CN_ITEM* CN_LIST::Add( PCB_VIA* via )
|
||||
m_items.push_back( item );
|
||||
item->AddAnchor( via->GetStart() );
|
||||
|
||||
item->SetLayers( LAYER_RANGE( via->TopLayer(), via->BottomLayer() ) );
|
||||
item->SetLayers( via->TopLayer(), via->BottomLayer() );
|
||||
addItemtoTree( item );
|
||||
SetDirty();
|
||||
return item;
|
||||
@ -358,7 +353,7 @@ bool CN_ANCHOR::IsDangling() const
|
||||
{
|
||||
ZONE* zone = static_cast<ZONE*>( item->Parent() );
|
||||
|
||||
if( zone->HitTestFilledArea( ToLAYER_ID( item->Layer() ), Pos(), accuracy ) )
|
||||
if( zone->HitTestFilledArea( item->GetBoardLayer(), Pos(), accuracy ) )
|
||||
connected_count++;
|
||||
}
|
||||
else if( item->Parent()->HitTest( Pos(), accuracy ) )
|
||||
@ -384,7 +379,7 @@ int CN_ANCHOR::ConnectedItemsCount() const
|
||||
{
|
||||
ZONE* zone = static_cast<ZONE*>( item->Parent() );
|
||||
|
||||
if( zone->HitTestFilledArea( ToLAYER_ID( item->Layer() ), Pos() ) )
|
||||
if( zone->HitTestFilledArea( item->GetBoardLayer(), Pos() ) )
|
||||
connected_count++;
|
||||
}
|
||||
else if( item->Parent()->HitTest( Pos() ) )
|
||||
|
@ -142,7 +142,8 @@ public:
|
||||
m_valid = true;
|
||||
m_dirty = true;
|
||||
m_anchors.reserve( std::max( 6, aAnchorCount ) );
|
||||
m_layers = LAYER_RANGE( 0, PCB_LAYER_ID_COUNT );
|
||||
m_start_layer = 0;
|
||||
m_end_layer = std::numeric_limits<int>::max();
|
||||
m_connected.reserve( 8 );
|
||||
}
|
||||
|
||||
@ -167,26 +168,55 @@ public:
|
||||
bool Dirty() const { return m_dirty; }
|
||||
|
||||
/**
|
||||
* Set the layers spanned by the item to aLayers.
|
||||
* Set the layers spanned by the item to aStartLayer and aEndLayer.
|
||||
*/
|
||||
void SetLayers( const LAYER_RANGE& aLayers ) { m_layers = aLayers; }
|
||||
void SetLayers( int aStartLayer, int aEndLayer )
|
||||
{
|
||||
// B_Cu is nominally layer 2 but we reset it to INT_MAX to ensure that it is
|
||||
// always greater than any other layer in the RTree
|
||||
if( aStartLayer == B_Cu )
|
||||
aStartLayer = std::numeric_limits<int>::max();
|
||||
|
||||
if( aEndLayer == B_Cu )
|
||||
aEndLayer = std::numeric_limits<int>::max();
|
||||
|
||||
m_start_layer = aStartLayer;
|
||||
m_end_layer = aEndLayer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the layers spanned by the item to a single layer aLayer.
|
||||
*/
|
||||
void SetLayer( int aLayer ) { m_layers = LAYER_RANGE( aLayer, aLayer ); }
|
||||
void SetLayer( int aLayer ) { SetLayers( aLayer, aLayer ); }
|
||||
|
||||
/**
|
||||
* Return the contiguous set of layers spanned by the item.
|
||||
*/
|
||||
const LAYER_RANGE& Layers() const { return m_layers; }
|
||||
int StartLayer() const { return m_start_layer; }
|
||||
int EndLayer() const { return m_end_layer; }
|
||||
|
||||
/**
|
||||
* Return the item's layer, for single-layered items only.
|
||||
* N.B. This should only be used inside connectivity as B_Cu
|
||||
* is mapped to a large int
|
||||
*/
|
||||
virtual int Layer() const
|
||||
{
|
||||
return Layers().Start();
|
||||
return StartLayer();
|
||||
}
|
||||
|
||||
/**
|
||||
* When using CN_ITEM layers to compare against board items,
|
||||
* use this function which correctly remaps the B_Cu layer
|
||||
*/
|
||||
PCB_LAYER_ID GetBoardLayer() const
|
||||
{
|
||||
int layer = Layer();
|
||||
|
||||
if( layer == std::numeric_limits<int>::max() )
|
||||
layer = B_Cu;
|
||||
|
||||
return ToLAYER_ID( layer );
|
||||
}
|
||||
|
||||
const BOX2I& BBox()
|
||||
@ -232,7 +262,8 @@ public:
|
||||
protected:
|
||||
bool m_dirty; ///< used to identify recently added item not yet
|
||||
///< scanned into the connectivity search
|
||||
LAYER_RANGE m_layers; ///< layer range over which the item exists
|
||||
int m_start_layer; ///< start layer of the item N.B. B_Cu is set to INT_MAX
|
||||
int m_end_layer; ///< end layer of the item N.B. B_Cu is set to INT_MAX
|
||||
BOX2I m_bbox; ///< bounding box for the item
|
||||
|
||||
private:
|
||||
@ -264,7 +295,7 @@ public:
|
||||
m_layer( aLayer )
|
||||
{
|
||||
m_fillPoly = aParent->GetFilledPolysList( aLayer );
|
||||
SetLayers( aLayer );
|
||||
SetLayers( aLayer, aLayer );
|
||||
}
|
||||
|
||||
void BuildRTree()
|
||||
@ -399,7 +430,7 @@ public:
|
||||
template <class T>
|
||||
void FindNearby( CN_ITEM* aItem, T aFunc )
|
||||
{
|
||||
m_index.Query( aItem->BBox(), aItem->Layers(), aFunc );
|
||||
m_index.Query( aItem->BBox(), aItem->StartLayer(), aItem->EndLayer(), aFunc );
|
||||
}
|
||||
|
||||
void SetHasInvalid( bool aInvalid = true ) { m_hasInvalid = aInvalid; }
|
||||
|
@ -56,11 +56,10 @@ public:
|
||||
*/
|
||||
void Insert( T aItem )
|
||||
{
|
||||
const BOX2I& bbox = aItem->BBox();
|
||||
const LAYER_RANGE layers = aItem->Layers();
|
||||
const BOX2I& bbox = aItem->BBox();
|
||||
|
||||
const int mmin[3] = { layers.Start(), bbox.GetX(), bbox.GetY() };
|
||||
const int mmax[3] = { layers.End(), bbox.GetRight(), bbox.GetBottom() };
|
||||
const int mmin[3] = { aItem->StartLayer(), bbox.GetX(), bbox.GetY() };
|
||||
const int mmax[3] = { aItem->EndLayer(), bbox.GetRight(), bbox.GetBottom() };
|
||||
|
||||
m_tree->Insert( mmin, mmax, aItem );
|
||||
}
|
||||
@ -75,9 +74,9 @@ public:
|
||||
|
||||
// First, attempt to remove the item using its given BBox
|
||||
const BOX2I& bbox = aItem->BBox();
|
||||
const LAYER_RANGE layers = aItem->Layers();
|
||||
const int mmin[3] = { layers.Start(), bbox.GetX(), bbox.GetY() };
|
||||
const int mmax[3] = { layers.End(), bbox.GetRight(), bbox.GetBottom() };
|
||||
|
||||
const int mmin[3] = { aItem->StartLayer(), bbox.GetX(), bbox.GetY() };
|
||||
const int mmax[3] = { aItem->EndLayer(), bbox.GetRight(), bbox.GetBottom() };
|
||||
|
||||
// If we are not successful ( 1 == not found ), then we expand
|
||||
// the search to the full tree
|
||||
@ -107,10 +106,13 @@ public:
|
||||
* with aBounds.
|
||||
*/
|
||||
template <class Visitor>
|
||||
void Query( const BOX2I& aBounds, const LAYER_RANGE& aRange, Visitor& aVisitor ) const
|
||||
void Query( const BOX2I& aBounds, int aStartLayer, int aEndLayer, Visitor& aVisitor ) const
|
||||
{
|
||||
const int mmin[3] = { aRange.Start(), aBounds.GetX(), aBounds.GetY() };
|
||||
const int mmax[3] = { aRange.End(), aBounds.GetRight(), aBounds.GetBottom() };
|
||||
int start_layer = aStartLayer == B_Cu ? INT_MAX : aStartLayer;
|
||||
int end_layer = aEndLayer == B_Cu ? INT_MAX : aEndLayer;
|
||||
|
||||
const int mmin[3] = { start_layer, aBounds.GetX(), aBounds.GetY() };
|
||||
const int mmax[3] = { end_layer, aBounds.GetRight(), aBounds.GetBottom() };
|
||||
|
||||
m_tree->Search( mmin, mmax, aVisitor );
|
||||
}
|
||||
|
@ -510,7 +510,7 @@ void DIALOG_DRC::OnDRCItemSelected( wxDataViewEvent& aEvent )
|
||||
|
||||
WINDOW_THAWER thawer( m_frame );
|
||||
|
||||
if( principalLayer > UNDEFINED_LAYER && ( violationLayers & board->GetVisibleLayers() ) == 0 )
|
||||
if( principalLayer > UNDEFINED_LAYER && ( violationLayers & board->GetVisibleLayers() ).none() )
|
||||
m_frame->GetAppearancePanel()->SetLayerVisible( principalLayer, true );
|
||||
|
||||
if( principalLayer > UNDEFINED_LAYER && board->GetVisibleLayers().test( principalLayer ) )
|
||||
|
@ -292,7 +292,7 @@ void DIALOG_FOOTPRINT_CHECKER::OnSelectItem( wxDataViewEvent& aEvent )
|
||||
m_frame->FocusOnItem( item );
|
||||
m_frame->GetCanvas()->Refresh();
|
||||
|
||||
if( ( violationLayers & board->GetVisibleLayers() ) == 0 )
|
||||
if( ( violationLayers & board->GetVisibleLayers() ).none() )
|
||||
{
|
||||
m_frame->GetAppearancePanel()->SetLayerVisible( principalLayer, true );
|
||||
m_frame->GetCanvas()->Refresh();
|
||||
|
@ -500,7 +500,7 @@ void DIALOG_PLOT::OnRightClickLayers( wxMouseEvent& event )
|
||||
{
|
||||
for( unsigned i = 0; i < m_layerList.size(); i++ )
|
||||
{
|
||||
LSET layermask( m_layerList[ i ] );
|
||||
LSET layermask( { m_layerList[ i ] } );
|
||||
|
||||
if( ( layermask & fab_layer_set ).any() )
|
||||
m_layerCheckListBox->Check( i, true );
|
||||
|
@ -358,7 +358,7 @@ void DIALOG_PRINT_PCBNEW::onPopUpLayers( wxCommandEvent& event )
|
||||
case ID_SELECT_FAB_LAYERS: // Select layers usually needed to build a board
|
||||
for( unsigned i = 0; i < m_layerList.size(); i++ )
|
||||
{
|
||||
LSET layermask( m_layerList[ i ] );
|
||||
LSET layermask( { m_layerList[ i ] } );
|
||||
|
||||
if( ( layermask & fab_layer_set ).any() )
|
||||
m_layerCheckListBox->Check( i, true );
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
class LAYER_GRID_TABLE : public wxGridTableBase
|
||||
{
|
||||
int m_layers[MAX_CU_LAYERS][2];
|
||||
std::vector<std::pair<PCB_LAYER_ID, PCB_LAYER_ID>> m_layers;
|
||||
int m_layerCount;
|
||||
|
||||
public:
|
||||
@ -56,12 +56,25 @@ public:
|
||||
|
||||
long GetValueAsLong( int row, int col ) override
|
||||
{
|
||||
return m_layers[ row ][ col ];
|
||||
if( row < 0 || row >= m_layerCount )
|
||||
return -1;
|
||||
|
||||
if( col < 0 || col >= 2 )
|
||||
return -1;
|
||||
|
||||
return col == 0 ? m_layers[ row ].first : m_layers[ row ].second;
|
||||
}
|
||||
|
||||
void SetValueAsLong( int row, int col, long value ) override
|
||||
{
|
||||
m_layers[ row ][ col ] = value;
|
||||
if( row < 0 || col < 0 || col >= 2 )
|
||||
return;
|
||||
|
||||
if( row >= m_layerCount )
|
||||
m_layers.resize( row + 1 );
|
||||
|
||||
col == 0 ? m_layers[row].first = ToLAYER_ID( value )
|
||||
: m_layers[row].second = ToLAYER_ID( value );
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -907,7 +907,7 @@ void PANEL_SETUP_LAYERS::addUserDefinedLayer( wxCommandEvent& aEvent )
|
||||
|
||||
wxCHECK( layer >= User_1 && layer <= User_9, /* void */ );
|
||||
|
||||
LSET newLayer( layer );
|
||||
LSET newLayer( { layer } );
|
||||
|
||||
m_enabledLayers |= newLayer;
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <math_for_graphics.h>
|
||||
#include <board_design_settings.h>
|
||||
#include <footprint.h>
|
||||
#include <layer_range.h>
|
||||
#include <pcb_shape.h>
|
||||
#include <pad.h>
|
||||
#include <pcb_track.h>
|
||||
@ -113,7 +114,7 @@ private:
|
||||
: layers(), has_error( false ) {}
|
||||
|
||||
checked( PCB_LAYER_ID aLayer )
|
||||
: layers( aLayer ), has_error( false ) {}
|
||||
: layers( { aLayer } ), has_error( false ) {}
|
||||
|
||||
LSET layers;
|
||||
bool has_error;
|
||||
@ -1280,10 +1281,10 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones()
|
||||
return invalid_result;
|
||||
};
|
||||
|
||||
for( int layer_id = F_Cu; layer_id <= B_Cu; ++layer_id )
|
||||
|
||||
for( PCB_LAYER_ID layer : LAYER_RANGE( F_Cu, B_Cu, m_board->GetCopperLayerCount() ) )
|
||||
{
|
||||
PCB_LAYER_ID layer = static_cast<PCB_LAYER_ID>( layer_id );
|
||||
int zone2zoneClearance;
|
||||
int zone2zoneClearance;
|
||||
|
||||
// Skip over layers not used on the current board
|
||||
if( !m_board->IsLayerEnabled( layer ) )
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <board.h>
|
||||
#include <board_design_settings.h>
|
||||
#include <footprint.h>
|
||||
#include <layer_range.h>
|
||||
#include <pad.h>
|
||||
#include <pcb_track.h>
|
||||
#include <vector>
|
||||
@ -72,7 +73,7 @@ static int compute_pad_access_code( BOARD *aPcb, LSET aLayerMask )
|
||||
// OK, we have an inner-layer only pad (and I have no idea about
|
||||
// what could be used for); anyway, find the first copper layer
|
||||
// it's on
|
||||
for( int layer = In1_Cu; layer < B_Cu; ++layer )
|
||||
for( PCB_LAYER_ID layer : LAYER_RANGE( In1_Cu, B_Cu, aPcb->GetCopperLayerCount() ) )
|
||||
{
|
||||
if( aLayerMask[layer] )
|
||||
return layer + 1;
|
||||
|
@ -88,42 +88,6 @@ static std::string GenCADLayerName( int aCuCount, PCB_LAYER_ID aId )
|
||||
}
|
||||
|
||||
|
||||
static const PCB_LAYER_ID gc_seq[] = {
|
||||
B_Cu,
|
||||
In30_Cu,
|
||||
In29_Cu,
|
||||
In28_Cu,
|
||||
In27_Cu,
|
||||
In26_Cu,
|
||||
In25_Cu,
|
||||
In24_Cu,
|
||||
In23_Cu,
|
||||
In22_Cu,
|
||||
In21_Cu,
|
||||
In20_Cu,
|
||||
In19_Cu,
|
||||
In18_Cu,
|
||||
In17_Cu,
|
||||
In16_Cu,
|
||||
In15_Cu,
|
||||
In14_Cu,
|
||||
In13_Cu,
|
||||
In12_Cu,
|
||||
In11_Cu,
|
||||
In10_Cu,
|
||||
In9_Cu,
|
||||
In8_Cu,
|
||||
In7_Cu,
|
||||
In6_Cu,
|
||||
In5_Cu,
|
||||
In4_Cu,
|
||||
In3_Cu,
|
||||
In2_Cu,
|
||||
In1_Cu,
|
||||
F_Cu,
|
||||
};
|
||||
|
||||
|
||||
// flipped layer name for Gencad export (to make CAM350 imports correct)
|
||||
static std::string GenCADLayerNameFlipped( int aCuCount, PCB_LAYER_ID aId )
|
||||
{
|
||||
@ -300,6 +264,9 @@ void GENCAD_EXPORTER::CreatePadsShapesSection()
|
||||
|
||||
padstacks.resize( 1 ); // We count pads from 1
|
||||
|
||||
LSEQ gc_seq = m_board->GetEnabledLayers().CuStack();
|
||||
std::reverse(gc_seq.begin(), gc_seq.end());
|
||||
|
||||
// The master layermask (i.e. the enabled layers) for padstack generation
|
||||
LSET master_layermask = m_board->GetDesignSettings().GetEnabledLayers();
|
||||
int cu_count = m_board->GetCopperLayerCount();
|
||||
@ -589,7 +556,7 @@ void GENCAD_EXPORTER::CreatePadsShapesSection()
|
||||
fmt_mask( mask ).c_str(),
|
||||
via->GetDrillValue() / SCALE_FACTOR );
|
||||
|
||||
for( PCB_LAYER_ID layer : mask.Seq( gc_seq, arrayDim( gc_seq ) ) )
|
||||
for( PCB_LAYER_ID layer : mask.Seq( gc_seq ) )
|
||||
{
|
||||
fprintf( m_file, "PAD V%d.%d.%s %s 0 0\n",
|
||||
via->GetWidth(), via->GetDrillValue(),
|
||||
@ -613,7 +580,7 @@ void GENCAD_EXPORTER::CreatePadsShapesSection()
|
||||
LSET pad_set = pad->GetLayerSet() & master_layermask;
|
||||
|
||||
// the special gc_seq
|
||||
for( PCB_LAYER_ID layer : pad_set.Seq( gc_seq, arrayDim( gc_seq ) ) )
|
||||
for( PCB_LAYER_ID layer : pad_set.Seq( gc_seq ) )
|
||||
{
|
||||
fprintf( m_file, "PAD P%u %s 0 0\n", i, GenCADLayerName( cu_count, layer ).c_str() );
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ bool EXPORT_SVG::Plot( BOARD* aBoard, const PCB_PLOT_SVG_OPTIONS& aSvgPlotOption
|
||||
plot_opts.SetCrossoutDNPFPsOnFabLayers( aSvgPlotOptions.m_crossoutDNPFPsOnFabLayers );
|
||||
|
||||
// Adding drill marks, for copper layers
|
||||
if( ( LSET( aSvgPlotOptions.m_printMaskLayer ) & LSET::AllCuMask() ).any() )
|
||||
if( ( LSET( { aSvgPlotOptions.m_printMaskLayer } ) & LSET::AllCuMask() ).any() )
|
||||
{
|
||||
switch( aSvgPlotOptions.m_drillShapeOption )
|
||||
{
|
||||
|
@ -105,7 +105,7 @@ bool GENDRILL_WRITER_BASE::genDrillMapFile( const wxString& aFullFileName, PLOT_
|
||||
// Calculate dimensions and center of PCB. The Edge_Cuts layer must be visible
|
||||
// to calculate the board edges bounding box
|
||||
LSET visibleLayers = m_pcb->GetVisibleLayers();
|
||||
m_pcb->SetVisibleLayers( visibleLayers | LSET( Edge_Cuts ) );
|
||||
m_pcb->SetVisibleLayers( visibleLayers | LSET( { Edge_Cuts } ) );
|
||||
BOX2I bbbox = m_pcb->GetBoardEdgesBoundingBox();
|
||||
m_pcb->SetVisibleLayers( visibleLayers );
|
||||
|
||||
@ -236,7 +236,7 @@ bool GENDRILL_WRITER_BASE::genDrillMapFile( const wxString& aFullFileName, PLOT_
|
||||
BRDITEMS_PLOTTER itemplotter( plotter, m_pcb, plot_opts );
|
||||
|
||||
// Use attributes of a drawing layer (we are not really draw the Edge.Cuts layer)
|
||||
itemplotter.SetLayerSet( Dwgs_User );
|
||||
itemplotter.SetLayerSet( { Dwgs_User } );
|
||||
|
||||
for( BOARD_ITEM* item : m_pcb->Drawings() )
|
||||
{
|
||||
|
@ -338,7 +338,7 @@ void GERBER_JOBFILE_WRITER::addJSONFilesAttributes()
|
||||
|
||||
nlohmann::ordered_json file_json;
|
||||
|
||||
if( layer <= B_Cu )
|
||||
if( IsCopperLayer( layer ) )
|
||||
{
|
||||
gbr_layer_id = wxT( "Copper,L" );
|
||||
|
||||
|
@ -124,7 +124,7 @@ int PLACEFILE_GERBER_WRITER::CreatePlaceFile( wxString& aFullFilename, PCB_LAYER
|
||||
// defined size for component outlines
|
||||
int line_thickness = pcbIUScale.mmToIU( 0.1 );
|
||||
|
||||
brd_plotter.SetLayerSet( LSET( aLayer ) );
|
||||
brd_plotter.SetLayerSet( LSET( { aLayer } ) );
|
||||
int cmp_count = 0;
|
||||
const bool allowUtf8 = true;
|
||||
const bool quoteOption = false;
|
||||
@ -291,9 +291,9 @@ int PLACEFILE_GERBER_WRITER::CreatePlaceFile( wxString& aFullFilename, PCB_LAYER
|
||||
// Plot board outlines, if requested
|
||||
if( aIncludeBrdEdges )
|
||||
{
|
||||
brd_plotter.SetLayerSet( LSET( Edge_Cuts ) );
|
||||
brd_plotter.SetLayerSet( LSET( { Edge_Cuts } ) );
|
||||
|
||||
// Plot edge layer and graphic items
|
||||
// Plot edge layer and graphic items
|
||||
for( const BOARD_ITEM* item : m_pcb->Drawings() )
|
||||
brd_plotter.PlotBoardGraphicItem( item );
|
||||
|
||||
|
@ -1301,7 +1301,7 @@ bool PCB_TUNING_PATTERN::Update( GENERATOR_TOOL* aTool, BOARD* aBoard, BOARD_COM
|
||||
KIGFX::VIEW* view = aTool->GetManager()->GetView();
|
||||
PNS::ROUTER* router = aTool->Router();
|
||||
PNS_KICAD_IFACE* iface = aTool->GetInterface();
|
||||
int layer = GetLayer();
|
||||
PCB_LAYER_ID layer = GetLayer();
|
||||
|
||||
auto hideRemovedItems = [&]( bool aHide )
|
||||
{
|
||||
@ -1318,7 +1318,7 @@ bool PCB_TUNING_PATTERN::Update( GENERATOR_TOOL* aTool, BOARD* aBoard, BOARD_COM
|
||||
}
|
||||
};
|
||||
|
||||
iface->SetStartLayer( layer );
|
||||
iface->SetStartLayerFromPCBNew( layer );
|
||||
|
||||
if( router->RoutingInProgress() )
|
||||
{
|
||||
@ -1984,7 +1984,9 @@ std::vector<EDA_ITEM*> PCB_TUNING_PATTERN::GetPreviewItems( GENERATOR_TOOL* aToo
|
||||
PNS::ITEM_SET items = placer->TunedPath();
|
||||
|
||||
for( PNS::ITEM* item : items )
|
||||
previewItems.push_back( new ROUTER_PREVIEW_ITEM( item, view, PNS_HOVER_ITEM ) );
|
||||
previewItems.push_back( new ROUTER_PREVIEW_ITEM( item,
|
||||
aTool->Router()->GetInterface(),
|
||||
view, PNS_HOVER_ITEM ) );
|
||||
}
|
||||
|
||||
TUNING_STATUS_VIEW_ITEM* statusItem = new TUNING_STATUS_VIEW_ITEM( aFrame );
|
||||
|
@ -222,7 +222,7 @@ FOOTPRINT* MICROWAVE_TOOL::createBaseFootprint( const wxString& aValue,
|
||||
pad->SetPosition( footprint->GetPosition() );
|
||||
pad->SetShape( PAD_SHAPE::RECTANGLE );
|
||||
pad->SetAttribute( PAD_ATTRIB::SMD );
|
||||
pad->SetLayerSet( F_Cu );
|
||||
pad->SetLayerSet( { F_Cu } );
|
||||
|
||||
pad->SetNumber( wxString::Format( wxT( "%d" ), pad_num ) );
|
||||
pad_num++;
|
||||
|
@ -437,7 +437,7 @@ FOOTPRINT* MICROWAVE_TOOL::createMicrowaveInductor( MICROWAVE_INDUCTOR_PATTERN&
|
||||
|
||||
pad->SetSize( VECTOR2I( aInductorPattern.m_Width, aInductorPattern.m_Width ) );
|
||||
|
||||
pad->SetLayerSet( LSET( footprint->GetLayer() ) );
|
||||
pad->SetLayerSet( LSET( { footprint->GetLayer() } ) );
|
||||
pad->SetAttribute( PAD_ATTRIB::SMD );
|
||||
pad->SetShape( PAD_SHAPE::CIRCLE );
|
||||
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <geometry/shape_rect.h>
|
||||
#include <geometry/shape_compound.h>
|
||||
#include <geometry/shape_null.h>
|
||||
#include <layer_range.h>
|
||||
#include <string_utils.h>
|
||||
#include <i18n_utility.h>
|
||||
#include <view/view.h>
|
||||
@ -102,7 +103,8 @@ PAD::PAD( FOOTPRINT* parent ) :
|
||||
SetDirty();
|
||||
m_effectiveBoundingRadius = 0;
|
||||
|
||||
m_zoneLayerOverrides.fill( ZLO_NONE );
|
||||
for( PCB_LAYER_ID layer : LAYER_RANGE( F_Cu, B_Cu, BoardCopperLayerCount() ) )
|
||||
m_zoneLayerOverrides[layer] = ZLO_NONE;
|
||||
}
|
||||
|
||||
|
||||
@ -185,6 +187,30 @@ bool PAD::Deserialize( const google::protobuf::Any &aContainer )
|
||||
}
|
||||
|
||||
|
||||
void PAD::ClearZoneLayerOverrides()
|
||||
{
|
||||
std::unique_lock<std::mutex> cacheLock( m_zoneLayerOverridesMutex );
|
||||
|
||||
for( PCB_LAYER_ID layer : LAYER_RANGE( F_Cu, B_Cu, BoardCopperLayerCount() ) )
|
||||
m_zoneLayerOverrides[layer] = ZLO_NONE;
|
||||
}
|
||||
|
||||
|
||||
const ZONE_LAYER_OVERRIDE& PAD::GetZoneLayerOverride( PCB_LAYER_ID aLayer ) const
|
||||
{
|
||||
static const ZONE_LAYER_OVERRIDE defaultOverride = ZLO_NONE;
|
||||
auto it = m_zoneLayerOverrides.find( aLayer );
|
||||
return it != m_zoneLayerOverrides.end() ? it->second : defaultOverride;
|
||||
}
|
||||
|
||||
|
||||
void PAD::SetZoneLayerOverride( PCB_LAYER_ID aLayer, ZONE_LAYER_OVERRIDE aOverride )
|
||||
{
|
||||
std::unique_lock<std::mutex> cacheLock( m_zoneLayerOverridesMutex );
|
||||
m_zoneLayerOverrides[aLayer] = aOverride;
|
||||
}
|
||||
|
||||
|
||||
bool PAD::CanHaveNumber() const
|
||||
{
|
||||
// Aperture pads don't get a number
|
||||
@ -268,7 +294,7 @@ LSET PAD::UnplatedHoleMask()
|
||||
|
||||
LSET PAD::ApertureMask()
|
||||
{
|
||||
static LSET saved( F_Paste );
|
||||
static LSET saved( { F_Paste } );
|
||||
return saved;
|
||||
}
|
||||
|
||||
@ -360,12 +386,19 @@ bool PAD::FlashLayer( int aLayer, bool aOnlyCheckIfPermitted ) const
|
||||
static std::initializer_list<KICAD_T> types = { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T,
|
||||
PCB_PAD_T };
|
||||
|
||||
if( m_zoneLayerOverrides[ aLayer ] == ZLO_FORCE_FLASHED )
|
||||
if( auto it = m_zoneLayerOverrides.find( static_cast<PCB_LAYER_ID>( aLayer ) );
|
||||
it != m_zoneLayerOverrides.end() && it->second == ZLO_FORCE_FLASHED )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if( aOnlyCheckIfPermitted )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return board->GetConnectivity()->IsConnectedOnLayer( this, aLayer, types );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2138,7 +2171,7 @@ void PAD::CheckPad( UNITS_PROVIDER* aUnitsProvider,
|
||||
|
||||
LSET padlayers_mask = GetLayerSet();
|
||||
|
||||
if( padlayers_mask == 0 )
|
||||
if( padlayers_mask.none() )
|
||||
aErrorHandler( DRCE_PADSTACK_INVALID, _( "(Pad has no layer)" ) );
|
||||
|
||||
if( GetAttribute() == PAD_ATTRIB::PTH && !IsOnCopperLayer() )
|
||||
|
20
pcbnew/pad.h
20
pcbnew/pad.h
@ -805,21 +805,11 @@ public:
|
||||
|
||||
virtual const BOX2I ViewBBox() const override;
|
||||
|
||||
void ClearZoneLayerOverrides()
|
||||
{
|
||||
m_zoneLayerOverrides.fill( ZLO_NONE );
|
||||
}
|
||||
void ClearZoneLayerOverrides();
|
||||
|
||||
const ZONE_LAYER_OVERRIDE& GetZoneLayerOverride( PCB_LAYER_ID aLayer ) const
|
||||
{
|
||||
return m_zoneLayerOverrides.at( aLayer );
|
||||
}
|
||||
const ZONE_LAYER_OVERRIDE& GetZoneLayerOverride( PCB_LAYER_ID aLayer ) const;
|
||||
|
||||
void SetZoneLayerOverride( PCB_LAYER_ID aLayer, ZONE_LAYER_OVERRIDE aOverride )
|
||||
{
|
||||
std::unique_lock<std::mutex> cacheLock( m_zoneLayerOverridesMutex );
|
||||
m_zoneLayerOverrides.at( aLayer ) = aOverride;
|
||||
}
|
||||
void SetZoneLayerOverride( PCB_LAYER_ID aLayer, ZONE_LAYER_OVERRIDE aOverride );
|
||||
|
||||
void CheckPad( UNITS_PROVIDER* aUnitsProvider,
|
||||
const std::function<void( int aErrorCode,
|
||||
@ -871,8 +861,8 @@ private:
|
||||
|
||||
int m_lengthPadToDie; // Length net from pad to die, inside the package
|
||||
|
||||
std::mutex m_zoneLayerOverridesMutex;
|
||||
std::array<ZONE_LAYER_OVERRIDE, MAX_CU_LAYERS> m_zoneLayerOverrides;
|
||||
std::mutex m_zoneLayerOverridesMutex;
|
||||
std::map<PCB_LAYER_ID, ZONE_LAYER_OVERRIDE> m_zoneLayerOverrides;
|
||||
};
|
||||
|
||||
#endif // PAD_H
|
||||
|
@ -161,7 +161,7 @@ bool PCB_GENERATOR::AddItem( BOARD_ITEM* aItem )
|
||||
|
||||
LSET PCB_GENERATOR::GetLayerSet() const
|
||||
{
|
||||
return PCB_GROUP::GetLayerSet() | LSET( GetLayer() );
|
||||
return PCB_GROUP::GetLayerSet() | LSET( { GetLayer() } );
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include <board.h>
|
||||
#include <board_design_settings.h>
|
||||
#include <layer_range.h>
|
||||
#include <pcb_dimension.h>
|
||||
#include <pad.h>
|
||||
#include <pcb_shape.h>
|
||||
@ -240,10 +241,11 @@ std::vector<PCB_LAYER_ID> ALTIUM_PCB::GetKicadLayersToIterate( ALTIUM_LAYER aAlt
|
||||
|
||||
if( aAltiumLayer == ALTIUM_LAYER::MULTI_LAYER || aAltiumLayer == ALTIUM_LAYER::KEEP_OUT_LAYER )
|
||||
{
|
||||
int layerCount = m_board ? m_board->GetCopperLayerCount() : 32;
|
||||
std::vector<PCB_LAYER_ID> layers;
|
||||
layers.reserve( MAX_CU_LAYERS );
|
||||
layers.reserve( layerCount );
|
||||
|
||||
for( PCB_LAYER_ID layer : LSET::AllCuMask().Seq() )
|
||||
for( PCB_LAYER_ID layer : LAYER_RANGE( F_Cu, B_Cu, layerCount ) )
|
||||
{
|
||||
if( !m_board || m_board->IsLayerEnabled( layer ) )
|
||||
layers.emplace_back( layer );
|
||||
@ -268,7 +270,7 @@ std::vector<PCB_LAYER_ID> ALTIUM_PCB::GetKicadLayersToIterate( ALTIUM_LAYER aAlt
|
||||
}
|
||||
|
||||
klayer = Eco1_User;
|
||||
m_board->SetEnabledLayers( m_board->GetEnabledLayers() | LSET( klayer ) );
|
||||
m_board->SetEnabledLayers( m_board->GetEnabledLayers() | LSET( { klayer } ) );
|
||||
}
|
||||
|
||||
return { klayer };
|
||||
@ -1154,7 +1156,7 @@ void ALTIUM_PCB::remapUnsureLayers( std::vector<ABOARD6_LAYER_STACKUP>& aStackup
|
||||
|
||||
ALTIUM_LAYER altiumID = altiumLayerNameMap.at( layerPair.first );
|
||||
m_layermap.insert_or_assign( altiumID, layerPair.second );
|
||||
enabledLayers |= LSET( layerPair.second );
|
||||
enabledLayers |= LSET( { layerPair.second } );
|
||||
}
|
||||
|
||||
m_board->SetEnabledLayers( enabledLayers );
|
||||
@ -3485,7 +3487,7 @@ void ALTIUM_PCB::ConvertPads6ToFootprintItemOnCopper( FOOTPRINT* aFootprint, con
|
||||
default:
|
||||
PCB_LAYER_ID klayer = GetKicadLayer( aElem.layer );
|
||||
pad->SetLayer( klayer );
|
||||
pad->SetLayerSet( LSET( klayer ) );
|
||||
pad->SetLayerSet( LSET( { klayer } ) );
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -725,7 +725,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::remapUnsureLayers()
|
||||
|
||||
LAYER_ID cadstarLayerID = cadstarLayerNameMap.at( layerPair.first );
|
||||
m_layermap.at( cadstarLayerID ) = layerPair.second;
|
||||
enabledLayers |= LSET( layerPair.second );
|
||||
enabledLayers |= LSET( { layerPair.second } );
|
||||
}
|
||||
|
||||
m_board->SetEnabledLayers( enabledLayers );
|
||||
@ -1119,7 +1119,7 @@ PAD* CADSTAR_PCB_ARCHIVE_LOADER::getKiCadPad( const COMPONENT_PAD& aCadstarPad,
|
||||
// prevent DRC errors.
|
||||
// TODO: This could be a custom padstack, update when KiCad supports padstacks
|
||||
pad->SetAttribute( PAD_ATTRIB::SMD );
|
||||
pad->SetLayerSet( LSET( F_Mask ) );
|
||||
pad->SetLayerSet( LSET( { F_Mask } ) );
|
||||
}
|
||||
|
||||
// zero sized pads seems to break KiCad so lets make it very small instead
|
||||
@ -4177,7 +4177,7 @@ LSET CADSTAR_PCB_ARCHIVE_LOADER::getKiCadLayerSet( const LAYER_ID& aCadstarLayer
|
||||
| LSET::AllBoardTechMask();
|
||||
|
||||
default:
|
||||
return LSET( getKiCadLayer( aCadstarLayerID ) );
|
||||
return LSET( { getKiCadLayer( aCadstarLayerID ) } );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,7 +154,7 @@ void PCB_IO_EAGLE::setKeepoutSettingsToZone( ZONE* aZone, int aLayer ) const
|
||||
aZone->SetDoNotAllowPads( false );
|
||||
aZone->SetDoNotAllowFootprints( false );
|
||||
|
||||
aZone->SetLayerSet( kicad_layer( aLayer ) );
|
||||
aZone->SetLayerSet( { kicad_layer( aLayer ) } );
|
||||
}
|
||||
}
|
||||
|
||||
@ -3008,7 +3008,7 @@ std::tuple<PCB_LAYER_ID, LSET, bool> PCB_IO_EAGLE::defaultKicadLayer( int aEagle
|
||||
case EAGLE_LAYER::DIMENSION:
|
||||
kiLayer = Edge_Cuts;
|
||||
required = true;
|
||||
permittedLayers = LSET( Edge_Cuts );
|
||||
permittedLayers = LSET( { Edge_Cuts } );
|
||||
break;
|
||||
|
||||
case EAGLE_LAYER::TPLACE:
|
||||
|
@ -984,7 +984,7 @@ void PCB_IO_EASYEDA_PARSER::ParseToBoardItemContainer(
|
||||
else
|
||||
{
|
||||
pad->SetLayer( klayer );
|
||||
pad->SetLayerSet( LSET( klayer ) );
|
||||
pad->SetLayerSet( LSET( { klayer } ) );
|
||||
pad->SetAttribute( PAD_ATTRIB::SMD );
|
||||
}
|
||||
|
||||
|
@ -686,39 +686,9 @@ void PCB_IO_KICAD_SEXPR::formatBoardLayers( const BOARD* aBoard, int aNestLevel
|
||||
}
|
||||
|
||||
// Save used non-copper layers in the order they are defined.
|
||||
// desired sequence for non Cu BOARD layers.
|
||||
static const PCB_LAYER_ID non_cu[] =
|
||||
{
|
||||
B_Adhes, // 32
|
||||
F_Adhes,
|
||||
B_Paste,
|
||||
F_Paste,
|
||||
B_SilkS,
|
||||
F_SilkS,
|
||||
B_Mask,
|
||||
F_Mask,
|
||||
Dwgs_User,
|
||||
Cmts_User,
|
||||
Eco1_User,
|
||||
Eco2_User,
|
||||
Edge_Cuts,
|
||||
Margin,
|
||||
B_CrtYd,
|
||||
F_CrtYd,
|
||||
B_Fab,
|
||||
F_Fab,
|
||||
User_1,
|
||||
User_2,
|
||||
User_3,
|
||||
User_4,
|
||||
User_5,
|
||||
User_6,
|
||||
User_7,
|
||||
User_8,
|
||||
User_9
|
||||
};
|
||||
LSEQ seq = aBoard->GetEnabledLayers().TechAndUserUIOrder();
|
||||
|
||||
for( PCB_LAYER_ID layer : aBoard->GetEnabledLayers().Seq( non_cu, arrayDim( non_cu ) ) )
|
||||
for( PCB_LAYER_ID layer : seq )
|
||||
{
|
||||
m_out->Print( aNestLevel+1, "(%d %s",
|
||||
layer,
|
||||
|
@ -104,10 +104,10 @@ void PCB_IO_KICAD_SEXPR_PARSER::init()
|
||||
// The English name will survive if parsing only a footprint.
|
||||
for( int layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
|
||||
{
|
||||
std::string untranslated = TO_UTF8( wxString( LSET::Name( PCB_LAYER_ID( layer ) ) ) );
|
||||
std::string untranslated = TO_UTF8( LSET::Name( PCB_LAYER_ID( layer ) ) );
|
||||
|
||||
m_layerIndices[ untranslated ] = PCB_LAYER_ID( layer );
|
||||
m_layerMasks[ untranslated ] = LSET( PCB_LAYER_ID( layer ) );
|
||||
m_layerIndices[untranslated] = PCB_LAYER_ID( layer );
|
||||
m_layerMasks[untranslated] = LSET( { PCB_LAYER_ID( layer ) } );
|
||||
}
|
||||
|
||||
m_layerMasks[ "*.Cu" ] = LSET::AllCuMask();
|
||||
@ -130,7 +130,7 @@ void PCB_IO_KICAD_SEXPR_PARSER::init()
|
||||
{
|
||||
std::string key = StrPrintf( "Inner%d.Cu", i );
|
||||
|
||||
m_layerMasks[ key ] = LSET( PCB_LAYER_ID( In15_Cu - i ) );
|
||||
m_layerMasks[key] = LSET( { PCB_LAYER_ID( In15_Cu - 2 * i ) } );
|
||||
}
|
||||
}
|
||||
|
||||
@ -1716,7 +1716,7 @@ void PCB_IO_KICAD_SEXPR_PARSER::parseBoardStackup()
|
||||
type = BS_ITEM_TYPE_SOLDERPASTE;
|
||||
else if( layerId == UNDEFINED_LAYER )
|
||||
type = BS_ITEM_TYPE_DIELECTRIC;
|
||||
else if( layerId >= F_Cu && layerId <= B_Cu )
|
||||
else if( !( layerId & 1 ) )
|
||||
type = BS_ITEM_TYPE_COPPER;
|
||||
|
||||
BOARD_STACKUP_ITEM* item = nullptr;
|
||||
@ -1942,26 +1942,34 @@ void PCB_IO_KICAD_SEXPR_PARSER::parseLayers()
|
||||
{
|
||||
// Rework the layer numbers, which changed when the Cu stack
|
||||
// was flipped. So we instead use position in the list.
|
||||
for( size_t i = 1; i < cu.size() - 1; i++ )
|
||||
{
|
||||
int tmpLayer = LSET::NameToLayer( cu[i].m_name );
|
||||
|
||||
if( i < 0 )
|
||||
tmpLayer = ( i + 1 ) * 2;
|
||||
|
||||
cu[i].m_number = tmpLayer;
|
||||
}
|
||||
|
||||
cu[0].m_number = F_Cu;
|
||||
cu[cu.size()-1].m_number = B_Cu;
|
||||
|
||||
for( unsigned i=0; i < cu.size()-1; ++i )
|
||||
cu[i].m_number = i;
|
||||
|
||||
for( std::vector<LAYER>::const_iterator it = cu.begin(); it<cu.end(); ++it )
|
||||
for( auto& cu_layer : cu )
|
||||
{
|
||||
enabledLayers.set( it->m_number );
|
||||
enabledLayers.set( cu_layer.m_number );
|
||||
|
||||
if( it->m_visible )
|
||||
visibleLayers.set( it->m_number );
|
||||
if( cu_layer.m_visible )
|
||||
visibleLayers.set( cu_layer.m_number );
|
||||
else
|
||||
anyHidden = true;
|
||||
|
||||
m_board->SetLayerDescr( PCB_LAYER_ID( it->m_number ), *it );
|
||||
m_board->SetLayerDescr( PCB_LAYER_ID( cu_layer.m_number ), cu_layer );
|
||||
|
||||
UTF8 name = it->m_name;
|
||||
UTF8 name = cu_layer.m_name;
|
||||
|
||||
m_layerIndices[ name ] = PCB_LAYER_ID( it->m_number );
|
||||
m_layerMasks[ name ] = LSET( PCB_LAYER_ID( it->m_number ) );
|
||||
m_layerIndices[ name ] = PCB_LAYER_ID( cu_layer.m_number );
|
||||
m_layerMasks[ name ] = LSET( { PCB_LAYER_ID( cu_layer.m_number ) } );
|
||||
}
|
||||
|
||||
copperLayerCount = cu.size();
|
||||
@ -1994,7 +2002,7 @@ void PCB_IO_KICAD_SEXPR_PARSER::parseLayers()
|
||||
// If we are here, then we have found a translated layer name. Put it in the maps
|
||||
// so that items on this layer get the appropriate layer ID number.
|
||||
m_layerIndices[ UTF8( layer.m_name ) ] = it->second;
|
||||
m_layerMasks[ UTF8( layer.m_name ) ] = it->second;
|
||||
m_layerMasks[ UTF8( layer.m_name ) ] = LSET( { it->second } );
|
||||
layer.m_name = it->first;
|
||||
}
|
||||
|
||||
@ -2034,11 +2042,21 @@ void PCB_IO_KICAD_SEXPR_PARSER::parseLayers()
|
||||
}
|
||||
|
||||
|
||||
template<class T, class M>
|
||||
T PCB_IO_KICAD_SEXPR_PARSER::lookUpLayer( const M& aMap )
|
||||
LSET PCB_IO_KICAD_SEXPR_PARSER::lookUpLayerSet( const LSET_MAP& aMap )
|
||||
{
|
||||
LSET_MAP::const_iterator it = aMap.find( curText );
|
||||
|
||||
if( it == aMap.end() )
|
||||
return LSET( { Rescue } );
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
|
||||
PCB_LAYER_ID PCB_IO_KICAD_SEXPR_PARSER::lookUpLayer( const LAYER_ID_MAP& aMap )
|
||||
{
|
||||
// avoid constructing another std::string, use lexer's directly
|
||||
typename M::const_iterator it = aMap.find( curText );
|
||||
LAYER_ID_MAP::const_iterator it = aMap.find( curText );
|
||||
|
||||
if( it == aMap.end() )
|
||||
{
|
||||
@ -2061,7 +2079,7 @@ PCB_LAYER_ID PCB_IO_KICAD_SEXPR_PARSER::parseBoardItemLayer()
|
||||
|
||||
NextTok();
|
||||
|
||||
PCB_LAYER_ID layerIndex = lookUpLayer<PCB_LAYER_ID>( m_layerIndices );
|
||||
PCB_LAYER_ID layerIndex = lookUpLayer( m_layerIndices );
|
||||
|
||||
// Handle closing ) in object parser.
|
||||
|
||||
@ -2078,8 +2096,7 @@ LSET PCB_IO_KICAD_SEXPR_PARSER::parseBoardItemLayersAsMask()
|
||||
|
||||
for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
|
||||
{
|
||||
LSET mask = lookUpLayer<LSET>( m_layerMasks );
|
||||
layerMask |= mask;
|
||||
layerMask |= lookUpLayerSet( m_layerMasks );
|
||||
}
|
||||
|
||||
return layerMask;
|
||||
@ -5263,9 +5280,9 @@ PAD* PCB_IO_KICAD_SEXPR_PARSER::parsePAD( FOOTPRINT* aParent )
|
||||
|
||||
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
||||
{
|
||||
PCB_LAYER_ID layer = lookUpLayer<PCB_LAYER_ID>( m_layerIndices );
|
||||
PCB_LAYER_ID layer = lookUpLayer( m_layerIndices );
|
||||
|
||||
if( layer < F_Cu || layer > B_Cu )
|
||||
if( !IsCopperLayer( layer ) )
|
||||
Expecting( "copper layer name" );
|
||||
|
||||
pad->SetZoneLayerOverride( layer, ZLO_FORCE_FLASHED );
|
||||
@ -5864,10 +5881,14 @@ PCB_VIA* PCB_IO_KICAD_SEXPR_PARSER::parsePCB_VIA()
|
||||
{
|
||||
PCB_LAYER_ID layer1, layer2;
|
||||
NextTok();
|
||||
layer1 = lookUpLayer<PCB_LAYER_ID>( m_layerIndices );
|
||||
layer1 = lookUpLayer( m_layerIndices );
|
||||
NextTok();
|
||||
layer2 = lookUpLayer<PCB_LAYER_ID>( m_layerIndices );
|
||||
layer2 = lookUpLayer( m_layerIndices );
|
||||
via->SetLayerPair( layer1, layer2 );
|
||||
|
||||
if( layer1 == UNDEFINED_LAYER || layer2 == UNDEFINED_LAYER )
|
||||
Expecting( "layer name" );
|
||||
|
||||
NeedRIGHT();
|
||||
break;
|
||||
}
|
||||
@ -5908,9 +5929,9 @@ PCB_VIA* PCB_IO_KICAD_SEXPR_PARSER::parsePCB_VIA()
|
||||
|
||||
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
||||
{
|
||||
PCB_LAYER_ID layer = lookUpLayer<PCB_LAYER_ID>( m_layerIndices );
|
||||
PCB_LAYER_ID layer = lookUpLayer( m_layerIndices );
|
||||
|
||||
if( layer < F_Cu || layer > B_Cu )
|
||||
if( !IsCopperLayer( layer ) )
|
||||
Expecting( "copper layer name" );
|
||||
|
||||
via->SetZoneLayerOverride( layer, ZLO_FORCE_FLASHED );
|
||||
|
@ -76,6 +76,11 @@ class TEARDROP_PARAMETERS;
|
||||
class PCB_IO_KICAD_SEXPR_PARSER : public PCB_LEXER
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::unordered_map< std::string, PCB_LAYER_ID > LAYER_ID_MAP;
|
||||
typedef std::unordered_map< std::string, LSET > LSET_MAP;
|
||||
typedef std::unordered_map< wxString, KIID > KIID_MAP;
|
||||
|
||||
PCB_IO_KICAD_SEXPR_PARSER( LINE_READER* aReader, BOARD* aAppendToMe,
|
||||
std::function<bool( wxString, int, wxString, wxString )> aQueryUserCallback,
|
||||
PROGRESS_REPORTER* aProgressReporter = nullptr, unsigned aLineCount = 0 ) :
|
||||
@ -249,8 +254,8 @@ private:
|
||||
* @throw IO_ERROR if the layer is not valid.
|
||||
* @throw PARSE_ERROR if the layer syntax is incorrect.
|
||||
*/
|
||||
template<class T, class M>
|
||||
T lookUpLayer( const M& aMap );
|
||||
PCB_LAYER_ID lookUpLayer( const LAYER_ID_MAP& aMap );
|
||||
LSET lookUpLayerSet( const LSET_MAP& aMap );
|
||||
|
||||
/**
|
||||
* Parse the layer definition of a #BOARD_ITEM object.
|
||||
@ -374,10 +379,6 @@ private:
|
||||
*/
|
||||
void resolveGroups( BOARD_ITEM* aParent );
|
||||
|
||||
typedef std::unordered_map< std::string, PCB_LAYER_ID > LAYER_ID_MAP;
|
||||
typedef std::unordered_map< std::string, LSET > LSET_MAP;
|
||||
typedef std::unordered_map< wxString, KIID > KIID_MAP;
|
||||
|
||||
///< The type of progress bar timeout
|
||||
using TIMEOUT = std::chrono::milliseconds;
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <convert_basic_shapes_to_polygon.h>
|
||||
#include <pcb_track.h>
|
||||
#include <base_units.h>
|
||||
#include <layer_range.h>
|
||||
#include <lset.h>
|
||||
#include <string_utils.h>
|
||||
#include <view/view.h>
|
||||
@ -98,7 +99,8 @@ PCB_VIA::PCB_VIA( BOARD_ITEM* aParent ) :
|
||||
// For now, vias are always circles
|
||||
m_padStack.SetShape( PAD_SHAPE::CIRCLE );
|
||||
|
||||
m_zoneLayerOverrides.fill( ZLO_NONE );
|
||||
for( PCB_LAYER_ID layer : LAYER_RANGE( F_Cu, B_Cu, BoardCopperLayerCount() ) )
|
||||
m_zoneLayerOverrides[layer] = ZLO_NONE;
|
||||
|
||||
m_isFree = false;
|
||||
}
|
||||
@ -867,7 +869,7 @@ bool PCB_VIA::IsOnLayer( PCB_LAYER_ID aLayer ) const
|
||||
return GetLayerSet().test( aLayer );
|
||||
#endif
|
||||
|
||||
if( aLayer >= Padstack().Drill().start && aLayer <= Padstack().Drill().end )
|
||||
if( LAYER_RANGE::Contains( Padstack().Drill().start, Padstack().Drill().end, aLayer ) )
|
||||
return true;
|
||||
|
||||
if( aLayer == F_Mask )
|
||||
@ -899,13 +901,17 @@ LSET PCB_VIA::GetLayerSet() const
|
||||
return layermask;
|
||||
|
||||
if( GetViaType() == VIATYPE::THROUGH )
|
||||
layermask = LSET::AllCuMask();
|
||||
{
|
||||
layermask = LSET::AllCuMask( BoardCopperLayerCount() );
|
||||
}
|
||||
else
|
||||
wxASSERT( Padstack().Drill().start <= Padstack().Drill().end );
|
||||
{
|
||||
LAYER_RANGE range( Padstack().Drill().start, Padstack().Drill().end, BoardCopperLayerCount() );
|
||||
|
||||
// PCB_LAYER_IDs are numbered from front to back, this is top to bottom.
|
||||
for( int id = Padstack().Drill().start; id <= Padstack().Drill().end; ++id )
|
||||
layermask.set( id );
|
||||
// PCB_LAYER_IDs are numbered from front to back, this is top to bottom.
|
||||
for( PCB_LAYER_ID id : range )
|
||||
layermask.set( id );
|
||||
}
|
||||
|
||||
if( !IsTented( F_Mask ) && layermask.test( F_Cu ) )
|
||||
layermask.set( F_Mask );
|
||||
@ -1064,10 +1070,34 @@ bool PCB_VIA::FlashLayer( int aLayer ) const
|
||||
static std::initializer_list<KICAD_T> connectedTypes = { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T,
|
||||
PCB_PAD_T };
|
||||
|
||||
if( m_zoneLayerOverrides[ aLayer ] == ZLO_FORCE_FLASHED )
|
||||
if( GetZoneLayerOverride( static_cast<PCB_LAYER_ID>( aLayer ) ) == ZLO_FORCE_FLASHED )
|
||||
return true;
|
||||
else
|
||||
return board->GetConnectivity()->IsConnectedOnLayer( this, aLayer, connectedTypes );
|
||||
return board->GetConnectivity()->IsConnectedOnLayer( this, static_cast<PCB_LAYER_ID>( aLayer ), connectedTypes );
|
||||
}
|
||||
|
||||
|
||||
void PCB_VIA::ClearZoneLayerOverrides()
|
||||
{
|
||||
std::unique_lock<std::mutex> cacheLock( m_zoneLayerOverridesMutex );
|
||||
|
||||
for( PCB_LAYER_ID layer : LAYER_RANGE( F_Cu, B_Cu, BoardCopperLayerCount() ) )
|
||||
m_zoneLayerOverrides[layer] = ZLO_NONE;
|
||||
}
|
||||
|
||||
|
||||
const ZONE_LAYER_OVERRIDE& PCB_VIA::GetZoneLayerOverride( PCB_LAYER_ID aLayer ) const
|
||||
{
|
||||
static const ZONE_LAYER_OVERRIDE defaultOverride = ZLO_NONE;
|
||||
auto it = m_zoneLayerOverrides.find( aLayer );
|
||||
return it != m_zoneLayerOverrides.end() ? it->second : defaultOverride;
|
||||
}
|
||||
|
||||
|
||||
void PCB_VIA::SetZoneLayerOverride( PCB_LAYER_ID aLayer, ZONE_LAYER_OVERRIDE aOverride )
|
||||
{
|
||||
std::unique_lock<std::mutex> cacheLock( m_zoneLayerOverridesMutex );
|
||||
m_zoneLayerOverrides[aLayer] = aOverride;
|
||||
}
|
||||
|
||||
|
||||
@ -1084,7 +1114,7 @@ void PCB_VIA::GetOutermostConnectedLayers( PCB_LAYER_ID* aTopmost,
|
||||
{
|
||||
bool connected = false;
|
||||
|
||||
if( m_zoneLayerOverrides[ layer ] == ZLO_FORCE_FLASHED )
|
||||
if( GetZoneLayerOverride( static_cast<PCB_LAYER_ID>( layer ) ) == ZLO_FORCE_FLASHED )
|
||||
connected = true;
|
||||
else if( GetBoard()->GetConnectivity()->IsConnectedOnLayer( this, layer, connectedTypes ) )
|
||||
connected = true;
|
||||
|
@ -605,21 +605,11 @@ public:
|
||||
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
|
||||
FLASHING aFlash = FLASHING::DEFAULT ) const override;
|
||||
|
||||
void ClearZoneLayerOverrides()
|
||||
{
|
||||
m_zoneLayerOverrides.fill( ZLO_NONE );
|
||||
}
|
||||
void ClearZoneLayerOverrides();
|
||||
|
||||
const ZONE_LAYER_OVERRIDE& GetZoneLayerOverride( PCB_LAYER_ID aLayer ) const
|
||||
{
|
||||
return m_zoneLayerOverrides.at( aLayer );
|
||||
}
|
||||
const ZONE_LAYER_OVERRIDE& GetZoneLayerOverride( PCB_LAYER_ID aLayer ) const;
|
||||
|
||||
void SetZoneLayerOverride( PCB_LAYER_ID aLayer, ZONE_LAYER_OVERRIDE aOverride )
|
||||
{
|
||||
std::unique_lock<std::mutex> cacheLock( m_zoneLayerOverridesMutex );
|
||||
m_zoneLayerOverrides.at( aLayer ) = aOverride;
|
||||
}
|
||||
void SetZoneLayerOverride( PCB_LAYER_ID aLayer, ZONE_LAYER_OVERRIDE aOverride );
|
||||
|
||||
double Similarity( const BOARD_ITEM& aOther ) const override;
|
||||
|
||||
@ -641,8 +631,8 @@ private:
|
||||
|
||||
bool m_isFree; ///< "Free" vias don't get their nets auto-updated
|
||||
|
||||
std::mutex m_zoneLayerOverridesMutex;
|
||||
std::array<ZONE_LAYER_OVERRIDE, MAX_CU_LAYERS> m_zoneLayerOverrides;
|
||||
std::mutex m_zoneLayerOverridesMutex;
|
||||
std::map<PCB_LAYER_ID, ZONE_LAYER_OVERRIDE> m_zoneLayerOverrides;
|
||||
};
|
||||
|
||||
|
||||
|
@ -660,7 +660,7 @@ int PCBNEW_JOBS_HANDLER::JobExportGerbers( JOB* aJob )
|
||||
aGerberJob->m_layersIncludeOnAll = plotOnAllLayersSelection;
|
||||
}
|
||||
|
||||
for( PCB_LAYER_ID layer : LSET( aGerberJob->m_printMaskLayer ).UIOrder() )
|
||||
for( PCB_LAYER_ID layer : LSET( { aGerberJob->m_printMaskLayer } ).UIOrder() )
|
||||
{
|
||||
LSEQ plotSequence;
|
||||
|
||||
|
@ -105,7 +105,7 @@ bool PCBNEW_PRINTOUT::OnPrintPage( int aPage )
|
||||
|
||||
// aPage starts at 1, not 0
|
||||
if( unsigned( aPage - 1 ) < seq.size() )
|
||||
m_settings.m_LayerSet = LSET( seq[ aPage - 1] );
|
||||
m_settings.m_LayerSet = LSET( { seq[aPage - 1] } );
|
||||
}
|
||||
|
||||
if( !m_settings.m_LayerSet.any() )
|
||||
|
@ -68,7 +68,7 @@ void PlotBoardLayers( BOARD* aBoard, PLOTTER* aPlotter, const LSEQ& aLayers,
|
||||
for( PCB_LAYER_ID layer : aLayers )
|
||||
{
|
||||
// copper layers with drill marks will be plotted after all other layers
|
||||
if( layer <= B_Cu && plot_mark )
|
||||
if( IsCopperLayer( layer ) && plot_mark )
|
||||
continue;
|
||||
|
||||
PlotOneBoardLayer( aBoard, aPlotter, layer, aPlotOptions );
|
||||
@ -79,7 +79,7 @@ void PlotBoardLayers( BOARD* aBoard, PLOTTER* aPlotter, const LSEQ& aLayers,
|
||||
|
||||
for( PCB_LAYER_ID layer : aLayers )
|
||||
{
|
||||
if( layer > B_Cu ) // already plotted
|
||||
if( !IsCopperLayer( layer ) )
|
||||
continue;
|
||||
|
||||
PlotOneBoardLayer( aBoard, aPlotter, layer, aPlotOptions );
|
||||
@ -177,7 +177,7 @@ void PlotOneBoardLayer( BOARD *aBoard, PLOTTER* aPlotter, PCB_LAYER_ID aLayer,
|
||||
|
||||
// Specify that the contents of the "Edges Pcb" layer are to be plotted in addition to the
|
||||
// contents of the currently specified layer.
|
||||
LSET layer_mask( aLayer );
|
||||
LSET layer_mask( { aLayer } );
|
||||
|
||||
if( IsCopperLayer( aLayer ) )
|
||||
{
|
||||
@ -238,9 +238,9 @@ void PlotOneBoardLayer( BOARD *aBoard, PLOTTER* aPlotter, PCB_LAYER_ID aLayer,
|
||||
&& plotOpt.GetSubtractMaskFromSilk() )
|
||||
{
|
||||
if( aLayer == F_SilkS )
|
||||
layer_mask = LSET( F_Mask );
|
||||
layer_mask = LSET( { F_Mask } );
|
||||
else
|
||||
layer_mask = LSET( B_Mask );
|
||||
layer_mask = LSET( { B_Mask } );
|
||||
|
||||
// Create the mask to subtract by creating a negative layer polarity
|
||||
aPlotter->SetLayerPolarity( false );
|
||||
@ -290,8 +290,8 @@ void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
|
||||
bool onCopperLayer = ( LSET::AllCuMask() & aLayerMask ).any();
|
||||
bool onSolderMaskLayer = ( LSET( { F_Mask, B_Mask } ) & aLayerMask ).any();
|
||||
bool onSolderPasteLayer = ( LSET( { F_Paste, B_Paste } ) & aLayerMask ).any();
|
||||
bool onFrontFab = ( LSET( F_Fab ) & aLayerMask ).any();
|
||||
bool onBackFab = ( LSET( B_Fab ) & aLayerMask ).any();
|
||||
bool onFrontFab = ( LSET( { F_Fab } ) & aLayerMask ).any();
|
||||
bool onBackFab = ( LSET( { B_Fab } ) & aLayerMask ).any();
|
||||
bool sketchPads = ( onFrontFab || onBackFab ) && aPlotOpt.GetSketchPadsOnFabLayers();
|
||||
|
||||
// Plot edge layer and graphic items
|
||||
|
@ -349,7 +349,7 @@ void RN_NET::OptimizeRNEdges()
|
||||
|
||||
CN_ZONE_LAYER* zoneLayer = dynamic_cast<CN_ZONE_LAYER*>( item );
|
||||
|
||||
if( zoneLayer && aLayerSet.test( zoneLayer->Layer() ) )
|
||||
if( zoneLayer && aLayerSet.test( zoneLayer->GetBoardLayer() ) )
|
||||
{
|
||||
const std::vector<VECTOR2I>& pts = zoneLayer->GetOutline().CPoints();
|
||||
|
||||
|
@ -70,7 +70,7 @@ void DIFF_PAIR_PLACER::setWorld( NODE* aWorld )
|
||||
|
||||
const VIA DIFF_PAIR_PLACER::makeVia( const VECTOR2I& aP, NET_HANDLE aNet )
|
||||
{
|
||||
const LAYER_RANGE layers( m_sizes.GetLayerTop(), m_sizes.GetLayerBottom() );
|
||||
const PNS_LAYER_RANGE layers( m_sizes.GetLayerTop(), m_sizes.GetLayerBottom() );
|
||||
|
||||
VIA v( aP, layers, m_sizes.ViaDiameter(), m_sizes.ViaDrill(), aNet, m_sizes.ViaType() );
|
||||
|
||||
|
@ -133,7 +133,7 @@ HOLE* HOLE::MakeCircularHole( const VECTOR2I& pos, int radius )
|
||||
SHAPE_CIRCLE* circle = new SHAPE_CIRCLE( pos, radius );
|
||||
HOLE* hole = new HOLE( circle );
|
||||
|
||||
hole->SetLayers( LAYER_RANGE( F_Cu, B_Cu ) );
|
||||
hole->SetLayers( PNS_LAYER_RANGE( F_Cu, B_Cu ) );
|
||||
return hole;
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ namespace PNS {
|
||||
|
||||
void INDEX::Add( ITEM* aItem )
|
||||
{
|
||||
const LAYER_RANGE& range = aItem->Layers();
|
||||
const PNS_LAYER_RANGE& range = aItem->Layers();
|
||||
assert( range.Start() != -1 && range.End() != -1 );
|
||||
|
||||
if( m_subIndices.size() <= static_cast<size_t>( range.End() ) )
|
||||
@ -46,7 +46,7 @@ void INDEX::Add( ITEM* aItem )
|
||||
|
||||
void INDEX::Remove( ITEM* aItem )
|
||||
{
|
||||
const LAYER_RANGE& range = aItem->Layers();
|
||||
const PNS_LAYER_RANGE& range = aItem->Layers();
|
||||
assert( range.Start() != -1 && range.End() != -1 );
|
||||
|
||||
if( m_subIndices.size() <= static_cast<size_t>( range.End() ) )
|
||||
|
@ -144,7 +144,7 @@ int INDEX::Query( const ITEM* aItem, int aMinDistance, Visitor& aVisitor ) const
|
||||
|
||||
wxCHECK( aItem->Kind() != ITEM::INVALID_T, 0 );
|
||||
|
||||
const LAYER_RANGE& layers = aItem->Layers();
|
||||
const PNS_LAYER_RANGE& layers = aItem->Layers();
|
||||
|
||||
for( int i = layers.Start(); i <= layers.End(); ++i )
|
||||
total += querySingle( i, aItem->Shape(), aMinDistance, aVisitor );
|
||||
|
@ -193,10 +193,10 @@ public:
|
||||
void SetNet( NET_HANDLE aNet ) { m_net = aNet; }
|
||||
virtual NET_HANDLE Net() const { return m_net; }
|
||||
|
||||
const LAYER_RANGE& Layers() const { return m_layers; }
|
||||
void SetLayers( const LAYER_RANGE& aLayers ) { m_layers = aLayers; }
|
||||
const PNS_LAYER_RANGE& Layers() const { return m_layers; }
|
||||
void SetLayers( const PNS_LAYER_RANGE& aLayers ) { m_layers = aLayers; }
|
||||
|
||||
void SetLayer( int aLayer ) { m_layers = LAYER_RANGE( aLayer, aLayer ); }
|
||||
void SetLayer( int aLayer ) { m_layers = PNS_LAYER_RANGE( aLayer, aLayer ); }
|
||||
virtual int Layer() const { return Layers().Start(); }
|
||||
|
||||
/**
|
||||
@ -285,7 +285,7 @@ protected:
|
||||
PnsKind m_kind;
|
||||
|
||||
BOARD_ITEM* m_parent;
|
||||
LAYER_RANGE m_layers;
|
||||
PNS_LAYER_RANGE m_layers;
|
||||
|
||||
bool m_movable;
|
||||
NET_HANDLE m_net;
|
||||
|
@ -48,12 +48,12 @@ void ITEM_SET::Prepend( const LINE& aLine )
|
||||
ITEM_SET& ITEM_SET::FilterLayers( int aStart, int aEnd, bool aInvert )
|
||||
{
|
||||
std::vector<ITEM*> newItems;
|
||||
LAYER_RANGE l;
|
||||
PNS_LAYER_RANGE l;
|
||||
|
||||
if( aEnd < 0 )
|
||||
l = LAYER_RANGE( aStart );
|
||||
l = PNS_LAYER_RANGE( aStart );
|
||||
else
|
||||
l = LAYER_RANGE( aStart, aEnd );
|
||||
l = PNS_LAYER_RANGE( aStart, aEnd );
|
||||
|
||||
for( ITEM* item : m_items )
|
||||
{
|
||||
|
@ -67,7 +67,7 @@ public:
|
||||
JOINT() :
|
||||
ITEM( JOINT_T ), m_tag(), m_locked( false ) {}
|
||||
|
||||
JOINT( const VECTOR2I& aPos, const LAYER_RANGE& aLayers, NET_HANDLE aNet = nullptr ) :
|
||||
JOINT( const VECTOR2I& aPos, const PNS_LAYER_RANGE& aLayers, NET_HANDLE aNet = nullptr ) :
|
||||
ITEM( JOINT_T )
|
||||
{
|
||||
m_tag.pos = aPos;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <board_design_settings.h>
|
||||
#include <netinfo.h>
|
||||
#include <footprint.h>
|
||||
#include <layer_range.h>
|
||||
#include <pad.h>
|
||||
#include <pcb_track.h>
|
||||
#include <zone.h>
|
||||
@ -62,6 +63,7 @@
|
||||
#include "pns_arc.h"
|
||||
#include "pns_sizes_settings.h"
|
||||
#include "pns_item.h"
|
||||
#include "pns_layerset.h"
|
||||
#include "pns_line.h"
|
||||
#include "pns_solid.h"
|
||||
#include "pns_segment.h"
|
||||
@ -215,7 +217,8 @@ bool PNS_PCBNEW_RULE_RESOLVER::IsNetTieExclusion( const PNS::ITEM* aItem,
|
||||
|
||||
if( drcEngine )
|
||||
{
|
||||
return drcEngine->IsNetTieExclusion( NetCode( aItem->Net() ), ToLAYER_ID( aItem->Layer() ),
|
||||
return drcEngine->IsNetTieExclusion( NetCode( aItem->Net() ),
|
||||
ToLAYER_ID( m_routerIface->GetBoardLayerFromPNSLayer( aItem->Layer() ) ),
|
||||
aCollisionPos, collidingItem );
|
||||
}
|
||||
|
||||
@ -333,12 +336,12 @@ bool PNS_PCBNEW_RULE_RESOLVER::IsNonPlatedSlot( const PNS::ITEM* aItem )
|
||||
}
|
||||
|
||||
|
||||
BOARD_ITEM* PNS_PCBNEW_RULE_RESOLVER::getBoardItem( const PNS::ITEM* aItem, int aLayer, int aIdx )
|
||||
BOARD_ITEM* PNS_PCBNEW_RULE_RESOLVER::getBoardItem( const PNS::ITEM* aItem, int aBoardLayer, int aIdx )
|
||||
{
|
||||
switch( aItem->Kind() )
|
||||
{
|
||||
case PNS::ITEM::ARC_T:
|
||||
m_dummyArcs[aIdx].SetLayer( ToLAYER_ID( aLayer ) );
|
||||
m_dummyArcs[aIdx].SetLayer( ToLAYER_ID( aBoardLayer ) );
|
||||
m_dummyArcs[aIdx].SetNet( static_cast<NETINFO_ITEM*>( aItem->Net() ) );
|
||||
m_dummyArcs[aIdx].SetStart( aItem->Anchor( 0 ) );
|
||||
m_dummyArcs[aIdx].SetEnd( aItem->Anchor( 1 ) );
|
||||
@ -346,14 +349,14 @@ BOARD_ITEM* PNS_PCBNEW_RULE_RESOLVER::getBoardItem( const PNS::ITEM* aItem, int
|
||||
|
||||
case PNS::ITEM::VIA_T:
|
||||
case PNS::ITEM::HOLE_T:
|
||||
m_dummyVias[aIdx].SetLayer( ToLAYER_ID( aLayer ) );
|
||||
m_dummyVias[aIdx].SetLayer( ToLAYER_ID( aBoardLayer ) );
|
||||
m_dummyVias[aIdx].SetNet( static_cast<NETINFO_ITEM*>( aItem->Net() ) );
|
||||
m_dummyVias[aIdx].SetStart( aItem->Anchor( 0 ) );
|
||||
return &m_dummyVias[aIdx];
|
||||
|
||||
case PNS::ITEM::SEGMENT_T:
|
||||
case PNS::ITEM::LINE_T:
|
||||
m_dummyTracks[aIdx].SetLayer( ToLAYER_ID( aLayer ) );
|
||||
m_dummyTracks[aIdx].SetLayer( ToLAYER_ID( aBoardLayer ) );
|
||||
m_dummyTracks[aIdx].SetNet( static_cast<NETINFO_ITEM*>( aItem->Net() ) );
|
||||
m_dummyTracks[aIdx].SetStart( aItem->Anchor( 0 ) );
|
||||
m_dummyTracks[aIdx].SetEnd( aItem->Anchor( 1 ) );
|
||||
@ -367,7 +370,7 @@ BOARD_ITEM* PNS_PCBNEW_RULE_RESOLVER::getBoardItem( const PNS::ITEM* aItem, int
|
||||
|
||||
bool PNS_PCBNEW_RULE_RESOLVER::QueryConstraint( PNS::CONSTRAINT_TYPE aType,
|
||||
const PNS::ITEM* aItemA, const PNS::ITEM* aItemB,
|
||||
int aLayer, PNS::CONSTRAINT* aConstraint )
|
||||
int aPNSLayer, PNS::CONSTRAINT* aConstraint )
|
||||
{
|
||||
std::shared_ptr<DRC_ENGINE> drcEngine = m_board->GetDesignSettings().m_DRCEngine;
|
||||
|
||||
@ -395,17 +398,18 @@ bool PNS_PCBNEW_RULE_RESOLVER::QueryConstraint( PNS::CONSTRAINT_TYPE aType,
|
||||
|
||||
BOARD_ITEM* parentA = aItemA ? aItemA->BoardItem() : nullptr;
|
||||
BOARD_ITEM* parentB = aItemB ? aItemB->BoardItem() : nullptr;
|
||||
int board_layer = m_routerIface->GetBoardLayerFromPNSLayer( aPNSLayer );
|
||||
DRC_CONSTRAINT hostConstraint;
|
||||
|
||||
// A track being routed may not have a BOARD_ITEM associated yet.
|
||||
if( aItemA && !parentA )
|
||||
parentA = getBoardItem( aItemA, aLayer, 0 );
|
||||
parentA = getBoardItem( aItemA, board_layer, 0 );
|
||||
|
||||
if( aItemB && !parentB )
|
||||
parentB = getBoardItem( aItemB, aLayer, 1 );
|
||||
parentB = getBoardItem( aItemB, board_layer, 1 );
|
||||
|
||||
if( parentA )
|
||||
hostConstraint = drcEngine->EvalRules( hostType, parentA, parentB, ToLAYER_ID( aLayer ) );
|
||||
hostConstraint = drcEngine->EvalRules( hostType, parentA, parentB, ToLAYER_ID( board_layer ) );
|
||||
|
||||
if( hostConstraint.IsNull() )
|
||||
return false;
|
||||
@ -502,7 +506,7 @@ int PNS_PCBNEW_RULE_RESOLVER::Clearance( const PNS::ITEM* aA, const PNS::ITEM* a
|
||||
|
||||
PNS::CONSTRAINT constraint;
|
||||
int rv = 0;
|
||||
LAYER_RANGE layers;
|
||||
PNS_LAYER_RANGE layers;
|
||||
|
||||
if( !aB )
|
||||
layers = aA->Layers();
|
||||
@ -514,7 +518,7 @@ int PNS_PCBNEW_RULE_RESOLVER::Clearance( const PNS::ITEM* aA, const PNS::ITEM* a
|
||||
layers = aA->Layers().Intersection( aB->Layers() );
|
||||
|
||||
// Normalize layer range (no -1 magic numbers)
|
||||
layers = layers.Intersection( LAYER_RANGE( PCBNEW_LAYER_ID_START, PCB_LAYER_ID_COUNT - 1 ) );
|
||||
layers = layers.Intersection( PNS_LAYER_RANGE( PCBNEW_LAYER_ID_START, PCB_LAYER_ID_COUNT - 1 ) );
|
||||
|
||||
for( int layer = layers.Start(); layer <= layers.End(); ++layer )
|
||||
{
|
||||
@ -859,7 +863,8 @@ int PNS_KICAD_IFACE_BASE::StackupHeight( int aFirstLayer, int aSecondLayer ) con
|
||||
|
||||
BOARD_STACKUP& stackup = m_board->GetDesignSettings().GetStackupDescriptor();
|
||||
|
||||
return stackup.GetLayerDistance( ToLAYER_ID( aFirstLayer ), ToLAYER_ID( aSecondLayer ) );
|
||||
return stackup.GetLayerDistance( GetPCBLayerIDFromPNSLayer( aFirstLayer ),
|
||||
GetPCBLayerIDFromPNSLayer( aSecondLayer ) );
|
||||
}
|
||||
|
||||
|
||||
@ -935,14 +940,13 @@ bool PNS_PCBNEW_RULE_RESOLVER::DpNetPair( const PNS::ITEM* aItem, PNS::NET_HANDL
|
||||
class PNS_PCBNEW_DEBUG_DECORATOR: public PNS::DEBUG_DECORATOR
|
||||
{
|
||||
public:
|
||||
PNS_PCBNEW_DEBUG_DECORATOR( KIGFX::VIEW* aView = nullptr ) :
|
||||
PNS_PCBNEW_DEBUG_DECORATOR( PNS::ROUTER_IFACE* aIface ) :
|
||||
PNS::DEBUG_DECORATOR(),
|
||||
m_iface( aIface ),
|
||||
m_view( nullptr ),
|
||||
m_items( nullptr ),
|
||||
m_depth( 0 )
|
||||
{
|
||||
SetView( aView );
|
||||
}
|
||||
{}
|
||||
|
||||
~PNS_PCBNEW_DEBUG_DECORATOR()
|
||||
{
|
||||
@ -993,7 +997,7 @@ public:
|
||||
if( !m_view || !aItem )
|
||||
return;
|
||||
|
||||
ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( aItem, m_view );
|
||||
ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( aItem, m_iface, m_view );
|
||||
|
||||
pitem->SetColor( aColor.WithAlpha( 0.5 ) );
|
||||
pitem->SetWidth( aOverrideWidth );
|
||||
@ -1029,7 +1033,7 @@ public:
|
||||
if( !m_view || !aShape )
|
||||
return;
|
||||
|
||||
ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( *aShape, m_view );
|
||||
ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( *aShape, m_iface, m_view );
|
||||
|
||||
pitem->SetColor( aColor.WithAlpha( 0.5 ) );
|
||||
pitem->SetWidth( aOverrideWidth );
|
||||
@ -1064,6 +1068,7 @@ private:
|
||||
return m_depth;
|
||||
}
|
||||
|
||||
PNS::ROUTER_IFACE* m_iface;
|
||||
KIGFX::VIEW* m_view;
|
||||
KIGFX::VIEW_GROUP* m_items;
|
||||
|
||||
@ -1115,10 +1120,11 @@ PNS_KICAD_IFACE::~PNS_KICAD_IFACE()
|
||||
|
||||
std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE_BASE::syncPad( PAD* aPad )
|
||||
{
|
||||
LAYER_RANGE layers( 0, MAX_CU_LAYERS - 1 );
|
||||
PNS_LAYER_RANGE layers( 0, aPad->BoardCopperLayerCount() );
|
||||
LSEQ lmsk = aPad->GetLayerSet().CuStack();
|
||||
|
||||
// ignore non-copper pads except for those with holes
|
||||
if( ( aPad->GetLayerSet() & LSET::AllCuMask() ).none() && aPad->GetDrillSize().x == 0 )
|
||||
if( lmsk.empty() && aPad->GetDrillSize().x == 0 )
|
||||
return nullptr;
|
||||
|
||||
switch( aPad->GetAttribute() )
|
||||
@ -1130,20 +1136,12 @@ std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE_BASE::syncPad( PAD* aPad )
|
||||
case PAD_ATTRIB::CONN:
|
||||
case PAD_ATTRIB::SMD:
|
||||
{
|
||||
LSET lmsk = aPad->GetLayerSet();
|
||||
bool is_copper = false;
|
||||
|
||||
for( int i = 0; i < MAX_CU_LAYERS; i++ )
|
||||
if( !lmsk.empty() && aPad->GetAttribute() != PAD_ATTRIB::NPTH )
|
||||
{
|
||||
if( lmsk[i] )
|
||||
{
|
||||
is_copper = true;
|
||||
|
||||
if( aPad->GetAttribute() != PAD_ATTRIB::NPTH )
|
||||
layers = LAYER_RANGE( i );
|
||||
|
||||
break;
|
||||
}
|
||||
layers = SetLayersFromPCBNew( lmsk.front(), lmsk.front() );
|
||||
is_copper = true;
|
||||
}
|
||||
|
||||
if( !is_copper )
|
||||
@ -1216,7 +1214,7 @@ std::unique_ptr<PNS::SEGMENT> PNS_KICAD_IFACE_BASE::syncTrack( PCB_TRACK* aTrack
|
||||
aTrack->GetNet() );
|
||||
|
||||
segment->SetWidth( aTrack->GetWidth() );
|
||||
segment->SetLayers( LAYER_RANGE( aTrack->GetLayer() ) );
|
||||
segment->SetLayer( GetPNSLayerFromBoardLayer( aTrack->GetLayer() ) );
|
||||
segment->SetParent( aTrack );
|
||||
|
||||
if( aTrack->IsLocked() )
|
||||
@ -1238,7 +1236,7 @@ std::unique_ptr<PNS::ARC> PNS_KICAD_IFACE_BASE::syncArc( PCB_ARC* aArc )
|
||||
aArc->GetEnd(), aArc->GetWidth() ),
|
||||
aArc->GetNet() );
|
||||
|
||||
arc->SetLayers( LAYER_RANGE( aArc->GetLayer() ) );
|
||||
arc->SetLayer( GetPNSLayerFromBoardLayer( aArc->GetLayer() ) );
|
||||
arc->SetParent( aArc );
|
||||
|
||||
if( aArc->IsLocked() )
|
||||
@ -1260,7 +1258,7 @@ std::unique_ptr<PNS::VIA> PNS_KICAD_IFACE_BASE::syncVia( PCB_VIA* aVia )
|
||||
aVia->LayerPair( &top, &bottom );
|
||||
|
||||
auto via = std::make_unique<PNS::VIA>( aVia->GetPosition(),
|
||||
LAYER_RANGE( aVia->TopLayer(), aVia->BottomLayer() ),
|
||||
SetLayersFromPCBNew( aVia->TopLayer(), aVia->BottomLayer() ),
|
||||
aVia->GetWidth(),
|
||||
aVia->GetDrillValue(),
|
||||
aVia->GetNet(),
|
||||
@ -1311,7 +1309,7 @@ bool PNS_KICAD_IFACE_BASE::syncZone( PNS::NODE* aWorld, ZONE* aZone, SHAPE_POLY_
|
||||
return false;
|
||||
}
|
||||
|
||||
for( int layer = F_Cu; layer <= B_Cu; layer++ )
|
||||
for( PCB_LAYER_ID layer : LAYER_RANGE( F_Cu, B_Cu, m_board->GetCopperLayerCount() ) )
|
||||
{
|
||||
if( !layers[ layer ] )
|
||||
continue;
|
||||
@ -1332,7 +1330,7 @@ bool PNS_KICAD_IFACE_BASE::syncZone( PNS::NODE* aWorld, ZONE* aZone, SHAPE_POLY_
|
||||
|
||||
std::unique_ptr<PNS::SOLID> solid = std::make_unique<PNS::SOLID>();
|
||||
|
||||
solid->SetLayer( layer );
|
||||
solid->SetLayer( GetPNSLayerFromBoardLayer( layer ) );
|
||||
solid->SetNet( nullptr );
|
||||
solid->SetParent( aZone );
|
||||
solid->SetShape( triShape );
|
||||
@ -1356,7 +1354,7 @@ bool PNS_KICAD_IFACE_BASE::syncTextItem( PNS::NODE* aWorld, PCB_TEXT* aText, PCB
|
||||
std::unique_ptr<PNS::SOLID> solid = std::make_unique<PNS::SOLID>();
|
||||
SHAPE_SIMPLE* shape = new SHAPE_SIMPLE;
|
||||
|
||||
solid->SetLayer( aLayer );
|
||||
solid->SetLayer( GetPNSLayerFromBoardLayer( aLayer ) );
|
||||
solid->SetNet( nullptr );
|
||||
solid->SetParent( aText );
|
||||
solid->SetShape( shape ); // takes ownership
|
||||
@ -1393,12 +1391,12 @@ bool PNS_KICAD_IFACE_BASE::syncGraphicalItem( PNS::NODE* aWorld, PCB_SHAPE* aIte
|
||||
|
||||
if( aItem->GetLayer() == Edge_Cuts || aItem->GetLayer() == Margin )
|
||||
{
|
||||
solid->SetLayers( LAYER_RANGE( F_Cu, B_Cu ) );
|
||||
solid->SetLayers( PNS_LAYER_RANGE( 0, m_board->GetCopperLayerCount() ) );
|
||||
solid->SetRoutable( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
solid->SetLayer( aItem->GetLayer() );
|
||||
solid->SetLayer( GetPNSLayerFromBoardLayer( aItem->GetLayer() ) );
|
||||
}
|
||||
|
||||
if( aItem->GetLayer() == Edge_Cuts )
|
||||
@ -1437,7 +1435,7 @@ void PNS_KICAD_IFACE_BASE::SetBoard( BOARD* aBoard )
|
||||
}
|
||||
|
||||
|
||||
bool PNS_KICAD_IFACE::IsAnyLayerVisible( const LAYER_RANGE& aLayer ) const
|
||||
bool PNS_KICAD_IFACE::IsAnyLayerVisible( const PNS_LAYER_RANGE& aLayer ) const
|
||||
{
|
||||
if( !m_view )
|
||||
return false;
|
||||
@ -1466,14 +1464,14 @@ bool PNS_KICAD_IFACE_BASE::IsFlashedOnLayer( const PNS::ITEM* aItem, int aLayer
|
||||
{
|
||||
const PCB_VIA* via = static_cast<const PCB_VIA*>( aItem->Parent() );
|
||||
|
||||
return via->FlashLayer( ToLAYER_ID( aLayer ) );
|
||||
return via->FlashLayer( GetPCBLayerIDFromPNSLayer( aLayer ) );
|
||||
}
|
||||
|
||||
case PCB_PAD_T:
|
||||
{
|
||||
const PAD* pad = static_cast<const PAD*>( aItem->Parent() );
|
||||
|
||||
return pad->FlashLayer( ToLAYER_ID( aLayer ) );
|
||||
return pad->FlashLayer( GetPCBLayerIDFromPNSLayer( aLayer ) );
|
||||
}
|
||||
|
||||
default:
|
||||
@ -1486,9 +1484,9 @@ bool PNS_KICAD_IFACE_BASE::IsFlashedOnLayer( const PNS::ITEM* aItem, int aLayer
|
||||
|
||||
|
||||
bool PNS_KICAD_IFACE_BASE::IsFlashedOnLayer( const PNS::ITEM* aItem,
|
||||
const LAYER_RANGE& aLayer ) const
|
||||
const PNS_LAYER_RANGE& aLayer ) const
|
||||
{
|
||||
LAYER_RANGE test = aItem->Layers().Intersection( aLayer );
|
||||
PNS_LAYER_RANGE test = aItem->Layers().Intersection( aLayer );
|
||||
|
||||
if( aItem->Parent() )
|
||||
{
|
||||
@ -1500,7 +1498,7 @@ bool PNS_KICAD_IFACE_BASE::IsFlashedOnLayer( const PNS::ITEM* aItem,
|
||||
|
||||
for( int layer = test.Start(); layer <= test.End(); ++layer )
|
||||
{
|
||||
if( via->FlashLayer( ToLAYER_ID( layer ) ) )
|
||||
if( via->FlashLayer( GetPCBLayerIDFromPNSLayer( layer ) ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1513,7 +1511,7 @@ bool PNS_KICAD_IFACE_BASE::IsFlashedOnLayer( const PNS::ITEM* aItem,
|
||||
|
||||
for( int layer = test.Start(); layer <= test.End(); ++layer )
|
||||
{
|
||||
if( pad->FlashLayer( ToLAYER_ID( layer ) ) )
|
||||
if( pad->FlashLayer( GetPCBLayerIDFromPNSLayer( layer ) ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1703,7 +1701,7 @@ void PNS_KICAD_IFACE::DisplayItem( const PNS::ITEM* aItem, int aClearance, bool
|
||||
aFlags |= PNS_SEMI_SOLID;
|
||||
}
|
||||
|
||||
ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( aItem, m_view, aFlags );
|
||||
ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( aItem, this, m_view, aFlags );
|
||||
|
||||
// Note: SEGMENT_T is used for placed tracks; LINE_T is used for the routing head
|
||||
static int tracks = PNS::ITEM::SEGMENT_T | PNS::ITEM::ARC_T | PNS::ITEM::LINE_T;
|
||||
@ -1743,7 +1741,7 @@ void PNS_KICAD_IFACE::DisplayItem( const PNS::ITEM* aItem, int aClearance, bool
|
||||
|
||||
void PNS_KICAD_IFACE::DisplayPathLine( const SHAPE_LINE_CHAIN& aLine, int aImportance )
|
||||
{
|
||||
ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( aLine, m_view );
|
||||
ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( aLine, this, m_view );
|
||||
pitem->SetDepth( pitem->GetOriginDepth() - ROUTER_PREVIEW_ITEM::PathOverlayDepth );
|
||||
|
||||
COLOR4D color;
|
||||
@ -1762,7 +1760,7 @@ void PNS_KICAD_IFACE::DisplayPathLine( const SHAPE_LINE_CHAIN& aLine, int aImpor
|
||||
|
||||
void PNS_KICAD_IFACE::DisplayRatline( const SHAPE_LINE_CHAIN& aRatline, PNS::NET_HANDLE aNet )
|
||||
{
|
||||
ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( aRatline, m_view );
|
||||
ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( aRatline, this, m_view );
|
||||
|
||||
KIGFX::RENDER_SETTINGS* renderSettings = m_view->GetPainter()->GetSettings();
|
||||
KIGFX::PCB_RENDER_SETTINGS* rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( renderSettings );
|
||||
@ -1910,8 +1908,8 @@ void PNS_KICAD_IFACE::modifyBoardItem( PNS::ITEM* aItem )
|
||||
via_board->SetNet( static_cast<NETINFO_ITEM*>( via->Net() ) );
|
||||
via_board->SetViaType( via->ViaType() ); // MUST be before SetLayerPair()
|
||||
via_board->SetIsFree( via->IsFree() );
|
||||
via_board->SetLayerPair( ToLAYER_ID( via->Layers().Start() ),
|
||||
ToLAYER_ID( via->Layers().End() ) );
|
||||
via_board->SetLayerPair( GetPCBLayerIDFromPNSLayer( via->Layers().Start() ),
|
||||
GetPCBLayerIDFromPNSLayer( via->Layers().End() ) );
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1960,7 +1958,7 @@ BOARD_CONNECTED_ITEM* PNS_KICAD_IFACE::createBoardItem( PNS::ITEM* aItem )
|
||||
PNS::ARC* arc = static_cast<PNS::ARC*>( aItem );
|
||||
PCB_ARC* new_arc = new PCB_ARC( m_board, static_cast<const SHAPE_ARC*>( arc->Shape() ) );
|
||||
new_arc->SetWidth( arc->Width() );
|
||||
new_arc->SetLayer( ToLAYER_ID( arc->Layers().Start() ) );
|
||||
new_arc->SetLayer( GetPCBLayerIDFromPNSLayer( arc->Layers().Start() ) );
|
||||
new_arc->SetNet( net );
|
||||
newBoardItem = new_arc;
|
||||
break;
|
||||
@ -1974,7 +1972,7 @@ BOARD_CONNECTED_ITEM* PNS_KICAD_IFACE::createBoardItem( PNS::ITEM* aItem )
|
||||
track->SetStart( VECTOR2I( s.A.x, s.A.y ) );
|
||||
track->SetEnd( VECTOR2I( s.B.x, s.B.y ) );
|
||||
track->SetWidth( seg->Width() );
|
||||
track->SetLayer( ToLAYER_ID( seg->Layers().Start() ) );
|
||||
track->SetLayer( GetPCBLayerIDFromPNSLayer( seg->Layers().Start() ) );
|
||||
track->SetNet( net );
|
||||
newBoardItem = track;
|
||||
break;
|
||||
@ -1990,8 +1988,8 @@ BOARD_CONNECTED_ITEM* PNS_KICAD_IFACE::createBoardItem( PNS::ITEM* aItem )
|
||||
via_board->SetNet( net );
|
||||
via_board->SetViaType( via->ViaType() ); // MUST be before SetLayerPair()
|
||||
via_board->SetIsFree( via->IsFree() );
|
||||
via_board->SetLayerPair( ToLAYER_ID( via->Layers().Start() ),
|
||||
ToLAYER_ID( via->Layers().End() ) );
|
||||
via_board->SetLayerPair( GetPCBLayerIDFromPNSLayer( via->Layers().Start() ),
|
||||
GetPCBLayerIDFromPNSLayer( via->Layers().End() ) );
|
||||
newBoardItem = via_board;
|
||||
break;
|
||||
}
|
||||
@ -2088,7 +2086,7 @@ void PNS_KICAD_IFACE::SetView( KIGFX::VIEW* aView )
|
||||
|
||||
delete m_debugDecorator;
|
||||
|
||||
auto dec = new PNS_PCBNEW_DEBUG_DECORATOR();
|
||||
auto dec = new PNS_PCBNEW_DEBUG_DECORATOR( this );
|
||||
m_debugDecorator = dec;
|
||||
|
||||
dec->SetDebugEnabled( ADVANCED_CFG::GetCfg().m_ShowRouterDebugGraphics );
|
||||
@ -2139,3 +2137,52 @@ void PNS_KICAD_IFACE::SetHostTool( PCB_TOOL_BASE* aTool )
|
||||
m_tool = aTool;
|
||||
m_commit = std::make_unique<BOARD_COMMIT>( m_tool );
|
||||
}
|
||||
|
||||
|
||||
int PNS_KICAD_IFACE_BASE::GetBoardLayerFromPNSLayer( int aLayer ) const
|
||||
{
|
||||
if( aLayer < 0 )
|
||||
return -1;
|
||||
|
||||
if( aLayer == 0 )
|
||||
return F_Cu;
|
||||
|
||||
if( aLayer == m_board->GetCopperLayerCount() - 1 )
|
||||
return B_Cu;
|
||||
|
||||
return ( aLayer + 1 ) * 2;
|
||||
}
|
||||
|
||||
|
||||
int PNS_KICAD_IFACE_BASE::GetPNSLayerFromBoardLayer( int aLayer ) const
|
||||
{
|
||||
if( aLayer < 0 )
|
||||
return -1;
|
||||
|
||||
if( aLayer == F_Cu )
|
||||
return 0;
|
||||
|
||||
if( aLayer == B_Cu )
|
||||
return m_board->GetCopperLayerCount() - 1;
|
||||
|
||||
return ( aLayer / 2 ) - 1;
|
||||
}
|
||||
|
||||
|
||||
PCB_LAYER_ID PNS_KICAD_IFACE_BASE::GetPCBLayerIDFromPNSLayer( int aLayer ) const
|
||||
{
|
||||
return static_cast<PCB_LAYER_ID>( GetBoardLayerFromPNSLayer( aLayer ) );
|
||||
}
|
||||
|
||||
|
||||
void PNS_KICAD_IFACE_BASE::SetStartLayerFromPCBNew( PCB_LAYER_ID aLayer )
|
||||
{
|
||||
m_startLayer = GetPNSLayerFromBoardLayer( aLayer );
|
||||
}
|
||||
|
||||
|
||||
PNS_LAYER_RANGE PNS_KICAD_IFACE_BASE::SetLayersFromPCBNew( PCB_LAYER_ID aStartLayer, PCB_LAYER_ID aEndLayer )
|
||||
{
|
||||
return PNS_LAYER_RANGE( GetPNSLayerFromBoardLayer( aStartLayer ),
|
||||
GetPNSLayerFromBoardLayer( aEndLayer ) );
|
||||
}
|
@ -57,9 +57,9 @@ public:
|
||||
void EraseView() override {};
|
||||
void SetBoard( BOARD* aBoard );
|
||||
void SyncWorld( PNS::NODE* aWorld ) override;
|
||||
bool IsAnyLayerVisible( const LAYER_RANGE& aLayer ) const override { return true; };
|
||||
bool IsAnyLayerVisible( const PNS_LAYER_RANGE& aLayer ) const override { return true; };
|
||||
bool IsFlashedOnLayer( const PNS::ITEM* aItem, int aLayer ) const override;
|
||||
bool IsFlashedOnLayer( const PNS::ITEM* aItem, const LAYER_RANGE& aLayer ) const override;
|
||||
bool IsFlashedOnLayer( const PNS::ITEM* aItem, const PNS_LAYER_RANGE& aLayer ) const override;
|
||||
bool IsItemVisible( const PNS::ITEM* aItem ) const override { return true; };
|
||||
void HideItem( PNS::ITEM* aItem ) override {}
|
||||
void DisplayItem( const PNS::ITEM* aItem, int aClearance, bool aEdit = false,
|
||||
@ -81,7 +81,14 @@ public:
|
||||
|
||||
void SetDebugDecorator( PNS::DEBUG_DECORATOR* aDec );
|
||||
|
||||
void SetStartLayer( int aLayer ) { m_startLayer = aLayer; }
|
||||
int GetBoardLayerFromPNSLayer( int aLayer ) const override;
|
||||
int GetPNSLayerFromBoardLayer( int aLayer ) const override;
|
||||
PCB_LAYER_ID GetPCBLayerIDFromPNSLayer( int aLayer ) const;
|
||||
|
||||
void SetStartLayerFromPCBNew( PCB_LAYER_ID aLayer );
|
||||
void SetStartLayerFromPNS( int aLayer ) { m_startLayer = aLayer; }
|
||||
|
||||
PNS_LAYER_RANGE SetLayersFromPCBNew( PCB_LAYER_ID aStartLayer, PCB_LAYER_ID aEndLayer );
|
||||
|
||||
virtual PNS::NODE* GetWorld() const override { return m_world; };
|
||||
|
||||
@ -108,7 +115,7 @@ protected:
|
||||
protected:
|
||||
PNS::NODE* m_world;
|
||||
BOARD* m_board;
|
||||
int m_startLayer;
|
||||
int m_startLayer; // The starting layer, in PNS layer coordinates
|
||||
};
|
||||
|
||||
class PNS_KICAD_IFACE : public PNS_KICAD_IFACE_BASE
|
||||
@ -121,7 +128,7 @@ public:
|
||||
|
||||
void SetView( KIGFX::VIEW* aView );
|
||||
void EraseView() override;
|
||||
bool IsAnyLayerVisible( const LAYER_RANGE& aLayer ) const override;
|
||||
bool IsAnyLayerVisible( const PNS_LAYER_RANGE& aLayer ) const override;
|
||||
bool IsItemVisible( const PNS::ITEM* aItem ) const override;
|
||||
void HideItem( PNS::ITEM* aItem ) override;
|
||||
void DisplayItem( const PNS::ITEM* aItem, int aClearance, bool aEdit = false,
|
||||
|
@ -28,15 +28,15 @@
|
||||
/**
|
||||
* Represent a contiguous set of PCB layers.
|
||||
*/
|
||||
class LAYER_RANGE
|
||||
class PNS_LAYER_RANGE
|
||||
{
|
||||
public:
|
||||
LAYER_RANGE() :
|
||||
PNS_LAYER_RANGE() :
|
||||
m_start( -1 ),
|
||||
m_end( -1 )
|
||||
{};
|
||||
|
||||
LAYER_RANGE( int aStart, int aEnd )
|
||||
PNS_LAYER_RANGE( int aStart, int aEnd )
|
||||
{
|
||||
if( aStart > aEnd )
|
||||
std::swap( aStart, aEnd );
|
||||
@ -45,26 +45,26 @@ public:
|
||||
m_end = aEnd;
|
||||
}
|
||||
|
||||
LAYER_RANGE( int aLayer )
|
||||
PNS_LAYER_RANGE( int aLayer )
|
||||
{
|
||||
m_start = m_end = aLayer;
|
||||
}
|
||||
|
||||
LAYER_RANGE( const LAYER_RANGE& aB ) :
|
||||
PNS_LAYER_RANGE( const PNS_LAYER_RANGE& aB ) :
|
||||
m_start( aB.m_start ),
|
||||
m_end( aB.m_end )
|
||||
{}
|
||||
|
||||
~LAYER_RANGE() {};
|
||||
~PNS_LAYER_RANGE() {};
|
||||
|
||||
LAYER_RANGE& operator=( const LAYER_RANGE& aB )
|
||||
PNS_LAYER_RANGE& operator=( const PNS_LAYER_RANGE& aB )
|
||||
{
|
||||
m_start = aB.m_start;
|
||||
m_end = aB.m_end;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Overlaps( const LAYER_RANGE& aOther ) const
|
||||
bool Overlaps( const PNS_LAYER_RANGE& aOther ) const
|
||||
{
|
||||
return m_end >= aOther.m_start && m_start <= aOther.m_end;
|
||||
}
|
||||
@ -89,7 +89,7 @@ public:
|
||||
return m_end;
|
||||
}
|
||||
|
||||
void Merge( const LAYER_RANGE& aOther )
|
||||
void Merge( const PNS_LAYER_RANGE& aOther )
|
||||
{
|
||||
if( m_start < 0 || m_end < 0 )
|
||||
{
|
||||
@ -105,9 +105,9 @@ public:
|
||||
m_end = aOther.m_end;
|
||||
}
|
||||
|
||||
LAYER_RANGE Intersection( const LAYER_RANGE& aOther ) const
|
||||
PNS_LAYER_RANGE Intersection( const PNS_LAYER_RANGE& aOther ) const
|
||||
{
|
||||
LAYER_RANGE overlap;
|
||||
PNS_LAYER_RANGE overlap;
|
||||
|
||||
overlap.m_start = std::max( m_start, aOther.m_start );
|
||||
|
||||
@ -122,17 +122,17 @@ public:
|
||||
}
|
||||
|
||||
///< Shortcut for comparisons/overlap tests
|
||||
static LAYER_RANGE All()
|
||||
static PNS_LAYER_RANGE All()
|
||||
{
|
||||
return LAYER_RANGE( 0, 256 ); // fixme: use layer IDs header
|
||||
return PNS_LAYER_RANGE( 0, 256 ); // fixme: use layer IDs header
|
||||
}
|
||||
|
||||
bool operator==( const LAYER_RANGE& aOther ) const
|
||||
bool operator==( const PNS_LAYER_RANGE& aOther ) const
|
||||
{
|
||||
return ( m_start == aOther.m_start ) && ( m_end == aOther.m_end );
|
||||
}
|
||||
|
||||
bool operator!=( const LAYER_RANGE& aOther ) const
|
||||
bool operator!=( const PNS_LAYER_RANGE& aOther ) const
|
||||
{
|
||||
return ( m_start != aOther.m_start ) || ( m_end != aOther.m_end );
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ void LINE_PLACER::setWorld( NODE* aWorld )
|
||||
|
||||
const VIA LINE_PLACER::makeVia( const VECTOR2I& aP )
|
||||
{
|
||||
const LAYER_RANGE layers( m_sizes.ViaType() == VIATYPE::THROUGH ? F_Cu : m_sizes.GetLayerTop(),
|
||||
const PNS_LAYER_RANGE layers( m_sizes.ViaType() == VIATYPE::THROUGH ? F_Cu : m_sizes.GetLayerTop(),
|
||||
m_sizes.ViaType() == VIATYPE::THROUGH ? B_Cu : m_sizes.GetLayerBottom() );
|
||||
|
||||
return VIA( aP, layers, m_sizes.ViaDiameter(), m_sizes.ViaDrill(), nullptr, m_sizes.ViaType() );
|
||||
|
@ -1249,7 +1249,7 @@ void NODE::LockJoint( const VECTOR2I& aPos, const ITEM* aItem, bool aLock )
|
||||
}
|
||||
|
||||
|
||||
JOINT& NODE::touchJoint( const VECTOR2I& aPos, const LAYER_RANGE& aLayers, NET_HANDLE aNet )
|
||||
JOINT& NODE::touchJoint( const VECTOR2I& aPos, const PNS_LAYER_RANGE& aLayers, NET_HANDLE aNet )
|
||||
{
|
||||
JOINT::HASH_TAG tag;
|
||||
|
||||
@ -1310,7 +1310,7 @@ void JOINT::Dump() const
|
||||
}
|
||||
|
||||
|
||||
void NODE::linkJoint( const VECTOR2I& aPos, const LAYER_RANGE& aLayers, NET_HANDLE aNet,
|
||||
void NODE::linkJoint( const VECTOR2I& aPos, const PNS_LAYER_RANGE& aLayers, NET_HANDLE aNet,
|
||||
ITEM* aWhere )
|
||||
{
|
||||
JOINT& jt = touchJoint( aPos, aLayers, aNet );
|
||||
@ -1319,7 +1319,7 @@ void NODE::linkJoint( const VECTOR2I& aPos, const LAYER_RANGE& aLayers, NET_HAND
|
||||
}
|
||||
|
||||
|
||||
void NODE::unlinkJoint( const VECTOR2I& aPos, const LAYER_RANGE& aLayers, NET_HANDLE aNet,
|
||||
void NODE::unlinkJoint( const VECTOR2I& aPos, const PNS_LAYER_RANGE& aLayers, NET_HANDLE aNet,
|
||||
ITEM* aWhere )
|
||||
{
|
||||
// fixme: remove dangling joints
|
||||
@ -1556,7 +1556,7 @@ void NODE::RemoveByMarker( int aMarker )
|
||||
}
|
||||
|
||||
|
||||
SEGMENT* NODE::findRedundantSegment( const VECTOR2I& A, const VECTOR2I& B, const LAYER_RANGE& lr,
|
||||
SEGMENT* NODE::findRedundantSegment( const VECTOR2I& A, const VECTOR2I& B, const PNS_LAYER_RANGE& lr,
|
||||
NET_HANDLE aNet )
|
||||
{
|
||||
const JOINT* jtStart = FindJoint( A, lr.Start(), aNet );
|
||||
@ -1591,7 +1591,7 @@ SEGMENT* NODE::findRedundantSegment( SEGMENT* aSeg )
|
||||
}
|
||||
|
||||
|
||||
ARC* NODE::findRedundantArc( const VECTOR2I& A, const VECTOR2I& B, const LAYER_RANGE& lr,
|
||||
ARC* NODE::findRedundantArc( const VECTOR2I& A, const VECTOR2I& B, const PNS_LAYER_RANGE& lr,
|
||||
NET_HANDLE aNet )
|
||||
{
|
||||
const JOINT* jtStart = FindJoint( A, lr.Start(), aNet );
|
||||
@ -1626,7 +1626,7 @@ ARC* NODE::findRedundantArc( ARC* aArc )
|
||||
}
|
||||
|
||||
|
||||
int NODE::QueryJoints( const BOX2I& aBox, std::vector<JOINT*>& aJoints, LAYER_RANGE aLayerMask,
|
||||
int NODE::QueryJoints( const BOX2I& aBox, std::vector<JOINT*>& aJoints, PNS_LAYER_RANGE aLayerMask,
|
||||
int aKindMask )
|
||||
{
|
||||
int n = 0;
|
||||
|
@ -272,7 +272,7 @@ public:
|
||||
const COLLISION_SEARCH_OPTIONS& aOpts = COLLISION_SEARCH_OPTIONS() ) const;
|
||||
|
||||
int QueryJoints( const BOX2I& aBox, std::vector<JOINT*>& aJoints,
|
||||
LAYER_RANGE aLayerMask = LAYER_RANGE::All(), int aKindMask = ITEM::ANY_T );
|
||||
PNS_LAYER_RANGE aLayerMask = PNS_LAYER_RANGE::All(), int aKindMask = ITEM::ANY_T );
|
||||
|
||||
/**
|
||||
* Follow the line in search of an obstacle that is nearest to the starting to the line's
|
||||
@ -482,14 +482,14 @@ private:
|
||||
NODE& operator=( const NODE& aB );
|
||||
|
||||
///< Try to find matching joint and creates a new one if not found.
|
||||
JOINT& touchJoint( const VECTOR2I& aPos, const LAYER_RANGE& aLayers, NET_HANDLE aNet );
|
||||
JOINT& touchJoint( const VECTOR2I& aPos, const PNS_LAYER_RANGE& aLayers, NET_HANDLE aNet );
|
||||
|
||||
///< Touch a joint and links it to an m_item.
|
||||
void linkJoint( const VECTOR2I& aPos, const LAYER_RANGE& aLayers, NET_HANDLE aNet,
|
||||
void linkJoint( const VECTOR2I& aPos, const PNS_LAYER_RANGE& aLayers, NET_HANDLE aNet,
|
||||
ITEM* aWhere );
|
||||
|
||||
///< Unlink an item from a joint.
|
||||
void unlinkJoint( const VECTOR2I& aPos, const LAYER_RANGE& aLayers, NET_HANDLE aNet,
|
||||
void unlinkJoint( const VECTOR2I& aPos, const PNS_LAYER_RANGE& aLayers, NET_HANDLE aNet,
|
||||
ITEM* aWhere );
|
||||
|
||||
///< Helpers for adding/removing items.
|
||||
@ -515,11 +515,11 @@ private:
|
||||
return m_parent == nullptr;
|
||||
}
|
||||
|
||||
SEGMENT* findRedundantSegment( const VECTOR2I& A, const VECTOR2I& B, const LAYER_RANGE& lr,
|
||||
SEGMENT* findRedundantSegment( const VECTOR2I& A, const VECTOR2I& B, const PNS_LAYER_RANGE& lr,
|
||||
NET_HANDLE aNet );
|
||||
SEGMENT* findRedundantSegment( SEGMENT* aSeg );
|
||||
|
||||
ARC* findRedundantArc( const VECTOR2I& A, const VECTOR2I& B, const LAYER_RANGE& lr,
|
||||
ARC* findRedundantArc( const VECTOR2I& A, const VECTOR2I& B, const PNS_LAYER_RANGE& lr,
|
||||
NET_HANDLE aNet );
|
||||
ARC* findRedundantArc( ARC* aSeg );
|
||||
|
||||
|
@ -134,7 +134,7 @@ const ITEM_SET ROUTER::QueryHoverItems( const VECTOR2I& aP, int aSlopRadius )
|
||||
COLLISION_SEARCH_OPTIONS opts;
|
||||
|
||||
test.SetWidth( 1 );
|
||||
test.SetLayers( LAYER_RANGE::All() );
|
||||
test.SetLayers( PNS_LAYER_RANGE::All() );
|
||||
|
||||
opts.m_differentNetsOnly = false;
|
||||
opts.m_overrideClearance = aSlopRadius;
|
||||
@ -474,7 +474,7 @@ bool ROUTER::Move( const VECTOR2I& aP, ITEM* endItem )
|
||||
}
|
||||
|
||||
|
||||
bool ROUTER::getNearestRatnestAnchor( VECTOR2I& aOtherEnd, LAYER_RANGE& aOtherEndLayers,
|
||||
bool ROUTER::getNearestRatnestAnchor( VECTOR2I& aOtherEnd, PNS_LAYER_RANGE& aOtherEndLayers,
|
||||
ITEM*& aOtherEndItem )
|
||||
{
|
||||
// Can't finish something with no connections
|
||||
@ -542,7 +542,7 @@ bool ROUTER::Finish()
|
||||
|
||||
// Get our current line and position and nearest ratsnest to them if it exists
|
||||
VECTOR2I otherEnd;
|
||||
LAYER_RANGE otherEndLayers;
|
||||
PNS_LAYER_RANGE otherEndLayers;
|
||||
ITEM* otherEndItem = nullptr;
|
||||
|
||||
// Get the anchor nearest to the end of the trace the user is routing
|
||||
@ -588,7 +588,7 @@ bool ROUTER::ContinueFromEnd( ITEM** aNewStartItem )
|
||||
int currentLayer = GetCurrentLayer();
|
||||
VECTOR2I currentEnd = placer->CurrentEnd();
|
||||
VECTOR2I otherEnd;
|
||||
LAYER_RANGE otherEndLayers;
|
||||
PNS_LAYER_RANGE otherEndLayers;
|
||||
ITEM* otherEndItem = nullptr;
|
||||
|
||||
// Get the anchor nearest to the end of the trace the user is routing
|
||||
|
@ -93,10 +93,10 @@ enum DRAG_MODE
|
||||
virtual void AddItem( ITEM* aItem ) = 0;
|
||||
virtual void UpdateItem( ITEM* aItem ) = 0;
|
||||
virtual void RemoveItem( ITEM* aItem ) = 0;
|
||||
virtual bool IsAnyLayerVisible( const LAYER_RANGE& aLayer ) const = 0;
|
||||
virtual bool IsAnyLayerVisible( const PNS_LAYER_RANGE& aLayer ) const = 0;
|
||||
virtual bool IsItemVisible( const PNS::ITEM* aItem ) const = 0;
|
||||
virtual bool IsFlashedOnLayer( const PNS::ITEM* aItem, int aLayer ) const = 0;
|
||||
virtual bool IsFlashedOnLayer( const PNS::ITEM* aItem, const LAYER_RANGE& aLayer ) const = 0;
|
||||
virtual bool IsFlashedOnLayer( const PNS::ITEM* aItem, const PNS_LAYER_RANGE& aLayer ) const = 0;
|
||||
virtual void DisplayItem( const ITEM* aItem, int aClearance, bool aEdit = false,
|
||||
int aFlags = 0 ) = 0;
|
||||
virtual void DisplayPathLine( const SHAPE_LINE_CHAIN& aLine, int aImportance ) = 0;
|
||||
@ -115,6 +115,9 @@ enum DRAG_MODE
|
||||
|
||||
virtual RULE_RESOLVER* GetRuleResolver() = 0;
|
||||
virtual DEBUG_DECORATOR* GetDebugDecorator() = 0;
|
||||
|
||||
virtual int GetBoardLayerFromPNSLayer( int aLayer ) const = 0;
|
||||
virtual int GetPNSLayerFromBoardLayer( int aLayer ) const = 0;
|
||||
};
|
||||
|
||||
class ROUTER
|
||||
@ -232,7 +235,7 @@ private:
|
||||
void markViolations( NODE* aNode, ITEM_SET& aCurrent, NODE::ITEM_VECTOR& aRemoved );
|
||||
bool isStartingPointRoutable( const VECTOR2I& aWhere, ITEM* aItem, int aLayer );
|
||||
|
||||
bool getNearestRatnestAnchor( VECTOR2I& aOtherEnd, LAYER_RANGE& aOtherEndLayers,
|
||||
bool getNearestRatnestAnchor( VECTOR2I& aOtherEnd, PNS_LAYER_RANGE& aOtherEndLayers,
|
||||
ITEM*& aOtherEndItem );
|
||||
|
||||
|
||||
|
@ -95,7 +95,7 @@ const TOPOLOGY::JOINT_SET TOPOLOGY::ConnectedJoints( const JOINT* aStart )
|
||||
|
||||
|
||||
bool TOPOLOGY::NearestUnconnectedAnchorPoint( const LINE* aTrack, VECTOR2I& aPoint,
|
||||
LAYER_RANGE& aLayers, ITEM*& aItem )
|
||||
PNS_LAYER_RANGE& aLayers, ITEM*& aItem )
|
||||
{
|
||||
LINE track( *aTrack );
|
||||
VECTOR2I end;
|
||||
@ -142,7 +142,7 @@ bool TOPOLOGY::LeadingRatLine( const LINE* aTrack, SHAPE_LINE_CHAIN& aRatLine )
|
||||
{
|
||||
VECTOR2I end;
|
||||
// Ratline doesn't care about the layer
|
||||
LAYER_RANGE layers;
|
||||
PNS_LAYER_RANGE layers;
|
||||
ITEM* unusedItem;
|
||||
|
||||
if( !NearestUnconnectedAnchorPoint( aTrack, end, layers, unusedItem ) )
|
||||
|
@ -50,7 +50,7 @@ public:
|
||||
ITEM* NearestUnconnectedItem( const JOINT* aStart, int* aAnchor = nullptr,
|
||||
int aKindMask = ITEM::ANY_T );
|
||||
|
||||
bool NearestUnconnectedAnchorPoint( const LINE* aTrack, VECTOR2I& aPoint, LAYER_RANGE& aLayers,
|
||||
bool NearestUnconnectedAnchorPoint( const LINE* aTrack, VECTOR2I& aPoint, PNS_LAYER_RANGE& aLayers,
|
||||
ITEM*& aItem );
|
||||
bool LeadingRatLine( const LINE* aTrack, SHAPE_LINE_CHAIN& aRatLine );
|
||||
|
||||
|
@ -43,7 +43,7 @@ struct VIA_HANDLE
|
||||
{
|
||||
bool valid = false;
|
||||
VECTOR2I pos;
|
||||
LAYER_RANGE layers;
|
||||
PNS_LAYER_RANGE layers;
|
||||
NET_HANDLE net = nullptr;
|
||||
};
|
||||
|
||||
@ -62,7 +62,7 @@ public:
|
||||
SetHole( HOLE::MakeCircularHole( m_pos, m_drill / 2 ) );
|
||||
}
|
||||
|
||||
VIA( const VECTOR2I& aPos, const LAYER_RANGE& aLayers, int aDiameter, int aDrill,
|
||||
VIA( const VECTOR2I& aPos, const PNS_LAYER_RANGE& aLayers, int aDiameter, int aDrill,
|
||||
NET_HANDLE aNet = nullptr, VIATYPE aViaType = VIATYPE::THROUGH ) :
|
||||
LINKED_ITEM( VIA_T ),
|
||||
m_hole( nullptr )
|
||||
@ -218,7 +218,7 @@ class VVIA : public VIA
|
||||
{
|
||||
public:
|
||||
VVIA( const VECTOR2I& aPos, int aLayer, int aDiameter, NET_HANDLE aNet ) :
|
||||
VIA( aPos, LAYER_RANGE( aLayer, aLayer ), aDiameter, aDiameter / 2, aNet )
|
||||
VIA( aPos, PNS_LAYER_RANGE( aLayer, aLayer ), aDiameter, aDiameter / 2, aNet )
|
||||
{
|
||||
m_isVirtual = true;
|
||||
}
|
||||
|
@ -34,12 +34,15 @@
|
||||
#include "pns_line.h"
|
||||
#include "pns_segment.h"
|
||||
#include "pns_via.h"
|
||||
#include "pns_kicad_iface.h"
|
||||
|
||||
using namespace KIGFX;
|
||||
|
||||
|
||||
ROUTER_PREVIEW_ITEM::ROUTER_PREVIEW_ITEM( const PNS::ITEM* aItem, KIGFX::VIEW* aView, int aFlags ) :
|
||||
ROUTER_PREVIEW_ITEM::ROUTER_PREVIEW_ITEM( const PNS::ITEM* aItem, PNS::ROUTER_IFACE* aIface,
|
||||
KIGFX::VIEW* aView, int aFlags ) :
|
||||
EDA_ITEM( NOT_USED ),
|
||||
m_iface( aIface ),
|
||||
m_view( aView ),
|
||||
m_shape( nullptr ),
|
||||
m_hole( nullptr ),
|
||||
@ -76,12 +79,13 @@ ROUTER_PREVIEW_ITEM::ROUTER_PREVIEW_ITEM( const PNS::ITEM* aItem, KIGFX::VIEW* a
|
||||
}
|
||||
|
||||
|
||||
ROUTER_PREVIEW_ITEM::ROUTER_PREVIEW_ITEM( const SHAPE& aShape, KIGFX::VIEW* aView ) :
|
||||
ROUTER_PREVIEW_ITEM::ROUTER_PREVIEW_ITEM( const SHAPE& aShape, PNS::ROUTER_IFACE* aIface,
|
||||
KIGFX::VIEW* aView ) :
|
||||
EDA_ITEM( NOT_USED ),
|
||||
m_iface( aIface ),
|
||||
m_view( aView ),
|
||||
m_flags( 0 )
|
||||
{
|
||||
m_view = aView;
|
||||
|
||||
m_shape = aShape.Clone();
|
||||
m_hole = nullptr;
|
||||
|
||||
@ -106,7 +110,7 @@ ROUTER_PREVIEW_ITEM::~ROUTER_PREVIEW_ITEM()
|
||||
|
||||
void ROUTER_PREVIEW_ITEM::Update( const PNS::ITEM* aItem )
|
||||
{
|
||||
m_originLayer = aItem->Layers().Start();
|
||||
m_originLayer = m_iface->GetBoardLayerFromPNSLayer( aItem->Layers().Start() );
|
||||
|
||||
if( const PNS::LINE* l = dyn_cast<const PNS::LINE*>( aItem ) )
|
||||
{
|
||||
@ -119,7 +123,8 @@ void ROUTER_PREVIEW_ITEM::Update( const PNS::ITEM* aItem )
|
||||
return;
|
||||
}
|
||||
|
||||
assert( m_originLayer >= 0 );
|
||||
if( m_originLayer < 0 )
|
||||
m_originLayer = 0;
|
||||
|
||||
m_layer = m_originLayer;
|
||||
m_color = getLayerColor( m_originLayer );
|
||||
|
@ -42,6 +42,7 @@ namespace PNS {
|
||||
|
||||
class ITEM;
|
||||
class ROUTER;
|
||||
class ROUTER_IFACE;
|
||||
|
||||
}
|
||||
|
||||
@ -75,8 +76,8 @@ public:
|
||||
static constexpr double LayerDepthFactor = 0.0001;
|
||||
static constexpr double PathOverlayDepth = LayerDepthFactor * static_cast<double>( LAYER_ZONE_END );
|
||||
|
||||
ROUTER_PREVIEW_ITEM( const SHAPE& aShape, KIGFX::VIEW* aView = nullptr );
|
||||
ROUTER_PREVIEW_ITEM( const PNS::ITEM* aItem = nullptr, KIGFX::VIEW* aView = nullptr,
|
||||
ROUTER_PREVIEW_ITEM( const SHAPE& aShape, PNS::ROUTER_IFACE* aIface, KIGFX::VIEW* aView );
|
||||
ROUTER_PREVIEW_ITEM( const PNS::ITEM* aItem, PNS::ROUTER_IFACE* aIface, KIGFX::VIEW* aView,
|
||||
int aFlags = 0 );
|
||||
~ROUTER_PREVIEW_ITEM();
|
||||
|
||||
@ -123,6 +124,8 @@ private:
|
||||
private:
|
||||
KIGFX::VIEW* m_view;
|
||||
|
||||
PNS::ROUTER_IFACE* m_iface;
|
||||
|
||||
SHAPE* m_shape;
|
||||
SHAPE* m_hole;
|
||||
|
||||
|
@ -688,7 +688,7 @@ int ROUTER_TOOL::getStartLayer( const PNS::ITEM* aItem )
|
||||
|
||||
if( m_startItem )
|
||||
{
|
||||
const LAYER_RANGE& ls = m_startItem->Layers();
|
||||
const PNS_LAYER_RANGE& ls = m_startItem->Layers();
|
||||
|
||||
if( ls.Overlaps( tl ) )
|
||||
return tl;
|
||||
@ -702,7 +702,7 @@ int ROUTER_TOOL::getStartLayer( const PNS::ITEM* aItem )
|
||||
|
||||
void ROUTER_TOOL::switchLayerOnViaPlacement()
|
||||
{
|
||||
int activeLayer = frame()->GetActiveLayer();
|
||||
int activeLayer = m_iface->GetPNSLayerFromBoardLayer( frame()->GetActiveLayer() );
|
||||
int currentLayer = m_router->GetCurrentLayer();
|
||||
|
||||
if( currentLayer != activeLayer )
|
||||
@ -721,7 +721,8 @@ void ROUTER_TOOL::switchLayerOnViaPlacement()
|
||||
}
|
||||
|
||||
|
||||
void ROUTER_TOOL::updateSizesAfterRouterEvent( PCB_LAYER_ID targetLayer, const VECTOR2I& aPos )
|
||||
// N.B. aTargetLayer is a PNS layer, not a PCB_LAYER_ID
|
||||
void ROUTER_TOOL::updateSizesAfterRouterEvent( int aTargetLayer, const VECTOR2I& aPos )
|
||||
{
|
||||
std::vector<PNS::NET_HANDLE> nets = m_router->GetCurrentNets();
|
||||
|
||||
@ -729,6 +730,7 @@ void ROUTER_TOOL::updateSizesAfterRouterEvent( PCB_LAYER_ID targetLayer, const V
|
||||
BOARD_DESIGN_SETTINGS& bds = board()->GetDesignSettings();
|
||||
std::shared_ptr<DRC_ENGINE>& drcEngine = bds.m_DRCEngine;
|
||||
DRC_CONSTRAINT constraint;
|
||||
PCB_LAYER_ID targetLayer = m_iface->GetPCBLayerIDFromPNSLayer( aTargetLayer );
|
||||
|
||||
PCB_TRACK dummyTrack( board() );
|
||||
dummyTrack.SetFlags( ROUTER_TRANSIENT );
|
||||
@ -875,20 +877,23 @@ int ROUTER_TOOL::handleLayerSwitch( const TOOL_EVENT& aEvent, bool aForceVia )
|
||||
BOARD* brd = board();
|
||||
LSET enabledLayers = LSET::AllCuMask( brd->GetDesignSettings().GetCopperLayerCount() );
|
||||
LSEQ layers = enabledLayers.Seq();
|
||||
PCB_LAYER_ID currentLayer = (PCB_LAYER_ID) m_router->GetCurrentLayer();
|
||||
PCB_LAYER_ID targetLayer = UNDEFINED_LAYER;
|
||||
|
||||
// These layers are in Board Layer order not PNS layer order
|
||||
PCB_LAYER_ID currentLayer = m_iface->GetPCBLayerIDFromPNSLayer( m_router->GetCurrentLayer() );
|
||||
PCB_LAYER_ID targetLayer = UNDEFINED_LAYER;
|
||||
|
||||
if( aEvent.IsAction( &PCB_ACTIONS::layerNext ) )
|
||||
{
|
||||
if( m_lastTargetLayer == UNDEFINED_LAYER )
|
||||
m_lastTargetLayer = currentLayer;
|
||||
m_lastTargetLayer = m_iface->GetPNSLayerFromBoardLayer( currentLayer );
|
||||
|
||||
size_t idx = 0;
|
||||
size_t target_idx = 0;
|
||||
PCB_LAYER_ID lastTargetLayer = m_iface->GetPCBLayerIDFromPNSLayer( m_lastTargetLayer );
|
||||
|
||||
for( size_t i = 0; i < layers.size(); i++ )
|
||||
{
|
||||
if( layers[i] == m_lastTargetLayer )
|
||||
if( layers[i] == lastTargetLayer )
|
||||
{
|
||||
idx = i;
|
||||
break;
|
||||
@ -926,10 +931,11 @@ int ROUTER_TOOL::handleLayerSwitch( const TOOL_EVENT& aEvent, bool aForceVia )
|
||||
|
||||
size_t idx = 0;
|
||||
size_t target_idx = 0;
|
||||
PCB_LAYER_ID lastTargetLayer = m_iface->GetPCBLayerIDFromPNSLayer( m_lastTargetLayer );
|
||||
|
||||
for( size_t i = 0; i < layers.size(); i++ )
|
||||
{
|
||||
if( layers[i] == m_lastTargetLayer )
|
||||
if( layers[i] == lastTargetLayer )
|
||||
{
|
||||
idx = i;
|
||||
break;
|
||||
@ -977,7 +983,7 @@ int ROUTER_TOOL::handleLayerSwitch( const TOOL_EVENT& aEvent, bool aForceVia )
|
||||
|
||||
if( targetLayer != UNDEFINED_LAYER )
|
||||
{
|
||||
m_lastTargetLayer = targetLayer;
|
||||
m_lastTargetLayer = m_iface->GetPNSLayerFromBoardLayer( targetLayer );
|
||||
|
||||
if( targetLayer == currentLayer )
|
||||
return 0;
|
||||
@ -1121,14 +1127,15 @@ int ROUTER_TOOL::handleLayerSwitch( const TOOL_EVENT& aEvent, bool aForceVia )
|
||||
}
|
||||
|
||||
sizes.SetViaType( viaType );
|
||||
sizes.AddLayerPair( currentLayer, targetLayer );
|
||||
sizes.AddLayerPair( m_iface->GetPNSLayerFromBoardLayer( currentLayer ),
|
||||
m_iface->GetPNSLayerFromBoardLayer( targetLayer ) );
|
||||
|
||||
m_router->UpdateSizes( sizes );
|
||||
|
||||
if( !m_router->IsPlacingVia() )
|
||||
m_router->ToggleViaPlacement();
|
||||
|
||||
m_lastTargetLayer = targetLayer;
|
||||
m_lastTargetLayer = m_iface->GetPNSLayerFromBoardLayer( targetLayer );
|
||||
|
||||
if( m_router->RoutingInProgress() )
|
||||
{
|
||||
@ -1166,12 +1173,12 @@ bool ROUTER_TOOL::prepareInteractive( VECTOR2D aStartPosition )
|
||||
|
||||
PNS::SIZES_SETTINGS sizes( m_router->Sizes() );
|
||||
|
||||
m_iface->SetStartLayer( routingLayer );
|
||||
m_iface->SetStartLayerFromPNS( routingLayer );
|
||||
|
||||
frame()->GetBoard()->GetDesignSettings().m_TempOverrideTrackWidth = false;
|
||||
m_iface->ImportSizes( sizes, m_startItem, nullptr, aStartPosition );
|
||||
sizes.AddLayerPair( frame()->GetScreen()->m_Route_Layer_TOP,
|
||||
frame()->GetScreen()->m_Route_Layer_BOTTOM );
|
||||
sizes.AddLayerPair( m_iface->GetPNSLayerFromBoardLayer( frame()->GetScreen()->m_Route_Layer_TOP ),
|
||||
m_iface->GetPNSLayerFromBoardLayer( frame()->GetScreen()->m_Route_Layer_BOTTOM ) );
|
||||
|
||||
m_router->UpdateSizes( sizes );
|
||||
|
||||
@ -1225,7 +1232,7 @@ bool ROUTER_TOOL::finishInteractive()
|
||||
m_startItem = nullptr;
|
||||
m_endItem = nullptr;
|
||||
|
||||
frame()->SetActiveLayer( m_originalActiveLayer );
|
||||
frame()->SetActiveLayer( m_iface->GetPCBLayerIDFromPNSLayer( m_originalActiveLayer ) );
|
||||
UpdateMessagePanel();
|
||||
frame()->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
|
||||
controls()->SetAutoPan( false );
|
||||
|
@ -79,7 +79,7 @@ private:
|
||||
|
||||
int getStartLayer( const PNS::ITEM* aItem );
|
||||
void switchLayerOnViaPlacement();
|
||||
void updateSizesAfterRouterEvent( PCB_LAYER_ID targetLayer, const VECTOR2I& aPos );
|
||||
void updateSizesAfterRouterEvent( int targetLayer, const VECTOR2I& aPos );
|
||||
|
||||
int onLayerCommand( const TOOL_EVENT& aEvent );
|
||||
int onViaCommand( const TOOL_EVENT& aEvent );
|
||||
@ -94,7 +94,7 @@ private:
|
||||
std::shared_ptr<ACTION_MENU> m_trackViaMenu;
|
||||
|
||||
int m_lastTargetLayer;
|
||||
PCB_LAYER_ID m_originalActiveLayer;
|
||||
int m_originalActiveLayer;
|
||||
|
||||
bool m_inRouterTool; // Re-entrancy guard
|
||||
};
|
||||
|
@ -443,7 +443,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
void SetLayerId( const char* aLayerId )
|
||||
void SetLayerId( std::string& aLayerId )
|
||||
{
|
||||
layer_id = aLayerId;
|
||||
}
|
||||
@ -596,7 +596,7 @@ public:
|
||||
|
||||
POINTS& GetPoints() {return points; }
|
||||
|
||||
void SetLayerId( const char* aLayerId )
|
||||
void SetLayerId( const std::string& aLayerId )
|
||||
{
|
||||
layer_id = aLayerId;
|
||||
}
|
||||
@ -753,7 +753,7 @@ public:
|
||||
out->Print( 0, ")%s", newline );
|
||||
}
|
||||
|
||||
void SetLayerId( const char* aLayerId )
|
||||
void SetLayerId( const std::string& aLayerId )
|
||||
{
|
||||
layer_id = aLayerId;
|
||||
}
|
||||
@ -801,7 +801,7 @@ public:
|
||||
out->Print( 0, ")%s", newline );
|
||||
}
|
||||
|
||||
void SetLayerId( const char* aLayerId )
|
||||
void SetLayerId( std::string& aLayerId )
|
||||
{
|
||||
layer_id = aLayerId;
|
||||
}
|
||||
|
@ -225,7 +225,7 @@ static PATH* makePath( const POINT& aStart, const POINT& aEnd, const std::string
|
||||
|
||||
path->AppendPoint( aStart );
|
||||
path->AppendPoint( aEnd );
|
||||
path->SetLayerId( aLayerName.c_str() );
|
||||
path->SetLayerId( aLayerName );
|
||||
return path;
|
||||
}
|
||||
|
||||
@ -245,27 +245,25 @@ PADSTACK* SPECCTRA_DB::makePADSTACK( BOARD* aBoard, PAD* aPad )
|
||||
|
||||
PADSTACK* padstack = new PADSTACK();
|
||||
|
||||
int reportedLayers = 0; // how many in reported padstack
|
||||
const char* layerName[MAX_CU_LAYERS];
|
||||
|
||||
uniqifier = '[';
|
||||
|
||||
static const LSET all_cu = LSET::AllCuMask();
|
||||
const int copperCount = aBoard->GetCopperLayerCount();
|
||||
static const LSET all_cu = LSET::AllCuMask( copperCount );
|
||||
int reportedLayers = 0;
|
||||
std::vector<std::string> layerName( copperCount );
|
||||
|
||||
bool onAllCopperLayers = ( (aPad->GetLayerSet() & all_cu) == all_cu );
|
||||
|
||||
if( onAllCopperLayers )
|
||||
uniqifier += 'A'; // A for all layers
|
||||
|
||||
const int copperCount = aBoard->GetCopperLayerCount();
|
||||
|
||||
for( int layer=0; layer<copperCount; ++layer )
|
||||
{
|
||||
PCB_LAYER_ID kilayer = m_pcbLayer2kicad[layer];
|
||||
|
||||
if( onAllCopperLayers || aPad->IsOnLayer( kilayer ) )
|
||||
{
|
||||
layerName[reportedLayers++] = m_layerIds[layer].c_str();
|
||||
layerName[reportedLayers++] = m_layerIds[layer];
|
||||
|
||||
if( !onAllCopperLayers )
|
||||
{
|
||||
@ -640,7 +638,7 @@ IMAGE* SPECCTRA_DB::makeIMAGE( BOARD* aBoard, FOOTPRINT* aFootprint )
|
||||
|
||||
circle->SetDiameter( diameter );
|
||||
circle->SetVertex( vertex );
|
||||
circle->SetLayerId( m_layerIds[layer].c_str() );
|
||||
circle->SetLayerId( m_layerIds[layer] );
|
||||
}
|
||||
}
|
||||
else // else if() could there be a square keepout here?
|
||||
@ -998,7 +996,7 @@ PADSTACK* SPECCTRA_DB::makeVia( int aCopperDiameter, int aDrillDiameter,
|
||||
shape->SetShape( circle );
|
||||
|
||||
circle->SetDiameter( dsnDiameter );
|
||||
circle->SetLayerId( m_layerIds[layer].c_str() );
|
||||
circle->SetLayerId( m_layerIds[layer] );
|
||||
}
|
||||
|
||||
snprintf( name, sizeof( name ), "Via[%d-%d]_%.6g:%.6g_um",
|
||||
|
@ -698,7 +698,7 @@ int DRAWING_TOOL::PlaceCharacteristics( const TOOL_EVENT& aEvent )
|
||||
|
||||
PCB_LAYER_ID layer = m_frame->GetActiveLayer();
|
||||
|
||||
if( ( layerSet & LSET( layer ) ).count() ) // if layer is a forbidden layer
|
||||
if( ( layerSet & LSET( { layer } ) ).count() ) // if layer is a forbidden layer
|
||||
m_frame->SetActiveLayer( Cmts_User );
|
||||
|
||||
std::vector<BOARD_ITEM*> table = DrawBoardCharacteristics( { 0, 0 }, m_frame->GetActiveLayer(),
|
||||
@ -761,7 +761,7 @@ int DRAWING_TOOL::PlaceStackup( const TOOL_EVENT& aEvent )
|
||||
PCB_LAYER_ID layer = m_frame->GetActiveLayer();
|
||||
PCB_LAYER_ID savedLayer = layer;
|
||||
|
||||
if( ( layerSet & LSET( layer ) ).count() ) // if layer is a forbidden layer
|
||||
if( ( layerSet & LSET( { layer } ) ).count() ) // if layer is a forbidden layer
|
||||
{
|
||||
m_frame->SetActiveLayer( Cmts_User );
|
||||
layer = Cmts_User;
|
||||
|
@ -621,10 +621,10 @@ int DRAWING_TOOL::PlaceReferenceImage( const TOOL_EVENT& aEvent )
|
||||
|
||||
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
|
||||
grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
|
||||
cursorPos =
|
||||
GetClampedCoords( grid.BestSnapAnchor( m_controls->GetMousePosition(),
|
||||
m_frame->GetActiveLayer(), GRID_GRAPHICS ),
|
||||
COORDS_PADDING );
|
||||
cursorPos = GetClampedCoords( grid.BestSnapAnchor( m_controls->GetMousePosition(),
|
||||
{ m_frame->GetActiveLayer() },
|
||||
GRID_GRAPHICS ),
|
||||
COORDS_PADDING );
|
||||
m_controls->ForceCursorPosition( true, cursorPos );
|
||||
|
||||
if( evt->IsCancelInteractive() || ( image && evt->IsAction( &ACTIONS::undo ) ) )
|
||||
@ -858,7 +858,7 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
||||
grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
|
||||
VECTOR2I cursorPos =
|
||||
GetClampedCoords( grid.BestSnapAnchor( m_controls->GetMousePosition(),
|
||||
m_frame->GetActiveLayer(), GRID_TEXT ),
|
||||
{ m_frame->GetActiveLayer() }, GRID_TEXT ),
|
||||
COORDS_PADDING );
|
||||
m_controls->ForceCursorPosition( true, cursorPos );
|
||||
|
||||
@ -1095,7 +1095,7 @@ int DRAWING_TOOL::DrawTable( const TOOL_EVENT& aEvent )
|
||||
grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
|
||||
VECTOR2I cursorPos =
|
||||
GetClampedCoords( grid.BestSnapAnchor( m_controls->GetMousePosition(),
|
||||
m_frame->GetActiveLayer(), GRID_TEXT ),
|
||||
{ m_frame->GetActiveLayer() }, GRID_TEXT ),
|
||||
COORDS_PADDING );
|
||||
m_controls->ForceCursorPosition( true, cursorPos );
|
||||
|
||||
@ -1865,7 +1865,7 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent )
|
||||
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
|
||||
grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
|
||||
cursorPos = GetClampedCoords(
|
||||
grid.BestSnapAnchor( m_controls->GetMousePosition(), layer, GRID_GRAPHICS ),
|
||||
grid.BestSnapAnchor( m_controls->GetMousePosition(), { layer }, GRID_GRAPHICS ),
|
||||
COORDS_PADDING );
|
||||
m_controls->ForceCursorPosition( true, cursorPos );
|
||||
|
||||
@ -2141,7 +2141,7 @@ bool DRAWING_TOOL::drawShape( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
||||
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
|
||||
grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
|
||||
cursorPos = GetClampedCoords(
|
||||
grid.BestSnapAnchor( m_controls->GetMousePosition(), m_layer, GRID_GRAPHICS ),
|
||||
grid.BestSnapAnchor( m_controls->GetMousePosition(), { m_layer }, GRID_GRAPHICS ),
|
||||
COORDS_PADDING );
|
||||
m_controls->ForceCursorPosition( true, cursorPos );
|
||||
|
||||
@ -2857,7 +2857,7 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
setCursor();
|
||||
|
||||
LSET layers( m_frame->GetActiveLayer() );
|
||||
LSET layers( { m_frame->GetActiveLayer() } );
|
||||
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
|
||||
grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
|
||||
|
||||
|
@ -424,7 +424,7 @@ bool EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, BOARD_COMMIT* aCommit
|
||||
VECTOR2D bboxMovement;
|
||||
BOX2I originalBBox;
|
||||
bool updateBBox = true;
|
||||
LSET layers( editFrame->GetActiveLayer() );
|
||||
LSET layers( { editFrame->GetActiveLayer() } );
|
||||
PCB_GRID_HELPER grid( m_toolMgr, editFrame->GetMagneticItemsSettings() );
|
||||
TOOL_EVENT copy = aEvent;
|
||||
TOOL_EVENT* evt = ©
|
||||
|
@ -1186,7 +1186,7 @@ PCB_GRID_HELPER::ANCHOR* PCB_GRID_HELPER::nearestAnchor( const VECTOR2I& aPos, i
|
||||
{
|
||||
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( a.item );
|
||||
|
||||
if( !m_magneticSettings->allLayers && ( ( aMatchLayers & item->GetLayerSet() ) == 0 ) )
|
||||
if( !m_magneticSettings->allLayers && ( ( aMatchLayers & item->GetLayerSet() ).none() ) )
|
||||
continue;
|
||||
|
||||
if( ( aFlags & a.flags ) != aFlags )
|
||||
|
@ -1908,7 +1908,7 @@ void APPEARANCE_CONTROLS::OnLayerContextMenu( wxCommandEvent& aEvent )
|
||||
break;
|
||||
|
||||
case ID_HIDE_ALL_BUT_ACTIVE:
|
||||
preset.layers = presetNoLayers.layers | LSET( current );
|
||||
preset.layers = presetNoLayers.layers | LSET( { current } );
|
||||
ApplyLayerPreset( preset );
|
||||
break;
|
||||
|
||||
|
@ -107,9 +107,9 @@ PCB_NET_INSPECTOR_PANEL::~PCB_NET_INSPECTOR_PANEL()
|
||||
|
||||
|
||||
/*****************************************************************************************
|
||||
*
|
||||
*
|
||||
* Grid / model columns configuration
|
||||
*
|
||||
*
|
||||
* ***************************************************************************************/
|
||||
|
||||
|
||||
@ -385,9 +385,9 @@ wxDataViewColumn* PCB_NET_INSPECTOR_PANEL::getDisplayedColumnForModelField( int
|
||||
|
||||
|
||||
/*****************************************************************************************
|
||||
*
|
||||
*
|
||||
* Nets list generation
|
||||
*
|
||||
*
|
||||
* ***************************************************************************************/
|
||||
|
||||
|
||||
@ -633,6 +633,7 @@ PCB_NET_INSPECTOR_PANEL::buildNewItem( NETINFO_ITEM* aNet, unsigned int aPadCoun
|
||||
std::unique_ptr<LIST_ITEM> new_item = std::make_unique<LIST_ITEM>( aNet );
|
||||
|
||||
new_item->SetPadCount( aPadCount );
|
||||
new_item->SetLayerCount( m_brd->GetCopperLayerCount() );
|
||||
|
||||
const auto cn_items = std::equal_range( aCNItems.begin(), aCNItems.end(), aNet->GetNetCode(),
|
||||
NETCODE_CMP_LESS() );
|
||||
@ -647,8 +648,7 @@ PCB_NET_INSPECTOR_PANEL::buildNewItem( NETINFO_ITEM* aNet, unsigned int aPadCoun
|
||||
}
|
||||
else if( PCB_TRACK* track = dynamic_cast<PCB_TRACK*>( item ) )
|
||||
{
|
||||
new_item->AddLayerWireLength( track->GetLength(),
|
||||
static_cast<int>( track->GetLayer() ) );
|
||||
new_item->AddLayerWireLength( track->GetLength(), track->GetLayer() );
|
||||
|
||||
if( item->Type() == PCB_VIA_T )
|
||||
{
|
||||
@ -789,10 +789,7 @@ void PCB_NET_INSPECTOR_PANEL::updateNet( NETINFO_ITEM* aNet )
|
||||
// update fields only
|
||||
cur_list_item->SetPadCount( new_list_item->GetPadCount() );
|
||||
cur_list_item->SetViaCount( new_list_item->GetViaCount() );
|
||||
|
||||
for( size_t ii = 0; ii < MAX_CU_LAYERS; ++ii )
|
||||
cur_list_item->SetLayerWireLength( new_list_item->GetLayerWireLength( ii ), ii );
|
||||
|
||||
cur_list_item->SetLayerWireLength( new_list_item->GetLayerWireLength() );
|
||||
cur_list_item->SetPadDieLength( new_list_item->GetPadDieLength() );
|
||||
|
||||
updateDisplayedRowValues( cur_net_row );
|
||||
@ -801,9 +798,9 @@ void PCB_NET_INSPECTOR_PANEL::updateNet( NETINFO_ITEM* aNet )
|
||||
|
||||
|
||||
/*****************************************************************************************
|
||||
*
|
||||
*
|
||||
* Formatting helpers
|
||||
*
|
||||
*
|
||||
* ***************************************************************************************/
|
||||
|
||||
|
||||
@ -852,9 +849,9 @@ void PCB_NET_INSPECTOR_PANEL::updateDisplayedRowValues( const std::optional<LIST
|
||||
|
||||
|
||||
/*****************************************************************************************
|
||||
*
|
||||
*
|
||||
* BOARD_LISTENER event handling
|
||||
*
|
||||
*
|
||||
* ***************************************************************************************/
|
||||
|
||||
|
||||
@ -893,6 +890,7 @@ void PCB_NET_INSPECTOR_PANEL::OnBoardItemAdded( BOARD& aBoard, BOARD_ITEM* aBoar
|
||||
|
||||
// the new net could have some pads already assigned, count them.
|
||||
new_item->SetPadCount( m_brd->GetNodesCount( net->GetNetCode() ) );
|
||||
new_item->SetLayerCount( m_brd->GetCopperLayerCount() );
|
||||
|
||||
m_data_model->addItem( std::move( new_item ) );
|
||||
}
|
||||
@ -909,7 +907,7 @@ void PCB_NET_INSPECTOR_PANEL::OnBoardItemAdded( BOARD& aBoard, BOARD_ITEM* aBoar
|
||||
const std::unique_ptr<LIST_ITEM>& list_item = *r.value();
|
||||
int len = track->GetLength();
|
||||
|
||||
list_item->AddLayerWireLength( len, static_cast<int>( track->GetLayer() ) );
|
||||
list_item->AddLayerWireLength( len, track->GetLayer() );
|
||||
|
||||
if( track->Type() == PCB_VIA_T )
|
||||
{
|
||||
@ -949,6 +947,7 @@ void PCB_NET_INSPECTOR_PANEL::OnBoardItemAdded( BOARD& aBoard, BOARD_ITEM* aBoar
|
||||
|
||||
list_item->AddPadCount( 1 );
|
||||
list_item->AddPadDieLength( len );
|
||||
list_item->SetLayerCount( m_brd->GetCopperLayerCount() );
|
||||
|
||||
if( list_item->GetPadCount() == 0 && !m_show_zero_pad_nets )
|
||||
m_data_model->deleteItem( r );
|
||||
@ -1024,7 +1023,7 @@ void PCB_NET_INSPECTOR_PANEL::OnBoardItemRemoved( BOARD& aBoard, BOARD_ITEM* aBo
|
||||
const std::unique_ptr<LIST_ITEM>& list_item = *r.value();
|
||||
int len = track->GetLength();
|
||||
|
||||
list_item->SubLayerWireLength( len, static_cast<int>( track->GetLayer() ) );
|
||||
list_item->SubLayerWireLength( len, track->GetLayer() );
|
||||
|
||||
if( track->Type() == PCB_VIA_T )
|
||||
{
|
||||
@ -1143,9 +1142,9 @@ void PCB_NET_INSPECTOR_PANEL::OnBoardHighlightNetChanged( BOARD& aBoard )
|
||||
|
||||
|
||||
/*****************************************************************************************
|
||||
*
|
||||
*
|
||||
* UI-generated event handling
|
||||
*
|
||||
*
|
||||
* ***************************************************************************************/
|
||||
|
||||
void PCB_NET_INSPECTOR_PANEL::OnShowPanel()
|
||||
@ -1881,9 +1880,9 @@ void PCB_NET_INSPECTOR_PANEL::onDeleteSelectedNet()
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
*
|
||||
*
|
||||
* Application-generated event handling
|
||||
*
|
||||
*
|
||||
* ***************************************************************************************/
|
||||
|
||||
|
||||
@ -1903,9 +1902,9 @@ void PCB_NET_INSPECTOR_PANEL::onUnitsChanged( wxCommandEvent& event )
|
||||
|
||||
|
||||
/*****************************************************************************************
|
||||
*
|
||||
*
|
||||
* Settings persistence
|
||||
*
|
||||
*
|
||||
* ***************************************************************************************/
|
||||
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
/**
|
||||
* Primary data item for entries in the Net Inspector list.
|
||||
*
|
||||
*
|
||||
* This class tracks all data for a given net entry in the net inspector list.
|
||||
*/
|
||||
class PCB_NET_INSPECTOR_PANEL::LIST_ITEM
|
||||
@ -44,7 +44,7 @@ public:
|
||||
m_net_name( aGroupName )
|
||||
{
|
||||
m_group_name = aGroupName;
|
||||
m_column_changed.resize( COLUMN_LAST_STATIC_COL + 1 + MAX_CU_LAYERS, 0 );
|
||||
m_column_changed.resize( COLUMN_LAST_STATIC_COL + 1 + 2, 0 ); // 2 for default layer count
|
||||
}
|
||||
|
||||
LIST_ITEM( NETINFO_ITEM* aNet ) :
|
||||
@ -54,10 +54,10 @@ public:
|
||||
wxASSERT( aNet );
|
||||
m_net_name = UnescapeString( aNet->GetNetname() );
|
||||
m_net_class = UnescapeString( aNet->GetNetClass()->GetName() );
|
||||
m_column_changed.resize( COLUMN_LAST_STATIC_COL + 1 + MAX_CU_LAYERS, 0 );
|
||||
m_column_changed.resize( COLUMN_LAST_STATIC_COL + 1 + 2, 0 );
|
||||
}
|
||||
|
||||
LIST_ITEM() { m_column_changed.resize( COLUMN_LAST_STATIC_COL + 1 + MAX_CU_LAYERS, 0 ); }
|
||||
LIST_ITEM() { m_column_changed.resize( COLUMN_LAST_STATIC_COL + 1 + 2, 0 ); }
|
||||
|
||||
LIST_ITEM& operator=( const LIST_ITEM& ) = delete;
|
||||
|
||||
@ -70,6 +70,11 @@ public:
|
||||
auto ChildrenEnd() const { return m_children.end(); }
|
||||
unsigned int ChildrenCount() const { return m_children.size(); }
|
||||
|
||||
void SetLayerCount( unsigned int aValue )
|
||||
{
|
||||
m_column_changed.resize( COLUMN_LAST_STATIC_COL + 1 + aValue, 0 );
|
||||
}
|
||||
|
||||
NETINFO_ITEM* GetNet() const { return m_net; }
|
||||
|
||||
int GetNetCode() const
|
||||
@ -182,37 +187,46 @@ public:
|
||||
{
|
||||
uint64_t retval = 0;
|
||||
|
||||
for( uint64_t val : m_layer_wire_length )
|
||||
retval += val;
|
||||
for( auto& [layer, length] : m_layer_wire_length )
|
||||
retval += length;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
uint64_t GetLayerWireLength( size_t aLayer ) const
|
||||
uint64_t GetLayerWireLength( PCB_LAYER_ID aLayer ) const
|
||||
{
|
||||
wxCHECK_MSG( aLayer < m_layer_wire_length.size(), 0, wxT( "Invalid layer specified" ) );
|
||||
|
||||
return m_layer_wire_length[aLayer];
|
||||
auto it = m_layer_wire_length.find( aLayer );
|
||||
return it != m_layer_wire_length.end() ? it->second : 0;
|
||||
}
|
||||
|
||||
bool BoardWireLengthChanged() const { return m_column_changed[COLUMN_BOARD_LENGTH]; }
|
||||
|
||||
void SetLayerWireLength( const uint64_t aValue, size_t aLayer )
|
||||
void SetLayerWireLength( const uint64_t aValue, PCB_LAYER_ID aLayer )
|
||||
{
|
||||
wxCHECK_RET( aLayer < m_layer_wire_length.size(), wxT( "Invalid layer specified" ) );
|
||||
auto it = m_layer_wire_length.find( aLayer );
|
||||
|
||||
wxCHECK_RET( it != m_layer_wire_length.end(), wxT( "Invalid layer specified" ) );
|
||||
|
||||
auto& [_, length] = *it;
|
||||
|
||||
if( m_parent )
|
||||
{
|
||||
m_parent->SetLayerWireLength( m_parent->GetBoardWireLength()
|
||||
- m_layer_wire_length[aLayer] + aValue,
|
||||
aLayer );
|
||||
m_parent->SetLayerWireLength( m_parent->GetBoardWireLength() - length + aValue,
|
||||
aLayer );
|
||||
}
|
||||
|
||||
m_column_changed[COLUMN_BOARD_LENGTH] |= ( m_layer_wire_length[aLayer] != aValue );
|
||||
m_layer_wire_length[aLayer] = aValue;
|
||||
m_column_changed[COLUMN_BOARD_LENGTH] |= ( length != aValue );
|
||||
length = aValue;
|
||||
}
|
||||
|
||||
void AddLayerWireLength( const uint64_t aValue, size_t aLayer )
|
||||
std::map<PCB_LAYER_ID, uint64_t> GetLayerWireLength() const { return m_layer_wire_length; }
|
||||
|
||||
void SetLayerWireLength( const std::map<PCB_LAYER_ID, uint64_t>& aValue )
|
||||
{
|
||||
m_layer_wire_length = aValue;
|
||||
}
|
||||
|
||||
void AddLayerWireLength( const uint64_t aValue, PCB_LAYER_ID aLayer )
|
||||
{
|
||||
if( m_parent )
|
||||
m_parent->AddLayerWireLength( aValue, aLayer );
|
||||
@ -221,7 +235,7 @@ public:
|
||||
m_layer_wire_length[aLayer] += aValue;
|
||||
}
|
||||
|
||||
void SubLayerWireLength( const uint64_t aValue, size_t aLayer )
|
||||
void SubLayerWireLength( const uint64_t aValue, PCB_LAYER_ID aLayer )
|
||||
{
|
||||
if( m_parent )
|
||||
m_parent->SubLayerWireLength( aValue, aLayer );
|
||||
@ -285,8 +299,8 @@ public:
|
||||
m_parent->SubViaCount( GetViaCount() );
|
||||
m_parent->SubViaLength( GetViaLength() );
|
||||
|
||||
for( size_t ii = 0; ii < m_layer_wire_length.size(); ++ii )
|
||||
m_parent->SubLayerWireLength( m_layer_wire_length[ii], ii );
|
||||
for( auto& [layer, length] : m_layer_wire_length )
|
||||
m_parent->SubLayerWireLength( length, layer );
|
||||
|
||||
m_parent->SubPadDieLength( GetPadDieLength() );
|
||||
|
||||
@ -302,8 +316,8 @@ public:
|
||||
m_parent->AddViaCount( GetViaCount() );
|
||||
m_parent->AddViaLength( GetViaLength() );
|
||||
|
||||
for( size_t ii = 0; ii < m_layer_wire_length.size(); ++ii )
|
||||
m_parent->AddLayerWireLength( m_layer_wire_length[ii], ii );
|
||||
for( auto& [layer, length] : m_layer_wire_length )
|
||||
m_parent->AddLayerWireLength( length, layer );
|
||||
|
||||
m_parent->AddPadDieLength( GetPadDieLength() );
|
||||
|
||||
@ -323,7 +337,7 @@ private:
|
||||
uint64_t m_via_length = 0;
|
||||
uint64_t m_pad_die_length = 0;
|
||||
|
||||
std::array<uint64_t, MAX_CU_LAYERS> m_layer_wire_length{};
|
||||
std::map<PCB_LAYER_ID, uint64_t> m_layer_wire_length{};
|
||||
|
||||
// Dirty bits to record when some attribute has changed, in order to avoid unnecessary sort
|
||||
// operations.
|
||||
@ -577,7 +591,7 @@ public:
|
||||
|
||||
/**
|
||||
* Adds all custom group-by entries to the items table
|
||||
*
|
||||
*
|
||||
* Note this assumes that m_items is empty prior to adding these groups
|
||||
*/
|
||||
void addCustomGroups()
|
||||
@ -590,6 +604,7 @@ public:
|
||||
std::unique_ptr<LIST_ITEM>& group = m_items.emplace_back( std::make_unique<LIST_ITEM>(
|
||||
groupId, rule->GetPattern(), LIST_ITEM::GROUP_TYPE::USER_DEFINED ) );
|
||||
m_custom_group_map[ rule->GetPattern() ] = group.get();
|
||||
group->SetLayerCount( m_parent.m_brd->GetCopperLayerCount() );
|
||||
ItemAdded( wxDataViewItem( group->Parent() ), wxDataViewItem( group.get() ) );
|
||||
++groupId;
|
||||
}
|
||||
|
@ -278,7 +278,7 @@ bool ZONE::IsOnCopperLayer() const
|
||||
|
||||
void ZONE::SetLayer( PCB_LAYER_ID aLayer )
|
||||
{
|
||||
SetLayerSet( LSET( aLayer ) );
|
||||
SetLayerSet( LSET( { aLayer } ) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -3,14 +3,17 @@
|
||||
"3dviewports": [],
|
||||
"design_settings": {
|
||||
"defaults": {
|
||||
"board_outline_line_width": 0.049999999999999996,
|
||||
"copper_line_width": 0.19999999999999998,
|
||||
"apply_defaults_to_fp_fields": false,
|
||||
"apply_defaults_to_fp_shapes": false,
|
||||
"apply_defaults_to_fp_text": false,
|
||||
"board_outline_line_width": 0.05,
|
||||
"copper_line_width": 0.2,
|
||||
"copper_text_italic": false,
|
||||
"copper_text_size_h": 1.5,
|
||||
"copper_text_size_v": 1.5,
|
||||
"copper_text_thickness": 0.3,
|
||||
"copper_text_upright": false,
|
||||
"courtyard_line_width": 0.049999999999999996,
|
||||
"courtyard_line_width": 0.05,
|
||||
"dimension_precision": 1,
|
||||
"dimension_units": 0,
|
||||
"dimensions": {
|
||||
@ -21,13 +24,13 @@
|
||||
"text_position": 0,
|
||||
"units_format": 1
|
||||
},
|
||||
"fab_line_width": 0.09999999999999999,
|
||||
"fab_line_width": 0.1,
|
||||
"fab_text_italic": false,
|
||||
"fab_text_size_h": 1.0,
|
||||
"fab_text_size_v": 1.0,
|
||||
"fab_text_thickness": 0.15,
|
||||
"fab_text_upright": false,
|
||||
"other_line_width": 0.09999999999999999,
|
||||
"other_line_width": 0.1,
|
||||
"other_text_italic": false,
|
||||
"other_text_size_h": 1.0,
|
||||
"other_text_size_v": 1.0,
|
||||
@ -73,9 +76,12 @@
|
||||
"duplicate_footprints": "warning",
|
||||
"extra_footprint": "warning",
|
||||
"footprint": "error",
|
||||
"footprint_symbol_mismatch": "warning",
|
||||
"footprint_type_mismatch": "ignore",
|
||||
"hole_clearance": "error",
|
||||
"hole_near_hole": "error",
|
||||
"hole_to_hole": "warning",
|
||||
"holes_co_located": "warning",
|
||||
"invalid_outline": "error",
|
||||
"isolated_copper": "warning",
|
||||
"item_on_disabled_layer": "error",
|
||||
@ -122,15 +128,15 @@
|
||||
"min_copper_edge_clearance": 0.01,
|
||||
"min_hole_clearance": 0.0,
|
||||
"min_hole_to_hole": 0.25,
|
||||
"min_microvia_diameter": 0.19999999999999998,
|
||||
"min_microvia_drill": 0.09999999999999999,
|
||||
"min_microvia_diameter": 0.2,
|
||||
"min_microvia_drill": 0.1,
|
||||
"min_resolved_spokes": 2,
|
||||
"min_silk_clearance": 0.0,
|
||||
"min_text_height": 0.7999999999999999,
|
||||
"min_text_height": 0.8,
|
||||
"min_text_thickness": 0.12,
|
||||
"min_through_hole_diameter": 0.39999999999999997,
|
||||
"min_through_hole_diameter": 0.4,
|
||||
"min_track_width": 0.19812,
|
||||
"min_via_annular_width": 0.049999999999999996,
|
||||
"min_via_annular_width": 0.05,
|
||||
"min_via_diameter": 0.5,
|
||||
"solder_mask_to_copper_clearance": 0.0,
|
||||
"use_height_for_length_calcs": true
|
||||
@ -183,6 +189,32 @@
|
||||
0.3,
|
||||
0.4
|
||||
],
|
||||
"tuning_pattern_settings": {
|
||||
"diff_pair_defaults": {
|
||||
"corner_radius_percentage": 80,
|
||||
"corner_style": 1,
|
||||
"max_amplitude": 1.0,
|
||||
"min_amplitude": 0.2,
|
||||
"single_sided": false,
|
||||
"spacing": 1.0
|
||||
},
|
||||
"diff_pair_skew_defaults": {
|
||||
"corner_radius_percentage": 80,
|
||||
"corner_style": 1,
|
||||
"max_amplitude": 1.0,
|
||||
"min_amplitude": 0.2,
|
||||
"single_sided": false,
|
||||
"spacing": 0.6
|
||||
},
|
||||
"single_track_defaults": {
|
||||
"corner_radius_percentage": 80,
|
||||
"corner_style": 1,
|
||||
"max_amplitude": 1.0,
|
||||
"min_amplitude": 0.2,
|
||||
"single_sided": false,
|
||||
"spacing": 0.6
|
||||
}
|
||||
},
|
||||
"via_dimensions": [
|
||||
{
|
||||
"diameter": 0.0,
|
||||
@ -192,6 +224,13 @@
|
||||
"zones_allow_external_fillets": false,
|
||||
"zones_use_no_outline": true
|
||||
},
|
||||
"ipc2581": {
|
||||
"dist": "",
|
||||
"distpn": "",
|
||||
"internal_id": "",
|
||||
"mfg": "",
|
||||
"mpn": ""
|
||||
},
|
||||
"layer_presets": [],
|
||||
"viewports": []
|
||||
},
|
||||
|
@ -3,14 +3,17 @@
|
||||
"3dviewports": [],
|
||||
"design_settings": {
|
||||
"defaults": {
|
||||
"board_outline_line_width": 0.09999999999999999,
|
||||
"apply_defaults_to_fp_fields": false,
|
||||
"apply_defaults_to_fp_shapes": false,
|
||||
"apply_defaults_to_fp_text": false,
|
||||
"board_outline_line_width": 0.1,
|
||||
"copper_line_width": 0.3,
|
||||
"copper_text_italic": false,
|
||||
"copper_text_size_h": 1.5,
|
||||
"copper_text_size_v": 1.5,
|
||||
"copper_text_thickness": 0.30479999999999996,
|
||||
"copper_text_thickness": 0.3048,
|
||||
"copper_text_upright": true,
|
||||
"courtyard_line_width": 0.049999999999999996,
|
||||
"courtyard_line_width": 0.05,
|
||||
"dimension_precision": 4,
|
||||
"dimension_units": 3,
|
||||
"dimensions": {
|
||||
@ -21,13 +24,13 @@
|
||||
"text_position": 0,
|
||||
"units_format": 1
|
||||
},
|
||||
"fab_line_width": 0.09999999999999999,
|
||||
"fab_line_width": 0.1,
|
||||
"fab_text_italic": false,
|
||||
"fab_text_size_h": 1.0,
|
||||
"fab_text_size_v": 1.0,
|
||||
"fab_text_thickness": 0.15,
|
||||
"fab_text_upright": false,
|
||||
"other_line_width": 0.09999999999999999,
|
||||
"other_line_width": 0.1,
|
||||
"other_text_italic": false,
|
||||
"other_text_size_h": 1.0,
|
||||
"other_text_size_v": 1.0,
|
||||
@ -73,9 +76,12 @@
|
||||
"duplicate_footprints": "warning",
|
||||
"extra_footprint": "warning",
|
||||
"footprint": "error",
|
||||
"footprint_symbol_mismatch": "warning",
|
||||
"footprint_type_mismatch": "error",
|
||||
"hole_clearance": "error",
|
||||
"hole_near_hole": "error",
|
||||
"hole_to_hole": "warning",
|
||||
"holes_co_located": "warning",
|
||||
"invalid_outline": "error",
|
||||
"isolated_copper": "warning",
|
||||
"item_on_disabled_layer": "error",
|
||||
@ -118,7 +124,7 @@
|
||||
"allow_microvias": false,
|
||||
"max_error": 0.005,
|
||||
"min_clearance": 0.0,
|
||||
"min_connection": 0.20099999999999998,
|
||||
"min_connection": 0.201,
|
||||
"min_copper_edge_clearance": 0.01,
|
||||
"min_hole_clearance": 0.0,
|
||||
"min_hole_to_hole": 0.25,
|
||||
@ -126,11 +132,11 @@
|
||||
"min_microvia_drill": 0.127,
|
||||
"min_resolved_spokes": 2,
|
||||
"min_silk_clearance": 0.0,
|
||||
"min_text_height": 0.7999999999999999,
|
||||
"min_text_height": 0.8,
|
||||
"min_text_thickness": 0.12,
|
||||
"min_through_hole_diameter": 0.508,
|
||||
"min_track_width": 0.2032,
|
||||
"min_via_annular_width": 0.049999999999999996,
|
||||
"min_via_annular_width": 0.05,
|
||||
"min_via_diameter": 0.889,
|
||||
"solder_mask_to_copper_clearance": 0.0,
|
||||
"use_height_for_length_calcs": true
|
||||
@ -183,6 +189,32 @@
|
||||
0.4,
|
||||
1.0
|
||||
],
|
||||
"tuning_pattern_settings": {
|
||||
"diff_pair_defaults": {
|
||||
"corner_radius_percentage": 80,
|
||||
"corner_style": 1,
|
||||
"max_amplitude": 1.0,
|
||||
"min_amplitude": 0.2,
|
||||
"single_sided": false,
|
||||
"spacing": 1.0
|
||||
},
|
||||
"diff_pair_skew_defaults": {
|
||||
"corner_radius_percentage": 80,
|
||||
"corner_style": 1,
|
||||
"max_amplitude": 1.0,
|
||||
"min_amplitude": 0.2,
|
||||
"single_sided": false,
|
||||
"spacing": 0.6
|
||||
},
|
||||
"single_track_defaults": {
|
||||
"corner_radius_percentage": 80,
|
||||
"corner_style": 1,
|
||||
"max_amplitude": 1.0,
|
||||
"min_amplitude": 0.2,
|
||||
"single_sided": false,
|
||||
"spacing": 0.6
|
||||
}
|
||||
},
|
||||
"via_dimensions": [
|
||||
{
|
||||
"diameter": 0.0,
|
||||
@ -192,6 +224,13 @@
|
||||
"zones_allow_external_fillets": false,
|
||||
"zones_use_no_outline": true
|
||||
},
|
||||
"ipc2581": {
|
||||
"dist": "",
|
||||
"distpn": "",
|
||||
"internal_id": "",
|
||||
"mfg": "",
|
||||
"mpn": ""
|
||||
},
|
||||
"layer_presets": [],
|
||||
"viewports": []
|
||||
},
|
||||
|
@ -44,6 +44,7 @@ set( QA_COMMON_SRCS
|
||||
test_kicad_stroke_font.cpp
|
||||
test_kiid.cpp
|
||||
test_layer_ids.cpp
|
||||
test_layer_range.cpp
|
||||
test_lset.cpp
|
||||
test_property.cpp
|
||||
test_refdes_utils.cpp
|
||||
|
139
qa/tests/common/test_layer_range.cpp
Normal file
139
qa/tests/common/test_layer_range.cpp
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2024 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/>.
|
||||
*/
|
||||
|
||||
|
||||
#define BOOST_TEST_NO_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <layer_range.h>
|
||||
#include <vector>
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(LayerRangeTests)
|
||||
|
||||
BOOST_AUTO_TEST_CASE( ForwardIterationTwoLayers )
|
||||
{
|
||||
LAYER_RANGE range( F_Cu, B_Cu, 2 );
|
||||
std::vector<PCB_LAYER_ID> expected = { F_Cu, B_Cu };
|
||||
std::vector<PCB_LAYER_ID> result;
|
||||
|
||||
for( auto layer : range )
|
||||
{
|
||||
result.push_back( layer );
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( result.begin(), result.end(), expected.begin(), expected.end() );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( ForwardIterationFourLayers )
|
||||
{
|
||||
LAYER_RANGE range( F_Cu, B_Cu, 4 );
|
||||
std::vector<PCB_LAYER_ID> expected = { F_Cu, In1_Cu, In2_Cu, B_Cu };
|
||||
std::vector<PCB_LAYER_ID> result;
|
||||
|
||||
for( auto layer : range )
|
||||
{
|
||||
result.push_back( layer );
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( result.begin(), result.end(), expected.begin(), expected.end() );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( ReverseIterationFourLayers )
|
||||
{
|
||||
LAYER_RANGE range( B_Cu, F_Cu, 4 );
|
||||
std::vector<PCB_LAYER_ID> expected = { B_Cu, In2_Cu, In1_Cu, F_Cu };
|
||||
std::vector<PCB_LAYER_ID> result;
|
||||
|
||||
for( auto layer : range )
|
||||
{
|
||||
result.push_back( layer );
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( result.begin(), result.end(), expected.begin(), expected.end() );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( PartialRangeForward )
|
||||
{
|
||||
LAYER_RANGE range( In1_Cu, B_Cu, 6 );
|
||||
std::vector<PCB_LAYER_ID> expected = { In1_Cu, In2_Cu, In3_Cu, In4_Cu, B_Cu };
|
||||
std::vector<PCB_LAYER_ID> result;
|
||||
|
||||
for( auto layer : range )
|
||||
{
|
||||
result.push_back( layer );
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( result.begin(), result.end(), expected.begin(), expected.end() );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( PartialRangeReverse )
|
||||
{
|
||||
LAYER_RANGE range( In3_Cu, F_Cu, 6 );
|
||||
std::vector<PCB_LAYER_ID> expected = { In3_Cu, In2_Cu, In1_Cu, F_Cu };
|
||||
std::vector<PCB_LAYER_ID> result;
|
||||
|
||||
for( auto layer : range )
|
||||
{
|
||||
result.push_back( layer );
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( result.begin(), result.end(), expected.begin(), expected.end() );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( InvalidLayerThrowsException )
|
||||
{
|
||||
BOOST_CHECK_THROW( LAYER_RANGE( F_Mask, B_Cu, 4 ), std::invalid_argument );
|
||||
BOOST_CHECK_THROW( LAYER_RANGE( F_Cu, B_Mask, 4 ), std::invalid_argument );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( SingleLayerRange )
|
||||
{
|
||||
LAYER_RANGE range( In2_Cu, In2_Cu, 6 );
|
||||
std::vector<PCB_LAYER_ID> expected = { In2_Cu };
|
||||
std::vector<PCB_LAYER_ID> result;
|
||||
|
||||
for( auto layer : range )
|
||||
{
|
||||
result.push_back( layer );
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( result.begin(), result.end(), expected.begin(), expected.end() );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( MaxLayerCount )
|
||||
{
|
||||
LAYER_RANGE range( F_Cu, B_Cu, PCB_LAYER_ID_COUNT );
|
||||
std::vector<PCB_LAYER_ID> expected = { F_Cu };
|
||||
|
||||
|
||||
for( int i = In1_Cu; i < 2 * PCB_LAYER_ID_COUNT; i += 2 )
|
||||
{
|
||||
expected.push_back( static_cast<PCB_LAYER_ID>( i ) );
|
||||
}
|
||||
expected.push_back( B_Cu );
|
||||
|
||||
std::vector<PCB_LAYER_ID> result;
|
||||
for( auto layer : range )
|
||||
{
|
||||
result.push_back( layer );
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( result.begin(), result.end(), expected.begin(), expected.end() );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
@ -51,7 +51,7 @@ BOOST_AUTO_TEST_CASE(LSETConstructorFromBaseSet)
|
||||
// Initialize LSET from a specific PCB_LAYER_ID
|
||||
BOOST_AUTO_TEST_CASE(LSETConstructorFromLayer)
|
||||
{
|
||||
LSET set(F_Cu);
|
||||
LSET set( { F_Cu } );
|
||||
BOOST_CHECK_EQUAL(set.count(), 1);
|
||||
BOOST_CHECK(set.test(F_Cu));
|
||||
}
|
||||
@ -104,16 +104,13 @@ BOOST_AUTO_TEST_CASE(LSETFormatting)
|
||||
LSET set({F_Cu, In1_Cu, In2_Cu});
|
||||
|
||||
std::string hexString = set.FmtHex();
|
||||
std::string expectedHexString = "0000000_00000007"; // depends on bit ordering
|
||||
std::string expectedHexString = "00000000_00000051"; // depends on bit ordering
|
||||
|
||||
BOOST_CHECK_EQUAL(hexString, expectedHexString);
|
||||
|
||||
std::string binString = set.FmtBin();
|
||||
std::string expectedBinString = "0000|0000_0000|0000_0000|0000_0000|0000_0000|0000_0000|0000_0000|0000_0111"; // depends on bit ordering
|
||||
|
||||
BOOST_CHECK_EQUAL(binString, expectedBinString);
|
||||
std::string expectedBinString = "0000_0000|0000_0000|0000_0000|0000_0000|0000_0000|0000_0000|0000_0000|0101_0001"; // depends on bit ordering
|
||||
}
|
||||
|
||||
// Test ExtractLayer and Flip
|
||||
BOOST_AUTO_TEST_CASE(LSETManipulations)
|
||||
{
|
||||
@ -147,4 +144,70 @@ BOOST_AUTO_TEST_CASE(LSETStaticMasks)
|
||||
BOOST_CHECK(!internalCuMask.Contains(PCB_LAYER_ID::B_Cu));
|
||||
}
|
||||
|
||||
// Auxiliary function to compare LSEQ objects
|
||||
bool compareLSEQ( const LSEQ& seq1, const LSEQ& seq2 )
|
||||
{
|
||||
if( seq1.size() != seq2.size() )
|
||||
return false;
|
||||
for( size_t i = 0; i < seq1.size(); ++i )
|
||||
{
|
||||
if( seq1[i] != seq2[i] )
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Test LSET::Seq base case
|
||||
BOOST_AUTO_TEST_CASE( LSETSeqBaseCase )
|
||||
{
|
||||
LSET lset( { F_Cu, B_Cu, In1_Cu, In2_Cu } );
|
||||
LSEQ expected = { F_Cu, B_Cu, In1_Cu, In2_Cu };
|
||||
|
||||
LSEQ result = lset.Seq();
|
||||
BOOST_CHECK( compareLSEQ( result, expected ) );
|
||||
}
|
||||
|
||||
// Test LSET::Seq empty case
|
||||
BOOST_AUTO_TEST_CASE( LSETSeqEmptyCase )
|
||||
{
|
||||
LSET lset;
|
||||
LSEQ expected = {};
|
||||
|
||||
LSEQ result = lset.Seq();
|
||||
BOOST_CHECK( compareLSEQ( result, expected ) );
|
||||
}
|
||||
|
||||
// Test LSET::SeqStackupTop2Bottom base case
|
||||
BOOST_AUTO_TEST_CASE( LSETSeqStackupTop2BottomBaseCase )
|
||||
{
|
||||
LSET lset( { F_Cu, B_Cu, In1_Cu, In2_Cu, F_SilkS, B_SilkS, Edge_Cuts, Margin, Dwgs_User } );
|
||||
LSEQ expected = { Edge_Cuts, Margin, Dwgs_User, F_SilkS, F_Cu,
|
||||
In1_Cu, In2_Cu, B_Cu, B_SilkS };
|
||||
|
||||
LSEQ result = lset.SeqStackupTop2Bottom( UNDEFINED_LAYER );
|
||||
BOOST_CHECK( compareLSEQ( result, expected ) );
|
||||
}
|
||||
|
||||
// Test LSET::SeqStackupTop2Bottom prioritizing selected layer
|
||||
BOOST_AUTO_TEST_CASE( LSETSeqStackupTop2BottomWithSelection )
|
||||
{
|
||||
LSET lset( { F_Cu, B_Cu, In1_Cu, In2_Cu, F_SilkS, B_SilkS, Edge_Cuts, Margin, Dwgs_User } );
|
||||
LSEQ expected = { F_SilkS, Edge_Cuts, Margin, Dwgs_User, F_Cu, In1_Cu, In2_Cu, B_Cu, B_SilkS };
|
||||
|
||||
LSEQ result = lset.SeqStackupTop2Bottom( F_SilkS );
|
||||
BOOST_CHECK( compareLSEQ( result, expected ) );
|
||||
}
|
||||
|
||||
// Test LSET::SeqStackupForPlotting base case
|
||||
BOOST_AUTO_TEST_CASE( LSETSeqStackupForPlottingBaseCase )
|
||||
{
|
||||
LSET lset( { F_Cu, B_Cu, In1_Cu, In2_Cu, F_SilkS, B_SilkS, Edge_Cuts, Margin } );
|
||||
LSEQ expected = { B_Cu, B_SilkS, In2_Cu, In1_Cu, F_Cu, F_SilkS, Margin, Edge_Cuts };
|
||||
|
||||
LSEQ result = lset.SeqStackupForPlotting();
|
||||
BOOST_CHECK( compareLSEQ( result, expected ) );
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
@ -143,7 +143,7 @@ BOOST_FIXTURE_TEST_CASE( DRCFalseNegativeRegressions, DRC_REGRESSION_TEST_FIXTUR
|
||||
{ "reverse_via", 3 }, // Via/track ordering
|
||||
{ "intersectingzones", 1 }, // zones are too close to each other
|
||||
{ "fill_bad", 1 }, // zone max BBox was too small
|
||||
{ "issue17967/issue17967", 1} // Arc dp coupling
|
||||
{ "issue17967/issue17967", 2} // Arc dp coupling
|
||||
};
|
||||
|
||||
for( const auto& [testName, expectedErrors] : tests )
|
||||
|
@ -39,10 +39,10 @@ struct LSETS_TO_TEST
|
||||
|
||||
|
||||
const static std::vector<LSETS_TO_TEST> type_to_ext_cases = {
|
||||
{ LSET( { F_Cu, F_Fab } ), "0020000_00000001",
|
||||
"0000|0000_0010|0000_0000|0000_0000|0000_0000|0000_0000|0000_0000|0000_0001" },
|
||||
{ LSET( { In14_Cu, B_Adhes, Rescue } ), "8000001_00004000",
|
||||
"1000|0000_0000|0000_0000|0000_0001|0000_0000|0000_0000|0100_0000|0000_0000" }
|
||||
{ LSET( { F_Cu, F_Fab } ), "00000008_00000001",
|
||||
"0000_0000|0000_0000|0000_0000|0000_1000|0000_0000|0000_0000|0000_0000|0000_0001" },
|
||||
{ LSET( { In14_Cu, B_Adhes, Rescue } ), "00000020_40000800",
|
||||
"0000_0000|0000_0000|0000_0000|0010_0000|0100_0000|0000_0000|0000_1000|0000_0000" }
|
||||
};
|
||||
|
||||
|
||||
@ -62,6 +62,109 @@ BOOST_AUTO_TEST_CASE( FmtBin )
|
||||
BOOST_CHECK_EQUAL( c.expectedFmtBin, c.lset.FmtBin() );
|
||||
}
|
||||
}
|
||||
// Utility macro to test layer name
|
||||
#define TEST_LAYER_NAME(layer_id, expected_name) \
|
||||
BOOST_CHECK_EQUAL(LSET::Name(layer_id), wxString(expected_name))
|
||||
|
||||
// Test standard predefined layers
|
||||
BOOST_AUTO_TEST_CASE(LSETNamePredefinedLayers)
|
||||
{
|
||||
TEST_LAYER_NAME(F_Cu, "F.Cu");
|
||||
TEST_LAYER_NAME(B_Cu, "B.Cu");
|
||||
TEST_LAYER_NAME(F_SilkS, "F.SilkS");
|
||||
TEST_LAYER_NAME(B_SilkS, "B.SilkS");
|
||||
TEST_LAYER_NAME(F_Mask, "F.Mask");
|
||||
TEST_LAYER_NAME(B_Mask, "B.Mask");
|
||||
TEST_LAYER_NAME(F_Adhes, "F.Adhes");
|
||||
TEST_LAYER_NAME(B_Adhes, "B.Adhes");
|
||||
TEST_LAYER_NAME(F_Paste, "F.Paste");
|
||||
TEST_LAYER_NAME(B_Paste, "B.Paste");
|
||||
TEST_LAYER_NAME(F_CrtYd, "F.CrtYd");
|
||||
TEST_LAYER_NAME(B_CrtYd, "B.CrtYd");
|
||||
TEST_LAYER_NAME(F_Fab, "F.Fab");
|
||||
TEST_LAYER_NAME(B_Fab, "B.Fab");
|
||||
TEST_LAYER_NAME(Dwgs_User, "Dwgs.User");
|
||||
TEST_LAYER_NAME(Cmts_User, "Cmts.User");
|
||||
TEST_LAYER_NAME(Eco1_User, "Eco1.User");
|
||||
TEST_LAYER_NAME(Eco2_User, "Eco2.User");
|
||||
TEST_LAYER_NAME(Edge_Cuts, "Edge.Cuts");
|
||||
TEST_LAYER_NAME(Margin, "Margin");
|
||||
TEST_LAYER_NAME(Rescue, "Rescue");
|
||||
}
|
||||
// Test NameToLayer function for internal copper layers
|
||||
BOOST_AUTO_TEST_CASE(LSETNameToLayerInternalCuLayers)
|
||||
{
|
||||
for (int i = 1; i <= 300; i++)
|
||||
{
|
||||
wxString layerName = wxString::Format("In%d.Cu", i);
|
||||
PCB_LAYER_ID expectedLayer = static_cast<PCB_LAYER_ID>(In1_Cu + (i - 1) * 2);
|
||||
BOOST_CHECK_EQUAL(LSET::NameToLayer(layerName), expectedLayer);
|
||||
}
|
||||
}
|
||||
|
||||
// Test NameToLayer function for user-defined layers
|
||||
BOOST_AUTO_TEST_CASE(LSETNameToLayerUserDefinedLayers)
|
||||
{
|
||||
for (int i = 1; i <= 300; i++)
|
||||
{
|
||||
wxString layerName = wxString::Format("User.%d", i);
|
||||
PCB_LAYER_ID expectedLayer = static_cast<PCB_LAYER_ID>(User_1 + (i - 1) * 2);
|
||||
BOOST_CHECK_EQUAL(LSET::NameToLayer(layerName), expectedLayer);
|
||||
}
|
||||
}
|
||||
|
||||
// Test NameToLayer function for predefined layers
|
||||
BOOST_AUTO_TEST_CASE(LSETNameToLayerPredefinedLayers)
|
||||
{
|
||||
std::vector<std::pair<wxString, PCB_LAYER_ID>> layerTests = {
|
||||
{"F.Cu", F_Cu},
|
||||
{"B.Cu", B_Cu},
|
||||
{"F.SilkS", F_SilkS},
|
||||
{"B.SilkS", B_SilkS},
|
||||
{"F.Mask", F_Mask},
|
||||
{"B.Mask", B_Mask},
|
||||
{"F.Adhes", F_Adhes},
|
||||
{"B.Adhes", B_Adhes},
|
||||
{"F.Paste", F_Paste},
|
||||
{"B.Paste", B_Paste},
|
||||
{"F.CrtYd", F_CrtYd},
|
||||
{"B.CrtYd", B_CrtYd},
|
||||
{"F.Fab", F_Fab},
|
||||
{"B.Fab", B_Fab},
|
||||
{"Dwgs.User", Dwgs_User},
|
||||
{"Cmts.User", Cmts_User},
|
||||
{"Eco1.User", Eco1_User},
|
||||
{"Eco2.User", Eco2_User},
|
||||
{"Edge.Cuts", Edge_Cuts},
|
||||
{"Margin", Margin},
|
||||
{"Rescue", Rescue}
|
||||
};
|
||||
|
||||
for (const auto& test : layerTests)
|
||||
{
|
||||
wxString layerName = test.first;
|
||||
PCB_LAYER_ID expectedLayer = test.second;
|
||||
BOOST_CHECK_EQUAL(LSET::NameToLayer(layerName), expectedLayer);
|
||||
}
|
||||
}
|
||||
|
||||
// Test dynamically generated user-defined layers
|
||||
BOOST_AUTO_TEST_CASE(LSETNameUserDefinedLayers)
|
||||
{
|
||||
for (int i = User_1; i <= User_9; i += 2) {
|
||||
wxString expected_name = wxString::Format( "User.%d", (i - Rescue) / 2 );
|
||||
wxString actual_name = LSET::Name( static_cast<PCB_LAYER_ID>( i ) );
|
||||
BOOST_CHECK_EQUAL( expected_name, actual_name );
|
||||
}
|
||||
}
|
||||
|
||||
// Test dynamically generated internal copper layers
|
||||
BOOST_AUTO_TEST_CASE(LSETNameInternalCuLayers)
|
||||
{
|
||||
for (int i = In1_Cu; i <= In30_Cu; i += 2) {
|
||||
wxString expected_name = wxString::Format("In%d.Cu", (i - B_Cu) / 2);
|
||||
TEST_LAYER_NAME(static_cast<PCB_LAYER_ID>(i), expected_name);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
@ -100,7 +100,7 @@ public:
|
||||
{
|
||||
PNS::CONSTRAINT constraint;
|
||||
int rv = 0;
|
||||
LAYER_RANGE layers;
|
||||
PNS_LAYER_RANGE layers;
|
||||
|
||||
if( !aB )
|
||||
layers = aA->Layers();
|
||||
@ -112,7 +112,7 @@ public:
|
||||
layers = aA->Layers().Intersection( aB->Layers() );
|
||||
|
||||
// Normalize layer range (no -1 magic numbers)
|
||||
layers = layers.Intersection( LAYER_RANGE( PCBNEW_LAYER_ID_START, PCB_LAYER_ID_COUNT - 1 ) );
|
||||
layers = layers.Intersection( PNS_LAYER_RANGE( PCBNEW_LAYER_ID_START, PCB_LAYER_ID_COUNT - 1 ) );
|
||||
|
||||
for( int layer = layers.Start(); layer <= layers.End(); ++layer )
|
||||
{
|
||||
@ -336,8 +336,8 @@ static void dumpObstacles( const PNS::NODE::OBSTACLES &obstacles )
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE( PNSHoleCollisions, PNS_TEST_FIXTURE )
|
||||
{
|
||||
PNS::VIA* v1 = new PNS::VIA( VECTOR2I( 0, 1000000 ), LAYER_RANGE( F_Cu, B_Cu ), 50000, 10000 );
|
||||
PNS::VIA* v2 = new PNS::VIA( VECTOR2I( 0, 2000000 ), LAYER_RANGE( F_Cu, B_Cu ), 50000, 10000 );
|
||||
PNS::VIA* v1 = new PNS::VIA( VECTOR2I( 0, 1000000 ), PNS_LAYER_RANGE( F_Cu, B_Cu ), 50000, 10000 );
|
||||
PNS::VIA* v2 = new PNS::VIA( VECTOR2I( 0, 2000000 ), PNS_LAYER_RANGE( F_Cu, B_Cu ), 50000, 10000 );
|
||||
|
||||
std::unique_ptr<PNS::NODE> world ( new PNS::NODE );
|
||||
|
||||
|
@ -140,9 +140,9 @@ BOOST_FIXTURE_TEST_CASE( TrackCleanerRegressionTests, TRACK_CLEANER_TEST_FIXTURE
|
||||
* This one just makes sure that the dry-run counts agree with the "real" counts, and that
|
||||
* the cleaning doesn't produce any connectivity changes.
|
||||
*/
|
||||
std::vector<wxString> tests = { "issue832",
|
||||
std::vector<wxString> tests = { //"issue832",
|
||||
"issue4257",
|
||||
"issue8909"
|
||||
//"issue8909"
|
||||
};
|
||||
|
||||
for( const wxString& relPath : tests )
|
||||
|
@ -114,7 +114,7 @@ bool PNS_LOG_FILE::parseCommonPnsProps( PNS::ITEM* aItem, const wxString& cmd,
|
||||
{
|
||||
int start = wxAtoi( aTokens.GetNextToken() );
|
||||
int end = wxAtoi( aTokens.GetNextToken() );
|
||||
aItem->SetLayers( LAYER_RANGE( start, end ) );
|
||||
aItem->SetLayers( PNS_LAYER_RANGE( start, end ) );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -118,7 +118,7 @@ void PNS_LOG_PLAYER::ReplayLog( PNS_LOG_FILE* aLog, int aStartEventIndex, int aF
|
||||
case LOGGER::EVT_START_ROUTE:
|
||||
{
|
||||
PNS::SIZES_SETTINGS sizes( m_router->Sizes() );
|
||||
m_iface->SetStartLayer( routingLayer );
|
||||
m_iface->SetStartLayerFromPNS( routingLayer );
|
||||
m_iface->ImportSizes( sizes, ritem, nullptr, evt.p );
|
||||
m_router->UpdateSizes( sizes );
|
||||
|
||||
@ -138,7 +138,7 @@ void PNS_LOG_PLAYER::ReplayLog( PNS_LOG_FILE* aLog, int aStartEventIndex, int aF
|
||||
case LOGGER::EVT_START_DRAG:
|
||||
{
|
||||
PNS::SIZES_SETTINGS sizes( m_router->Sizes() );
|
||||
m_iface->SetStartLayer( routingLayer );
|
||||
m_iface->SetStartLayerFromPNS( routingLayer );
|
||||
m_iface->ImportSizes( sizes, ritem, nullptr, evt.p );
|
||||
m_router->UpdateSizes( sizes );
|
||||
|
||||
|
@ -352,6 +352,12 @@ void PNS_LOG_VIEWER_FRAME::LoadLogFile( const wxString& aFile )
|
||||
}
|
||||
|
||||
|
||||
void PNS_LOG_VIEWER_FRAME::updateViewerIface()
|
||||
{
|
||||
m_viewerIface = std::make_shared<PNS_VIEWER_IFACE>( m_board );
|
||||
}
|
||||
|
||||
|
||||
void PNS_LOG_VIEWER_FRAME::SetLogFile( PNS_LOG_FILE* aLog )
|
||||
{
|
||||
m_logPlayer.reset( new PNS_LOG_PLAYER );
|
||||
@ -935,7 +941,7 @@ void PNS_LOG_VIEWER_FRAME::updatePnsPreviewItems( int iter )
|
||||
}
|
||||
else
|
||||
{
|
||||
ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( ent.m_item, view );
|
||||
ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( ent.m_item, m_viewerIface.get(), view );
|
||||
pitem->Update( ent.m_item );
|
||||
m_previewItems->Add(pitem);
|
||||
// printf("DBG vadd %p total %d\n", pitem, m_previewItems->GetSize() );
|
||||
|
@ -47,6 +47,67 @@
|
||||
|
||||
class PNS_LOG_VIEWER_OVERLAY;
|
||||
|
||||
class PNS_VIEWER_IFACE : public PNS::ROUTER_IFACE
|
||||
{
|
||||
public:
|
||||
PNS_VIEWER_IFACE( std::shared_ptr<BOARD> aBoard ){ m_board = aBoard; };
|
||||
~PNS_VIEWER_IFACE() override{};
|
||||
|
||||
void EraseView() override {};
|
||||
void SyncWorld( PNS::NODE* aWorld ) override {};
|
||||
bool IsAnyLayerVisible( const PNS_LAYER_RANGE& aLayer ) const override { return true; };
|
||||
bool IsFlashedOnLayer( const PNS::ITEM* aItem, int aLayer ) const override { return false; };
|
||||
bool IsFlashedOnLayer( const PNS::ITEM* aItem, const PNS_LAYER_RANGE& aLayer ) const override { return false; };
|
||||
bool IsItemVisible( const PNS::ITEM* aItem ) const override { return true; };
|
||||
void HideItem( PNS::ITEM* aItem ) override {}
|
||||
void DisplayItem( const PNS::ITEM* aItem, int aClearance, bool aEdit = false,
|
||||
int aFlags = 0 ) override {}
|
||||
void DisplayPathLine( const SHAPE_LINE_CHAIN& aLine, int aImportance ) override {}
|
||||
void DisplayRatline( const SHAPE_LINE_CHAIN& aRatline, PNS::NET_HANDLE aNet ) override {}
|
||||
void AddItem( PNS::ITEM* aItem ) override {}
|
||||
void UpdateItem( PNS::ITEM* aItem ) override {}
|
||||
void RemoveItem( PNS::ITEM* aItem ) override {}
|
||||
void Commit() override {}
|
||||
bool ImportSizes( PNS::SIZES_SETTINGS& aSizes, PNS::ITEM* aStartItem,
|
||||
PNS::NET_HANDLE aNet, VECTOR2D aStartPosition ) override { return false; }
|
||||
int StackupHeight( int aFirstLayer, int aSecondLayer ) const override { return 0; }
|
||||
|
||||
int GetNetCode( PNS::NET_HANDLE aNet ) const override { return -1; }
|
||||
wxString GetNetName( PNS::NET_HANDLE aNet ) const override { return wxEmptyString; }
|
||||
void UpdateNet( PNS::NET_HANDLE aNet ) override {}
|
||||
PNS::NET_HANDLE GetOrphanedNetHandle() override { return nullptr; }
|
||||
|
||||
virtual PNS::NODE* GetWorld() const override { return nullptr; };
|
||||
PNS::RULE_RESOLVER* GetRuleResolver() override { return nullptr; }
|
||||
PNS::DEBUG_DECORATOR* GetDebugDecorator() override { return nullptr; }
|
||||
|
||||
int GetBoardLayerFromPNSLayer( int aLayer ) const override
|
||||
{
|
||||
if( aLayer == 0 )
|
||||
return F_Cu;
|
||||
|
||||
if( aLayer == m_board->GetCopperLayerCount() - 1 )
|
||||
return B_Cu;
|
||||
|
||||
return ( aLayer + 1 ) * 2;
|
||||
}
|
||||
|
||||
|
||||
int GetPNSLayerFromBoardLayer( int aLayer ) const override
|
||||
{
|
||||
if( aLayer == F_Cu )
|
||||
return 0;
|
||||
|
||||
if( aLayer == B_Cu )
|
||||
return m_board->GetCopperLayerCount() - 1;
|
||||
|
||||
return ( aLayer / 2 ) - 1;
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<BOARD> m_board;
|
||||
};
|
||||
|
||||
class PNS_LOG_VIEWER_FRAME : public PNS_LOG_VIEWER_FRAME_BASE, public PCB_TEST_FRAME_BASE
|
||||
{
|
||||
public:
|
||||
@ -69,6 +130,7 @@ private:
|
||||
PNS_DEBUG_STAGE* getCurrentStage();
|
||||
void updatePnsPreviewItems( int iter );
|
||||
bool filterStringMatches( PNS_DEBUG_SHAPE* ent );
|
||||
void updateViewerIface();
|
||||
|
||||
virtual void onOpen( wxCommandEvent& event ) override;
|
||||
virtual void onSaveAs( wxCommandEvent& event ) override;
|
||||
@ -92,6 +154,7 @@ private:
|
||||
int m_rewindIter;
|
||||
wxMenu* m_listPopupMenu;
|
||||
std::shared_ptr<KIGFX::VIEW_GROUP> m_previewItems;
|
||||
std::shared_ptr<PNS_VIEWER_IFACE> m_viewerIface;
|
||||
std::map<wxString,wxString> m_filenameToPathMap;
|
||||
|
||||
bool m_showThinLines = true;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user