Browse Source

Separate flashing check for connectivity

When building the connectivity database, we should not be using the
connectivity to check for shapes.

To make this deterministic, we introduce two flags (ALWAYS_FLASH and
NEVER_FLASH) that are used with connectivity building to determine
whether a pad is flashed for connectivity or not.  ZONE <-> PAD/VIA
connectivity will be checked with ALWAYS_FLASHED and all other
connectivity will be checked with NEVER_FLASHED if they are marked for
potential annular ring removal.  If they are not marked for removal,
they will be checked ALWAYS_FLASHED.

Fixes https://gitlab.com/kicad/code/kicad/issues/11114
7.0
Seth Hillbrand 4 years ago
parent
commit
442aae19d9
  1. 3
      include/board_item.h
  2. 11
      include/layer_ids.h
  3. 2
      pcbnew/board_item.cpp
  4. 38
      pcbnew/connectivity/connectivity_algo.cpp
  5. 6
      pcbnew/footprint.cpp
  6. 3
      pcbnew/footprint.h
  7. 2
      pcbnew/fp_text.cpp
  8. 3
      pcbnew/fp_text.h
  9. 2
      pcbnew/fp_textbox.cpp
  10. 3
      pcbnew/fp_textbox.h
  11. 5
      pcbnew/pad.cpp
  12. 3
      pcbnew/pad.h
  13. 2
      pcbnew/pcb_dimension.cpp
  14. 3
      pcbnew/pcb_dimension.h
  15. 2
      pcbnew/pcb_marker.cpp
  16. 3
      pcbnew/pcb_marker.h
  17. 2
      pcbnew/pcb_shape.cpp
  18. 3
      pcbnew/pcb_shape.h
  19. 2
      pcbnew/pcb_target.cpp
  20. 3
      pcbnew/pcb_target.h
  21. 2
      pcbnew/pcb_text.cpp
  22. 3
      pcbnew/pcb_text.h
  23. 4
      pcbnew/pcb_textbox.cpp
  24. 3
      pcbnew/pcb_textbox.h
  25. 9
      pcbnew/pcb_track.cpp
  26. 9
      pcbnew/pcb_track.h
  27. 2
      pcbnew/zone.cpp
  28. 3
      pcbnew/zone.h

3
include/board_item.h

@ -134,7 +134,8 @@ public:
* @param aLayer in case of items spanning multiple layers, only the shapes belonging to aLayer
* will be returned. Pass UNDEFINED_LAYER to return shapes for all layers.
*/
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) const;
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
FLASHING aFlash = FLASHING::DEFAULT ) const;
BOARD_ITEM_CONTAINER* GetParent() const { return (BOARD_ITEM_CONTAINER*) m_parent; }

11
include/layer_ids.h

