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 <board_connected_item.h>
#include <fp_text.h>
#include <fp_shape.h>
#include <class_module.h>
#include <class_track.h>
#include <class_zone.h>
@ -37,14 +36,11 @@
#include <view/view.h>
#include <view/view_item.h>
#include <view/view_group.h>
#include <gal/graphics_abstraction_layer.h>
#include <pcb_painter.h>
#include <geometry/shape.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_simple.h>
@ -62,7 +58,6 @@
#include "pns_solid.h"
#include "pns_segment.h"
#include "pns_node.h"
#include "pns_topology.h"
#include "pns_router.h"
#include "pns_debug_decorator.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
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();
@ -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 );
// ignore non-copper pads except for those with holes
if( ( aPad->GetLayerSet() & LSET::AllCuMask()).none() &&
aPad->GetAttribute() != PAD_ATTRIB_NPTH )
if( ( aPad->GetLayerSet() & LSET::AllCuMask() ).none() && aPad->GetDrillSize().x == 0 )
return NULL;
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 );
if( aPad->GetAttribute() == PAD_ATTRIB_PTH ||
aPad->GetAttribute() == PAD_ATTRIB_NPTH )
solid->SetAlternateShape( aPad->GetEffectiveHoleShape()->Clone() );
if( aPad->GetDrillSize().x > 0 )
{
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 )
solid->SetRoutable( false );
@ -637,7 +640,6 @@ std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE_BASE::syncPad( D_PAD* aPad )
solid->SetPadToDie( aPad->GetPadToDieLength() );
wxPoint wx_c = aPad->ShapePos();
wxSize wx_sz = aPad->GetSize();
wxPoint offset = aPad->GetOffset();
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->SetOffset( VECTOR2I( offset.x, offset.y ) );
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 );
}
solid->SetShape( aPad->GetEffectiveShape()->Clone() );
return solid;
}

View File

@ -152,80 +152,84 @@ 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 );
for( int s = 0; s < aL.SegmentCount(); s++ )
gal->DrawLine( aL.CSegment( s ).A, aL.CSegment( s ).B );
for( int s = 0; s < aL->GetSegmentCount(); s++ )
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() );
auto angle = DEG2RAD( arc.GetCentralAngle() );
double start_angle = DEG2RAD( arc.GetStartAngle() );
double angle = DEG2RAD( arc.GetCentralAngle() );
gal->DrawArc( arc.GetCenter(), arc.GetRadius(), start_angle, start_angle + angle);
}
if( aL.IsClosed() )
gal->DrawLine( aL.CSegment( -1 ).B, aL.CSegment( 0 ).A );
if( aL->IsClosed() )
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();
//col.Brighten(0.7);
if( m_type == PR_SHAPE )
switch( aShape->Type() )
{
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 );
switch( m_shape->Type() )
case SH_POLY_SET_TRIANGLE:
{
case SH_LINE_CHAIN:
{
const SHAPE_LINE_CHAIN* l = (const SHAPE_LINE_CHAIN*) m_shape;
const SHAPE_LINE_CHAIN_BASE* l = (const SHAPE_LINE_CHAIN_BASE*) aShape;
if( m_showTrackClearance && m_clearance > 0 )
{
gal->SetLineWidth( m_width + 2 * m_clearance );
drawLineChain( *l, gal );
drawLineChain( l, gal );
}
gal->SetLayerDepth( m_depth );
gal->SetLineWidth( m_width );
gal->SetStrokeColor( m_color );
gal->SetFillColor( m_color );
drawLineChain( *l, gal );
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*) m_shape;
const SHAPE_SEGMENT* s = (const SHAPE_SEGMENT*) aShape;
const int w = s->GetWidth();
if( m_showTrackClearance && m_clearance > 0 )
{
gal->SetLineWidth( m_width + 2 * m_clearance );
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( m_width );
gal->SetLineWidth( w );
gal->SetStrokeColor( m_color );
gal->SetFillColor( m_color );
gal->DrawSegment( s->GetSeg().A, s->GetSeg().B, s->GetWidth() );
@ -234,7 +238,7 @@ void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
case SH_CIRCLE:
{
const SHAPE_CIRCLE* c = (const SHAPE_CIRCLE*) m_shape;
const SHAPE_CIRCLE* c = (const SHAPE_CIRCLE*) aShape;
gal->SetStrokeColor( m_color );
if( m_showViaClearance && m_clearance > 0 )
@ -254,7 +258,8 @@ void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
case SH_RECT:
{
const SHAPE_RECT* r = (const SHAPE_RECT*) m_shape;
const SHAPE_RECT* r = (const SHAPE_RECT*) aShape;
const int w = r->GetWidth();
gal->SetFillColor( m_color );
if( m_clearance > 0 )
@ -269,8 +274,8 @@ void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
}
gal->SetLayerDepth( m_depth );
gal->SetIsStroke( m_width ? true : false );
gal->SetLineWidth( m_width );
gal->SetIsStroke( w ? true : false );
gal->SetLineWidth( w );
gal->SetStrokeColor( m_color );
gal->DrawRectangle( r->GetPosition(), r->GetPosition() + r->GetSize() );
@ -279,8 +284,9 @@ void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
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>();
for( int i = 0; i < c->PointCount(); 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:
{
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 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 )
{
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->SetLayerDepth( m_depth );
gal->SetStrokeColor( m_color );
gal->SetFillColor( m_color );
gal->SetLineWidth( m_width );
gal->SetLineWidth( w );
gal->DrawArc( arc->GetCenter(), arc->GetRadius(), start_angle, start_angle + angle );
break;
}
case SH_POLY_SET:
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;
}
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:
const KIGFX::COLOR4D assignColor( int aStyle ) const;