Finish up custom-shaped pad spoke templates.

Also fixes a bug in number box for rotated pads.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/13962
This commit is contained in:
Jeff Young 2023-09-13 18:27:00 +01:00
parent 948fea4be8
commit e492efe3c5
6 changed files with 53 additions and 10 deletions

View File

@ -146,6 +146,7 @@ gr_poly
gr_rect
gr_text
gr_text_box
gr_vector
hatch
hatch_thickness
hatch_gap

View File

@ -1192,7 +1192,10 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
{
if( primitive->IsProxyItem() && primitive->GetShape() == SHAPE_T::RECTANGLE )
{
position = aPad->GetPosition() + primitive->GetCenter();
position = primitive->GetCenter();
RotatePoint( position, aPad->GetOrientation() );
position += aPad->ShapePos();
padsize.x = abs( primitive->GetBotRight().x - primitive->GetTopLeft().x );
padsize.y = abs( primitive->GetBotRight().y - primitive->GetTopLeft().y );
@ -1736,10 +1739,24 @@ void PCB_PAINTER::draw( const PCB_SHAPE* aShape, int aLayer )
case SHAPE_T::SEGMENT:
if( aShape->IsProxyItem() )
{
m_gal->SetIsFill( false );
m_gal->SetIsStroke( true );
std::vector<VECTOR2I> pts;
VECTOR2I offset = ( aShape->GetEnd() - aShape->GetStart() ).Perpendicular();
offset = offset.Resize( thickness / 2 );
pts.push_back( aShape->GetStart() + offset );
pts.push_back( aShape->GetStart() - offset );
pts.push_back( aShape->GetEnd() - offset );
pts.push_back( aShape->GetEnd() + offset );
m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
m_gal->DrawSegment( aShape->GetStart(), aShape->GetEnd(), thickness );
m_gal->DrawLine( pts[0], pts[1] );
m_gal->DrawLine( pts[1], pts[2] );
m_gal->DrawLine( pts[2], pts[3] );
m_gal->DrawLine( pts[3], pts[0] );
m_gal->DrawLine( ( pts[0] + pts[1] ) / 2, ( pts[1] + pts[2] ) / 2 );
m_gal->DrawLine( ( pts[1] + pts[2] ) / 2, ( pts[2] + pts[3] ) / 2 );
m_gal->DrawLine( ( pts[2] + pts[3] ) / 2, ( pts[3] + pts[0] ) / 2 );
m_gal->DrawLine( ( pts[3] + pts[0] ) / 2, ( pts[0] + pts[1] ) / 2 );
}
else if( outline_mode )
{

View File

@ -2520,7 +2520,7 @@ PCB_SHAPE* PCB_PARSER::parsePCB_SHAPE( BOARD_ITEM* aParent )
CurTok() == T_fp_rect || CurTok() == T_fp_line || CurTok() == T_fp_poly ||
CurTok() == T_gr_arc || CurTok() == T_gr_circle || CurTok() == T_gr_curve ||
CurTok() == T_gr_rect || CurTok() == T_gr_bbox || CurTok() == T_gr_line ||
CurTok() == T_gr_poly, nullptr,
CurTok() == T_gr_poly || CurTok() == T_gr_vector, nullptr,
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as PCB_SHAPE." ) );
T token;
@ -2720,6 +2720,7 @@ PCB_SHAPE* PCB_PARSER::parsePCB_SHAPE( BOARD_ITEM* aParent )
NeedRIGHT();
break;
case T_gr_vector:
case T_gr_line:
case T_fp_line:
// Default PCB_SHAPE type is S_SEGMENT.
@ -4590,6 +4591,14 @@ PAD* PCB_PARSER::parsePAD( FOOTPRINT* aParent )
break;
}
case T_gr_vector:
{
PCB_SHAPE* spokeTemplate = parsePCB_SHAPE( nullptr );
spokeTemplate->SetIsProxyItem();
pad->AddPrimitive( spokeTemplate );
break;
}
default:
Expecting( "gr_line, gr_arc, gr_circle, gr_curve, gr_rect, gr_bbox or gr_poly" );
break;

View File

@ -1698,9 +1698,18 @@ void PCB_PLUGIN::format( const PAD* aPad, int aNestLevel ) const
switch( primitive->GetShape() )
{
case SHAPE_T::SEGMENT:
m_out->Print( nested_level, "(gr_line (start %s) (end %s)",
formatInternalUnits( primitive->GetStart() ).c_str(),
formatInternalUnits( primitive->GetEnd() ).c_str() );
if( primitive->IsProxyItem() )
{
m_out->Print( nested_level, "(gr_vector (start %s) (end %s)",
formatInternalUnits( primitive->GetStart() ).c_str(),
formatInternalUnits( primitive->GetEnd() ).c_str() );
}
else
{
m_out->Print( nested_level, "(gr_line (start %s) (end %s)",
formatInternalUnits( primitive->GetStart() ).c_str(),
formatInternalUnits( primitive->GetEnd() ).c_str() );
}
break;
case SHAPE_T::RECTANGLE:
@ -1757,7 +1766,8 @@ void PCB_PLUGIN::format( const PAD* aPad, int aNestLevel ) const
break;
}
m_out->Print( 0, " (width %s)", formatInternalUnits( primitive->GetWidth() ).c_str() );
if( !primitive->IsProxyItem() )
m_out->Print( 0, " (width %s)", formatInternalUnits( primitive->GetWidth() ).c_str() );
// The filled flag represents if a solid fill is present on circles,
// rectangles and polygons

View File

@ -139,7 +139,8 @@ class PCB_PLUGIN; // forward decl
//#define SEXPR_BOARD_FILE_VERSION 20230620 // PCB Fields
//#define SEXPR_BOARD_FILE_VERSION 20230730 // Connectivity for graphic shapes
//#define SEXPR_BOARD_FILE_VERSION 20230825 // Textbox explicit border flag
#define SEXPR_BOARD_FILE_VERSION 20230906 // Multiple image type support in files
//#define SEXPR_BOARD_FILE_VERSION 20230906 // Multiple image type support in files
#define SEXPR_BOARD_FILE_VERSION 20230913 // Custom-shaped-pad spoke templates
#define BOARD_FILE_HOST_VERSION 20200825 ///< Earlier files than this include the host tag
#define LEGACY_ARC_FORMATTING 20210925 ///< These were the last to use old arc formatting

View File

@ -1858,6 +1858,11 @@ void ZONE_FILLER::buildThermalSpokes( const ZONE* aZone, PCB_LAYER_ID aLayer,
SEG seg( primitive->GetStart(), primitive->GetEnd() );
SHAPE_LINE_CHAIN::INTERSECTIONS intersections;
RotatePoint( seg.A, pad->GetOrientation() );
RotatePoint( seg.B, pad->GetOrientation() );
seg.A += pad->ShapePos();
seg.B += pad->ShapePos();
// Make sure seg.A is the origin
if( !pad->GetEffectivePolygon()->Contains( seg.A ) )
seg.Reverse();