@ -139,6 +139,17 @@ enum PCB_LAYER_ID: int
#define MAX_CU_LAYERS (B_Cu - F_Cu + 1)
/**
* Enum used during connectivity building to ensure we do not query connectivity while building
* the database
*/
enum class FLASHING
{
DEFAULT, // Flashing follows connectivity
ALWAYS_FLASHED, // Always flashed for connectivity
NEVER_FLASHED, // Never flashed for connectivity
};
/// Dedicated layers for net names used in Pcbnew
enum NETNAMES_LAYER_ID: int
{

2
pcbnew/board_item.cpp

@ -194,7 +194,7 @@ bool BOARD_ITEM::ptr_cmp::operator() ( const BOARD_ITEM* a, const BOARD_ITEM* b
}
std::shared_ptr<SHAPE> BOARD_ITEM::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
std::shared_ptr<SHAPE> BOARD_ITEM::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
{
std::shared_ptr<SHAPE> shape;

38
pcbnew/connectivity/connectivity_algo.cpp

@ -769,6 +769,16 @@ void CN_VISITOR::checkZoneItemConnection( CN_ZONE_LAYER* aZoneLayer, CN_ITEM* aI
}
}
if( aItem->Parent()->Type() == PCB_VIA_T || aItem->Parent()->Type() == PCB_PAD_T )
{
// As long as the pad/via crosses the zone layer, check for the full effective shape
// We check for the overlapping layers above
if( aZoneLayer->Collide( aItem->Parent()->GetEffectiveShape( layer, FLASHING::ALWAYS_FLASHED ).get() ) )
connect();
return;
}
if( aZoneLayer->Collide( aItem->Parent()->GetEffectiveShape( layer ).get() ) )
connect();
}
@ -867,7 +877,33 @@ bool CN_VISITOR::operator()( CN_ITEM* aCandidate )
for( PCB_LAYER_ID layer : commonLayers.Seq() )
{
if( parentA->GetEffectiveShape( layer )->Collide( parentB->GetEffectiveShape( layer ).get() ) )
FLASHING flashingA = FLASHING::NEVER_FLASHED;
FLASHING flashingB = FLASHING::NEVER_FLASHED;
if( const PAD* pad = dyn_cast<const PAD*>( parentA ) )
{
if( !pad->GetRemoveUnconnected() || ( ( layer == F_Cu || layer == B_Cu ) && pad->GetKeepTopBottom() ) )
flashingA = FLASHING::ALWAYS_FLASHED;
}
else if( const PCB_VIA* via = dyn_cast<const PCB_VIA*>( parentA ) )
{
if( !via->GetRemoveUnconnected() || ( ( layer == F_Cu || layer == B_Cu ) && via->GetKeepTopBottom() ) )
flashingA = FLASHING::ALWAYS_FLASHED;
}
if( const PAD* pad = dyn_cast<const PAD*>( parentB ) )
{
if( !pad->GetRemoveUnconnected() || ( ( layer == F_Cu || layer == B_Cu ) && pad->GetKeepTopBottom() ) )
flashingB = FLASHING::ALWAYS_FLASHED;
}
else if( const PCB_VIA* via = dyn_cast<const PCB_VIA*>( parentB ) )
{
if( !via->GetRemoveUnconnected() || ( ( layer == F_Cu || layer == B_Cu ) && via->GetKeepTopBottom() ) )
flashingB = FLASHING::ALWAYS_FLASHED;
}
if( parentA->GetEffectiveShape( layer, flashingA )->Collide(
parentB->GetEffectiveShape( layer, flashingB ).get() ) )
{
m_item->Connect( aCandidate );
aCandidate->Connect( m_item );

6
pcbnew/footprint.cpp

@ -2100,7 +2100,7 @@ double FOOTPRINT::CoverageRatio( const GENERAL_COLLECTOR& aCollector ) const
}
std::shared_ptr<SHAPE> FOOTPRINT::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
std::shared_ptr<SHAPE> FOOTPRINT::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
{
std::shared_ptr<SHAPE_COMPOUND> shape = std::make_shared<SHAPE_COMPOUND>();
@ -2112,12 +2112,12 @@ std::shared_ptr<SHAPE> FOOTPRINT::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
// We'll go with (2) for now....
for( PAD* pad : Pads() )
shape->AddShape( pad->GetEffectiveShape( aLayer )->Clone() );
shape->AddShape( pad->GetEffectiveShape( aLayer, aFlash )->Clone() );
for( BOARD_ITEM* item : GraphicalItems() )
{
if( item->Type() == PCB_FP_SHAPE_T )
shape->AddShape( item->GetEffectiveShape( aLayer )->Clone() );
shape->AddShape( item->GetEffectiveShape( aLayer, aFlash )->Clone() );
}
return shape;

3
pcbnew/footprint.h

@ -700,7 +700,8 @@ public:
*/
void BuildPolyCourtyards( OUTLINE_ERROR_HANDLER* aErrorHandler = nullptr );
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) const override;
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
FLASHING aFlash = FLASHING::DEFAULT ) const override;
virtual void SwapData( BOARD_ITEM* aImage ) override;

2
pcbnew/fp_text.cpp

@ -438,7 +438,7 @@ wxString FP_TEXT::GetShownText( int aDepth ) const
}
std::shared_ptr<SHAPE> FP_TEXT::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
std::shared_ptr<SHAPE> FP_TEXT::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
{
return GetEffectiveTextShape();
}

3
pcbnew/fp_text.h

@ -169,7 +169,8 @@ public:
int aError, ERROR_LOC aErrorLoc ) const;
// @copydoc BOARD_ITEM::GetEffectiveShape
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) const override;
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
FLASHING aFlash = FLASHING::DEFAULT ) const override;
wxString GetClass() const override
{

2
pcbnew/fp_textbox.cpp

@ -323,7 +323,7 @@ wxString FP_TEXTBOX::GetShownText( int aDepth ) const
}
std::shared_ptr<SHAPE> FP_TEXTBOX::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
std::shared_ptr<SHAPE> FP_TEXTBOX::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
{
return GetEffectiveTextShape();
}

