Fixes for realtime connectivity being off.

Fixes https://gitlab.com/kicad/code/kicad/issues/9628
This commit is contained in:
Jeff Young 2021-11-24 13:19:50 +00:00
parent 9e999f4de4
commit 7fc04c3cf2
15 changed files with 253 additions and 94 deletions

View File

@ -46,7 +46,7 @@
#include <string_utils.h> #include <string_utils.h>
#include <wx/log.h> #include <wx/log.h>
#include <advanced_config.h> // for realtime connectivity switch #include <advanced_config.h> // for realtime connectivity switch in release builds
/* /*
@ -364,10 +364,7 @@ void CONNECTION_SUBGRAPH::UpdateItemConnections()
for( SCH_ITEM* item : m_items ) for( SCH_ITEM* item : m_items )
{ {
SCH_CONNECTION* item_conn = item->Connection( &m_sheet ); SCH_CONNECTION* item_conn = item->GetOrInitConnection( m_sheet, m_graph );
if( !item_conn )
item_conn = item->InitializeConnection( m_sheet, m_graph );
if( ( m_driver_connection->IsBus() && item_conn->IsNet() ) || if( ( m_driver_connection->IsBus() && item_conn->IsNet() ) ||
( m_driver_connection->IsNet() && item_conn->IsBus() ) ) ( m_driver_connection->IsNet() && item_conn->IsBus() ) )
@ -397,7 +394,7 @@ CONNECTION_SUBGRAPH::PRIORITY CONNECTION_SUBGRAPH::GetDriverPriority( SCH_ITEM*
case SCH_GLOBAL_LABEL_T: return PRIORITY::GLOBAL; case SCH_GLOBAL_LABEL_T: return PRIORITY::GLOBAL;
case SCH_PIN_T: case SCH_PIN_T:
{ {
auto sch_pin = static_cast<SCH_PIN*>( aDriver ); SCH_PIN* sch_pin = static_cast<SCH_PIN*>( aDriver );
if( sch_pin->IsPowerConnection() ) if( sch_pin->IsPowerConnection() )
return PRIORITY::POWER_PIN; return PRIORITY::POWER_PIN;
@ -543,7 +540,7 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
else else
{ {
m_items.emplace_back( item ); m_items.emplace_back( item );
auto conn = item->InitializeConnection( aSheet, this ); SCH_CONNECTION* conn = item->InitializeConnection( aSheet, this );
// Set bus/net property here so that the propagation code uses it // Set bus/net property here so that the propagation code uses it
switch( item->Type() ) switch( item->Type() )
@ -648,7 +645,7 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
for( auto test_it = primary_it + 1; test_it != connection_vec.end(); test_it++ ) for( auto test_it = primary_it + 1; test_it != connection_vec.end(); test_it++ )
{ {
auto test_item = *test_it; SCH_ITEM* test_item = *test_it;
if( connected_item != test_item && if( connected_item != test_item &&
connected_item->ConnectionPropagatesTo( test_item ) && connected_item->ConnectionPropagatesTo( test_item ) &&
@ -678,8 +675,8 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
if( !bus_entry->m_connected_bus_item ) if( !bus_entry->m_connected_bus_item )
{ {
auto screen = aSheet.LastScreen(); SCH_SCREEN* screen = aSheet.LastScreen();
auto bus = screen->GetBus( it.first ); SCH_LINE* bus = screen->GetBus( it.first );
if( bus ) if( bus )
bus_entry->m_connected_bus_item = bus; bus_entry->m_connected_bus_item = bus;
@ -721,8 +718,8 @@ void CONNECTION_GRAPH::buildConnectionGraph()
{ {
for( const auto& it : item->m_connection_map ) for( const auto& it : item->m_connection_map )
{ {
const auto sheet = it.first; const SCH_SHEET_PATH& sheet = it.first;
auto connection = it.second; SCH_CONNECTION* connection = it.second;
if( connection->SubgraphCode() == 0 ) if( connection->SubgraphCode() == 0 )
{ {
@ -741,10 +738,7 @@ void CONNECTION_GRAPH::buildConnectionGraph()
auto get_items = auto get_items =
[&]( SCH_ITEM* aItem ) -> bool [&]( SCH_ITEM* aItem ) -> bool
{ {
SCH_CONNECTION* conn = aItem->Connection( &sheet ); SCH_CONNECTION* conn = aItem->GetOrInitConnection( sheet, this );
if( !conn )
conn = aItem->InitializeConnection( sheet, this );
return ( conn->SubgraphCode() == 0 ); return ( conn->SubgraphCode() == 0 );
}; };
@ -907,7 +901,7 @@ void CONNECTION_GRAPH::buildConnectionGraph()
} }
case SCH_PIN_T: case SCH_PIN_T:
{ {
auto pin = static_cast<SCH_PIN*>( driver ); SCH_PIN* pin = static_cast<SCH_PIN*>( driver );
wxASSERT( pin->IsPowerConnection() ); wxASSERT( pin->IsPowerConnection() );
m_global_label_cache[name].push_back( subgraph ); m_global_label_cache[name].push_back( subgraph );
break; break;
@ -936,10 +930,7 @@ void CONNECTION_GRAPH::buildConnectionGraph()
continue; continue;
} }
SCH_CONNECTION* connection = pin->Connection( &sheet ); SCH_CONNECTION* connection = pin->GetOrInitConnection( sheet, this );
if( !connection )
connection = pin->InitializeConnection( sheet, this );
// If this pin already has a subgraph, don't need to process // If this pin already has a subgraph, don't need to process
if( connection->SubgraphCode() > 0 ) if( connection->SubgraphCode() > 0 )
@ -984,7 +975,7 @@ void CONNECTION_GRAPH::buildConnectionGraph()
// codes, merging subgraphs together that use label connections, etc. // codes, merging subgraphs together that use label connections, etc.
// Cache remaining valid subgraphs by sheet path // Cache remaining valid subgraphs by sheet path
for( auto subgraph : m_driver_subgraphs ) for( CONNECTION_SUBGRAPH* subgraph : m_driver_subgraphs )
m_sheet_to_subgraphs_map[ subgraph->m_sheet ].emplace_back( subgraph ); m_sheet_to_subgraphs_map[ subgraph->m_sheet ].emplace_back( subgraph );
std::unordered_set<CONNECTION_SUBGRAPH*> invalidated_subgraphs; std::unordered_set<CONNECTION_SUBGRAPH*> invalidated_subgraphs;
@ -2059,8 +2050,7 @@ std::vector<const CONNECTION_SUBGRAPH*> CONNECTION_GRAPH::GetBusesNeedingMigrati
if( !subgraph->m_driver ) if( !subgraph->m_driver )
continue; continue;
auto sheet = subgraph->m_sheet; SCH_CONNECTION* connection = subgraph->m_driver->Connection( &subgraph->m_sheet );
auto connection = subgraph->m_driver->Connection( &sheet );
if( !connection->IsBus() ) if( !connection->IsBus() )
continue; continue;

View File

@ -37,6 +37,8 @@
#include <netclass.h> #include <netclass.h>
#include <trigo.h> #include <trigo.h>
#include <board_item.h> #include <board_item.h>
#include <advanced_config.h>
#include <connection_graph.h>
#include "sch_painter.h" #include "sch_painter.h"
@ -63,6 +65,10 @@ SCH_BUS_WIRE_ENTRY::SCH_BUS_WIRE_ENTRY( const wxPoint& pos, bool aFlipY ) :
{ {
m_layer = LAYER_WIRE; m_layer = LAYER_WIRE;
m_connected_bus_item = nullptr; m_connected_bus_item = nullptr;
m_lastResolvedWidth = Mils2iu( DEFAULT_WIRE_WIDTH_MILS );
m_lastResolvedLineStyle = PLOT_DASH_TYPE::SOLID;
m_lastResolvedColor = COLOR4D::UNSPECIFIED;
} }
@ -80,6 +86,10 @@ SCH_BUS_WIRE_ENTRY::SCH_BUS_WIRE_ENTRY( const wxPoint& pos, int aQuadrant ) :
m_layer = LAYER_WIRE; m_layer = LAYER_WIRE;
m_connected_bus_item = nullptr; m_connected_bus_item = nullptr;
m_lastResolvedWidth = Mils2iu( DEFAULT_WIRE_WIDTH_MILS );
m_lastResolvedLineStyle = PLOT_DASH_TYPE::SOLID;
m_lastResolvedColor = COLOR4D::UNSPECIFIED;
} }
@ -89,6 +99,10 @@ SCH_BUS_BUS_ENTRY::SCH_BUS_BUS_ENTRY( const wxPoint& pos, bool aFlipY ) :
m_layer = LAYER_BUS; m_layer = LAYER_BUS;
m_connected_bus_items[0] = nullptr; m_connected_bus_items[0] = nullptr;
m_connected_bus_items[1] = nullptr; m_connected_bus_items[1] = nullptr;
m_lastResolvedWidth = Mils2iu( DEFAULT_WIRE_WIDTH_MILS );
m_lastResolvedLineStyle = PLOT_DASH_TYPE::SOLID;
m_lastResolvedColor = COLOR4D::UNSPECIFIED;
} }
@ -124,6 +138,10 @@ void SCH_BUS_ENTRY_BASE::SwapData( SCH_ITEM* aItem )
std::swap( m_pos, item->m_pos ); std::swap( m_pos, item->m_pos );
std::swap( m_size, item->m_size ); std::swap( m_size, item->m_size );
std::swap( m_stroke, item->m_stroke ); std::swap( m_stroke, item->m_stroke );
std::swap( m_lastResolvedWidth, item->m_lastResolvedWidth );
std::swap( m_lastResolvedLineStyle, item->m_lastResolvedLineStyle );
std::swap( m_lastResolvedColor, item->m_lastResolvedColor );
} }
@ -151,57 +169,87 @@ const EDA_RECT SCH_BUS_ENTRY_BASE::GetBoundingBox() const
COLOR4D SCH_BUS_ENTRY_BASE::GetStrokeColor() const COLOR4D SCH_BUS_ENTRY_BASE::GetStrokeColor() const
{ {
NETCLASSPTR netclass = NetClass(); if( m_stroke.GetColor() != COLOR4D::UNSPECIFIED )
{
m_lastResolvedColor = m_stroke.GetColor();
}
else if( IsConnectable() && !IsConnectivityDirty() )
{
NETCLASSPTR netclass = NetClass();
if( netclass && netclass->GetSchematicColor() != COLOR4D::UNSPECIFIED ) if( netclass )
return netclass->GetSchematicColor(); m_lastResolvedColor = netclass->GetSchematicColor();
}
else
{
wxASSERT_MSG( !IsConnectable()
|| !ADVANCED_CFG::GetCfg().m_RealTimeConnectivity
|| !Schematic() || !Schematic()->ConnectionGraph()->m_allowRealTime,
"Connectivity shouldn't be dirty if realtime connectivity is on!" );
}
return m_stroke.GetColor(); return m_lastResolvedColor;
} }
PLOT_DASH_TYPE SCH_BUS_ENTRY_BASE::GetStrokeStyle() const PLOT_DASH_TYPE SCH_BUS_ENTRY_BASE::GetStrokeStyle() const
{ {
NETCLASSPTR netclass = NetClass(); if( m_stroke.GetPlotStyle() != PLOT_DASH_TYPE::DEFAULT )
{
m_lastResolvedLineStyle = m_stroke.GetPlotStyle();
}
else if( IsConnectable() && !IsConnectivityDirty() )
{
NETCLASSPTR netclass = NetClass();
if( netclass ) if( netclass )
return (PLOT_DASH_TYPE) netclass->GetLineStyle(); m_lastResolvedLineStyle = static_cast<PLOT_DASH_TYPE>( netclass->GetLineStyle() );
}
else
{
wxASSERT_MSG( !IsConnectable()
|| !ADVANCED_CFG::GetCfg().m_RealTimeConnectivity
|| !Schematic() || !Schematic()->ConnectionGraph()->m_allowRealTime,
"Connectivity shouldn't be dirty if realtime connectivity is on!" );
}
return m_stroke.GetPlotStyle(); return m_lastResolvedLineStyle;
} }
int SCH_BUS_WIRE_ENTRY::GetPenWidth() const int SCH_BUS_WIRE_ENTRY::GetPenWidth() const
{ {
if( m_stroke.GetWidth() > 0 ) if( m_stroke.GetWidth() > 0 )
return m_stroke.GetWidth(); {
m_lastResolvedWidth = m_stroke.GetWidth();
}
else if( IsConnectable() && !IsConnectivityDirty() )
{
NETCLASSPTR netclass = NetClass();
NETCLASSPTR netclass = NetClass(); if( netclass )
m_lastResolvedWidth = netclass->GetWireWidth();
}
if( !netclass && Schematic() ) return m_lastResolvedWidth;
netclass = Schematic()->Prj().GetProjectFile().NetSettings().m_NetClasses.GetDefault();
if( netclass )
return netclass->GetWireWidth();
return Mils2iu( DEFAULT_WIRE_WIDTH_MILS );
} }
int SCH_BUS_BUS_ENTRY::GetPenWidth() const int SCH_BUS_BUS_ENTRY::GetPenWidth() const
{ {
if( m_stroke.GetWidth() > 0 ) if( m_stroke.GetWidth() > 0 )
return m_stroke.GetWidth(); {
m_lastResolvedWidth = m_stroke.GetWidth();
}
else if( IsConnectable() && !IsConnectivityDirty() )
{
NETCLASSPTR netclass = NetClass();
NETCLASSPTR netclass = NetClass(); if( netclass )
m_lastResolvedWidth = netclass->GetBusWidth();
}
if( !netclass && Schematic() ) return m_lastResolvedWidth;
netclass = Schematic()->Prj().GetProjectFile().NetSettings().m_NetClasses.GetDefault();
if( netclass )
return netclass->GetBusWidth();
return Mils2iu( DEFAULT_BUS_WIDTH_MILS );
} }
@ -492,7 +540,10 @@ void SCH_BUS_ENTRY_BASE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame,
aList.emplace_back( _( "Bus Entry Type" ), msg ); aList.emplace_back( _( "Bus Entry Type" ), msg );
SCH_CONNECTION* conn = dynamic_cast<SCH_EDIT_FRAME*>( aFrame ) ? Connection() : nullptr; SCH_CONNECTION* conn = nullptr;
if( !IsConnectivityDirty() && dynamic_cast<SCH_EDIT_FRAME*>( aFrame ) )
conn = Connection();
if( conn ) if( conn )
{ {

View File

@ -123,6 +123,13 @@ protected:
bool m_isDanglingStart; bool m_isDanglingStart;
bool m_isDanglingEnd; bool m_isDanglingEnd;
STROKE_PARAMS m_stroke; STROKE_PARAMS m_stroke;
// If real-time connectivity gets disabled (due to being too slow on a particular
// design), we can no longer rely on getting the NetClass to find netclass-specific
// linestyles, linewidths and colors.
mutable PLOT_DASH_TYPE m_lastResolvedLineStyle;
mutable int m_lastResolvedWidth;
mutable COLOR4D m_lastResolvedColor;
}; };
/** /**

View File

@ -810,6 +810,8 @@ void SCH_EDIT_FRAME::OnModify()
if( ADVANCED_CFG::GetCfg().m_RealTimeConnectivity && CONNECTION_GRAPH::m_allowRealTime ) if( ADVANCED_CFG::GetCfg().m_RealTimeConnectivity && CONNECTION_GRAPH::m_allowRealTime )
RecalculateConnections( NO_CLEANUP ); RecalculateConnections( NO_CLEANUP );
else
GetScreen()->SetConnectivityDirty();
GetCanvas()->Refresh(); GetCanvas()->Refresh();
UpdateHierarchyNavigator(); UpdateHierarchyNavigator();

View File

@ -29,9 +29,6 @@
#include <sch_sheet_path.h> #include <sch_sheet_path.h>
#include <sch_draw_panel.h> #include <sch_draw_panel.h>
#include <sch_edit_frame.h> #include <sch_edit_frame.h>
#include <sch_symbol.h>
#include <sch_sheet.h>
#include <sch_pin.h>
#include <schematic.h> #include <schematic.h>
#include <general.h> #include <general.h>
#include <netclass.h> #include <netclass.h>
@ -47,9 +44,9 @@
SCH_ITEM::SCH_ITEM( EDA_ITEM* aParent, KICAD_T aType ) : SCH_ITEM::SCH_ITEM( EDA_ITEM* aParent, KICAD_T aType ) :
EDA_ITEM( aParent, aType ) EDA_ITEM( aParent, aType )
{ {
m_layer = LAYER_WIRE; // It's only a default, in fact m_layer = LAYER_WIRE; // It's only a default, in fact
m_fieldsAutoplaced = FIELDS_AUTOPLACED_NO; m_fieldsAutoplaced = FIELDS_AUTOPLACED_NO;
m_connectivity_dirty = true; m_connectivity_dirty = false; // Item is unconnected until it is placed, so it's clean
} }
@ -58,7 +55,7 @@ SCH_ITEM::SCH_ITEM( const SCH_ITEM& aItem ) :
{ {
m_layer = aItem.m_layer; m_layer = aItem.m_layer;
m_fieldsAutoplaced = aItem.m_fieldsAutoplaced; m_fieldsAutoplaced = aItem.m_fieldsAutoplaced;
m_connectivity_dirty = true; m_connectivity_dirty = false; // Item is unconnected until it is placed, so it's clean
} }
@ -66,7 +63,7 @@ SCH_ITEM& SCH_ITEM::operator=( const SCH_ITEM& aItem )
{ {
m_layer = aItem.m_layer; m_layer = aItem.m_layer;
m_fieldsAutoplaced = aItem.m_fieldsAutoplaced; m_fieldsAutoplaced = aItem.m_fieldsAutoplaced;
m_connectivity_dirty = true; m_connectivity_dirty = false; // Item is unconnected until it is placed, so it's clean
return *this; return *this;
} }
@ -140,6 +137,12 @@ bool SCH_ITEM::IsConnected( const wxPoint& aPosition ) const
SCH_CONNECTION* SCH_ITEM::Connection( const SCH_SHEET_PATH* aSheet ) const SCH_CONNECTION* SCH_ITEM::Connection( const SCH_SHEET_PATH* aSheet ) const
{ {
if( !IsConnectable() )
return nullptr;
wxASSERT_MSG( !IsConnectivityDirty(),
"Shouldn't be asking for connection if connectivity is dirty!" );
if( !aSheet ) if( !aSheet )
aSheet = &Schematic()->CurrentSheet(); aSheet = &Schematic()->CurrentSheet();
@ -186,6 +189,8 @@ void SCH_ITEM::AddConnectionTo( const SCH_SHEET_PATH& aSheet, SCH_ITEM* aItem )
SCH_CONNECTION* SCH_ITEM::InitializeConnection( const SCH_SHEET_PATH& aSheet, SCH_CONNECTION* SCH_ITEM::InitializeConnection( const SCH_SHEET_PATH& aSheet,
CONNECTION_GRAPH* aGraph ) CONNECTION_GRAPH* aGraph )
{ {
SetConnectivityDirty( false );
SCH_CONNECTION* connection = Connection( &aSheet ); SCH_CONNECTION* connection = Connection( &aSheet );
if( connection ) if( connection )
@ -204,6 +209,20 @@ SCH_CONNECTION* SCH_ITEM::InitializeConnection( const SCH_SHEET_PATH& aSheet,
} }
SCH_CONNECTION* SCH_ITEM::GetOrInitConnection( const SCH_SHEET_PATH& aSheet,
CONNECTION_GRAPH* aGraph )
{
SetConnectivityDirty( false );
SCH_CONNECTION* connection = Connection( &aSheet );
if( connection )
return connection;
else
return InitializeConnection( aSheet, aGraph );
}
void SCH_ITEM::SwapData( SCH_ITEM* aItem ) void SCH_ITEM::SwapData( SCH_ITEM* aItem )
{ {
UNIMPLEMENTED_FOR( GetClass() ); UNIMPLEMENTED_FOR( GetClass() );

View File

@ -403,12 +403,14 @@ public:
*/ */
SCH_CONNECTION* InitializeConnection( const SCH_SHEET_PATH& aPath, CONNECTION_GRAPH* aGraph ); SCH_CONNECTION* InitializeConnection( const SCH_SHEET_PATH& aPath, CONNECTION_GRAPH* aGraph );
SCH_CONNECTION* GetOrInitConnection( const SCH_SHEET_PATH& aPath, CONNECTION_GRAPH* aGraph );
/** /**
* Return true if this item should propagate connection info to \a aItem. * Return true if this item should propagate connection info to \a aItem.
*/ */
virtual bool ConnectionPropagatesTo( const EDA_ITEM* aItem ) const { return true; } virtual bool ConnectionPropagatesTo( const EDA_ITEM* aItem ) const { return true; }
bool IsConnectivityDirty() { return m_connectivity_dirty; } bool IsConnectivityDirty() const { return m_connectivity_dirty; }
void SetConnectivityDirty( bool aDirty = true ) { m_connectivity_dirty = aDirty; } void SetConnectivityDirty( bool aDirty = true ) { m_connectivity_dirty = aDirty; }

