mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-04-18 20:59:17 +00: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
3d-viewer
3d_canvas
3d_rendering/opengl
common
gerbview
include
kicad/cli
pcbnew
autorouter
board.cppboard_item.cppconnectivity
connectivity_algo.cppconnectivity_data.cppconnectivity_items.cppconnectivity_items.hconnectivity_rtree.h
dialogs
dialog_drc.cppdialog_footprint_checker.cppdialog_plot.cppdialog_print_pcbnew.cppdialog_swap_layers.cpppanel_setup_layers.cpp
drc
exporters
export_d356.cppexport_gencad_writer.cppexport_svg.cppgen_drill_report_files.cppgerber_jobfile_writer.cppgerber_placefile_writer.cpp
generators
microwave
pad.cpppad.hpcb_generator.cpppcb_io
altium
cadstar
eagle
easyeda
kicad_sexpr
ratsnest
router
pns_diff_pair_placer.cpppns_hole.cpppns_index.cpppns_index.hpns_item.hpns_itemset.cpppns_joint.hpns_kicad_iface.cpppns_kicad_iface.hpns_layerset.hpns_line_placer.cpppns_node.cpppns_node.hpns_router.cpppns_router.hpns_topology.cpppns_topology.hpns_via.hrouter_preview_item.cpprouter_preview_item.hrouter_tool.cpprouter_tool.h
specctra_import_export
tools
widgets
zone.cppqa
data/pcbnew
tests
common
pcbnew
tools/pns
thirdparty
@ -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();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user