kicad-source/include/layer_ids.h
Wayne Stambaugh eb3fd10af8 Fix obscured object selection issue in board and footprint editors.
This selection improvement feature is hidden behind the advanced
configuration key "PcbSelectionVisibilityRatio".  It is turned off (1.0)
by default.  Value values are from 0.0 to less that 1.0.  From testing,
using a value between 0.1 and 0.3 produces the best results.

This fix uses normal alpha blending described in the link below.  The
current design only uses the alpha of the object's color.  It could be
improved by doing a full color alpha blending but using the color alpha
alone seems to result in satisfactory results.

https://en.wikipedia.org/wiki/Alpha_compositing

Fixes https://gitlab.com/kicad/code/kicad/-/issues/16126
2023-12-17 16:43:56 -05:00

1083 lines
31 KiB
C++

/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2010 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2007-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef LAYER_IDS_H
#define LAYER_IDS_H
#include <set>
#include <vector>
#include <bitset>
#include <stdexcept>
#include <wx/string.h>
#include <kicommon.h>
/**
* A quick note on layer IDs:
*
* The layers are stored in separate enums so that certain functions can
* take in the enums as data types and don't have to know about layers from
* other applications.
*
* Layers that are shared between applications should be in the GAL_LAYER_ID enum.
*
* The PCB_LAYER_ID struct must start at zero for compatibility with legacy board files.
*
* Some functions accept any layer ID, so they start at zero (i.e. F_Cu) and go up to
* the LAYER_ID_COUNT, which needs to be kept up-to-date if new enums are added.
*/
/**
* This is the definition of all layers used in Pcbnew.
*
* The PCB layer types are fixed at value 0 through LAYER_ID_COUNT to ensure compatibility
* with legacy board files.
*/
enum PCB_LAYER_ID: int
{
UNDEFINED_LAYER = -1,
UNSELECTED_LAYER = -2,
PCBNEW_LAYER_ID_START = 0,
F_Cu = PCBNEW_LAYER_ID_START,
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_Adhes,
F_Adhes,
B_Paste,
F_Paste,
B_SilkS,
F_SilkS,
B_Mask,
F_Mask, // 39
Dwgs_User,
Cmts_User,
Eco1_User,
Eco2_User,
Edge_Cuts,
Margin, // 45
B_CrtYd,
F_CrtYd,
B_Fab,
F_Fab, // 49
// User definable layers.
User_1,
User_2,
User_3,
User_4,
User_5,
User_6,
User_7,
User_8,
User_9,
Rescue, // 59
// Four reserved layers (60 - 63) for future expansion within the 64 bit integer limit.
PCB_LAYER_ID_COUNT
};
#define MAX_CU_LAYERS (B_Cu - F_Cu + 1)
/**
* Enum used during connectivity building to ensure we do not query connectivity while building
* the database
*/
enum class FLASHING
{
DEFAULT, // Flashing follows connectivity
ALWAYS_FLASHED, // Always flashed for connectivity
NEVER_FLASHED, // Never flashed for connectivity
};
/// Dedicated layers for net names used in Pcbnew
enum NETNAMES_LAYER_ID: int
{
NETNAMES_LAYER_ID_START = PCB_LAYER_ID_COUNT,
/// Reserved space for board layer netnames
NETNAMES_LAYER_ID_RESERVED = NETNAMES_LAYER_ID_START + PCB_LAYER_ID_COUNT,
/// Additional netnames layers (not associated with a PCB layer)
LAYER_PAD_FR_NETNAMES,
LAYER_PAD_BK_NETNAMES,
LAYER_PAD_NETNAMES,
LAYER_VIA_NETNAMES,
NETNAMES_LAYER_ID_END
};
/// Macro for obtaining netname layer for a given PCB layer
#define NETNAMES_LAYER_INDEX( layer ) ( NETNAMES_LAYER_ID_START + layer )
/**
* GAL layers are "virtual" layers, i.e. not tied into design data.
* Some layers here are shared between applications.
*
* NOTE: Be very careful where you add new layers here. Layers up to GAL_LAYER_ID_BITMASK_END
* must never be re-ordered and new layers must always be added after this value, because the
* layers before this value are mapped to bit locations in legacy board files.
*
* The values in this enum that are used to store visibility state are explicitly encoded with an
* offset from GAL_LAYER_ID_START, which is explicitly encoded itself. The exact value of
* GAL_LAYER_ID_START is not that sensitive, but the offsets should never be changed or else any
* existing visibility settings will be disrupted.
*/
enum GAL_LAYER_ID: int
{
GAL_LAYER_ID_START = NETNAMES_LAYER_ID_END,
LAYER_VIAS = GAL_LAYER_ID_START + 0, ///< Meta control for all vias opacity/visibility
LAYER_VIA_MICROVIA = GAL_LAYER_ID_START + 1, ///< to draw micro vias
LAYER_VIA_BBLIND = GAL_LAYER_ID_START + 2, ///< to draw blind/buried vias
LAYER_VIA_THROUGH = GAL_LAYER_ID_START + 3, ///< to draw usual through hole vias
LAYER_NON_PLATEDHOLES = GAL_LAYER_ID_START + 4, ///< handle color for not plated holes (holes, not pads)
LAYER_FP_TEXT = GAL_LAYER_ID_START + 5,
// LAYER_MOD_TEXT_BK deprecated + 6,
LAYER_HIDDEN_TEXT = GAL_LAYER_ID_START + 7, ///< text marked as invisible
LAYER_ANCHOR = GAL_LAYER_ID_START + 8, ///< anchor of items having an anchor point (texts, footprints)
LAYER_PADS_SMD_FR = GAL_LAYER_ID_START + 9, ///< smd pads, front layer
LAYER_PADS_SMD_BK = GAL_LAYER_ID_START + 10, ///< smd pads, back layer
LAYER_RATSNEST = GAL_LAYER_ID_START + 11,
LAYER_GRID = GAL_LAYER_ID_START + 12,
LAYER_GRID_AXES = GAL_LAYER_ID_START + 13,
// LAYER_NO_CONNECTS deprecated + 14, ///< show a marker on pads with no nets
LAYER_FOOTPRINTS_FR = GAL_LAYER_ID_START + 15, ///< show footprints on front
LAYER_FOOTPRINTS_BK = GAL_LAYER_ID_START + 16, ///< show footprints on back
LAYER_FP_VALUES = GAL_LAYER_ID_START + 17, ///< show footprints values (when texts are visible)
LAYER_FP_REFERENCES = GAL_LAYER_ID_START + 18, ///< show footprints references (when texts are visible)
LAYER_TRACKS = GAL_LAYER_ID_START + 19,
LAYER_PADS_TH = GAL_LAYER_ID_START + 20, ///< multilayer pads, usually with holes
LAYER_PAD_PLATEDHOLES = GAL_LAYER_ID_START + 21, ///< to draw pad holes (plated)
LAYER_VIA_HOLES = GAL_LAYER_ID_START + 22, ///< to draw via holes (pad holes do not use this layer)
LAYER_DRC_ERROR = GAL_LAYER_ID_START + 23, ///< layer for drc markers with SEVERITY_ERROR
LAYER_DRAWINGSHEET = GAL_LAYER_ID_START + 24, ///< drawingsheet frame and titleblock
LAYER_GP_OVERLAY = GAL_LAYER_ID_START + 25, ///< general purpose overlay
LAYER_SELECT_OVERLAY = GAL_LAYER_ID_START + 26, ///< currently selected items overlay
LAYER_PCB_BACKGROUND = GAL_LAYER_ID_START + 27, ///< PCB background color
LAYER_CURSOR = GAL_LAYER_ID_START + 28, ///< PCB cursor
LAYER_AUX_ITEMS = GAL_LAYER_ID_START + 29, ///< Auxiliary items (guides, rule, etc)
LAYER_DRAW_BITMAPS = GAL_LAYER_ID_START + 30, ///< to handle and draw images bitmaps
/// This is the end of the layers used for visibility bit masks in legacy board files
GAL_LAYER_ID_BITMASK_END = GAL_LAYER_ID_START + 31,
// Layers in this section have visibility controls but were not present in legacy board files.
LAYER_PADS = GAL_LAYER_ID_START + 32, ///< Meta control for all pads opacity/visibility (color ignored)
LAYER_ZONES = GAL_LAYER_ID_START + 33, ///< Control for copper zone opacity/visibility (color ignored)
LAYER_PAD_HOLEWALLS = GAL_LAYER_ID_START + 34,
LAYER_VIA_HOLEWALLS = GAL_LAYER_ID_START + 35,
LAYER_DRC_WARNING = GAL_LAYER_ID_START + 36, ///< layer for drc markers with SEVERITY_WARNING
LAYER_DRC_EXCLUSION = GAL_LAYER_ID_START + 37, ///< layer for drc markers which have been individually excluded
LAYER_MARKER_SHADOWS = GAL_LAYER_ID_START + 38, ///< shadows for drc markers
LAYER_LOCKED_ITEM_SHADOW = GAL_LAYER_ID_START + 39, ///< shadow layer for locked items
LAYER_CONFLICTS_SHADOW = GAL_LAYER_ID_START + 40, ///< shadow layer for items flagged conficting
// Add layers below this point that do not have visibility controls, so don't need explicit
// enum values
LAYER_DRAWINGSHEET_PAGE1, ///< for drawingsheetEditor previewing
LAYER_DRAWINGSHEET_PAGEn, ///< for drawingsheetEditor previewing
LAYER_PAGE_LIMITS, ///< color for drawing the page extents (visibility stored in
///< PCBNEW_SETTINGS::m_ShowPageLimits)
/// Virtual layers for stacking zones and tracks on a given copper layer
LAYER_ZONE_START,
LAYER_ZONE_END = LAYER_ZONE_START + PCB_LAYER_ID_COUNT,
/// Virtual layers for background images per board layer
LAYER_BITMAP_START,
LAYER_BITMAP_END = LAYER_BITMAP_START + PCB_LAYER_ID_COUNT,
GAL_LAYER_ID_END
};
/// Use this macro to convert a GAL layer to a 0-indexed offset from LAYER_VIAS
#define GAL_LAYER_INDEX( x ) ( x - GAL_LAYER_ID_START )
/// Macros for getting the extra layers for a given board layer
#define BITMAP_LAYER_FOR( boardLayer ) ( LAYER_BITMAP_START + boardLayer )
#define ZONE_LAYER_FOR( boardLayer ) ( LAYER_ZONE_START + boardLayer )
constexpr int GAL_LAYER_ID_COUNT = GAL_LAYER_ID_END - GAL_LAYER_ID_START;
inline GAL_LAYER_ID operator++( GAL_LAYER_ID& a )
{
a = GAL_LAYER_ID( int( a ) + 1 );
return a;
}
inline GAL_LAYER_ID ToGalLayer( int aInteger )
{
wxASSERT( aInteger >= GAL_LAYER_ID_START && aInteger <= GAL_LAYER_ID_END );
return static_cast<GAL_LAYER_ID>( aInteger );
}
/// Used for via types
inline GAL_LAYER_ID operator+( const GAL_LAYER_ID& a, int b )
{
GAL_LAYER_ID t = GAL_LAYER_ID( int( a ) + b );
wxASSERT( t <= GAL_LAYER_ID_END );
return t;
}
/// @brief Wraps a std::bitset
typedef std::bitset<GAL_LAYER_ID_COUNT> GAL_BASE_SET;
/// Helper for storing and iterating over GAL_LAYER_IDs
class KICOMMON_API GAL_SET : public GAL_BASE_SET
{
private:
static constexpr int start = static_cast<int>( GAL_LAYER_ID_START );
public:
GAL_SET() : std::bitset<GAL_LAYER_ID_COUNT>()
{
}
GAL_SET( const GAL_SET& aOther ) : std::bitset<GAL_LAYER_ID_COUNT>( aOther )
{
}
GAL_SET( const GAL_LAYER_ID* aArray, unsigned aCount );
GAL_SET& set()
{
GAL_BASE_SET::set();
return *this;
}
GAL_SET& set( int aPos, bool aVal = true )
{
GAL_BASE_SET::set( aPos, aVal );
return *this;
}
GAL_SET& set( GAL_LAYER_ID aPos, bool aVal = true )
{
GAL_BASE_SET::set( static_cast<std::size_t>( aPos ) - start, aVal );
return *this;
}
bool Contains( GAL_LAYER_ID aPos )
{
return test( static_cast<std::size_t>( aPos ) - start );
}
std::vector<GAL_LAYER_ID> Seq() const;
static GAL_SET DefaultVisible();
};
/// Eeschema drawing layers
enum SCH_LAYER_ID: int
{
SCH_LAYER_ID_START = GAL_LAYER_ID_END,
LAYER_WIRE = SCH_LAYER_ID_START,
LAYER_BUS,
LAYER_JUNCTION,
LAYER_LOCLABEL,
LAYER_GLOBLABEL,
LAYER_HIERLABEL,
LAYER_PINNUM,
LAYER_PINNAM,
LAYER_REFERENCEPART,
LAYER_VALUEPART,
LAYER_FIELDS,
LAYER_INTERSHEET_REFS,
LAYER_NETCLASS_REFS,
LAYER_DEVICE,
LAYER_NOTES,
LAYER_PRIVATE_NOTES,
LAYER_NOTES_BACKGROUND,
LAYER_PIN,
LAYER_SHEET,
LAYER_SHEETNAME,
LAYER_SHEETFILENAME,
LAYER_SHEETFIELDS,
LAYER_SHEETLABEL,
LAYER_NOCONNECT,
LAYER_DANGLING,
LAYER_DNP_MARKER,
LAYER_ERC_WARN,
LAYER_ERC_ERR,
LAYER_ERC_EXCLUSION,
LAYER_DEVICE_BACKGROUND,
LAYER_SHEET_BACKGROUND,
LAYER_SCHEMATIC_GRID,
LAYER_SCHEMATIC_GRID_AXES,
LAYER_SCHEMATIC_BACKGROUND,
LAYER_SCHEMATIC_CURSOR,
LAYER_HOVERED,
LAYER_BRIGHTENED,
LAYER_HIDDEN,
LAYER_SELECTION_SHADOWS,
LAYER_SCHEMATIC_DRAWINGSHEET,
LAYER_SCHEMATIC_PAGE_LIMITS,
LAYER_BUS_JUNCTION,
LAYER_SCHEMATIC_AUX_ITEMS,
LAYER_SCHEMATIC_ANCHOR,
LAYER_OP_VOLTAGES,
LAYER_OP_CURRENTS,
SCH_LAYER_ID_END
};
#define SCH_LAYER_ID_COUNT ( SCH_LAYER_ID_END - SCH_LAYER_ID_START )
#define SCH_LAYER_INDEX( x ) ( x - SCH_LAYER_ID_START )
inline SCH_LAYER_ID operator++( SCH_LAYER_ID& a )
{
a = SCH_LAYER_ID( int( a ) + 1 );
return a;
}
// number of draw layers in Gerbview
#define GERBER_DRAWLAYERS_COUNT PCB_LAYER_ID_COUNT
/// GerbView draw layers
enum GERBVIEW_LAYER_ID: int
{
GERBVIEW_LAYER_ID_START = SCH_LAYER_ID_END,
/// GerbView draw layers and d-code layers
GERBVIEW_LAYER_ID_RESERVED = GERBVIEW_LAYER_ID_START + ( 2 * GERBER_DRAWLAYERS_COUNT ),
LAYER_DCODES,
LAYER_NEGATIVE_OBJECTS,
LAYER_GERBVIEW_GRID,
LAYER_GERBVIEW_AXES,
LAYER_GERBVIEW_BACKGROUND,
LAYER_GERBVIEW_DRAWINGSHEET,
LAYER_GERBVIEW_PAGE_LIMITS,
GERBVIEW_LAYER_ID_END
};
#define GERBER_DRAW_LAYER( x ) ( GERBVIEW_LAYER_ID_START + x )
#define GERBER_DCODE_LAYER( x ) ( GERBER_DRAWLAYERS_COUNT + x )
#define GERBER_DRAW_LAYER_INDEX( x ) ( x - GERBVIEW_LAYER_ID_START )
/// 3D Viewer virtual layers for color settings
enum LAYER_3D_ID : int
{
LAYER_3D_START = GERBVIEW_LAYER_ID_END,
LAYER_3D_BACKGROUND_BOTTOM,
LAYER_3D_BACKGROUND_TOP,
LAYER_3D_BOARD,
LAYER_3D_COPPER_TOP,
LAYER_3D_COPPER_BOTTOM,
LAYER_3D_SILKSCREEN_BOTTOM,
LAYER_3D_SILKSCREEN_TOP,
LAYER_3D_SOLDERMASK_BOTTOM,
LAYER_3D_SOLDERMASK_TOP,
LAYER_3D_SOLDERPASTE,
LAYER_3D_ADHESIVE,
LAYER_3D_USER_COMMENTS,
LAYER_3D_USER_DRAWINGS,
LAYER_3D_USER_ECO1,
LAYER_3D_USER_ECO2,
LAYER_3D_TH_MODELS,
LAYER_3D_SMD_MODELS,
LAYER_3D_VIRTUAL_MODELS,
LAYER_3D_MODELS_NOT_IN_POS,
LAYER_3D_MODELS_MARKED_DNP,
LAYER_3D_AXES,
LAYER_3D_BOUNDING_BOXES,
LAYER_3D_OFF_BOARD_SILK,
LAYER_3D_END
};
/// Must update this if you add any enums after GerbView!
#define LAYER_ID_COUNT LAYER_3D_END
/**
* Returns the string equivalent of a given layer
* @param aLayer is a valid layer ID
*/
KICOMMON_API wxString LayerName( int aLayer );
// Some elements do not have yet a visibility control
// from a dialog, but have a visibility control flag.
// Here is a mask to set them visible, to be sure they are displayed
// after loading a board for instance
#define MIN_VISIBILITY_MASK int( ( 1 << GAL_LAYER_INDEX( LAYER_PAD_PLATEDHOLES ) ) +\
( 1 << GAL_LAYER_INDEX( LAYER_VIA_HOLES ) ) +\
( 1 << GAL_LAYER_INDEX( LAYER_SELECT_OVERLAY ) ) +\
( 1 << GAL_LAYER_INDEX( LAYER_GP_OVERLAY ) ) +\
( 1 << GAL_LAYER_INDEX( LAYER_RATSNEST ) ) )
/// A sequence of layers, a sequence provides a certain order.
typedef std::vector<PCB_LAYER_ID> BASE_SEQ;
/**
* LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs. A sequence provides
* a certain order.
* <p>
* It can also be used as an iterator:
* <code>
*
* for( LSEQ cu_stack = aSet.CuStack(); cu_stack; ++cu_stack )
* {
* layer_id = *cu_stack;
* :
* things to do with layer_id;
* }
*
* </code>
*/
class KICOMMON_API LSEQ : public BASE_SEQ
{
unsigned m_index;
public:
LSEQ() :
m_index( 0 )
{}
template <class InputIterator>
LSEQ( InputIterator aStart, InputIterator aEnd ) :
BASE_SEQ( aStart, aEnd ), m_index( 0 )
{}
LSEQ( std::initializer_list<PCB_LAYER_ID> aLayers ) :
BASE_SEQ( aLayers ), m_index( 0 )
{}
void Rewind() { m_index = 0; }
void operator ++ () { ++m_index; } // returns nothing, used in simple statements only.
void operator ++ (int) { ++m_index; }
operator bool () { return m_index < size(); }
PCB_LAYER_ID operator * () const
{
return at( m_index ); // throws std::out_of_range
}
int TestLayers( PCB_LAYER_ID aRhs, PCB_LAYER_ID aLhs ) const
{
if( aRhs == aLhs )
return 0;
auto itRhs = std::find( begin(), end(), aRhs );
auto itLhs = std::find( begin(), end(), aLhs );
return std::distance( itRhs, itLhs );
}
};
typedef std::bitset<PCB_LAYER_ID_COUNT> BASE_SET;
/**
* LSET is a set of PCB_LAYER_IDs. It can be converted to numerous purpose LSEQs using
* the various member functions, most of which are based on Seq(). The advantage
* of converting to LSEQ using purposeful code, is it removes any dependency
* on order/sequence inherent in this set.
*/
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() // all bits are set to zero in BASE_SET()
{
}
LSET( const BASE_SET& aOther ) :
BASE_SET( aOther )
{
}
/**
* Take a PCB_LAYER_ID and sets that bit. This makes the following code into
* a bug:
*
* <code> LSET s = 0; </code>
*
* Instead use:
*
* <code>
* LSET s;
* </code>
*
* for an empty set.
*/
LSET( PCB_LAYER_ID aLayer ) : // PCB_LAYER_ID deliberately excludes int and relatives
BASE_SET()
{
set( aLayer );
}
/**
* Create an array or LSEQ.
*/
LSET( const PCB_LAYER_ID* aArray, unsigned aCount );
/**
* Take one or more PCB_LAYER_IDs in the argument list to construct the set. Typically
* only used in static construction.
*
* @param aIdCount is the number of PCB_LAYER_IDs which follow.
* @param aFirst is the first included in @a aIdCount and must always be present, and can
* be followed by any number of additional PCB_LAYER_IDs so long as @a aIdCount accurately
* reflects the count.
*
* Parameter is 'int' to avoid va_start undefined behavior.
*/
LSET( unsigned aIdCount, int aFirst, ... ); // args chosen to prevent LSET( int ) from compiling
LSET( const LSEQ& aSeq );
/**
* See if the layer set contains a PCB layer.
*
* @param aLayer is the layer to check
* @return true if the layer is included
*/
bool Contains( PCB_LAYER_ID aLayer )
{
try
{
return test( aLayer );
}
catch( std::out_of_range& )
{
return false;
}
}
/**
* Return the fixed name association with aLayerId.
*/
static const wxChar* Name( PCB_LAYER_ID aLayerId );
/**
* Return a complete set of internal copper layers which is all Cu layers
* except F_Cu and B_Cu.
*/
static LSET InternalCuMask();
/**
* Return a complete set of all top assembly layers which is all F_SilkS and F_Mask
*/
static LSET FrontAssembly();
/**
* Return a complete set of all bottom assembly layers which is all B_SilkS and B_Mask
*/
static LSET BackAssembly();
/**
* Return a mask holding the requested number of Cu PCB_LAYER_IDs.
*/
static LSET AllCuMask( int aCuLayerCount = MAX_CU_LAYERS );
/**
* Return a mask holding the Front and Bottom layers.
*/
static LSET ExternalCuMask();
/**
* Return a mask holding all layer minus CU layers.
*/
static LSET AllNonCuMask();
static LSET AllLayersMask();
/**
* Return a mask holding all technical layers (no CU layer) on front side.
*/
static LSET FrontTechMask();
/**
* Return a mask holding technical layers used in a board fabrication
* (no CU layer) on front side.
*/
static LSET FrontBoardTechMask();
/**
* Return a mask holding all technical layers (no CU layer) on back side.
*/
static LSET BackTechMask();
/**
* Return a mask holding technical layers used in a board fabrication
* (no CU layer) on Back side.
*/
static LSET BackBoardTechMask();
/**
* Return a mask holding all technical layers (no CU layer) on both side.
*/
static LSET AllTechMask();
/**
* Return a mask holding board technical layers (no CU layer) on both side.
*/
static LSET AllBoardTechMask();
/**
* Return a mask holding all technical layers and the external CU layer on front side.
*/
static LSET FrontMask();
/**
* Return a mask holding all technical layers and the external CU layer on back side.
*/
static LSET BackMask();
static LSET SideSpecificMask();
static LSET UserMask();
/**
* Return a mask holding all layers which are physically realized. Equivalent to the copper
* layers + the board tech mask.
*/
static LSET PhysicalLayersMask();
/**
* Return a mask with all of the allowable user defined layers.
*/
static LSET UserDefinedLayers();
/**
* Layers which are not allowed within footprint definitions. Currently internal
* copper layers and Margin.
*/
static LSET ForbiddenFootprintLayers();
/**
* 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.
*/
LSEQ CuStack() const;
/**
* Return a sequence of technical layers. A sequence provides a certain order.
*
* @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;
LSEQ UIOrder() const;
/**
* Return an LSEQ from the union of this LSET and a desired sequence. The LSEQ
* 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;
/**
* Return a LSEQ from this LSET in ascending PCB_LAYER_ID order. Each LSEQ
* element will be in the same sequence as in PCB_LAYER_ID and only present
* in the resultant LSEQ if present in this set. Therefore the sequence is
* subject to change, use it only when enumeration and not order is important.
*/
LSEQ Seq() const;
/**
* Generate a sequence of layers that represent a top to bottom stack of this set of layers.
*
* @param aSelectedLayer is the layer to put at the top of stack when defined.
*
* @return the top to bottom layer sequence.
*/
LSEQ SeqStackupTop2Bottom( PCB_LAYER_ID aSelectedLayer = UNDEFINED_LAYER ) const;
/**
* Return the sequence that is typical for a bottom-to-top stack-up.
* For instance, to plot multiple layers in a single image, the top layers output last.
*/
LSEQ SeqStackupForPlotting() const;
/**
* Return a hex string showing contents of this LSEQ.
*/
std::string FmtHex() const;
/**
* Convert the output of FmtHex() and replaces this set's values
* with those given in the input string. Parsing stops at the first
* non hex ASCII byte, except that marker bytes output from FmtHex are
* not terminators.
* @return int - number of bytes consumed
*/
int ParseHex( const char* aStart, int aCount );
/**
* Return a binary string showing contents of this LSEQ.
*/
std::string FmtBin() const;
/**
* Find the first set PCB_LAYER_ID. Returns UNDEFINED_LAYER if more
* than one is set or UNSELECTED_LAYER if none is set.
*/
PCB_LAYER_ID ExtractLayer() const;
private:
/// Take this off the market, it may not be used because of LSET( PCB_LAYER_ID ).
LSET( unsigned long __val )
{
// not usable, it's private.
}
};
/**
* Test whether a given integer is a valid layer index, i.e. can
* be safely put in a PCB_LAYER_ID
*
* @param aLayerId = Layer index to test. It can be an int, so its useful during I/O
* @return true if aLayerIndex is a valid layer index
*/
inline bool IsValidLayer( int aLayerId )
{
return unsigned( aLayerId ) < PCB_LAYER_ID_COUNT;
}
/**
* Test whether a layer is a valid layer for Pcbnew
*
* @param aLayer = Layer to test
* @return true if aLayer is a layer valid in Pcbnew
*/
inline bool IsPcbLayer( int aLayer )
{
return aLayer >= F_Cu && aLayer < PCB_LAYER_ID_COUNT;
}
/**
* Tests whether a layer is a copper layer.
*
* @param aLayerId = Layer to test
* @return true if aLayer is a valid copper layer
*/
inline bool IsCopperLayer( int aLayerId )
{
return aLayerId >= F_Cu && aLayerId <= B_Cu;
}
/**
* Test whether a layer is a non copper layer.
*
* @param aLayerId = Layer to test
* @return true if aLayer is a non copper layer
*/
inline bool IsNonCopperLayer( int aLayerId )
{
return aLayerId > B_Cu && aLayerId <= PCB_LAYER_ID_COUNT;
}
/**
* Tests whether a layer is a copper layer, optionally including synthetic copper layers such
* as LAYER_VIA_THROUGH, LAYER_PADS_SMD_FR, etc.
*
* @param aLayerId
* @param aIncludeSyntheticCopperLayers
* @return
*/
inline bool IsCopperLayer( int aLayerId, bool aIncludeSyntheticCopperLayers )
{
if( aIncludeSyntheticCopperLayers )
return !IsNonCopperLayer( aLayerId );
else
return IsCopperLayer( aLayerId );
}
inline bool IsViaPadLayer( int aLayer )
{
return aLayer == LAYER_VIA_THROUGH
|| aLayer == LAYER_VIA_MICROVIA
|| aLayer == LAYER_VIA_BBLIND;
}
inline bool IsHoleLayer( int aLayer )
{
return aLayer == LAYER_VIA_HOLES
|| aLayer == LAYER_VIA_HOLEWALLS
|| aLayer == LAYER_PAD_PLATEDHOLES
|| aLayer == LAYER_PAD_HOLEWALLS
|| aLayer == LAYER_NON_PLATEDHOLES;
}
/**
* Test whether a layer is a non copper and a non tech layer.
*
* @param aLayerId = Layer to test
* @return true if aLayer is a user layer
*/
inline bool IsUserLayer( PCB_LAYER_ID aLayerId )
{
return aLayerId >= Dwgs_User && aLayerId <= Eco2_User;
}
/*
* IMPORTANT: If a layer is not a front layer that doesn't necessarily mean it's a back layer.
*
* So a layer can be:
* - Front
* - Back
* - Neither (internal or auxiliary)
*
* The check most frequent is for back layers, since it involves flips.
*/
/**
* Layer classification: check if it's a front layer
*/
inline bool IsFrontLayer( PCB_LAYER_ID aLayerId )
{
switch( aLayerId )
{
case F_Cu:
case F_Adhes:
case F_Paste:
case F_SilkS:
case F_Mask:
case F_CrtYd:
case F_Fab:
return true;
default:
;
}
return false;
}
/**
* Layer classification: check if it's a back layer
*/
inline bool IsBackLayer( PCB_LAYER_ID aLayerId )
{
switch( aLayerId )
{
case B_Cu:
case B_Adhes:
case B_Paste:
case B_SilkS:
case B_Mask:
case B_CrtYd:
case B_Fab:
return true;
default:
return false;
}
}
/**
* @return the layer number after flipping an item
* some (not all) layers: external copper, and paired layers( Mask, Paste, solder ... )
* are swapped between front and back sides
* internal layers are flipped only if the copper layers count is known
* @param aLayerId = the PCB_LAYER_ID to flip
* @param aCopperLayersCount = the number of copper layers. if 0 (in fact if < 4 )
* internal layers will be not flipped because the layer count is not known
*/
KICOMMON_API PCB_LAYER_ID FlipLayer( PCB_LAYER_ID aLayerId, int aCopperLayersCount = 0 );
/**
* Calculate the mask layer when flipping a footprint.
*
* BACK and FRONT copper layers, mask, paste, solder layers are swapped
* internal layers are flipped only if the copper layers count is known
* @param aMask = the LSET to flip
* @param aCopperLayersCount = the number of copper layers. if 0 (in fact if < 4 )
* internal layers will be not flipped because the layer count is not known
*/
KICOMMON_API LSET FlipLayerMask( LSET aMask, int aCopperLayersCount = 0 );
/**
* Returns a netname layer corresponding to the given layer.
*/
inline int GetNetnameLayer( int aLayer )
{
if( IsCopperLayer( aLayer ) )
return NETNAMES_LAYER_INDEX( aLayer );
else if( aLayer == LAYER_PADS_TH )
return LAYER_PAD_NETNAMES;
else if( aLayer == LAYER_PADS_SMD_FR )
return LAYER_PAD_FR_NETNAMES;
else if( aLayer == LAYER_PADS_SMD_BK )
return LAYER_PAD_BK_NETNAMES;
else if( IsViaPadLayer( aLayer ) )
return LAYER_VIA_NETNAMES;
// Fallback
return Cmts_User;
}
/**
* Test whether a layer is a netname layer.
*
* @param aLayer = Layer to test
* @return true if aLayer is a valid netname layer
*/
inline bool IsNetnameLayer( int aLayer )
{
return aLayer >= NETNAMES_LAYER_INDEX( F_Cu ) && aLayer < NETNAMES_LAYER_ID_END;
}
inline bool IsZoneFillLayer( int aLayer )
{
return aLayer >= LAYER_ZONE_START && aLayer <= LAYER_ZONE_END;
}
inline bool IsDCodeLayer( int aLayer )
{
return aLayer >= ( GERBVIEW_LAYER_ID_START + GERBER_DRAWLAYERS_COUNT )
&& aLayer < ( GERBVIEW_LAYER_ID_START + ( 2 * GERBER_DRAWLAYERS_COUNT ) );
}
/**
* Checks if the given layer is "net copper", meaning it is eligible for net coloring.
*
* @param aLayer is the layer to test
* @return true if the layer is one that participates in net coloring
*/
inline bool IsNetCopperLayer( int aLayer )
{
static std::set<int> netCopperLayers =
{
LAYER_PADS_SMD_FR,
LAYER_PADS_SMD_BK,
LAYER_PADS_TH,
LAYER_PAD_HOLEWALLS,
LAYER_VIA_THROUGH,
LAYER_VIA_BBLIND,
LAYER_VIA_MICROVIA,
LAYER_VIA_HOLEWALLS
};
return IsCopperLayer( aLayer ) || netCopperLayers.count( aLayer );
}
KICOMMON_API PCB_LAYER_ID ToLAYER_ID( int aLayer );
#endif // LAYER_IDS_H