View File

@ -30,10 +30,12 @@
#include <sch_edit_frame.h> #include <sch_edit_frame.h>
#include <settings/color_settings.h> #include <settings/color_settings.h>
#include <schematic.h> #include <schematic.h>
#include <connection_graph.h>
#include <project/project_file.h> #include <project/project_file.h>
#include <project/net_settings.h> #include <project/net_settings.h>
#include <trigo.h> #include <trigo.h>
#include <board_item.h> #include <board_item.h>
#include <advanced_config.h>
SCH_LINE::SCH_LINE( const wxPoint& pos, int layer ) : SCH_LINE::SCH_LINE( const wxPoint& pos, int layer ) :
SCH_ITEM( nullptr, SCH_LINE_T ) SCH_ITEM( nullptr, SCH_LINE_T )
@ -55,6 +57,16 @@ SCH_LINE::SCH_LINE( const wxPoint& pos, int layer ) :
m_startIsDangling = m_endIsDangling = true; m_startIsDangling = m_endIsDangling = true;
else else
m_startIsDangling = m_endIsDangling = false; m_startIsDangling = m_endIsDangling = false;
if( layer == LAYER_WIRE )
m_lastResolvedWidth = Mils2iu( DEFAULT_WIRE_WIDTH_MILS );
else if( layer == LAYER_BUS )
m_lastResolvedWidth = Mils2iu( DEFAULT_BUS_WIDTH_MILS );
else
m_lastResolvedWidth = Mils2iu( DEFAULT_LINE_WIDTH_MILS );
m_lastResolvedLineStyle = GetDefaultStyle();
m_lastResolvedColor = COLOR4D::UNSPECIFIED;
} }
@ -66,6 +78,10 @@ SCH_LINE::SCH_LINE( const SCH_LINE& aLine ) :
m_stroke = aLine.m_stroke; m_stroke = aLine.m_stroke;
m_startIsDangling = aLine.m_startIsDangling; m_startIsDangling = aLine.m_startIsDangling;
m_endIsDangling = aLine.m_endIsDangling; m_endIsDangling = aLine.m_endIsDangling;
m_lastResolvedLineStyle = aLine.m_lastResolvedLineStyle;
m_lastResolvedWidth = aLine.m_lastResolvedWidth;
m_lastResolvedColor = aLine.m_lastResolvedColor;
} }
@ -201,7 +217,9 @@ void SCH_LINE::SetLineColor( const double r, const double g, const double b, con
COLOR4D newColor(r, g, b, a); COLOR4D newColor(r, g, b, a);
if( newColor == COLOR4D::UNSPECIFIED ) if( newColor == COLOR4D::UNSPECIFIED )
{
m_stroke.SetColor( COLOR4D::UNSPECIFIED ); m_stroke.SetColor( COLOR4D::UNSPECIFIED );
}
else else
{ {
// Eeschema does not allow alpha channel in colors // Eeschema does not allow alpha channel in colors
@ -214,14 +232,25 @@ void SCH_LINE::SetLineColor( const double r, const double g, const double b, con
COLOR4D SCH_LINE::GetLineColor() const COLOR4D SCH_LINE::GetLineColor() const
{ {
if( m_stroke.GetColor() != COLOR4D::UNSPECIFIED ) if( m_stroke.GetColor() != COLOR4D::UNSPECIFIED )
return m_stroke.GetColor(); {
m_lastResolvedColor = m_stroke.GetColor();
}
else if( IsConnectable() && !IsConnectivityDirty() )
{
NETCLASSPTR netclass = NetClass();
NETCLASSPTR netclass = NetClass(); if( netclass )
m_lastResolvedColor = netclass->GetSchematicColor();
}
else
{
wxASSERT_MSG( !IsConnectable()
|| !ADVANCED_CFG::GetCfg().m_RealTimeConnectivity
|| !Schematic() || !Schematic()->ConnectionGraph()->m_allowRealTime,
"Connectivity shouldn't be dirty if realtime connectivity is on!" );
}
if( netclass ) return m_lastResolvedColor;
return netclass->GetSchematicColor();
return m_stroke.GetColor();
} }
@ -261,14 +290,25 @@ PLOT_DASH_TYPE SCH_LINE::GetLineStyle() const
PLOT_DASH_TYPE SCH_LINE::GetEffectiveLineStyle() const PLOT_DASH_TYPE SCH_LINE::GetEffectiveLineStyle() const
{ {
if( m_stroke.GetPlotStyle() != PLOT_DASH_TYPE::DEFAULT ) if( m_stroke.GetPlotStyle() != PLOT_DASH_TYPE::DEFAULT )
return m_stroke.GetPlotStyle(); {
m_lastResolvedLineStyle = m_stroke.GetPlotStyle();
}
else if( IsConnectable() && !IsConnectivityDirty() )
{
NETCLASSPTR netclass = NetClass();
NETCLASSPTR netclass = NetClass(); if( netclass )
m_lastResolvedLineStyle = static_cast<PLOT_DASH_TYPE>( netclass->GetLineStyle() );
}
else
{
wxASSERT_MSG( !IsConnectable()
|| !ADVANCED_CFG::GetCfg().m_RealTimeConnectivity
|| !Schematic() || !Schematic()->ConnectionGraph()->m_allowRealTime,
"Connectivity shouldn't be dirty if realtime connectivity is on!" );
}
if( netclass ) return m_lastResolvedLineStyle;
return (PLOT_DASH_TYPE) netclass->GetLineStyle();
return GetLineStyle();
} }
@ -280,6 +320,7 @@ void SCH_LINE::SetLineWidth( const int aSize )
int SCH_LINE::GetPenWidth() const int SCH_LINE::GetPenWidth() const
{ {
SCHEMATIC* schematic = Schematic();
NETCLASSPTR netclass; NETCLASSPTR netclass;
switch ( m_layer ) switch ( m_layer )
@ -288,38 +329,46 @@ int SCH_LINE::GetPenWidth() const
if( m_stroke.GetWidth() > 0 ) if( m_stroke.GetWidth() > 0 )
return m_stroke.GetWidth(); return m_stroke.GetWidth();
if( Schematic() ) if( schematic )
return Schematic()->Settings().m_DefaultLineWidth; return schematic->Settings().m_DefaultLineWidth;
return Mils2iu( DEFAULT_LINE_WIDTH_MILS ); return Mils2iu( DEFAULT_LINE_WIDTH_MILS );
case LAYER_WIRE: case LAYER_WIRE:
if( m_stroke.GetWidth() > 0 ) if( m_stroke.GetWidth() > 0 )
return m_stroke.GetWidth(); {
m_lastResolvedWidth = m_stroke.GetWidth();
}
else if( !IsConnectivityDirty() )
{
netclass = NetClass();
netclass = NetClass(); if( !netclass && schematic )
netclass = schematic->Prj().GetProjectFile().NetSettings().m_NetClasses.GetDefault();
if( !netclass && Schematic() ) if( netclass )
netclass = Schematic()->Prj().GetProjectFile().NetSettings().m_NetClasses.GetDefault(); m_lastResolvedWidth = netclass->GetWireWidth();
}
if( netclass ) return m_lastResolvedWidth;
return netclass->GetWireWidth();
return Mils2iu( DEFAULT_WIRE_WIDTH_MILS );
case LAYER_BUS: case LAYER_BUS:
if( m_stroke.GetWidth() > 0 ) if( m_stroke.GetWidth() > 0 )
return m_stroke.GetWidth(); {
m_lastResolvedWidth = m_stroke.GetWidth();
}
else if( !IsConnectivityDirty() )
{
netclass = NetClass();
netclass = NetClass(); if( !netclass && schematic )
netclass = schematic->Prj().GetProjectFile().NetSettings().m_NetClasses.GetDefault();
if( !netclass && Schematic() ) if( netclass )
netclass = Schematic()->Prj().GetProjectFile().NetSettings().m_NetClasses.GetDefault(); m_lastResolvedWidth = netclass->GetBusWidth();
}
if( netclass ) return m_lastResolvedWidth;
return netclass->GetBusWidth();
return Mils2iu( DEFAULT_BUS_WIDTH_MILS );
} }
} }
@ -882,7 +931,10 @@ void SCH_LINE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_IT
aList.emplace_back( _( "Line Style" ), msg ); aList.emplace_back( _( "Line Style" ), msg );
SCH_CONNECTION* conn = dynamic_cast<SCH_EDIT_FRAME*>( aFrame ) ? Connection() : nullptr; SCH_CONNECTION* conn = nullptr;
if( !IsConnectivityDirty() && dynamic_cast<SCH_EDIT_FRAME*>( aFrame ) )
conn = Connection();
if( conn ) if( conn )
{ {

View File

@ -267,6 +267,13 @@ private:
wxPoint m_start; ///< Line start point wxPoint m_start; ///< Line start point
wxPoint m_end; ///< Line end point wxPoint m_end; ///< Line end point
STROKE_PARAMS m_stroke; ///< Line stroke properties. STROKE_PARAMS m_stroke; ///< Line stroke properties.
// If real-time connectivity gets disabled (due to being too slow on a particular
// design), we can no longer rely on getting the NetClass to find netclass-specific
// linestyles, linewidths and colors.
mutable PLOT_DASH_TYPE m_lastResolvedLineStyle;
mutable int m_lastResolvedWidth;
mutable COLOR4D m_lastResolvedColor;
}; };

View File

@ -1326,7 +1326,10 @@ void SCH_PAINTER::draw( const SCH_TEXT *aText, int aLayer )
if( m_schematic ) if( m_schematic )
{ {
SCH_CONNECTION* conn = aText->Connection(); SCH_CONNECTION* conn = nullptr;
if( !aText->IsConnectivityDirty() )
conn = aText->Connection();
if( conn && conn->IsBus() ) if( conn && conn->IsBus() )
color = getRenderColor( aText, LAYER_BUS, drawingShadows ); color = getRenderColor( aText, LAYER_BUS, drawingShadows );
@ -1642,7 +1645,10 @@ void SCH_PAINTER::draw( SCH_HIERLABEL *aLabel, int aLayer )
if( m_schematic ) if( m_schematic )
{ {
SCH_CONNECTION* conn = aLabel->Connection(); SCH_CONNECTION* conn = nullptr;
if( !aLabel->IsConnectivityDirty() )
conn = aLabel->Connection();
if( conn && conn->IsBus() ) if( conn && conn->IsBus() )
color = getRenderColor( aLabel, LAYER_BUS, drawingShadows ); color = getRenderColor( aLabel, LAYER_BUS, drawingShadows );

View File

@ -218,7 +218,7 @@ void SCH_PIN::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITE
aList.emplace_back( symbol->GetRef( currentSheet ), symbol->GetValue( currentSheet, true ) ); aList.emplace_back( symbol->GetRef( currentSheet ), symbol->GetValue( currentSheet, true ) );
#if defined(DEBUG) #if defined(DEBUG)
if( dynamic_cast<SCH_EDIT_FRAME*>( aFrame ) ) if( !IsConnectivityDirty() && dynamic_cast<SCH_EDIT_FRAME*>( aFrame ) )
{ {
SCH_CONNECTION* conn = Connection(); SCH_CONNECTION* conn = Connection();

View File

@ -82,6 +82,8 @@ public:
const EDA_RECT GetBoundingBox() const override; const EDA_RECT GetBoundingBox() const override;
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
bool IsConnectable() const override { return true; }
bool IsDangling() const override { return m_isDangling; } bool IsDangling() const override { return m_isDangling; }
void SetIsDangling( bool isDangling ) { m_isDangling = isDangling; } void SetIsDangling( bool isDangling ) { m_isDangling = isDangling; }

View File

@ -787,6 +787,13 @@ void SCH_SCREEN::UpdateLocalLibSymbolLinks()
} }
void SCH_SCREEN::SetConnectivityDirty()
{
for( SCH_ITEM* item : Items() )
item->SetConnectivityDirty( true );
}
void SCH_SCREEN::Print( const RENDER_SETTINGS* aSettings ) void SCH_SCREEN::Print( const RENDER_SETTINGS* aSettings )
{ {
// Ensure links are up to date, even if a library was reloaded for some reason: // Ensure links are up to date, even if a library was reloaded for some reason:

View File

@ -161,6 +161,8 @@ public:
void IncRefCount(); void IncRefCount();
int GetRefCount() const { return m_refCount; } int GetRefCount() const { return m_refCount; }
void SetConnectivityDirty();
/** /**
* Return the number of times this screen is used. * Return the number of times this screen is used.
* *

View File

@ -784,7 +784,10 @@ void SCH_TEXT::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_IT
aList.emplace_back( _( "Justification" ), msg ); aList.emplace_back( _( "Justification" ), msg );
SCH_CONNECTION* conn = dynamic_cast<SCH_EDIT_FRAME*>( aFrame ) ? Connection() : nullptr; SCH_CONNECTION* conn = nullptr;
if( !IsConnectivityDirty() && dynamic_cast<SCH_EDIT_FRAME*>( aFrame ) )
conn = Connection();
if( conn ) if( conn )
{ {

View File

@ -215,6 +215,9 @@ int SCH_EDITOR_CONTROL::RemapSymbols( const TOOL_EVENT& aEvent )
int SCH_EDITOR_CONTROL::Print( const TOOL_EVENT& aEvent ) int SCH_EDITOR_CONTROL::Print( const TOOL_EVENT& aEvent )
{ {
if( !ADVANCED_CFG::GetCfg().m_RealTimeConnectivity || !CONNECTION_GRAPH::m_allowRealTime )
m_frame->RecalculateConnections( NO_CLEANUP );
InvokeDialogPrintUsingPrinter( m_frame ); InvokeDialogPrintUsingPrinter( m_frame );
wxFileName fn = m_frame->Prj().AbsolutePath( m_frame->Schematic().RootScreen()->GetFileName() ); wxFileName fn = m_frame->Prj().AbsolutePath( m_frame->Schematic().RootScreen()->GetFileName() );
@ -228,6 +231,9 @@ int SCH_EDITOR_CONTROL::Print( const TOOL_EVENT& aEvent )
int SCH_EDITOR_CONTROL::Plot( const TOOL_EVENT& aEvent ) int SCH_EDITOR_CONTROL::Plot( const TOOL_EVENT& aEvent )
{ {
if( !ADVANCED_CFG::GetCfg().m_RealTimeConnectivity || !CONNECTION_GRAPH::m_allowRealTime )
m_frame->RecalculateConnections( NO_CLEANUP );
DIALOG_PLOT_SCHEMATIC dlg( m_frame ); DIALOG_PLOT_SCHEMATIC dlg( m_frame );
dlg.ShowModal(); dlg.ShowModal();
@ -2052,6 +2058,9 @@ int SCH_EDITOR_CONTROL::GenerateBOM( const TOOL_EVENT& aEvent )
int SCH_EDITOR_CONTROL::DrawSheetOnClipboard( const TOOL_EVENT& aEvent ) int SCH_EDITOR_CONTROL::DrawSheetOnClipboard( const TOOL_EVENT& aEvent )
{ {
if( !ADVANCED_CFG::GetCfg().m_RealTimeConnectivity || !CONNECTION_GRAPH::m_allowRealTime )
m_frame->RecalculateConnections( LOCAL_CLEANUP );
m_frame->DrawCurrentSheetToClipboard(); m_frame->DrawCurrentSheetToClipboard();
return 0; return 0;
} }