Mark the colliding shape so we know which one to highlight.

Also checks the nets when checking for a pad being flashed on a particular
layer (so we don't end up thinking the currently-routing-collided track
is a connection).
This commit is contained in:
Jeff Young 2020-10-05 20:54:12 +01:00
parent 8f870e87d6
commit 6d50c9749c
11 changed files with 77 additions and 49 deletions

View File

@ -347,15 +347,25 @@ bool CONNECTIVITY_DATA::IsConnectedOnLayer( const BOARD_CONNECTED_ITEM *aItem, i
{
CN_CONNECTIVITY_ALGO::ITEM_MAP_ENTRY &entry = m_connAlgo->ItemEntry( aItem );
for( auto citem : entry.GetItems() )
auto matchType = [&]( KICAD_T aItemType )
{
for( auto connected : citem->ConnectedItems() )
if( aTypes.empty() )
return true;
return std::count( aTypes.begin(), aTypes.end(), aItemType ) > 0;
};
for( CN_ITEM* citem : entry.GetItems() )
{
for( CN_ITEM* connected : citem->ConnectedItems() )
{
if( connected->Valid() && connected->Layers().Overlaps( aLayer )
&& ( aTypes.empty()
|| std::count( aTypes.begin(), aTypes.end(),
connected->Parent()->Type() ) > 0 ) )
if( connected->Valid()
&& connected->Layers().Overlaps( aLayer )
&& connected->Net() == aItem->GetNetCode()
&& matchType( connected->Parent()->Type() ) )
{
return true;
}
}
}

View File

@ -37,11 +37,15 @@ void INDEX::Add( ITEM* aItem )
if( !ROUTER::GetInstance()->GetInterface()->IsOnLayer( aItem, i ) )
{
if( aItem->AlternateShape() )
{
m_subIndices[i].Add( aItem, aItem->AlternateShape()->BBox() );
}
else
{
wxLogError( "Missing expected Alternate shape for %s at %d %d",
aItem->Parent()->GetClass(), aItem->Anchor( 0 ).x, aItem->Anchor( 0 ).y );
aItem->Parent()->GetClass(),
aItem->Anchor( 0 ).x,
aItem->Anchor( 0 ).y );
m_subIndices[i].Add( aItem );
}

View File

@ -31,8 +31,9 @@ namespace PNS {
bool ITEM::collideSimple( const ITEM* aOther, int aClearance, bool aNeedMTV, VECTOR2I* aMTV,
const NODE* aParentNode, bool aDifferentNetsOnly ) const
{
const SHAPE* shapeA = Shape();
const SHAPE* shapeB = aOther->Shape();
const ROUTER_IFACE* iface = ROUTER::GetInstance()->GetInterface();
const SHAPE* shapeA = Shape();
const SHAPE* shapeB = aOther->Shape();
// same nets? no collision!
if( aDifferentNetsOnly && m_net == aOther->m_net && m_net >= 0 && aOther->m_net >= 0 )
@ -42,26 +43,36 @@ bool ITEM::collideSimple( const ITEM* aOther, int aClearance, bool aNeedMTV, VEC
if( !m_layers.Overlaps( aOther->m_layers ) )
return false;
if( !aOther->Layers().IsMultilayer()
&& !ROUTER::GetInstance()->GetInterface()->IsOnLayer( this, aOther->Layer() ) )
if( !aOther->Layers().IsMultilayer() && !iface->IsOnLayer( this, aOther->Layer() ) )
{
if( !AlternateShape() )
wxLogError
( "Missing expected Alternate shape for %s at %d %d", m_parent->GetClass(),
Anchor( 0 ).x, Anchor( 0 ).y );
{
wxLogError( "Missing expected Alternate shape for %s at %d %d",
m_parent->GetClass(),
Anchor( 0 ).x,
Anchor( 0 ).y );
}
else
{
shapeA = AlternateShape();
Mark( MK_ALT_SHAPE );
}
}
if( !Layers().IsMultilayer()
&& !ROUTER::GetInstance()->GetInterface()->IsOnLayer( aOther, Layer() ) )
if( !Layers().IsMultilayer() && !iface->IsOnLayer( aOther, Layer() ) )
{
if( !aOther->AlternateShape() )
wxLogError
( "Missing expected Alternate shape for %s at %d %d", aOther->Parent()->GetClass(),
aOther->Anchor( 0 ).x, aOther->Anchor( 0 ).y );
{
wxLogError( "Missing expected Alternate shape for %s at %d %d",
aOther->Parent()->GetClass(),
aOther->Anchor( 0 ).x,
aOther->Anchor( 0 ).y );
}
else
{
shapeB = aOther->AlternateShape();
aOther->Mark( MK_ALT_SHAPE );
}
}
if( aNeedMTV )

View File

@ -40,7 +40,8 @@ enum LineMarker {
MK_HEAD = ( 1 << 0 ),
MK_VIOLATION = ( 1 << 3 ),
MK_LOCKED = ( 1 << 4 ),
MK_DP_COUPLED = ( 1 << 5 )
MK_DP_COUPLED = ( 1 << 5 ),
MK_ALT_SHAPE = ( 1 << 6 )
};
@ -221,8 +222,8 @@ public:
return Shape();
}
virtual void Mark( int aMarker ) { m_marker = aMarker; }
virtual void Unmark( int aMarker = -1 ) { m_marker &= ~aMarker; }
virtual void Mark( int aMarker ) const { m_marker |= aMarker; }
virtual void Unmark( int aMarker = -1 ) const { m_marker &= ~aMarker; }
virtual int Marker() const { return m_marker; }
virtual void SetRank( int aRank ) { m_rank = aRank; }
@ -259,7 +260,7 @@ protected:
bool m_movable;
int m_net;
int m_marker;
mutable int m_marker;
int m_rank;
bool m_routable;
};

View File

@ -583,9 +583,9 @@ std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE_BASE::syncPad( D_PAD* aPad )
switch( aPad->GetAttribute() )
{
case PAD_ATTRIB_PTH:
case PAD_ATTRIB_NPTH:
break;
case PAD_ATTRIB_NPTH:
case PAD_ATTRIB_CONN:
case PAD_ATTRIB_SMD:
{
@ -605,8 +605,7 @@ std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE_BASE::syncPad( D_PAD* aPad )
}
}
/// Keep the NPTH pads because we will use the drill as alternate shape
if( !is_copper && aPad->GetAttribute() != PAD_ATTRIB_NPTH )
if( !is_copper )
return NULL;
}
break;
@ -865,7 +864,7 @@ void PNS_KICAD_IFACE_BASE::SetBoard( BOARD* aBoard )
}
bool PNS_KICAD_IFACE::IsAnyLayerVisible( const LAYER_RANGE& aLayer )
bool PNS_KICAD_IFACE::IsAnyLayerVisible( const LAYER_RANGE& aLayer ) const
{
if( !m_view )
return false;
@ -878,7 +877,7 @@ bool PNS_KICAD_IFACE::IsAnyLayerVisible( const LAYER_RANGE& aLayer )
}
bool PNS_KICAD_IFACE::IsOnLayer( const PNS::ITEM* aItem, int aLayer )
bool PNS_KICAD_IFACE::IsOnLayer( const PNS::ITEM* aItem, int aLayer ) const
{
/// Default is all layers
if( aLayer < 0 )
@ -911,7 +910,7 @@ bool PNS_KICAD_IFACE::IsOnLayer( const PNS::ITEM* aItem, int aLayer )
}
bool PNS_KICAD_IFACE::IsItemVisible( const PNS::ITEM* aItem )
bool PNS_KICAD_IFACE::IsItemVisible( const PNS::ITEM* aItem ) const
{
// by default, all items are visible (new ones created by the router have parent == NULL as they have not been
// committed yet to the BOARD)
@ -984,9 +983,9 @@ void PNS_KICAD_IFACE_BASE::SyncWorld( PNS::NODE *aWorld )
for( MODULE* module : m_board->Modules() )
{
for( auto pad : module->Pads() )
for( D_PAD* pad : module->Pads() )
{
if( auto solid = syncPad( pad ) )
if( std::unique_ptr<PNS::SOLID> solid = syncPad( pad ) )
aWorld->Add( std::move( solid ) );
worstPadClearance = std::max( worstPadClearance, pad->GetLocalClearance() );

View File

@ -52,9 +52,9 @@ public:
void EraseView() override {};
void SetBoard( BOARD* aBoard );
void SyncWorld( PNS::NODE* aWorld ) override;
bool IsAnyLayerVisible( const LAYER_RANGE& aLayer ) override { return true; };
bool IsOnLayer( const PNS::ITEM* aItem, int aLayer ) override { return true; };
bool IsItemVisible( const PNS::ITEM* aItem ) override { return true; }
bool IsAnyLayerVisible( const LAYER_RANGE& aLayer ) const override { return true; };
bool IsOnLayer( const PNS::ITEM* aItem, int aLayer ) const override { return true; };
bool IsItemVisible( const PNS::ITEM* aItem ) const override { return true; }
void HideItem( PNS::ITEM* aItem ) override {}
void DisplayItem( const PNS::ITEM* aItem, int aColor = 0, int aClearance = 0, bool aEdit = false ) override {}
void AddItem( PNS::ITEM* aItem ) override;
@ -104,9 +104,9 @@ public:
void SetView( KIGFX::VIEW* aView );
void EraseView() override;
bool IsAnyLayerVisible( const LAYER_RANGE& aLayer ) override;
bool IsItemVisible( const PNS::ITEM* aItem ) override;
bool IsOnLayer( const PNS::ITEM* aItem, int aLayer ) override;
bool IsAnyLayerVisible( const LAYER_RANGE& aLayer ) const override;
bool IsItemVisible( const PNS::ITEM* aItem ) const override;
bool IsOnLayer( const PNS::ITEM* aItem, int aLayer ) const override;
void HideItem( PNS::ITEM* aItem ) override;
void DisplayItem( const PNS::ITEM* aItem, int aColor = 0, int aClearance = 0, bool aEdit = false ) override;
void Commit() override;

View File

@ -85,19 +85,19 @@ LINE* LINE::Clone() const
}
void LINE::Mark( int aMarker )
void LINE::Mark( int aMarker ) const
{
m_marker = aMarker;
for( auto s : m_links )
for( const LINKED_ITEM* s : m_links )
s->Mark( aMarker );
}
void LINE::Unmark( int aMarker )
void LINE::Unmark( int aMarker ) const
{
for( auto s : m_links )
for( const LINKED_ITEM* s : m_links )
s->Unmark( aMarker );
m_marker = 0;

View File

@ -238,8 +238,8 @@ public:
const VIA& Via() const { return m_via; }
virtual void Mark( int aMarker ) override;
virtual void Unmark( int aMarker = -1 ) override;
virtual void Mark( int aMarker ) const override;
virtual void Unmark( int aMarker = -1 ) const override;
virtual int Marker() const override;
void DragSegment( const VECTOR2I& aP, int aIndex, bool aFreeAngle = false );

View File

@ -412,11 +412,10 @@ public:
void AllItemsInNet( int aNet, std::set<ITEM*>& aItems, int aKindMask = -1 );
void ClearRanks( int aMarkerMask = MK_HEAD | MK_VIOLATION );
void ClearRanks( int aMarkerMask = MK_HEAD | MK_VIOLATION | MK_ALT_SHAPE );
void RemoveByMarker( int aMarker );
const ITEM_SET FindItemsByParent( const BOARD_CONNECTED_ITEM* aParent );
ITEM* FindItemByParent( const BOARD_CONNECTED_ITEM* aParent );
bool HasChildren() const

View File

@ -98,9 +98,9 @@ enum DRAG_MODE
virtual void SyncWorld( NODE* aNode ) = 0;
virtual void AddItem( ITEM* aItem ) = 0;
virtual void RemoveItem( ITEM* aItem ) = 0;
virtual bool IsAnyLayerVisible( const LAYER_RANGE& aLayer ) = 0;
virtual bool IsItemVisible( const PNS::ITEM* aItem ) = 0;
virtual bool IsOnLayer( const PNS::ITEM* aItem, int aLayer ) = 0;
virtual bool IsAnyLayerVisible( const LAYER_RANGE& aLayer ) const = 0;
virtual bool IsItemVisible( const PNS::ITEM* aItem ) const = 0;
virtual bool IsOnLayer( const PNS::ITEM* aItem, int aLayer ) const = 0;
virtual void DisplayItem( const ITEM* aItem, int aColor = -1, int aClearance = -1, bool aEdit = false ) = 0;
virtual void HideItem( ITEM* aItem ) = 0;
virtual void Commit() = 0;

View File

@ -85,7 +85,11 @@ void ROUTER_PREVIEW_ITEM::Update( const PNS::ITEM* aItem )
m_color = getLayerColor( m_originLayer );
m_color.a = 0.8;
m_depth = BaseOverlayDepth - aItem->Layers().Start();
m_shape = aItem->Shape()->Clone();
if( ( aItem->Marker() & PNS::MK_ALT_SHAPE ) && aItem->AlternateShape() )
m_shape = aItem->AlternateShape()->Clone();
else
m_shape = aItem->Shape()->Clone();
switch( aItem->Kind() )
{