diff --git a/pcbnew/router/pns_kicad_iface.cpp b/pcbnew/router/pns_kicad_iface.cpp index fee2757a7a..d6bb18b634 100644 --- a/pcbnew/router/pns_kicad_iface.cpp +++ b/pcbnew/router/pns_kicad_iface.cpp @@ -1185,10 +1185,24 @@ std::unique_ptr PNS_KICAD_IFACE_BASE::syncPad( PAD* aPad ) if( aPad->GetDrillSize().x > 0 ) solid->SetHole( new PNS::HOLE( aPad->GetEffectiveHoleShape()->Clone() ) ); - std::shared_ptr shape = aPad->GetEffectivePolygon(); + std::shared_ptr shape = aPad->GetEffectiveShape( UNDEFINED_LAYER, + FLASHING::ALWAYS_FLASHED ); + std::shared_ptr polygon = aPad->GetEffectivePolygon(); - if( shape->OutlineCount() ) - solid->SetShape( new SHAPE_SIMPLE( shape->Outline( 0 ) ) ); + if( shape->HasIndexableSubshapes() && polygon->OutlineCount() ) + { + solid->SetShape( new SHAPE_SIMPLE( polygon->Outline( 0 ) ) ); + + // GetEffectivePolygon may produce an approximation of the shape, so we need to account for + // this when building hulls around this shape. + solid->SetExtraClearance( m_board->GetDesignSettings().m_MaxError ); + } + else + { + // Prefer using the original shape if it's not a compound shape; the hulls for + // circular and rectangular pads can be exact. + solid->SetShape( shape->Clone() ); + } return solid; } diff --git a/pcbnew/router/pns_solid.cpp b/pcbnew/router/pns_solid.cpp index e9fba10479..5901bc8ce5 100644 --- a/pcbnew/router/pns_solid.cpp +++ b/pcbnew/router/pns_solid.cpp @@ -41,6 +41,8 @@ const SHAPE_LINE_CHAIN SOLID::Hull( int aClearance, int aWalkaroundThickness, in if( !m_shape ) return SHAPE_LINE_CHAIN(); + aClearance += ExtraClearance(); + if( m_shape->Type() == SH_COMPOUND ) { SHAPE_COMPOUND* cmpnd = static_cast( m_shape ); diff --git a/pcbnew/router/pns_solid.h b/pcbnew/router/pns_solid.h index 988c08387f..3d4a24a58e 100644 --- a/pcbnew/router/pns_solid.h +++ b/pcbnew/router/pns_solid.h @@ -38,7 +38,8 @@ public: SOLID() : ITEM( SOLID_T ), m_shape( nullptr ), - m_hole( nullptr ) + m_hole( nullptr ), + m_extraClearance( 0 ) { m_movable = false; m_padToDie = 0; @@ -65,6 +66,7 @@ public: m_padToDie = aSolid.m_padToDie; m_orientation = aSolid.m_orientation; m_anchorPoints = aSolid.m_anchorPoints; + m_extraClearance = aSolid.m_extraClearance; } SOLID& operator=( const SOLID& aB ) @@ -79,6 +81,7 @@ public: m_padToDie = aB.m_padToDie; m_orientation = aB.m_orientation; m_anchorPoints = aB.m_anchorPoints; + m_extraClearance = aB.m_extraClearance; return *this; } @@ -135,6 +138,9 @@ public: virtual bool HasHole() const override { return m_hole != nullptr; } virtual HOLE *Hole() const override { return m_hole; } + int ExtraClearance() const { return m_extraClearance; } + void SetExtraClearance( int aClearance ) { m_extraClearance = aClearance; } + private: VECTOR2I m_pos; SHAPE* m_shape; @@ -143,6 +149,7 @@ private: EDA_ANGLE m_orientation; HOLE* m_hole; std::vector m_anchorPoints; + int m_extraClearance; }; }