Move PNS pad solids to COMPOUND_SHAPE.

Also fixes plated holes solids to include plating thickness.
This commit is contained in:
Jeff Young 2020-10-05 14:55:52 +01:00
parent 0751965b2b
commit d063c56971
3 changed files with 177 additions and 144 deletions

View File

@ -23,7 +23,6 @@
#include <class_board.h> #include <class_board.h>
#include <board_connected_item.h> #include <board_connected_item.h>
#include <fp_text.h> #include <fp_text.h>
#include <fp_shape.h>
#include <class_module.h> #include <class_module.h>
#include <class_track.h> #include <class_track.h>
#include <class_zone.h> #include <class_zone.h>
@ -37,14 +36,11 @@
#include <view/view.h> #include <view/view.h>
#include <view/view_item.h> #include <view/view_item.h>
#include <view/view_group.h> #include <view/view_group.h>
#include <gal/graphics_abstraction_layer.h>
#include <pcb_painter.h> #include <pcb_painter.h>
#include <geometry/shape.h> #include <geometry/shape.h>
#include <geometry/shape_line_chain.h> #include <geometry/shape_line_chain.h>
#include <geometry/shape_rect.h>
#include <geometry/shape_circle.h>
#include <geometry/shape_arc.h> #include <geometry/shape_arc.h>
#include <geometry/shape_simple.h> #include <geometry/shape_simple.h>
@ -62,7 +58,6 @@
#include "pns_solid.h" #include "pns_solid.h"
#include "pns_segment.h" #include "pns_segment.h"
#include "pns_node.h" #include "pns_node.h"
#include "pns_topology.h"
#include "pns_router.h" #include "pns_router.h"
#include "pns_debug_decorator.h" #include "pns_debug_decorator.h"
#include "router_preview_item.h" #include "router_preview_item.h"
@ -137,11 +132,11 @@ PNS_PCBNEW_RULE_RESOLVER::PNS_PCBNEW_RULE_RESOLVER( BOARD* aBoard, PNS::ROUTER_I
} }
// Build clearance cache for pads // Build clearance cache for pads
for( auto mod : m_board->Modules() ) for( MODULE* mod : m_board->Modules() )
{ {
auto moduleClearance = mod->GetLocalClearance(); int moduleClearance = mod->GetLocalClearance();
for( auto pad : mod->Pads() ) for( D_PAD* pad : mod->Pads() )
{ {
int padClearance = pad->GetLocalClearance(); int padClearance = pad->GetLocalClearance();
@ -582,8 +577,7 @@ std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE_BASE::syncPad( D_PAD* aPad )
LAYER_RANGE layers( 0, MAX_CU_LAYERS - 1 ); LAYER_RANGE layers( 0, MAX_CU_LAYERS - 1 );
// ignore non-copper pads except for those with holes // ignore non-copper pads except for those with holes
if( ( aPad->GetLayerSet() & LSET::AllCuMask()).none() && if( ( aPad->GetLayerSet() & LSET::AllCuMask() ).none() && aPad->GetDrillSize().x == 0 )
aPad->GetAttribute() != PAD_ATTRIB_NPTH )
return NULL; return NULL;
switch( aPad->GetAttribute() ) switch( aPad->GetAttribute() )
@ -624,9 +618,18 @@ std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE_BASE::syncPad( D_PAD* aPad )
std::unique_ptr< PNS::SOLID > solid( new PNS::SOLID ); std::unique_ptr< PNS::SOLID > solid( new PNS::SOLID );
if( aPad->GetAttribute() == PAD_ATTRIB_PTH || if( aPad->GetDrillSize().x > 0 )
aPad->GetAttribute() == PAD_ATTRIB_NPTH ) {
solid->SetAlternateShape( aPad->GetEffectiveHoleShape()->Clone() ); SHAPE_SEGMENT* slot = (SHAPE_SEGMENT*) aPad->GetEffectiveHoleShape()->Clone();
if( aPad->GetAttribute() != PAD_ATTRIB_NPTH )
{
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
slot->SetWidth( slot->GetWidth() + bds.GetHolePlatingThickness() * 2 );
}
solid->SetAlternateShape( slot );
}
if( aPad->GetAttribute() == PAD_ATTRIB_NPTH ) if( aPad->GetAttribute() == PAD_ATTRIB_NPTH )
solid->SetRoutable( false ); solid->SetRoutable( false );
@ -637,7 +640,6 @@ std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE_BASE::syncPad( D_PAD* aPad )
solid->SetPadToDie( aPad->GetPadToDieLength() ); solid->SetPadToDie( aPad->GetPadToDieLength() );
wxPoint wx_c = aPad->ShapePos(); wxPoint wx_c = aPad->ShapePos();
wxSize wx_sz = aPad->GetSize();
wxPoint offset = aPad->GetOffset(); wxPoint offset = aPad->GetOffset();
VECTOR2I c( wx_c.x, wx_c.y ); VECTOR2I c( wx_c.x, wx_c.y );
@ -646,27 +648,7 @@ std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE_BASE::syncPad( D_PAD* aPad )
solid->SetPos( VECTOR2I( c.x - offset.x, c.y - offset.y ) ); solid->SetPos( VECTOR2I( c.x - offset.x, c.y - offset.y ) );
solid->SetOffset( VECTOR2I( offset.x, offset.y ) ); solid->SetOffset( VECTOR2I( offset.x, offset.y ) );
solid->SetShape( aPad->GetEffectiveShape()->Clone() );
auto shapes = std::dynamic_pointer_cast<SHAPE_COMPOUND>( aPad->GetEffectiveShape() );
if( shapes && shapes->Size() == 1 )
{
solid->SetShape( shapes->Shapes()[0]->Clone() );
}
else
{
// JEY TODO:
// TOM TODO: move to SHAPE_COMPOUND...
const std::shared_ptr<SHAPE_POLY_SET>& outline = aPad->GetEffectivePolygon();
SHAPE_SIMPLE* shape = new SHAPE_SIMPLE();
for( auto iter = outline->CIterate( 0 ); iter; iter++ )
shape->Append( *iter );
solid->SetShape( shape );
}
return solid; return solid;
} }

View File

@ -152,135 +152,141 @@ const BOX2I ROUTER_PREVIEW_ITEM::ViewBBox() const
} }
void ROUTER_PREVIEW_ITEM::drawLineChain( const SHAPE_LINE_CHAIN& aL, KIGFX::GAL* gal ) const void ROUTER_PREVIEW_ITEM::drawLineChain( const SHAPE_LINE_CHAIN_BASE* aL, KIGFX::GAL* gal ) const
{ {
gal->SetIsFill( false ); gal->SetIsFill( false );
for( int s = 0; s < aL.SegmentCount(); s++ ) for( int s = 0; s < aL->GetSegmentCount(); s++ )
gal->DrawLine( aL.CSegment( s ).A, aL.CSegment( s ).B ); gal->DrawLine( aL->GetSegment( s ).A, aL->GetSegment( s ).B );
for( size_t s = 0; s < aL.ArcCount(); s++ ) const SHAPE_LINE_CHAIN* lineChain = dynamic_cast<const SHAPE_LINE_CHAIN*>( aL );
for( size_t s = 0; lineChain && s < lineChain->ArcCount(); s++ )
{ {
auto arc = aL.CArcs()[s]; const SHAPE_ARC& arc = lineChain->CArcs()[s];
auto start_angle = DEG2RAD( arc.GetStartAngle() ); double start_angle = DEG2RAD( arc.GetStartAngle() );
auto angle = DEG2RAD( arc.GetCentralAngle() ); double angle = DEG2RAD( arc.GetCentralAngle() );
gal->DrawArc( arc.GetCenter(), arc.GetRadius(), start_angle, start_angle + angle); gal->DrawArc( arc.GetCenter(), arc.GetRadius(), start_angle, start_angle + angle);
} }
if( aL.IsClosed() ) if( aL->IsClosed() )
gal->DrawLine( aL.CSegment( -1 ).B, aL.CSegment( 0 ).A ); gal->DrawLine( aL->GetSegment( -1 ).B, aL->GetSegment( 0 ).A );
} }
void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const void ROUTER_PREVIEW_ITEM::drawShape( const SHAPE* aShape, KIGFX::GAL* gal ) const
{ {
auto gal = aView->GetGAL(); switch( aShape->Type() )
//col.Brighten(0.7);
if( m_type == PR_SHAPE )
{ {
if( !m_shape ) case SH_POLY_SET_TRIANGLE:
return; {
const SHAPE_LINE_CHAIN_BASE* l = (const SHAPE_LINE_CHAIN_BASE*) aShape;
// N.B. The order of draw here is important if( m_showTrackClearance && m_clearance > 0 )
// Cairo doesn't current support z-ordering, so we need {
// to draw the clearance first to ensure it is in the background gal->SetLineWidth( m_width + 2 * m_clearance );
gal->SetLayerDepth( ClearanceOverlayDepth ); drawLineChain( l, gal );
//TODO(snh) Add configuration option for the color/alpha here }
gal->SetStrokeColor( COLOR4D( DARKDARKGRAY ).WithAlpha( 0.9 ) );
gal->SetFillColor( COLOR4D( DARKDARKGRAY ).WithAlpha( 0.7 ) ); gal->SetLayerDepth( m_depth );
gal->SetLineWidth( m_width );
gal->SetStrokeColor( m_color );
gal->SetFillColor( m_color );
drawLineChain( l, gal );
break;
}
case SH_LINE_CHAIN:
{
const SHAPE_LINE_CHAIN* l = (const SHAPE_LINE_CHAIN*) aShape;
const int w = l->Width();
if( m_showTrackClearance && m_clearance > 0 )
{
gal->SetLineWidth( w + 2 * m_clearance );
drawLineChain( l, gal );
}
gal->SetLayerDepth( m_depth );
gal->SetLineWidth( w );
gal->SetStrokeColor( m_color );
gal->SetFillColor( m_color );
drawLineChain( l, gal );
break;
}
case SH_SEGMENT:
{
const SHAPE_SEGMENT* s = (const SHAPE_SEGMENT*) aShape;
const int w = s->GetWidth();
if( m_showTrackClearance && m_clearance > 0 )
{
gal->SetLineWidth( w + 2 * m_clearance );
gal->DrawSegment( s->GetSeg().A, s->GetSeg().B, s->GetWidth() + 2 * m_clearance );
}
gal->SetLayerDepth( m_depth );
gal->SetLineWidth( w );
gal->SetStrokeColor( m_color );
gal->SetFillColor( m_color );
gal->DrawSegment( s->GetSeg().A, s->GetSeg().B, s->GetWidth() );
break;
}
case SH_CIRCLE:
{
const SHAPE_CIRCLE* c = (const SHAPE_CIRCLE*) aShape;
gal->SetStrokeColor( m_color );
if( m_showViaClearance && m_clearance > 0 )
{
gal->SetIsStroke( false );
gal->DrawCircle( c->GetCenter(), c->GetRadius() + m_clearance );
}
gal->SetLayerDepth( m_depth );
gal->SetIsStroke( m_width ? true : false ); gal->SetIsStroke( m_width ? true : false );
gal->SetIsFill( true ); gal->SetLineWidth( m_width );
gal->SetFillColor( m_color );
gal->DrawCircle( c->GetCenter(), c->GetRadius() );
switch( m_shape->Type() ) break;
}
case SH_RECT:
{
const SHAPE_RECT* r = (const SHAPE_RECT*) aShape;
const int w = r->GetWidth();
gal->SetFillColor( m_color );
if( m_clearance > 0 )
{ {
case SH_LINE_CHAIN: VECTOR2I p0( r->GetPosition() ), s( r->GetSize() );
{ gal->SetIsStroke( true );
const SHAPE_LINE_CHAIN* l = (const SHAPE_LINE_CHAIN*) m_shape; gal->SetLineWidth( 2 * m_clearance );
gal->DrawLine( p0, VECTOR2I( p0.x + s.x, p0.y ) );
if( m_showTrackClearance && m_clearance > 0 ) gal->DrawLine( p0, VECTOR2I( p0.x, p0.y + s.y ) );
{ gal->DrawLine( p0 + s , VECTOR2I( p0.x + s.x, p0.y ) );
gal->SetLineWidth( m_width + 2 * m_clearance ); gal->DrawLine( p0 + s, VECTOR2I( p0.x, p0.y + s.y ) );
drawLineChain( *l, gal );
}
gal->SetLayerDepth( m_depth );
gal->SetLineWidth( m_width );
gal->SetStrokeColor( m_color );
gal->SetFillColor( m_color );
drawLineChain( *l, gal );
break;
} }
case SH_SEGMENT: gal->SetLayerDepth( m_depth );
{ gal->SetIsStroke( w ? true : false );
const SHAPE_SEGMENT* s = (const SHAPE_SEGMENT*) m_shape; gal->SetLineWidth( w );
gal->SetStrokeColor( m_color );
gal->DrawRectangle( r->GetPosition(), r->GetPosition() + r->GetSize() );
if( m_showTrackClearance && m_clearance > 0 ) break;
{ }
gal->SetLineWidth( m_width + 2 * m_clearance );
gal->DrawSegment( s->GetSeg().A, s->GetSeg().B, s->GetWidth() + 2 * m_clearance );
}
gal->SetLayerDepth( m_depth );
gal->SetLineWidth( m_width );
gal->SetStrokeColor( m_color );
gal->SetFillColor( m_color );
gal->DrawSegment( s->GetSeg().A, s->GetSeg().B, s->GetWidth() );
break;
}
case SH_CIRCLE:
{
const SHAPE_CIRCLE* c = (const SHAPE_CIRCLE*) m_shape;
gal->SetStrokeColor( m_color );
if( m_showViaClearance && m_clearance > 0 )
{
gal->SetIsStroke( false );
gal->DrawCircle( c->GetCenter(), c->GetRadius() + m_clearance );
}
gal->SetLayerDepth( m_depth );
gal->SetIsStroke( m_width ? true : false );
gal->SetLineWidth( m_width );
gal->SetFillColor( m_color );
gal->DrawCircle( c->GetCenter(), c->GetRadius() );
break;
}
case SH_RECT:
{
const SHAPE_RECT* r = (const SHAPE_RECT*) m_shape;
gal->SetFillColor( m_color );
if( m_clearance > 0 )
{
VECTOR2I p0( r->GetPosition() ), s( r->GetSize() );
gal->SetIsStroke( true );
gal->SetLineWidth( 2 * m_clearance );
gal->DrawLine( p0, VECTOR2I( p0.x + s.x, p0.y ) );
gal->DrawLine( p0, VECTOR2I( p0.x, p0.y + s.y ) );
gal->DrawLine( p0 + s , VECTOR2I( p0.x + s.x, p0.y ) );
gal->DrawLine( p0 + s, VECTOR2I( p0.x, p0.y + s.y ) );
}
gal->SetLayerDepth( m_depth );
gal->SetIsStroke( m_width ? true : false );
gal->SetLineWidth( m_width );
gal->SetStrokeColor( m_color );
gal->DrawRectangle( r->GetPosition(), r->GetPosition() + r->GetSize() );
break;
}
case SH_SIMPLE: case SH_SIMPLE:
{ {
const SHAPE_SIMPLE* c = (const SHAPE_SIMPLE*) m_shape; const SHAPE_SIMPLE* c = (const SHAPE_SIMPLE*) aShape;
std::deque<VECTOR2D> polygon = std::deque<VECTOR2D>(); std::deque<VECTOR2D> polygon = std::deque<VECTOR2D>();
for( int i = 0; i < c->PointCount(); i++ ) for( int i = 0; i < c->PointCount(); i++ )
{ {
polygon.push_back( c->CDPoint( i ) ); polygon.push_back( c->CDPoint( i ) );
@ -307,7 +313,8 @@ void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
case SH_ARC: case SH_ARC:
{ {
const auto arc = static_cast<const SHAPE_ARC*>( m_shape ); const SHAPE_ARC* arc = static_cast<const SHAPE_ARC*>( aShape );
const int w = arc->GetWidth();
auto start_angle = DEG2RAD( arc->GetStartAngle() ); auto start_angle = DEG2RAD( arc->GetStartAngle() );
auto angle = DEG2RAD( arc->GetCentralAngle() ); auto angle = DEG2RAD( arc->GetCentralAngle() );
@ -317,21 +324,63 @@ void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
if( m_showTrackClearance && m_clearance > 0 ) if( m_showTrackClearance && m_clearance > 0 )
{ {
gal->SetLineWidth( m_width + 2 * m_clearance ); gal->SetLineWidth( w + 2 * m_clearance );
gal->DrawArc( arc->GetCenter(), arc->GetRadius(), start_angle, start_angle + angle ); gal->DrawArc( arc->GetCenter(), arc->GetRadius(), start_angle, start_angle + angle );
} }
gal->SetLayerDepth( m_depth ); gal->SetLayerDepth( m_depth );
gal->SetStrokeColor( m_color ); gal->SetStrokeColor( m_color );
gal->SetFillColor( m_color ); gal->SetFillColor( m_color );
gal->SetLineWidth( m_width ); gal->SetLineWidth( w );
gal->DrawArc( arc->GetCenter(), arc->GetRadius(), start_angle, start_angle + angle ); gal->DrawArc( arc->GetCenter(), arc->GetRadius(), start_angle, start_angle + angle );
break; break;
} }
case SH_POLY_SET:
case SH_COMPOUND: case SH_COMPOUND:
break; // Not yet in use wxFAIL_MSG( "Router preview item: nested compound shapes not supported" );
break;
case SH_POLY_SET:
wxFAIL_MSG( "Router preview item: SHAPE_POLY_SET not supported" );
break;
case SH_NULL:
break;
}
}
void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
{
GAL* gal = aView->GetGAL();
//col.Brighten(0.7);
if( m_type == PR_SHAPE )
{
if( !m_shape )
return;
// N.B. The order of draw here is important
// Cairo doesn't current support z-ordering, so we need
// to draw the clearance first to ensure it is in the background
gal->SetLayerDepth( ClearanceOverlayDepth );
//TODO(snh) Add configuration option for the color/alpha here
gal->SetStrokeColor( COLOR4D( DARKDARKGRAY ).WithAlpha( 0.9 ) );
gal->SetFillColor( COLOR4D( DARKDARKGRAY ).WithAlpha( 0.7 ) );
gal->SetIsStroke( m_width ? true : false );
gal->SetIsFill( true );
if( m_shape->HasIndexableSubshapes() )
{
std::vector<SHAPE*> subshapes;
m_shape->GetIndexableSubshapes( subshapes );
for( SHAPE* shape : subshapes )
drawShape( shape, gal );
}
else
{
drawShape( m_shape, gal );
} }
} }
} }

View File

@ -109,7 +109,9 @@ public:
aCount = 1; aCount = 1;
} }
void drawLineChain( const SHAPE_LINE_CHAIN& aL, KIGFX::GAL* aGal ) const; void drawLineChain( const SHAPE_LINE_CHAIN_BASE* aL, KIGFX::GAL* aGal ) const;
void drawShape( const SHAPE* aShape, KIGFX::GAL* aGal ) const;
private: private:
const KIGFX::COLOR4D assignColor( int aStyle ) const; const KIGFX::COLOR4D assignColor( int aStyle ) const;