Incremental schematic connectivity fixes.

This commit is contained in:
Wayne Stambaugh 2024-01-21 16:53:05 +00:00
parent c2bd158194
commit 2cfb7a5310
6 changed files with 90 additions and 9 deletions

View File

@ -240,7 +240,7 @@ ADVANCED_CFG::ADVANCED_CFG()
m_Use3DConnexionDriver = true;
m_IncrementalConnectivity = false;
m_IncrementalConnectivity = true;
m_DisambiguationMenuDelay = 300;

View File

@ -183,6 +183,7 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
bool itemsDeselected = false;
bool selectedModified = false;
bool dirtyConnectivity = false;
SCH_CLEANUP_FLAGS connectivityCleanUp = NO_CLEANUP;
if( Empty() )
return;
@ -210,8 +211,18 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
selectedModified = true;
if( !( aCommitFlags & SKIP_CONNECTIVITY ) && schItem->IsConnectable() )
{
dirtyConnectivity = true;
// Do a local clean up if there are any connectable objects in the commit.
if( connectivityCleanUp == NO_CLEANUP )
connectivityCleanUp = LOCAL_CLEANUP;
// Do a full rebauild of the connectivity if there is a sheet in the commit.
if( schItem->Type() == SCH_SHEET_T )
connectivityCleanUp = GLOBAL_CLEANUP;
}
switch( changeType )
{
case CHT_ADD:
@ -327,7 +338,7 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
frame->SaveCopyInUndoList( undoList, UNDO_REDO::UNSPECIFIED, false, dirtyConnectivity );
if( dirtyConnectivity )
frame->RecalculateConnections( this, NO_CLEANUP );
frame->RecalculateConnections( this, connectivityCleanUp );
}
}

View File

@ -54,6 +54,7 @@
#include <sch_painter.h>
#include <sch_sheet.h>
#include <sch_marker.h>
#include <sch_sheet_pin.h>
#include <schematic.h>
#include <sch_commit.h>
#include <settings/settings_manager.h>
@ -1703,21 +1704,23 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_COMMIT* aCommit, SCH_CLEANUP_FL
for( unsigned ii = 0; ii < changed_list->GetCount(); ++ii )
{
EDA_ITEM* item = changed_list->GetPickedItem( ii );
SCH_ITEM* item = static_cast<SCH_ITEM*>( changed_list->GetPickedItem( ii ) );
if( !item || !IsEeschemaType( item->Type() ) )
wxCHECK2( item, continue );
// Ignore objects that are not connectable.
if( !item->IsConnectable() )
continue;
SCH_SCREEN* screen = static_cast<SCH_SCREEN*>( changed_list->GetScreenForItem( ii ) );
SCH_ITEM* sch_item = static_cast<SCH_ITEM*>( item );
SCH_SHEET_PATHS& paths = screen->GetClientSheetPaths();
std::vector<VECTOR2I> tmp_pts = sch_item->GetConnectionPoints();
std::vector<VECTOR2I> tmp_pts = item->GetConnectionPoints();
pts.insert( pts.end(), tmp_pts.begin(), tmp_pts.end() );
changed_items.insert( sch_item );
changed_items.insert( item );
for( SCH_SHEET_PATH& path : paths )
item_paths.insert( std::make_pair( path, sch_item ) );
item_paths.insert( std::make_pair( path, item ) );
}
for( VECTOR2I& pt: pts )
@ -1736,8 +1739,18 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_COMMIT* aCommit, SCH_CLEANUP_FL
changed_items.insert( pins.begin(), pins.end() );
}
else if( item->IsConnectable() )
else if( item->Type() == SCH_SHEET_T )
{
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
wxCHECK2( sheet, continue );
std::vector<SCH_SHEET_PIN*> sheetPins = sheet->GetPins();
changed_items.insert( sheetPins.begin(), sheetPins.end() );
}
else
{
// Non-connectable objects have already been pruned.
if( item->IsConnected( pt ) )
changed_items.insert( item );
}

View File

@ -1345,3 +1345,18 @@ bool SCH_SHEET_LIST::HasPath( const KIID_PATH& aPath ) const
return false;
}
bool SCH_SHEET_LIST::ContainsSheet( const SCH_SHEET* aSheet ) const
{
for( const SCH_SHEET_PATH& path : *this )
{
for( size_t i = 0; i < path.size(); i++ )
{
if( path.at( i ) == aSheet )
return true;
}
}
return false;
}

View File

@ -681,6 +681,8 @@ public:
bool HasPath( const KIID_PATH& aPath ) const;
bool ContainsSheet( const SCH_SHEET* aSheet ) const;
private:
SCH_SHEET_PATH m_currentSheetPath;
};

View File

@ -1485,10 +1485,25 @@ SCH_SHEET_PATH SCH_EDITOR_CONTROL::updatePastedSheet( const SCH_SHEET_PATH& aPas
for( SCH_ITEM* item : aSheet->GetScreen()->Items() )
{
if( item->IsConnectable() )
item->SetConnectivityDirty();
if( item->Type() == SCH_SYMBOL_T )
{
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
wxCHECK2( symbol, continue );
// Only do this once if the symbol is shared across multiple sheets.
if( !m_pastedSymbols.count( symbol ) )
{
for( SCH_PIN* pin : symbol->GetPins() )
{
const_cast<KIID&>( pin->m_Uuid ) = KIID();
pin->SetConnectivityDirty();
}
}
updatePastedSymbol( symbol, aSheet->GetScreen(), sheetPath, aClipPath,
aForceKeepAnnotations );
}
@ -1496,6 +1511,18 @@ SCH_SHEET_PATH SCH_EDITOR_CONTROL::updatePastedSheet( const SCH_SHEET_PATH& aPas
{
SCH_SHEET* subsheet = static_cast<SCH_SHEET*>( item );
wxCHECK2( subsheet, continue );
// Make sure pins get a new UUID and set the dirty connectivity flag.
if( !aPastedSheetsSoFar->ContainsSheet( subsheet ) )
{
for( SCH_SHEET_PIN* pin : subsheet->GetPins() )
{
const_cast<KIID&>( pin->m_Uuid ) = KIID();
pin->SetConnectivityDirty();
}
}
KIID_PATH newClipPath = aClipPath;
newClipPath.push_back( subsheet->m_Uuid );
@ -1721,6 +1748,13 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
{
KIID_PATH clipPath( wxT( "/" ) ); // clipboard is at root
SCH_ITEM* schItem = static_cast<SCH_ITEM*>( item );
wxCHECK2( schItem, continue );
if( schItem->IsConnectable() )
schItem->SetConnectivityDirty();
if( item->Type() == SCH_SYMBOL_T )
{
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
@ -1759,7 +1793,10 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
// Make sure pins get a new UUID
for( SCH_PIN* pin : symbol->GetPins() )
{
const_cast<KIID&>( pin->m_Uuid ) = KIID();
pin->SetConnectivityDirty();
}
for( SCH_SHEET_PATH& sheetPath : sheetPathsForScreen )
{
@ -1845,7 +1882,10 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
// Make sure pins get a new UUID
for( SCH_SHEET_PIN* pin : sheet->GetPins() )
{
const_cast<KIID&>( pin->m_Uuid ) = KIID();
pin->SetConnectivityDirty();
}
// Once we have our new KIID we can update all pasted instances. This will either
// reset the annotations or copy "kept" annotations from the supplementary clipboard.