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;
|
||||
|
||||
|
||||
BOARD_COMMIT::BOARD_COMMIT( PCB_TOOL_BASE* aTool )
|
||||
BOARD_COMMIT::BOARD_COMMIT( PCB_TOOL_BASE* aTool ) :
|
||||
m_resolveNetConflicts( false )
|
||||
{
|
||||
m_toolMgr = aTool->GetManager();
|
||||
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_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();
|
||||
|
||||
if( m_resolveNetConflicts )
|
||||
connectivity->PropagateNets( this, PROPAGATE_MODE::RESOLVE_CONFLICTS );
|
||||
|
||||
connectivity->RecalculateRatsnest( this );
|
||||
connectivity->ClearDynamicRatsnest();
|
||||
frame->GetCanvas()->RedrawRatsnest();
|
||||
|
|
|
@ -51,12 +51,23 @@ public:
|
|||
COMMIT& Stage(
|
||||
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:
|
||||
virtual EDA_ITEM* parentObject( EDA_ITEM* aItem ) const override;
|
||||
|
||||
private:
|
||||
TOOL_MANAGER* m_toolMgr;
|
||||
bool m_isFootprintEditor;
|
||||
bool m_resolveNetConflicts;
|
||||
};
|
||||
|
||||
#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 )
|
||||
{
|
||||
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(),
|
||||
(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 );
|
||||
propagateConnections( aCommit );
|
||||
propagateConnections( aCommit, aMode );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -168,7 +168,8 @@ private:
|
|||
|
||||
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>
|
||||
void add( Container& c, BItem brditem )
|
||||
|
@ -239,8 +240,10 @@ public:
|
|||
/**
|
||||
* Propagates nets from pads to other items in clusters
|
||||
* @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 );
|
||||
|
||||
|
|
|
@ -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,
|
||||
std::vector<KICAD_T> aTypes ) const
|
||||
{
|
||||
|
|
|
@ -82,6 +82,15 @@ struct RN_DYNAMIC_LINE
|
|||
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
|
||||
class CONNECTIVITY_DATA
|
||||
{
|
||||
|
@ -155,10 +164,12 @@ public:
|
|||
RN_NET* GetRatsnestForNet( int aNet );
|
||||
|
||||
/**
|
||||
* Function PropagateNets()
|
||||
* 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 );
|
||||
|
||||
|
@ -202,10 +213,10 @@ public:
|
|||
* @param aItem is the reference item to find other connected items.
|
||||
* @param aAnchor is the position to find connected items on.
|
||||
* @param aTypes allows one to filter by item types.
|
||||
* @return
|
||||
* @return
|
||||
*/
|
||||
const std::vector<BOARD_CONNECTED_ITEM*> GetConnectedItemsAtAnchor( const BOARD_CONNECTED_ITEM* aItem,
|
||||
const VECTOR2I& aAnchor,
|
||||
const VECTOR2I& aAnchor,
|
||||
const KICAD_T aTypes[] ) 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_commit.SetResolveNetConflicts();
|
||||
m_commit.Push( _( "Update netlist" ) );
|
||||
|
||||
m_board->SynchronizeNetsAndNetClasses();
|
||||
|
|
Loading…
Reference in New Issue