Incremental schematic connectivity fixes.

(cherry picked from commit 2cfb7a5310)
This commit is contained in:
Wayne Stambaugh 2024-01-21 16:53:05 +00:00
parent c855702918
commit 1d880cdcf6
4 changed files with 84 additions and 16 deletions

View File

@ -51,6 +51,7 @@
#include <sch_painter.h>
#include <sch_sheet.h>
#include <sch_marker.h>
#include <sch_sheet_pin.h>
#include <schematic.h>
#include <settings/settings_manager.h>
#include <advanced_config.h>
@ -1502,37 +1503,48 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags )
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 )
{
for( SCH_ITEM* item : GetScreen()->Items().Overlapping(pt ) )
{
if( !item->IsConnectable() )
continue;
if( SCH_LINE* line = dyn_cast<SCH_LINE*>( item ) )
if( item->Type() == SCH_LINE_T )
{
if( line->HitTest( pt ) )
{
if( item->HitTest( pt ) )
changed_items.insert( item );
}
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 );
continue;
}
}
if( SCH_SYMBOL* sym = dyn_cast<SCH_SYMBOL*>( item ) )
@ -1548,8 +1560,7 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags )
}
std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> all_items =
Schematic().ConnectionGraph()->ExtractAffectedItems(
changed_items );
Schematic().ConnectionGraph()->ExtractAffectedItems( changed_items );
all_items.insert( item_paths.begin(), item_paths.end() );

View File

@ -1318,3 +1318,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

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

View File

@ -1483,10 +1483,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 );
}
@ -1494,6 +1509,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 );
@ -1704,6 +1731,13 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
EDA_ITEM* item = loadedItems[i];
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 );
@ -1742,7 +1776,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& instance : pasteInstances )
{
@ -1828,7 +1865,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.