Fix connectivity to only resolve conflicts on netlist load
Fixes https://gitlab.com/kicad/code/kicad/-/issues/8007
This commit is contained in:
parent
a94ce75c02
commit
f57dcf2a34
|
@ -37,14 +37,16 @@
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
|
|
||||||
|
|
||||||
BOARD_COMMIT::BOARD_COMMIT( PCB_TOOL_BASE* aTool )
|
BOARD_COMMIT::BOARD_COMMIT( PCB_TOOL_BASE* aTool ) :
|
||||||
|
m_resolveNetConflicts( false )
|
||||||
{
|
{
|
||||||
m_toolMgr = aTool->GetManager();
|
m_toolMgr = aTool->GetManager();
|
||||||
m_isFootprintEditor = aTool->IsFootprintEditor();
|
m_isFootprintEditor = aTool->IsFootprintEditor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOARD_COMMIT::BOARD_COMMIT( EDA_DRAW_FRAME* aFrame )
|
BOARD_COMMIT::BOARD_COMMIT( EDA_DRAW_FRAME* aFrame ) :
|
||||||
|
m_resolveNetConflicts( false )
|
||||||
{
|
{
|
||||||
m_toolMgr = aFrame->GetToolManager();
|
m_toolMgr = aFrame->GetToolManager();
|
||||||
m_isFootprintEditor = aFrame->IsType( FRAME_FOOTPRINT_EDITOR );
|
m_isFootprintEditor = aFrame->IsType( FRAME_FOOTPRINT_EDITOR );
|
||||||
|
@ -350,6 +352,9 @@ void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry, bool a
|
||||||
{
|
{
|
||||||
size_t num_changes = m_changes.size();
|
size_t num_changes = m_changes.size();
|
||||||
|
|
||||||
|
if( m_resolveNetConflicts )
|
||||||
|
connectivity->PropagateNets( this, PROPAGATE_MODE::RESOLVE_CONFLICTS );
|
||||||
|
|
||||||
connectivity->RecalculateRatsnest( this );
|
connectivity->RecalculateRatsnest( this );
|
||||||
connectivity->ClearDynamicRatsnest();
|
connectivity->ClearDynamicRatsnest();
|
||||||
frame->GetCanvas()->RedrawRatsnest();
|
frame->GetCanvas()->RedrawRatsnest();
|
||||||
|
|
|
@ -51,12 +51,23 @@ public:
|
||||||
COMMIT& Stage(
|
COMMIT& Stage(
|
||||||
const PICKED_ITEMS_LIST& aItems, UNDO_REDO aModFlag = UNDO_REDO::UNSPECIFIED ) override;
|
const PICKED_ITEMS_LIST& aItems, UNDO_REDO aModFlag = UNDO_REDO::UNSPECIFIED ) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a flag that will cause Push() to resolve net conflicts on track/via clusters instead
|
||||||
|
* of the default behavior which is to skip updating track/via clusters that have conflicts.
|
||||||
|
* This is used in the netlist updater to update any clusters that were changed due to pad nets
|
||||||
|
* changing, but should not be used for other changes as you typically don't want to change
|
||||||
|
* track/via nets due to temporary conflicts created by board editing operations.
|
||||||
|
* @param aResolve is true if this commit should resolve conflicting track/via net assignments
|
||||||
|
*/
|
||||||
|
void SetResolveNetConflicts( bool aResolve = true ) { m_resolveNetConflicts = aResolve; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual EDA_ITEM* parentObject( EDA_ITEM* aItem ) const override;
|
virtual EDA_ITEM* parentObject( EDA_ITEM* aItem ) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TOOL_MANAGER* m_toolMgr;
|
TOOL_MANAGER* m_toolMgr;
|
||||||
bool m_isFootprintEditor;
|
bool m_isFootprintEditor;
|
||||||
|
bool m_resolveNetConflicts;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -477,11 +477,19 @@ void CN_CONNECTIVITY_ALGO::Build( const std::vector<BOARD_ITEM*>& aItems )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CN_CONNECTIVITY_ALGO::propagateConnections( BOARD_COMMIT* aCommit )
|
void CN_CONNECTIVITY_ALGO::propagateConnections( BOARD_COMMIT* aCommit, PROPAGATE_MODE aMode )
|
||||||
{
|
{
|
||||||
|
bool skipConflicts = ( aMode == PROPAGATE_MODE::SKIP_CONFLICTS );
|
||||||
|
|
||||||
|
wxLogTrace( "CN", "propagateConnections: propagate skip conflicts? %d", skipConflicts );
|
||||||
|
|
||||||
for( const auto& cluster : m_connClusters )
|
for( const auto& cluster : m_connClusters )
|
||||||
{
|
{
|
||||||
if( cluster->IsOrphaned() )
|
if( skipConflicts && cluster->IsConflicting() )
|
||||||
|
{
|
||||||
|
wxLogTrace( "CN", "Conflicting nets in cluster %p; skipping update", cluster.get() );
|
||||||
|
}
|
||||||
|
else if( cluster->IsOrphaned() )
|
||||||
{
|
{
|
||||||
wxLogTrace( "CN", "Skipping orphaned cluster %p [net: %s]", cluster.get(),
|
wxLogTrace( "CN", "Skipping orphaned cluster %p [net: %s]", cluster.get(),
|
||||||
(const char*) cluster->OriginNetName().c_str() );
|
(const char*) cluster->OriginNetName().c_str() );
|
||||||
|
@ -531,10 +539,10 @@ void CN_CONNECTIVITY_ALGO::propagateConnections( BOARD_COMMIT* aCommit )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CN_CONNECTIVITY_ALGO::PropagateNets( BOARD_COMMIT* aCommit )
|
void CN_CONNECTIVITY_ALGO::PropagateNets( BOARD_COMMIT* aCommit, PROPAGATE_MODE aMode )
|
||||||
{
|
{
|
||||||
m_connClusters = SearchClusters( CSM_PROPAGATE );
|
m_connClusters = SearchClusters( CSM_PROPAGATE );
|
||||||
propagateConnections( aCommit );
|
propagateConnections( aCommit, aMode );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -168,7 +168,8 @@ private:
|
||||||
|
|
||||||
void searchConnections();
|
void searchConnections();
|
||||||
|
|
||||||
void propagateConnections( BOARD_COMMIT* aCommit = nullptr );
|
void propagateConnections( BOARD_COMMIT* aCommit = nullptr,
|
||||||
|
PROPAGATE_MODE aMode = PROPAGATE_MODE::SKIP_CONFLICTS );
|
||||||
|
|
||||||
template <class Container, class BItem>
|
template <class Container, class BItem>
|
||||||
void add( Container& c, BItem brditem )
|
void add( Container& c, BItem brditem )
|
||||||
|
@ -239,8 +240,10 @@ public:
|
||||||
/**
|
/**
|
||||||
* Propagates nets from pads to other items in clusters
|
* Propagates nets from pads to other items in clusters
|
||||||
* @param aCommit is used to store undo information for items modified by the call
|
* @param aCommit is used to store undo information for items modified by the call
|
||||||
|
* @param aMode controls how clusters with conflicting nets are resolved
|
||||||
*/
|
*/
|
||||||
void PropagateNets( BOARD_COMMIT* aCommit = nullptr );
|
void PropagateNets( BOARD_COMMIT* aCommit = nullptr,
|
||||||
|
PROPAGATE_MODE aMode = PROPAGATE_MODE::SKIP_CONFLICTS );
|
||||||
|
|
||||||
void FindIsolatedCopperIslands( ZONE* aZone, PCB_LAYER_ID aLayer, std::vector<int>& aIslands );
|
void FindIsolatedCopperIslands( ZONE* aZone, PCB_LAYER_ID aLayer, std::vector<int>& aIslands );
|
||||||
|
|
||||||
|
|
|
@ -339,11 +339,12 @@ void CONNECTIVITY_DATA::HideDynamicRatsnest()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CONNECTIVITY_DATA::PropagateNets()
|
void CONNECTIVITY_DATA::PropagateNets( BOARD_COMMIT* aCommit, PROPAGATE_MODE aMode )
|
||||||
{
|
{
|
||||||
m_connAlgo->PropagateNets();
|
m_connAlgo->PropagateNets( aCommit, aMode );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool CONNECTIVITY_DATA::IsConnectedOnLayer( const BOARD_CONNECTED_ITEM *aItem, int aLayer,
|
bool CONNECTIVITY_DATA::IsConnectedOnLayer( const BOARD_CONNECTED_ITEM *aItem, int aLayer,
|
||||||
std::vector<KICAD_T> aTypes ) const
|
std::vector<KICAD_T> aTypes ) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -82,6 +82,15 @@ struct RN_DYNAMIC_LINE
|
||||||
VECTOR2I a, b;
|
VECTOR2I a, b;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls how nets are propagated through clusters
|
||||||
|
*/
|
||||||
|
enum class PROPAGATE_MODE
|
||||||
|
{
|
||||||
|
SKIP_CONFLICTS, /// Clusters with conflicting drivers are not updated (default)
|
||||||
|
RESOLVE_CONFLICTS /// Clusters with conflicting drivers are updated to the most popular net
|
||||||
|
};
|
||||||
|
|
||||||
// a wrapper class encompassing the connectivity computation algorithm and the
|
// a wrapper class encompassing the connectivity computation algorithm and the
|
||||||
class CONNECTIVITY_DATA
|
class CONNECTIVITY_DATA
|
||||||
{
|
{
|
||||||
|
@ -155,10 +164,12 @@ public:
|
||||||
RN_NET* GetRatsnestForNet( int aNet );
|
RN_NET* GetRatsnestForNet( int aNet );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function PropagateNets()
|
|
||||||
* Propagates the net codes from the source pads to the tracks/vias.
|
* Propagates the net codes from the source pads to the tracks/vias.
|
||||||
|
* @param aCommit is used to save the undo state of items modified by this call
|
||||||
|
* @param aMode controls how conflicts between pads are resolved
|
||||||
*/
|
*/
|
||||||
void PropagateNets();
|
void PropagateNets( BOARD_COMMIT* aCommit = nullptr,
|
||||||
|
PROPAGATE_MODE aMode = PROPAGATE_MODE::SKIP_CONFLICTS );
|
||||||
|
|
||||||
bool CheckConnectivity( std::vector<CN_DISJOINT_NET_ENTRY>& aReport );
|
bool CheckConnectivity( std::vector<CN_DISJOINT_NET_ENTRY>& aReport );
|
||||||
|
|
||||||
|
@ -202,10 +213,10 @@ public:
|
||||||
* @param aItem is the reference item to find other connected items.
|
* @param aItem is the reference item to find other connected items.
|
||||||
* @param aAnchor is the position to find connected items on.
|
* @param aAnchor is the position to find connected items on.
|
||||||
* @param aTypes allows one to filter by item types.
|
* @param aTypes allows one to filter by item types.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
const std::vector<BOARD_CONNECTED_ITEM*> GetConnectedItemsAtAnchor( const BOARD_CONNECTED_ITEM* aItem,
|
const std::vector<BOARD_CONNECTED_ITEM*> GetConnectedItemsAtAnchor( const BOARD_CONNECTED_ITEM* aItem,
|
||||||
const VECTOR2I& aAnchor,
|
const VECTOR2I& aAnchor,
|
||||||
const KICAD_T aTypes[] ) const;
|
const KICAD_T aTypes[] ) const;
|
||||||
|
|
||||||
void GetUnconnectedEdges( std::vector<CN_EDGE>& aEdges ) const;
|
void GetUnconnectedEdges( std::vector<CN_EDGE>& aEdges ) const;
|
||||||
|
|
|
@ -1095,6 +1095,7 @@ bool BOARD_NETLIST_UPDATER::UpdateNetlist( NETLIST& aNetlist )
|
||||||
}
|
}
|
||||||
|
|
||||||
m_board->GetNetInfo().RemoveUnusedNets();
|
m_board->GetNetInfo().RemoveUnusedNets();
|
||||||
|
m_commit.SetResolveNetConflicts();
|
||||||
m_commit.Push( _( "Update netlist" ) );
|
m_commit.Push( _( "Update netlist" ) );
|
||||||
|
|
||||||
m_board->SynchronizeNetsAndNetClasses();
|
m_board->SynchronizeNetsAndNetClasses();
|
||||||
|
|
Loading…
Reference in New Issue