3
pcbnew/fp_textbox.h

@ -111,7 +111,8 @@ public:
int aError, ERROR_LOC aErrorLoc ) const;
// @copydoc BOARD_ITEM::GetEffectiveShape
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) const override;
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
FLASHING aFlash = FLASHING::DEFAULT ) const override;
wxString GetClass() const override
{

5
pcbnew/pad.cpp

@ -325,9 +325,10 @@ const std::shared_ptr<SHAPE_POLY_SET>& PAD::GetEffectivePolygon() const
}
std::shared_ptr<SHAPE> PAD::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
std::shared_ptr<SHAPE> PAD::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
{
if( aLayer != UNDEFINED_LAYER && !FlashLayer( aLayer ) )
if( ( GetAttribute() == PAD_ATTRIB::PTH && aFlash == FLASHING::NEVER_FLASHED )
|| ( aLayer != UNDEFINED_LAYER && !FlashLayer( aLayer ) ) )
{
if( GetAttribute() == PAD_ATTRIB::PTH )
{

3
pcbnew/pad.h

@ -424,7 +424,8 @@ public:
int aError, ERROR_LOC aErrorLoc ) const;
// @copydoc BOARD_ITEM::GetEffectiveShape
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) const override;
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
FLASHING aFlash = FLASHING::DEFAULT ) const override;
const std::shared_ptr<SHAPE_POLY_SET>& GetEffectivePolygon() const;

2
pcbnew/pcb_dimension.cpp

@ -338,7 +338,7 @@ void PCB_DIMENSION_BASE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame,
}
std::shared_ptr<SHAPE> PCB_DIMENSION_BASE::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
std::shared_ptr<SHAPE> PCB_DIMENSION_BASE::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
{
std::shared_ptr<SHAPE_COMPOUND> effectiveShape = std::make_shared<SHAPE_COMPOUND>();

3
pcbnew/pcb_dimension.h

@ -242,7 +242,8 @@ public:
const EDA_RECT GetBoundingBox() const override;
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer ) const override;
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer,
FLASHING aFlash = FLASHING::DEFAULT ) const override;
wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;

2
pcbnew/pcb_marker.cpp

@ -176,7 +176,7 @@ void PCB_MARKER::Flip( const VECTOR2I& aCentre, bool aFlipLeftRight )
}
std::shared_ptr<SHAPE> PCB_MARKER::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
std::shared_ptr<SHAPE> PCB_MARKER::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
{
// Markers do not participate in the board geometry space, and therefore have no
// effectiven shape.

3
pcbnew/pcb_marker.h

@ -88,7 +88,8 @@ public:
GAL_LAYER_ID GetColorLayer() const;
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer ) const override;
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer,
FLASHING aFlash = FLASHING::DEFAULT ) const override;
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;

2
pcbnew/pcb_shape.cpp

@ -241,7 +241,7 @@ const BOX2I PCB_SHAPE::ViewBBox() const
}
std::shared_ptr<SHAPE> PCB_SHAPE::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
std::shared_ptr<SHAPE> PCB_SHAPE::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
{
return std::make_shared<SHAPE_COMPOUND>( MakeEffectiveShapes() );
}

3
pcbnew/pcb_shape.h

@ -105,7 +105,8 @@ public:
/**
* Make a set of SHAPE objects representing the PCB_SHAPE. Caller owns the objects.
*/
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) const override;
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
FLASHING aFlash = FLASHING::DEFAULT ) const override;
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;

2
pcbnew/pcb_target.cpp

@ -113,7 +113,7 @@ const EDA_RECT PCB_TARGET::GetBoundingBox() const
}
std::shared_ptr<SHAPE> PCB_TARGET::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
std::shared_ptr<SHAPE> PCB_TARGET::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
{
return std::make_shared<SHAPE_CIRCLE>( m_pos, m_size / 2 );
}

3
pcbnew/pcb_target.h

@ -84,7 +84,8 @@ public:
// Virtual function
const EDA_RECT GetBoundingBox() const override;
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer ) const override;
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer,
FLASHING aFlash = FLASHING::DEFAULT ) const override;
wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;

