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:
parent
8f870e87d6
commit
6d50c9749c
|
@ -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 );
|
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 )
|
if( connected->Valid()
|
||||||
&& ( aTypes.empty()
|
&& connected->Layers().Overlaps( aLayer )
|
||||||
|| std::count( aTypes.begin(), aTypes.end(),
|
&& connected->Net() == aItem->GetNetCode()
|
||||||
connected->Parent()->Type() ) > 0 ) )
|
&& matchType( connected->Parent()->Type() ) )
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,11 +37,15 @@ void INDEX::Add( ITEM* aItem )
|
||||||
if( !ROUTER::GetInstance()->GetInterface()->IsOnLayer( aItem, i ) )
|
if( !ROUTER::GetInstance()->GetInterface()->IsOnLayer( aItem, i ) )
|
||||||
{
|
{
|
||||||
if( aItem->AlternateShape() )
|
if( aItem->AlternateShape() )
|
||||||
|
{
|
||||||
m_subIndices[i].Add( aItem, aItem->AlternateShape()->BBox() );
|
m_subIndices[i].Add( aItem, aItem->AlternateShape()->BBox() );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wxLogError( "Missing expected Alternate shape for %s at %d %d",
|
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 );
|
m_subIndices[i].Add( aItem );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,9 @@ namespace PNS {
|
||||||
bool ITEM::collideSimple( const ITEM* aOther, int aClearance, bool aNeedMTV, VECTOR2I* aMTV,
|
bool ITEM::collideSimple( const ITEM* aOther, int aClearance, bool aNeedMTV, VECTOR2I* aMTV,
|
||||||
const NODE* aParentNode, bool aDifferentNetsOnly ) const
|
const NODE* aParentNode, bool aDifferentNetsOnly ) const
|
||||||
{
|
{
|
||||||
const SHAPE* shapeA = Shape();
|
const ROUTER_IFACE* iface = ROUTER::GetInstance()->GetInterface();
|
||||||
const SHAPE* shapeB = aOther->Shape();
|
const SHAPE* shapeA = Shape();
|
||||||
|
const SHAPE* shapeB = aOther->Shape();
|
||||||
|
|
||||||
// same nets? no collision!
|
// same nets? no collision!
|
||||||
if( aDifferentNetsOnly && m_net == aOther->m_net && m_net >= 0 && aOther->m_net >= 0 )
|
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 ) )
|
if( !m_layers.Overlaps( aOther->m_layers ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if( !aOther->Layers().IsMultilayer()
|
if( !aOther->Layers().IsMultilayer() && !iface->IsOnLayer( this, aOther->Layer() ) )
|
||||||
&& !ROUTER::GetInstance()->GetInterface()->IsOnLayer( this, aOther->Layer() ) )
|
|
||||||
{
|
{
|
||||||
if( !AlternateShape() )
|
if( !AlternateShape() )
|
||||||
wxLogError
|
{
|
||||||
( "Missing expected Alternate shape for %s at %d %d", m_parent->GetClass(),
|
wxLogError( "Missing expected Alternate shape for %s at %d %d",
|
||||||
Anchor( 0 ).x, Anchor( 0 ).y );
|
m_parent->GetClass(),
|
||||||
|
Anchor( 0 ).x,
|
||||||
|
Anchor( 0 ).y );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
shapeA = AlternateShape();
|
shapeA = AlternateShape();
|
||||||
|
Mark( MK_ALT_SHAPE );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !Layers().IsMultilayer()
|
if( !Layers().IsMultilayer() && !iface->IsOnLayer( aOther, Layer() ) )
|
||||||
&& !ROUTER::GetInstance()->GetInterface()->IsOnLayer( aOther, Layer() ) )
|
|
||||||
{
|
{
|
||||||
if( !aOther->AlternateShape() )
|
if( !aOther->AlternateShape() )
|
||||||
wxLogError
|
{
|
||||||
( "Missing expected Alternate shape for %s at %d %d", aOther->Parent()->GetClass(),
|
wxLogError( "Missing expected Alternate shape for %s at %d %d",
|
||||||
aOther->Anchor( 0 ).x, aOther->Anchor( 0 ).y );
|
aOther->Parent()->GetClass(),
|
||||||
|
aOther->Anchor( 0 ).x,
|
||||||
|
aOther->Anchor( 0 ).y );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
shapeB = aOther->AlternateShape();
|
shapeB = aOther->AlternateShape();
|
||||||
|
aOther->Mark( MK_ALT_SHAPE );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( aNeedMTV )
|
if( aNeedMTV )
|
||||||
|
|
|
@ -40,7 +40,8 @@ enum LineMarker {
|
||||||
MK_HEAD = ( 1 << 0 ),
|
MK_HEAD = ( 1 << 0 ),
|
||||||
MK_VIOLATION = ( 1 << 3 ),
|
MK_VIOLATION = ( 1 << 3 ),
|
||||||
MK_LOCKED = ( 1 << 4 ),
|
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();
|
return Shape();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Mark( int aMarker ) { m_marker = aMarker; }
|
virtual void Mark( int aMarker ) const { m_marker |= aMarker; }
|
||||||
virtual void Unmark( int aMarker = -1 ) { m_marker &= ~aMarker; }
|
virtual void Unmark( int aMarker = -1 ) const { m_marker &= ~aMarker; }
|
||||||
virtual int Marker() const { return m_marker; }
|
virtual int Marker() const { return m_marker; }
|
||||||
|
|
||||||
virtual void SetRank( int aRank ) { m_rank = aRank; }
|
virtual void SetRank( int aRank ) { m_rank = aRank; }
|
||||||
|
@ -259,7 +260,7 @@ protected:
|
||||||
|
|
||||||
bool m_movable;
|
bool m_movable;
|
||||||
int m_net;
|
int m_net;
|
||||||
int m_marker;
|
mutable int m_marker;
|
||||||
int m_rank;
|
int m_rank;
|
||||||
bool m_routable;
|
bool m_routable;
|
||||||
};
|
};
|
||||||
|
|
|
@ -583,9 +583,9 @@ std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE_BASE::syncPad( D_PAD* aPad )
|
||||||
switch( aPad->GetAttribute() )
|
switch( aPad->GetAttribute() )
|
||||||
{
|
{
|
||||||
case PAD_ATTRIB_PTH:
|
case PAD_ATTRIB_PTH:
|
||||||
|
case PAD_ATTRIB_NPTH:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PAD_ATTRIB_NPTH:
|
|
||||||
case PAD_ATTRIB_CONN:
|
case PAD_ATTRIB_CONN:
|
||||||
case PAD_ATTRIB_SMD:
|
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 )
|
||||||
if( !is_copper && aPad->GetAttribute() != PAD_ATTRIB_NPTH )
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
break;
|
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 )
|
if( !m_view )
|
||||||
return false;
|
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
|
/// Default is all layers
|
||||||
if( aLayer < 0 )
|
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
|
// 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)
|
// 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( 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 ) );
|
aWorld->Add( std::move( solid ) );
|
||||||
|
|
||||||
worstPadClearance = std::max( worstPadClearance, pad->GetLocalClearance() );
|
worstPadClearance = std::max( worstPadClearance, pad->GetLocalClearance() );
|
||||||
|
|
|
@ -52,9 +52,9 @@ public:
|
||||||
void EraseView() override {};
|
void EraseView() override {};
|
||||||
void SetBoard( BOARD* aBoard );
|
void SetBoard( BOARD* aBoard );
|
||||||
void SyncWorld( PNS::NODE* aWorld ) override;
|
void SyncWorld( PNS::NODE* aWorld ) override;
|
||||||
bool IsAnyLayerVisible( const LAYER_RANGE& aLayer ) override { return true; };
|
bool IsAnyLayerVisible( const LAYER_RANGE& aLayer ) const override { return true; };
|
||||||
bool IsOnLayer( const PNS::ITEM* aItem, int aLayer ) override { return true; };
|
bool IsOnLayer( const PNS::ITEM* aItem, int aLayer ) const override { return true; };
|
||||||
bool IsItemVisible( const PNS::ITEM* aItem ) override { return true; }
|
bool IsItemVisible( const PNS::ITEM* aItem ) const override { return true; }
|
||||||
void HideItem( PNS::ITEM* aItem ) override {}
|
void HideItem( PNS::ITEM* aItem ) override {}
|
||||||
void DisplayItem( const PNS::ITEM* aItem, int aColor = 0, int aClearance = 0, bool aEdit = false ) override {}
|
void DisplayItem( const PNS::ITEM* aItem, int aColor = 0, int aClearance = 0, bool aEdit = false ) override {}
|
||||||
void AddItem( PNS::ITEM* aItem ) override;
|
void AddItem( PNS::ITEM* aItem ) override;
|
||||||
|
@ -104,9 +104,9 @@ public:
|
||||||
|
|
||||||
void SetView( KIGFX::VIEW* aView );
|
void SetView( KIGFX::VIEW* aView );
|
||||||
void EraseView() override;
|
void EraseView() override;
|
||||||
bool IsAnyLayerVisible( const LAYER_RANGE& aLayer ) override;
|
bool IsAnyLayerVisible( const LAYER_RANGE& aLayer ) const override;
|
||||||
bool IsItemVisible( const PNS::ITEM* aItem ) override;
|
bool IsItemVisible( const PNS::ITEM* aItem ) const override;
|
||||||
bool IsOnLayer( const PNS::ITEM* aItem, int aLayer ) override;
|
bool IsOnLayer( const PNS::ITEM* aItem, int aLayer ) const override;
|
||||||
void HideItem( PNS::ITEM* aItem ) override;
|
void HideItem( PNS::ITEM* aItem ) override;
|
||||||
void DisplayItem( const PNS::ITEM* aItem, int aColor = 0, int aClearance = 0, bool aEdit = false ) override;
|
void DisplayItem( const PNS::ITEM* aItem, int aColor = 0, int aClearance = 0, bool aEdit = false ) override;
|
||||||
void Commit() override;
|
void Commit() override;
|
||||||
|
|
|
@ -85,19 +85,19 @@ LINE* LINE::Clone() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LINE::Mark( int aMarker )
|
void LINE::Mark( int aMarker ) const
|
||||||
{
|
{
|
||||||
m_marker = aMarker;
|
m_marker = aMarker;
|
||||||
|
|
||||||
for( auto s : m_links )
|
for( const LINKED_ITEM* s : m_links )
|
||||||
s->Mark( aMarker );
|
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 );
|
s->Unmark( aMarker );
|
||||||
|
|
||||||
m_marker = 0;
|
m_marker = 0;
|
||||||
|
|
|
@ -238,8 +238,8 @@ public:
|
||||||
|
|
||||||
const VIA& Via() const { return m_via; }
|
const VIA& Via() const { return m_via; }
|
||||||
|
|
||||||
virtual void Mark( int aMarker ) override;
|
virtual void Mark( int aMarker ) const override;
|
||||||
virtual void Unmark( int aMarker = -1 ) override;
|
virtual void Unmark( int aMarker = -1 ) const override;
|
||||||
virtual int Marker() const override;
|
virtual int Marker() const override;
|
||||||
|
|
||||||
void DragSegment( const VECTOR2I& aP, int aIndex, bool aFreeAngle = false );
|
void DragSegment( const VECTOR2I& aP, int aIndex, bool aFreeAngle = false );
|
||||||
|
|
|
@ -412,11 +412,10 @@ public:
|
||||||
|
|
||||||
void AllItemsInNet( int aNet, std::set<ITEM*>& aItems, int aKindMask = -1 );
|
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 );
|
void RemoveByMarker( int aMarker );
|
||||||
|
|
||||||
const ITEM_SET FindItemsByParent( const BOARD_CONNECTED_ITEM* aParent );
|
|
||||||
ITEM* FindItemByParent( const BOARD_CONNECTED_ITEM* aParent );
|
ITEM* FindItemByParent( const BOARD_CONNECTED_ITEM* aParent );
|
||||||
|
|
||||||
bool HasChildren() const
|
bool HasChildren() const
|
||||||
|
|
|
@ -98,9 +98,9 @@ enum DRAG_MODE
|
||||||
virtual void SyncWorld( NODE* aNode ) = 0;
|
virtual void SyncWorld( NODE* aNode ) = 0;
|
||||||
virtual void AddItem( ITEM* aItem ) = 0;
|
virtual void AddItem( ITEM* aItem ) = 0;
|
||||||
virtual void RemoveItem( ITEM* aItem ) = 0;
|
virtual void RemoveItem( ITEM* aItem ) = 0;
|
||||||
virtual bool IsAnyLayerVisible( const LAYER_RANGE& aLayer ) = 0;
|
virtual bool IsAnyLayerVisible( const LAYER_RANGE& aLayer ) const = 0;
|
||||||
virtual bool IsItemVisible( const PNS::ITEM* aItem ) = 0;
|
virtual bool IsItemVisible( const PNS::ITEM* aItem ) const = 0;
|
||||||
virtual bool IsOnLayer( const PNS::ITEM* aItem, int aLayer ) = 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 DisplayItem( const ITEM* aItem, int aColor = -1, int aClearance = -1, bool aEdit = false ) = 0;
|
||||||
virtual void HideItem( ITEM* aItem ) = 0;
|
virtual void HideItem( ITEM* aItem ) = 0;
|
||||||
virtual void Commit() = 0;
|
virtual void Commit() = 0;
|
||||||
|
|
|
@ -85,7 +85,11 @@ void ROUTER_PREVIEW_ITEM::Update( const PNS::ITEM* aItem )
|
||||||
m_color = getLayerColor( m_originLayer );
|
m_color = getLayerColor( m_originLayer );
|
||||||
m_color.a = 0.8;
|
m_color.a = 0.8;
|
||||||
m_depth = BaseOverlayDepth - aItem->Layers().Start();
|
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() )
|
switch( aItem->Kind() )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue