kicad/pcbnew/pcb_track.h

645 lines
21 KiB
C
Raw Normal View History

/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
* Copyright (C) 1992-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 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
*/
/**
2021-06-11 21:07:02 +00:00
* @brief A single base class (PCB_TRACK) represents both tracks and vias, with subclasses
* for curved tracks (PCB_ARC) and vias (PCB_VIA). All told there are three KICAD_Ts:
* PCB_TRACK_T, PCB_ARC_T, and PCB_VIA_T.
*
* For vias there is a further VIATYPE which indicates THROUGH, BLIND_BURIED, or MICROVIA,
* which are supported by the synthetic KICAD_Ts PCB_LOCATE_STDVIA_T, PCB_LOCATE_BBVIA_T, and
* PCB_LOCATE_UVIA_T.
*/
#ifndef CLASS_TRACK_H
#define CLASS_TRACK_H
2023-01-15 17:18:56 +00:00
#include <mutex>
#include <array>
2018-02-02 20:57:12 +00:00
#include <board_connected_item.h>
#include <base_units.h>
#include <geometry/shape_segment.h>
#include <core/minoptmax.h>
#include <core/arraydim.h>
#include <padstack.h>
2021-06-11 21:07:02 +00:00
class PCB_TRACK;
class PCB_VIA;
2020-11-12 22:30:02 +00:00
class PAD;
class MSG_PANEL_ITEM;
class SHAPE_POLY_SET;
2021-06-06 12:59:05 +00:00
class SHAPE_ARC;
// Flag used in locate routines (from which endpoint work)
enum ENDPOINT_T : int
{
ENDPOINT_START = 0,
ENDPOINT_END = 1
};
// Note that this enum must be synchronized to GAL_LAYER_ID
enum class VIATYPE : int
{
2019-12-28 00:55:11 +00:00
THROUGH = 3, /* Always a through hole via */
BLIND_BURIED = 2, /* this via can be on internal layers */
MICROVIA = 1, /* this via which connect from an external layer
2023-03-06 12:12:11 +00:00
* to the near neighbor internal layer */
2019-12-28 00:55:11 +00:00
NOT_DEFINED = 0 /* not yet used */
};
enum class TENTING_MODE
{
FROM_RULES = 0,
TENTED = 1,
NOT_TENTED = 2
};
#define UNDEFINED_DRILL_DIAMETER -1 //< Undefined via drill diameter.
// Used for tracks and vias for algorithmic safety, not to enforce constraints
2022-09-17 00:45:14 +00:00
#define GEOMETRY_MIN_SIZE (int) ( 0.001 * pcbIUScale.IU_PER_MM )
2021-06-11 21:07:02 +00:00
class PCB_TRACK : public BOARD_CONNECTED_ITEM
{
public:
static inline bool ClassOf( const EDA_ITEM* aItem )
{
return aItem && PCB_TRACE_T == aItem->Type();
}
2021-06-11 21:07:02 +00:00
PCB_TRACK( BOARD_ITEM* aParent, KICAD_T idtype = PCB_TRACE_T );
2007-09-01 12:00:30 +00:00
// Do not create a copy constructor. The one generated by the compiler is adequate.
2007-08-08 20:51:08 +00:00
void Move( const VECTOR2I& aMoveVector ) override
2009-08-01 19:26:05 +00:00
{
m_Start += aMoveVector;
2011-12-01 22:50:41 +00:00
m_End += aMoveVector;
2009-08-01 19:26:05 +00:00
}
void Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle ) override;
2009-08-01 19:26:05 +00:00
virtual void Mirror( const VECTOR2I& aCentre, bool aMirrorAroundXAxis );
void Flip( const VECTOR2I& aCentre, bool aFlipLeftRight ) override;
2009-08-01 19:26:05 +00:00
void SetPosition( const VECTOR2I& aPos ) override { m_Start = aPos; }
VECTOR2I GetPosition() const override { return m_Start; }
const VECTOR2I GetFocusPosition() const override { return ( m_Start + m_End ) / 2; }
void SetWidth( int aWidth ) { m_Width = aWidth; }
int GetWidth() const { return m_Width; }
2011-11-30 07:43:46 +00:00
void SetEnd( const VECTOR2I& aEnd ) { m_End = aEnd; }
const VECTOR2I& GetEnd() const { return m_End; }
void SetStart( const VECTOR2I& aStart ) { m_Start = aStart; }
const VECTOR2I& GetStart() const { return m_Start; }
2011-11-30 07:43:46 +00:00
void SetEndX( int aX ) { m_End.x = aX; }
void SetEndY( int aY ) { m_End.y = aY; }
int GetEndX() const { return m_End.x; }
int GetEndY() const { return m_End.y; }
/// Return the selected endpoint (start or end)
const VECTOR2I& GetEndPoint( ENDPOINT_T aEndPoint ) const
{
if( aEndPoint == ENDPOINT_START )
return m_Start;
else
return m_End;
}
// Virtual function
2022-08-31 09:15:42 +00:00
const BOX2I GetBoundingBox() const override;
2008-03-05 22:39:33 +00:00
2007-10-13 06:18:44 +00:00
/**
2023-03-06 12:12:11 +00:00
* Get the length of the track using the hypotenuse calculation.
*
* @return the length of the track.
2007-10-13 06:18:44 +00:00
*/
2021-06-06 12:59:05 +00:00
virtual double GetLength() const;
2010-11-12 15:17:10 +00:00
/**
2023-03-06 12:12:11 +00:00
* Convert the track shape to a closed polygon.
*
* Circles (vias) and arcs (ends of tracks) are approximated by segments.
*
* @param aBuffer is a buffer to store the polygon
* @param aClearance is the clearance around the pad
* @param aError is the maximum deviation from true circle
* @param ignoreLineWidth is used for edge cut items where the line width is only for
* visualization
*/
void TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance,
int aError, ERROR_LOC aErrorLoc,
bool ignoreLineWidth = false ) const override;
// @copydoc BOARD_ITEM::GetEffectiveShape
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
FLASHING aFlash = FLASHING::DEFAULT ) const override;
/**
2023-03-06 12:12:11 +00:00
* Return STARTPOINT if point if near (dist = min_dist) start point, ENDPOINT if
* point if near (dist = min_dist) end point,STARTPOINT|ENDPOINT if point if near
* (dist = min_dist) both ends, or 0 if none of the above.
2023-03-06 12:12:11 +00:00
*
* If min_dist < 0: min_dist = track_width/2
*/
EDA_ITEM_FLAGS IsPointOnEnds( const VECTOR2I& point, int min_dist = 0 ) const;
/**
2023-03-06 12:12:11 +00:00
* Return true if segment length is zero.
*/
2019-05-31 02:30:28 +00:00
bool IsNull() const
{
return ( Type() == PCB_VIA_T ) || ( m_Start == m_End );
}
2007-08-08 20:51:08 +00:00
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
2022-12-22 22:44:40 +00:00
wxString GetFriendlyName() const override;
INSPECT_RESULT Visit( INSPECTOR inspector, void* testData,
const std::vector<KICAD_T>& aScanTypes ) override;
bool HitTest( const VECTOR2I& aPosition, int aAccuracy = 0 ) const override;
2022-08-31 09:33:46 +00:00
bool HitTest( const BOX2I& aRect, bool aContained, int aAccuracy = 0 ) const override;
2021-06-11 21:07:02 +00:00
bool ApproxCollinear( const PCB_TRACK& aTrack );
2016-09-24 18:53:15 +00:00
wxString GetClass() const override
2007-08-08 20:51:08 +00:00
{
2021-06-11 21:07:02 +00:00
return wxT( "PCB_TRACK" );
2007-08-08 20:51:08 +00:00
}
virtual MINOPTMAX<int> GetWidthConstraint( wxString* aSource = nullptr ) const;
wxString GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const override;
BITMAPS GetMenuImage() const override;
2016-09-24 18:53:15 +00:00
virtual EDA_ITEM* Clone() const override;
2016-09-24 18:53:15 +00:00
virtual void ViewGetLayers( int aLayers[], int& aCount ) const override;
2013-07-08 07:57:23 +00:00
double ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const override;
2013-07-08 07:57:23 +00:00
const BOX2I ViewBBox() const override;
/**
* @return true because a track or a via is always on a copper layer.
*/
bool IsOnCopperLayer() const override
{
return true;
}
virtual double Similarity( const BOARD_ITEM& aOther ) const override;
virtual bool operator==( const BOARD_ITEM& aOther ) const override;
virtual bool operator==( const PCB_TRACK& aOther ) const;
struct cmp_tracks
{
2021-06-11 21:07:02 +00:00
bool operator()( const PCB_TRACK* aFirst, const PCB_TRACK* aSecond ) const;
};
void Serialize( google::protobuf::Any &aContainer ) const override;
bool Deserialize( const google::protobuf::Any &aContainer ) override;
#if defined (DEBUG)
2016-09-24 18:53:15 +00:00
virtual void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
#endif
protected:
virtual void swapData( BOARD_ITEM* aImage ) override;
2023-03-06 12:12:11 +00:00
void GetMsgPanelInfoBase_Common( EDA_DRAW_FRAME* aFrame,
std::vector<MSG_PANEL_ITEM>& aList ) const;
protected:
int m_Width; ///< Thickness of track, or via diameter
VECTOR2I m_Start; ///< Line start point
VECTOR2I m_End; ///< Line end point
};
2007-09-01 12:00:30 +00:00
2021-06-11 21:07:02 +00:00
class PCB_ARC : public PCB_TRACK
{
public:
2021-06-11 21:07:02 +00:00
PCB_ARC( BOARD_ITEM* aParent ) :
PCB_TRACK( aParent, PCB_ARC_T )
{ }
2021-06-11 21:07:02 +00:00
PCB_ARC( BOARD_ITEM* aParent, const SHAPE_ARC* aArc );
static inline bool ClassOf( const EDA_ITEM *aItem )
{
return aItem && PCB_ARC_T == aItem->Type();
}
virtual void Move( const VECTOR2I& aMoveVector ) override
{
m_Start += aMoveVector;
m_Mid += aMoveVector;
m_End += aMoveVector;
}
void Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle ) override;
void Mirror( const VECTOR2I& aCentre, bool aMirrorAroundXAxis ) override;
void Flip( const VECTOR2I& aCentre, bool aFlipLeftRight ) override;
void SetMid( const VECTOR2I& aMid ) { m_Mid = aMid; }
const VECTOR2I& GetMid() const { return m_Mid; }
void SetPosition( const VECTOR2I& aPos ) override { m_Start = aPos; }
virtual VECTOR2I GetPosition() const override;
const VECTOR2I GetFocusPosition() const override { return m_Mid; }
virtual VECTOR2I GetCenter() const override { return GetPosition(); }
double GetRadius() const;
2022-01-14 15:34:41 +00:00
EDA_ANGLE GetAngle() const;
EDA_ANGLE GetArcAngleStart() const;
2023-06-06 14:49:41 +00:00
EDA_ANGLE GetArcAngleEnd() const; // Called by Python; ignore CLion's claim that it's unused
virtual bool HitTest( const VECTOR2I& aPosition, int aAccuracy = 0 ) const override;
2023-03-06 12:12:11 +00:00
virtual bool HitTest( const BOX2I& aRect, bool aContained = true,
int aAccuracy = 0 ) const override;
bool IsCCW() const;
wxString GetClass() const override
{
2021-06-11 21:07:02 +00:00
return wxT( "PCB_ARC" );
}
2020-08-13 10:08:16 +00:00
// @copydoc BOARD_ITEM::GetEffectiveShape
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
FLASHING aFlash = FLASHING::DEFAULT ) const override;
2020-08-13 10:08:16 +00:00
/**
2023-03-06 12:12:11 +00:00
* Return the length of the arc track.
*
* @return double - the length of the track
*/
virtual double GetLength() const override
{
2022-01-14 15:34:41 +00:00
return GetRadius() * std::abs( GetAngle().AsRadians() );
}
EDA_ITEM* Clone() const override;
/**
* @return true if the arc is too small to allow a safe calculation
* of center position and arc angles i.e if distance between m_Mid and each arc end
* is only a few internal units.
* @param aThreshold is the minimal dist in internal units. Default id 5 IU
*/
bool IsDegenerated( int aThreshold = 5 ) const;
double Similarity( const BOARD_ITEM& aOther ) const override;
bool operator==( const BOARD_ITEM& aOther ) const override;
void Serialize( google::protobuf::Any &aContainer ) const override;
bool Deserialize( const google::protobuf::Any &aContainer ) override;
protected:
virtual void swapData( BOARD_ITEM* aImage ) override;
private:
VECTOR2I m_Mid; ///< Arc mid point, halfway between start and end
};
2021-06-11 21:07:02 +00:00
class PCB_VIA : public PCB_TRACK
{
public:
2021-06-11 21:07:02 +00:00
PCB_VIA( BOARD_ITEM* aParent );
2007-09-01 12:00:30 +00:00
static inline bool ClassOf( const EDA_ITEM *aItem )
{
return aItem && PCB_VIA_T == aItem->Type();
}
PCB_VIA( const PCB_VIA& aOther );
PCB_VIA& operator=( const PCB_VIA &aOther );
bool IsType( const std::vector<KICAD_T>& aScanTypes ) const override
{
if( BOARD_CONNECTED_ITEM::IsType( aScanTypes ) )
return true;
for( KICAD_T scanType : aScanTypes )
{
if( scanType == PCB_LOCATE_STDVIA_T && m_viaType == VIATYPE::THROUGH )
return true;
else if( scanType == PCB_LOCATE_UVIA_T && m_viaType == VIATYPE::MICROVIA )
return true;
else if( scanType == PCB_LOCATE_BBVIA_T && m_viaType == VIATYPE::BLIND_BURIED )
return true;
}
return false;
}
2020-11-14 14:29:11 +00:00
VIATYPE GetViaType() const { return m_viaType; }
void SetViaType( VIATYPE aViaType ) { m_viaType = aViaType; }
const PADSTACK& Padstack() const { return m_padStack; }
PADSTACK& Padstack() { return m_padStack; }
void SetPadstack( const PADSTACK& aPadstack ) { m_padStack = aPadstack; }
bool HasHole() const override
{
return true;
}
bool HasDrilledHole() const override
{
return m_viaType == VIATYPE::THROUGH || m_viaType == VIATYPE::BLIND_BURIED;
}
std::shared_ptr<SHAPE_SEGMENT> GetEffectiveHoleShape() const override;
MINOPTMAX<int> GetWidthConstraint( wxString* aSource = nullptr ) const override;
MINOPTMAX<int> GetDrillConstraint( wxString* aSource = nullptr ) const;
void SetFrontTentingMode( TENTING_MODE aMode );
TENTING_MODE GetFrontTentingMode() const;
void SetBackTentingMode( TENTING_MODE aMode );
TENTING_MODE GetBackTentingMode() const;
bool IsTented( PCB_LAYER_ID aLayer ) const override;
int GetSolderMaskExpansion() const;
PCB_LAYER_ID GetLayer() const override;
void SetLayer( PCB_LAYER_ID aLayer ) override;
bool IsOnLayer( PCB_LAYER_ID aLayer ) const override;
2016-09-24 18:53:15 +00:00
virtual LSET GetLayerSet() const override;
/**
* Note SetLayerSet() initialize the first and last copper layers connected by the via.
* So currently SetLayerSet ignore non copper layers
*/
virtual void SetLayerSet( LSET aLayers ) override;
/**
2023-03-06 12:12:11 +00:00
* For a via m_layer contains the top layer, the other layer is in m_bottomLayer/
*
* @param aTopLayer is the first layer connected by the via.
* @param aBottomLayer is last layer connected by the via.
*/
void SetLayerPair( PCB_LAYER_ID aTopLayer, PCB_LAYER_ID aBottomLayer );
void SetBottomLayer( PCB_LAYER_ID aLayer );
void SetTopLayer( PCB_LAYER_ID aLayer );
/**
2023-03-06 12:12:11 +00:00
* Return the 2 layers used by the via (the via actually uses all layers between these
* 2 layers)
*
* @param[out] top_layer is storage for the first layer of the via (can be null).
* @param[out] bottom_layer is storage for the last layer of the via(can be null).
*/
void LayerPair( PCB_LAYER_ID* top_layer, PCB_LAYER_ID* bottom_layer ) const;
PCB_LAYER_ID TopLayer() const;
PCB_LAYER_ID BottomLayer() const;
/**
2023-03-06 12:12:11 +00:00
* Check so that the layers are correct depending on the type of via, and
* so that the top actually is on top.
*/
void SanitizeLayers();
VECTOR2I GetPosition() const override { return m_Start; }
void SetPosition( const VECTOR2I& aPoint ) override { m_Start = aPoint; m_End = aPoint; }
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
bool HitTest( const VECTOR2I& aPosition, int aAccuracy = 0 ) const override;
2022-08-31 09:33:46 +00:00
bool HitTest( const BOX2I& aRect, bool aContained, int aAccuracy = 0 ) const override;
2014-05-01 06:50:11 +00:00
2016-09-24 18:53:15 +00:00
wxString GetClass() const override
2007-08-08 20:51:08 +00:00
{
2021-06-11 21:07:02 +00:00
return wxT( "PCB_VIA" );
2007-08-08 20:51:08 +00:00
}
wxString GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const override;
BITMAPS GetMenuImage() const override;
2016-09-24 18:53:15 +00:00
EDA_ITEM* Clone() const override;
void ViewGetLayers( int aLayers[], int& aCount ) const override;
Introduction of Graphics Abstraction Layer based rendering for pcbnew. New classes: - VIEW - represents view that is seen by user, takes care of layer ordering & visibility and how it is displayed (which location, how much zoomed, etc.) - VIEW_ITEM - Base class for every item that can be displayed on VIEW (the biggest change is that now it may be necessary to override ViewBBox & ViewGetLayers method for derived classes). - EDA_DRAW_PANEL_GAL - Inherits after EDA_DRAW_PANEL, displays VIEW output, right now it is not editable (in opposite to usual EDA_DRAW_PANEL). - GAL/OPENGL_GAL/CAIRO_GAL - Base Graphics Abstraction Layer class + two different flavours (Cairo is not fully supported yet), that offers methods to draw primitives using different libraries. - WX_VIEW_CONTROLS - Controller for VIEW, handles user events, allows zooming, panning, etc. - PAINTER/PCB_PAINTER - Classes that uses GAL interface to draw items (as you may have already guessed - PCB_PAINTER is a class for drawing PCB specific object, PAINTER is an abstract class). Its methods are invoked by VIEW, when an item has to be drawn. To display a new type of item - you need to implement draw(ITEM_TYPE*) method that draws it using GAL methods. - STROKE_FONT - Implements stroke font drawing using GAL methods. Most important changes to Kicad original code: * EDA_ITEM now inherits from VIEW_ITEM, which is a base class for all drawable objects. * EDA_DRAW_FRAME contains both usual EDA_DRAW_PANEL and new EDA_DRAW_PANEL_GAL, that can be switched anytime. * There are some new layers for displaying multilayer pads, vias & pads holes (these are not shown yet on the right sidebar in pcbnew) * Display order of layers is different than in previous versions (if you are curious - you may check m_galLayerOrder@pcbnew/basepcbframe.cpp). Preserving usual order would result in not very natural display, such as showing silkscreen texts on the bottom. * Introduced new hotkey (Alt+F12) and new menu option (View->Switch canvas) for switching canvas during runtime. * Some of classes (mostly derived from BOARD_ITEM) now includes ViewBBox & ViewGetLayers methods. * Removed tools/class_painter.h, as now it is extended and included in source code. Build changes: * GAL-based rendering option is turned on by a new compilation CMake option KICAD_GAL. * When compiling with CMake option KICAD_GAL=ON, GLEW and Cairo libraries are required. * GAL-related code is compiled into a static library (common/libgal). * Build with KICAD_GAL=OFF should not need any new libraries and should come out as a standard version of Kicad Currently most of items in pcbnew can be displayed using OpenGL (to be done are DIMENSIONS and MARKERS). More details about GAL can be found in: http://www.ohwr.org/attachments/1884/view-spec.pdf
2013-04-02 06:54:03 +00:00
double ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const override;
void Flip( const VECTOR2I& aCentre, bool aFlipLeftRight ) override;
#if defined (DEBUG)
void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
#endif
int GetMinAnnulus( PCB_LAYER_ID aLayer, wxString* aSource ) const;
/**
* @deprecated - use Padstack().SetUnconnectedLayerMode()
* Sets the unconnected removal property. If true, the copper is removed on zone fill
* or when specifically requested when the via is not connected on a layer.
*/
void SetRemoveUnconnected( bool aSet )
{
m_padStack.SetUnconnectedLayerMode( aSet
? PADSTACK::UNCONNECTED_LAYER_MODE::REMOVE_ALL
: PADSTACK::UNCONNECTED_LAYER_MODE::KEEP_ALL );
}
bool GetRemoveUnconnected() const
{
return m_padStack.UnconnectedLayerMode() != PADSTACK::UNCONNECTED_LAYER_MODE::KEEP_ALL;
}
/**
* @deprecated - use Padstack().SetUnconnectedLayerMode()
* Sets whether we keep the start and end annular rings even if they are not connected
*/
void SetKeepStartEnd( bool aSet )
{
m_padStack.SetUnconnectedLayerMode( aSet
? PADSTACK::UNCONNECTED_LAYER_MODE::REMOVE_EXCEPT_START_AND_END
: PADSTACK::UNCONNECTED_LAYER_MODE::REMOVE_ALL );
}
bool GetKeepStartEnd() const
{
return m_padStack.UnconnectedLayerMode()
== PADSTACK::UNCONNECTED_LAYER_MODE::REMOVE_EXCEPT_START_AND_END;
}
bool ConditionallyFlashed( PCB_LAYER_ID aLayer ) const
{
switch( m_padStack.UnconnectedLayerMode() )
{
case PADSTACK::UNCONNECTED_LAYER_MODE::KEEP_ALL:
return false;
case PADSTACK::UNCONNECTED_LAYER_MODE::REMOVE_ALL:
return true;
case PADSTACK::UNCONNECTED_LAYER_MODE::REMOVE_EXCEPT_START_AND_END:
{
if( aLayer == m_padStack.Drill().start || aLayer == m_padStack.Drill().end )
return false;
}
}
return true;
}
/**
2023-03-06 12:12:11 +00:00
* Check to see whether the via should have a pad on the specific layer.
*
* @param aLayer Layer to check for connectivity
* @return true if connected by pad or track (or optionally zone)
*/
bool FlashLayer( int aLayer ) const;
/**
2023-03-06 12:12:11 +00:00
* Check to see if the via is present on any of the layers in the set.
*
* @param aLayers is the set of layers to check the via against.
* @return true if connected by pad or track (or optionally zone) on any of the associated
* layers.
*/
bool FlashLayer( LSET aLayers ) const;
/**
* Return the top-most and bottom-most connected layers.
* @param aTopmost
* @param aBottommost
*/
void GetOutermostConnectedLayers( PCB_LAYER_ID* aTopmost,
PCB_LAYER_ID* aBottommost ) const;
/**
2023-03-06 12:12:11 +00:00
* Set the drill value for vias.
*
* @param aDrill is the new drill diameter
2023-03-06 12:12:11 +00:00
*/
void SetDrill( int aDrill )
{
m_padStack.Drill().size = { aDrill, aDrill };
}
/**
2023-03-06 12:12:11 +00:00
* Return the local drill setting for this PCB_VIA.
*
* @note Use GetDrillValue() to get the calculated value.
*/
int GetDrill() const { return m_padStack.Drill().size.x; }
/**
* Calculate the drill value for vias (m_drill if > 0, or default drill value for the board).
2023-03-06 12:12:11 +00:00
*
* @return the calculated drill value.
*/
int GetDrillValue() const;
/**
2023-03-06 12:12:11 +00:00
* Set the drill value for vias to the default value #UNDEFINED_DRILL_DIAMETER.
*/
void SetDrillDefault()
{
m_padStack.Drill().size = { UNDEFINED_DRILL_DIAMETER, UNDEFINED_DRILL_DIAMETER };
}
/**
2023-03-06 12:12:11 +00:00
* Check if the via is a free via (as opposed to one created on a track by the router).
*
* Free vias don't have their nets automatically updated by the connectivity algorithm.
2023-03-06 12:12:11 +00:00
*
* @return true if the via is a free via
*/
bool GetIsFree() const { return m_isFree; }
void SetIsFree( bool aFree = true ) { m_isFree = aFree; }
2020-08-13 10:08:16 +00:00
// @copydoc BOARD_ITEM::GetEffectiveShape
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
FLASHING aFlash = FLASHING::DEFAULT ) const override;
2020-08-13 10:08:16 +00:00
void ClearZoneLayerOverrides()
2023-03-06 12:12:11 +00:00
{
m_zoneLayerOverrides.fill( ZLO_NONE );
}
const ZONE_LAYER_OVERRIDE& GetZoneLayerOverride( PCB_LAYER_ID aLayer ) const
{
return m_zoneLayerOverrides.at( aLayer );
}
void SetZoneLayerOverride( PCB_LAYER_ID aLayer, ZONE_LAYER_OVERRIDE aOverride )
{
std::unique_lock<std::mutex> cacheLock( m_zoneLayerOverridesMutex );
m_zoneLayerOverrides.at( aLayer ) = aOverride;
}
double Similarity( const BOARD_ITEM& aOther ) const override;
2024-06-05 01:34:14 +00:00
bool operator==( const PCB_VIA& aOther ) const;
bool operator==( const BOARD_ITEM& aOther ) const override;
void Serialize( google::protobuf::Any &aContainer ) const override;
bool Deserialize( const google::protobuf::Any &aContainer ) override;
protected:
void swapData( BOARD_ITEM* aImage ) override;
2020-11-16 11:16:44 +00:00
wxString layerMaskDescribe() const override;
private:
2020-11-14 14:29:11 +00:00
VIATYPE m_viaType; ///< through, blind/buried or micro
PADSTACK m_padStack;
bool m_isFree; ///< "Free" vias don't get their nets auto-updated
std::mutex m_zoneLayerOverridesMutex;
std::array<ZONE_LAYER_OVERRIDE, MAX_CU_LAYERS> m_zoneLayerOverrides;
};
#endif // CLASS_TRACK_H