2
pcbnew/pcb_text.cpp

@ -233,7 +233,7 @@ void PCB_TEXT::SwapData( BOARD_ITEM* aImage )
}
std::shared_ptr<SHAPE> PCB_TEXT::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
std::shared_ptr<SHAPE> PCB_TEXT::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
{
return GetEffectiveTextShape();
}

3
pcbnew/pcb_text.h

@ -133,7 +133,8 @@ public:
bool aIgnoreLineWidth = false ) const override;
// @copydoc BOARD_ITEM::GetEffectiveShape
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) const override;
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
FLASHING aFlash = FLASHING::DEFAULT ) const override;
wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;

4
pcbnew/pcb_textbox.cpp

@ -295,10 +295,10 @@ void PCB_TEXTBOX::SwapData( BOARD_ITEM* aImage )
}
std::shared_ptr<SHAPE> PCB_TEXTBOX::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
std::shared_ptr<SHAPE> PCB_TEXTBOX::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
{
if( PCB_SHAPE::GetStroke().GetWidth() >= 0 )
return PCB_SHAPE::GetEffectiveShape( aLayer );
return PCB_SHAPE::GetEffectiveShape( aLayer, aFlash );
else
return GetEffectiveTextShape();
}

3
pcbnew/pcb_textbox.h

@ -112,7 +112,8 @@ public:
bool aIgnoreLineWidth = false ) const override;
// @copydoc BOARD_ITEM::GetEffectiveShape
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) const override;
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
FLASHING aFlash = FLASHING::DEFAULT ) const override;
wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;

9
pcbnew/pcb_track.cpp

@ -1060,15 +1060,16 @@ bool PCB_TRACK::cmp_tracks::operator() ( const PCB_TRACK* a, const PCB_TRACK* b
}
std::shared_ptr<SHAPE> PCB_TRACK::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
std::shared_ptr<SHAPE> PCB_TRACK::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
{
return std::make_shared<SHAPE_SEGMENT>( m_Start, m_End, m_Width );
}
std::shared_ptr<SHAPE> PCB_VIA::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
std::shared_ptr<SHAPE> PCB_VIA::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
{
if( FlashLayer( aLayer ) )
if( aFlash == FLASHING::ALWAYS_FLASHED
|| ( aFlash == FLASHING::DEFAULT && FlashLayer( aLayer ) ) )
{
return std::make_shared<SHAPE_CIRCLE>( m_Start, m_Width / 2 );
}
@ -1084,7 +1085,7 @@ std::shared_ptr<SHAPE> PCB_VIA::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
}
std::shared_ptr<SHAPE> PCB_ARC::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
std::shared_ptr<SHAPE> PCB_ARC::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
{
return std::make_shared<SHAPE_ARC>( GetStart(), GetMid(), GetEnd(), GetWidth() );
}

9
pcbnew/pcb_track.h

@ -149,7 +149,8 @@ public:
bool ignoreLineWidth = false ) const override;
// @copydoc BOARD_ITEM::GetEffectiveShape
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) const override;
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
FLASHING aFlash = FLASHING::DEFAULT ) const override;
/**
* Function IsPointOnEnds
@ -295,7 +296,8 @@ public:
}
// @copydoc BOARD_ITEM::GetEffectiveShape
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) const override;
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
FLASHING aFlash = FLASHING::DEFAULT ) const override;
/**
* Function GetLength
@ -490,7 +492,8 @@ public:
void SwapData( BOARD_ITEM* aImage ) override;
// @copydoc BOARD_ITEM::GetEffectiveShape
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) const override;
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
FLASHING aFlash = FLASHING::DEFAULT ) const override;
protected:
wxString layerMaskDescribe() const override;

2
pcbnew/zone.cpp

@ -1286,7 +1286,7 @@ double FP_ZONE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
}
std::shared_ptr<SHAPE> ZONE::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
std::shared_ptr<SHAPE> ZONE::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
{
std::shared_ptr<SHAPE> shape;

3
pcbnew/zone.h

@ -334,7 +334,8 @@ public:
// @copydoc BOARD_ITEM::GetEffectiveShape
virtual std::shared_ptr<SHAPE>
GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) const override;
GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
FLASHING aFlash = FLASHING::DEFAULT ) const override;
/**
* Test if a point is near an outline edge or a corner of this zone.

Loading…
Cancel
Save