Adding Arcs to TRACKS
This expands the TRACKS class to also include ARCS
This commit is contained in:
parent
c52b3ce0e4
commit
3af868e3d1
|
@ -134,6 +134,7 @@ loss_tangent
|
|||
max_error
|
||||
material
|
||||
micro
|
||||
mid
|
||||
min_thickness
|
||||
mirror
|
||||
mod_edge_width
|
||||
|
|
|
@ -95,6 +95,7 @@ enum KICAD_T
|
|||
PCB_MODULE_ZONE_AREA_T, ///< class ZONE_CONTAINER, managed by a footprint
|
||||
PCB_TRACE_T, ///< class TRACK, a track segment (segment on a copper layer)
|
||||
PCB_VIA_T, ///< class VIA, a via (like a track segment on a copper layer)
|
||||
PCB_ARC_T, ///< class ARC, an arc track segment on a copper layer
|
||||
PCB_MARKER_T, ///< class MARKER_PCB, a marker used to show something
|
||||
PCB_DIMENSION_T, ///< class DIMENSION, a dimension (graphic item)
|
||||
PCB_TARGET_T, ///< class PCB_TARGET, a target (graphic item)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
|
||||
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2019 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
|
||||
|
@ -53,7 +53,8 @@ static bool ShowClearance( const PCB_DISPLAY_OPTIONS& aDisplOpts, const TRACK* a
|
|||
{
|
||||
// maybe return true for tracks and vias, not for zone segments
|
||||
return IsCopperLayer( aTrack->GetLayer() )
|
||||
&& ( aTrack->Type() == PCB_TRACE_T || aTrack->Type() == PCB_VIA_T )
|
||||
&& ( aTrack->Type() == PCB_TRACE_T || aTrack->Type() == PCB_VIA_T
|
||||
|| aTrack->Type() == PCB_ARC_T )
|
||||
&& ( ( aDisplOpts.m_ShowTrackClearanceMode == PCB_DISPLAY_OPTIONS::SHOW_CLEARANCE_NEW_AND_EDITED_TRACKS_AND_VIA_AREAS
|
||||
&& ( aTrack->IsDragging() || aTrack->IsMoving() || aTrack->IsNew() ) )
|
||||
|| ( aDisplOpts.m_ShowTrackClearanceMode == PCB_DISPLAY_OPTIONS::SHOW_CLEARANCE_ALWAYS )
|
||||
|
@ -75,7 +76,14 @@ EDA_ITEM* TRACK::Clone() const
|
|||
}
|
||||
|
||||
|
||||
VIA::VIA( BOARD_ITEM* aParent ) : TRACK( aParent, PCB_VIA_T )
|
||||
EDA_ITEM* ARC::Clone() const
|
||||
{
|
||||
return new ARC( *this );
|
||||
}
|
||||
|
||||
|
||||
VIA::VIA( BOARD_ITEM* aParent ) :
|
||||
TRACK( aParent, PCB_VIA_T )
|
||||
{
|
||||
SetViaType( VIATYPE::THROUGH );
|
||||
m_BottomLayer = B_Cu;
|
||||
|
@ -229,6 +237,14 @@ void TRACK::Rotate( const wxPoint& aRotCentre, double aAngle )
|
|||
}
|
||||
|
||||
|
||||
void ARC::Rotate( const wxPoint& aRotCentre, double aAngle )
|
||||
{
|
||||
RotatePoint( &m_Start, aRotCentre, aAngle );
|
||||
RotatePoint( &m_End, aRotCentre, aAngle );
|
||||
RotatePoint( &m_Mid, aRotCentre, aAngle );
|
||||
}
|
||||
|
||||
|
||||
void TRACK::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
|
||||
{
|
||||
if( aFlipLeftRight )
|
||||
|
@ -247,6 +263,26 @@ void TRACK::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
|
|||
}
|
||||
|
||||
|
||||
void ARC::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
|
||||
{
|
||||
if( aFlipLeftRight )
|
||||
{
|
||||
m_Start.x = aCentre.x - ( m_Start.x - aCentre.x );
|
||||
m_End.x = aCentre.x - ( m_End.x - aCentre.x );
|
||||
m_Mid.x = aCentre.x - ( m_Mid.x - aCentre.x );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Start.y = aCentre.y - ( m_Start.y - aCentre.y );
|
||||
m_End.y = aCentre.y - ( m_End.y - aCentre.y );
|
||||
m_Mid.y = aCentre.y - ( m_Mid.y - aCentre.y );
|
||||
}
|
||||
|
||||
int copperLayerCount = GetBoard()->GetCopperLayerCount();
|
||||
SetLayer( FlipLayer( GetLayer(), copperLayerCount ) );
|
||||
}
|
||||
|
||||
|
||||
void VIA::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
|
||||
{
|
||||
if( aFlipLeftRight )
|
||||
|
@ -938,6 +974,22 @@ bool TRACK::HitTest( const wxPoint& aPosition, int aAccuracy ) const
|
|||
}
|
||||
|
||||
|
||||
bool ARC::HitTest( const wxPoint& aPosition, int aAccuracy ) const
|
||||
{
|
||||
int max_dist = aAccuracy + ( m_Width / 2 );
|
||||
|
||||
auto rel_start = EuclideanNorm( aPosition - m_Start );
|
||||
auto rel_mid = EuclideanNorm( aPosition - m_Mid );
|
||||
auto rel_end = EuclideanNorm( aPosition - m_End );
|
||||
|
||||
if( rel_start <= max_dist || rel_mid <= max_dist || rel_end <= max_dist )
|
||||
return true;
|
||||
|
||||
//TODO: Calculate along arc
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool VIA::HitTest( const wxPoint& aPosition, int aAccuracy ) const
|
||||
{
|
||||
int max_dist = aAccuracy + ( m_Width / 2 );
|
||||
|
@ -963,6 +1015,25 @@ bool TRACK::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) con
|
|||
}
|
||||
|
||||
|
||||
bool ARC::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
|
||||
{
|
||||
EDA_RECT box;
|
||||
EDA_RECT arect = aRect;
|
||||
arect.Inflate( aAccuracy );
|
||||
|
||||
box.SetOrigin( GetStart() );
|
||||
box.Merge( GetMid() );
|
||||
box.Merge( GetEnd() );
|
||||
|
||||
box.Inflate( GetWidth() / 2 );
|
||||
|
||||
if( aContained )
|
||||
return arect.Contains( box );
|
||||
else
|
||||
return arect.Intersects( box );
|
||||
}
|
||||
|
||||
|
||||
bool VIA::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
|
||||
{
|
||||
EDA_RECT box;
|
||||
|
@ -1005,6 +1076,13 @@ void TRACK::SwapData( BOARD_ITEM* aImage )
|
|||
std::swap( *((TRACK*) this), *((TRACK*) aImage) );
|
||||
}
|
||||
|
||||
void ARC::SwapData( BOARD_ITEM* aImage )
|
||||
{
|
||||
assert( aImage->Type() == PCB_ARC_T );
|
||||
|
||||
std::swap( *this, *static_cast<ARC*>( aImage ) );
|
||||
}
|
||||
|
||||
void VIA::SwapData( BOARD_ITEM* aImage )
|
||||
{
|
||||
assert( aImage->Type() == PCB_VIA_T );
|
||||
|
|
|
@ -136,7 +136,7 @@ public:
|
|||
* returns the length of the track using the hypotenuse calculation.
|
||||
* @return double - the length of the track
|
||||
*/
|
||||
double GetLength() const
|
||||
virtual double GetLength() const
|
||||
{
|
||||
return GetLineLength( m_Start, m_End );
|
||||
}
|
||||
|
@ -257,6 +257,63 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
class ARC : public TRACK
|
||||
{
|
||||
public:
|
||||
ARC( BOARD_ITEM* aParent ) : TRACK( aParent, PCB_ARC_T ){};
|
||||
|
||||
static inline bool ClassOf( const EDA_ITEM *aItem )
|
||||
{
|
||||
return aItem && PCB_ARC_T == aItem->Type();
|
||||
}
|
||||
|
||||
virtual void Move( const wxPoint& aMoveVector ) override
|
||||
{
|
||||
m_Start += aMoveVector;
|
||||
m_Mid += aMoveVector;
|
||||
m_End += aMoveVector;
|
||||
}
|
||||
|
||||
virtual void Rotate( const wxPoint& aRotCentre, double aAngle ) override;
|
||||
|
||||
virtual void Flip( const wxPoint& aCentre, bool aFlipLeftRight ) override;
|
||||
|
||||
void SetMid( const wxPoint& aMid ) { m_Mid = aMid; }
|
||||
const wxPoint& GetMid() const { return m_Mid; }
|
||||
|
||||
virtual bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
|
||||
|
||||
virtual bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const override;
|
||||
|
||||
wxString GetClass() const override
|
||||
{
|
||||
return wxT( "ARC" );
|
||||
}
|
||||
|
||||
//TODO(snh): Add GetSelectMenuText() and GetMsgPanelInfoBase()
|
||||
|
||||
/**
|
||||
* Function GetLength
|
||||
* returns the length of the track using the hypotenuse calculation.
|
||||
* @return double - the length of the track
|
||||
*/
|
||||
virtual double GetLength() const override
|
||||
{
|
||||
//TODO(snh): Add proper arc length calc
|
||||
return GetLineLength( m_Start, m_Mid ) + GetLineLength( m_Mid, m_End );
|
||||
}
|
||||
|
||||
EDA_ITEM* Clone() const override;
|
||||
|
||||
virtual void SwapData( BOARD_ITEM* aImage ) override;
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
wxPoint m_Mid; ///< Arc mid point, halfway between start and end
|
||||
};
|
||||
|
||||
|
||||
class VIA : public TRACK
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -1706,6 +1706,18 @@ void PCB_IO::format( TRACK* aTrack, int aNestLevel ) const
|
|||
m_out->Quotew( m_board->GetLayerName( layer1 ) ).c_str(),
|
||||
m_out->Quotew( m_board->GetLayerName( layer2 ) ).c_str() );
|
||||
}
|
||||
else if( aTrack->Type() == PCB_ARC_T )
|
||||
{
|
||||
const ARC* arc = static_cast<const ARC*>( aTrack );
|
||||
|
||||
m_out->Print( aNestLevel, "(arc (start %s) (mid %s) (end %s) (width %s)",
|
||||
FormatInternalUnits( arc->GetStart() ).c_str(),
|
||||
FormatInternalUnits( arc->GetMid() ).c_str(),
|
||||
FormatInternalUnits( arc->GetEnd() ).c_str(),
|
||||
FormatInternalUnits( arc->GetWidth() ).c_str() );
|
||||
|
||||
m_out->Print( 0, " (layer %s)", m_out->Quotew( aTrack->GetLayerName() ).c_str() );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_out->Print( aNestLevel, "(segment (start %s) (end %s) (width %s)",
|
||||
|
|
|
@ -65,7 +65,8 @@ class TEXTE_PCB;
|
|||
//#define SEXPR_BOARD_FILE_VERSION 20190905 // Add board physical stackup info in setup section
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20190907 // Keepout areas in footprints
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20191123 // pin function in pads
|
||||
#define SEXPR_BOARD_FILE_VERSION 20200104 // pad property for fabrication
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20200104 // pad property for fabrication
|
||||
#define SEXPR_BOARD_FILE_VERSION 20200119 // arcs in tracks
|
||||
|
||||
#define CTL_STD_LAYER_NAMES (1 << 0) ///< Use English Standard layer names
|
||||
#define CTL_OMIT_NETS (1 << 1) ///< Omit pads net names (useless in library)
|
||||
|
|
|
@ -586,6 +586,10 @@ BOARD* PCB_PARSER::parseBOARD_unchecked()
|
|||
m_board->Add( parseTRACK(), ADD_MODE::INSERT );
|
||||
break;
|
||||
|
||||
case T_arc:
|
||||
m_board->Add( parseARC(), ADD_INSERT );
|
||||
break;
|
||||
|
||||
case T_via:
|
||||
m_board->Add( parseVIA(), ADD_MODE::INSERT );
|
||||
break;
|
||||
|
@ -3349,6 +3353,77 @@ bool PCB_PARSER::parseD_PAD_option( D_PAD* aPad )
|
|||
}
|
||||
|
||||
|
||||
ARC* PCB_PARSER::parseARC()
|
||||
{
|
||||
wxCHECK_MSG( CurTok() == T_arc, NULL,
|
||||
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as ARC." ) );
|
||||
|
||||
wxPoint pt;
|
||||
T token;
|
||||
|
||||
std::unique_ptr<ARC> arc( new ARC( m_board ) );
|
||||
|
||||
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
||||
{
|
||||
if( token != T_LEFT )
|
||||
Expecting( T_LEFT );
|
||||
|
||||
token = NextTok();
|
||||
|
||||
switch( token )
|
||||
{
|
||||
case T_start:
|
||||
pt.x = parseBoardUnits( "start x" );
|
||||
pt.y = parseBoardUnits( "start y" );
|
||||
arc->SetStart( pt );
|
||||
break;
|
||||
|
||||
case T_mid:
|
||||
pt.x = parseBoardUnits( "mid x" );
|
||||
pt.y = parseBoardUnits( "mid y" );
|
||||
arc->SetMid( pt );
|
||||
break;
|
||||
|
||||
case T_end:
|
||||
pt.x = parseBoardUnits( "end x" );
|
||||
pt.y = parseBoardUnits( "end y" );
|
||||
arc->SetEnd( pt );
|
||||
break;
|
||||
|
||||
case T_width:
|
||||
arc->SetWidth( parseBoardUnits( "width" ) );
|
||||
break;
|
||||
|
||||
case T_layer:
|
||||
arc->SetLayer( parseBoardItemLayer() );
|
||||
break;
|
||||
|
||||
case T_net:
|
||||
if( !arc->SetNetCode( getNetCode( parseInt( "net number" ) ), /* aNoAssert */ true ) )
|
||||
THROW_IO_ERROR( wxString::Format(
|
||||
_( "Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
|
||||
GetChars( CurSource() ), CurLineNumber(), CurOffset() ) );
|
||||
break;
|
||||
|
||||
case T_tstamp:
|
||||
arc->SetTimeStamp( parseHex() );
|
||||
break;
|
||||
|
||||
case T_status:
|
||||
arc->SetStatus( static_cast<STATUS_FLAGS>( parseHex() ) );
|
||||
break;
|
||||
|
||||
default:
|
||||
Expecting( "start, mid, end, width, layer, net, tstamp, or status" );
|
||||
}
|
||||
|
||||
NeedRIGHT();
|
||||
}
|
||||
|
||||
return arc.release();
|
||||
}
|
||||
|
||||
|
||||
TRACK* PCB_PARSER::parseTRACK()
|
||||
{
|
||||
wxCHECK_MSG( CurTok() == T_segment, NULL,
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <unordered_map>
|
||||
|
||||
|
||||
class ARC;
|
||||
class BOARD;
|
||||
class BOARD_ITEM;
|
||||
class BOARD_ITEM_CONTAINER;
|
||||
|
@ -155,6 +156,7 @@ class PCB_PARSER : public PCB_LEXER
|
|||
D_PAD* parseD_PAD( MODULE* aParent = NULL );
|
||||
// Parse only the (option ...) inside a pad description
|
||||
bool parseD_PAD_option( D_PAD* aPad );
|
||||
ARC* parseARC();
|
||||
TRACK* parseTRACK();
|
||||
VIA* parseVIA();
|
||||
ZONE_CONTAINER* parseZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent );
|
||||
|
|
Loading…
Reference in New Issue