diff --git a/eeschema/connection_graph.cpp b/eeschema/connection_graph.cpp index f7542fbf64..61928d1437 100644 --- a/eeschema/connection_graph.cpp +++ b/eeschema/connection_graph.cpp @@ -1325,6 +1325,31 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet, else { updateGenericItemConnectivity( aSheet, item, connection_map ); + + /// Special case for labels that overlap wires + /// While this is an ERC error as there is not an explicit junction, + /// we want to enforce connectivity for all items under the label position. + if( dynamic_cast( item ) ) + { + VECTOR2I point = item->GetPosition(); + SCH_SCREEN* screen = aSheet.LastScreen(); + auto items = screen->Items().Overlapping( point ); + std::vector overlapping_items; + + std::copy_if( items.begin(), items.end(), std::back_inserter( overlapping_items ), + [&]( SCH_ITEM* test_item ) + { + return test_item->Type() == SCH_LINE_T + && test_item->HitTest( point, -1 ); + } ); + + // We need at least two connnectable lines that are not the label here + // Otherwise, the label will be normally assigned to one or the other + if( overlapping_items.size() < 2 ) continue; + + for( SCH_ITEM* test_item : overlapping_items ) + connection_map[point].push_back( test_item ); + } } } diff --git a/qa/tests/eeschema/CMakeLists.txt b/qa/tests/eeschema/CMakeLists.txt index 04ddf71533..f81169b253 100644 --- a/qa/tests/eeschema/CMakeLists.txt +++ b/qa/tests/eeschema/CMakeLists.txt @@ -68,6 +68,7 @@ set( QA_EESCHEMA_SRCS test_annotation_units_conflicts.cpp test_annotation_units_integration.cpp test_connectivity_algo.cpp + test_crossing_label.cpp test_eagle_plugin.cpp test_junction_helpers.cpp test_bus_entry_concurrency.cpp diff --git a/qa/tests/eeschema/test_crossing_label.cpp b/qa/tests/eeschema/test_crossing_label.cpp new file mode 100644 index 0000000000..836ce5d9df --- /dev/null +++ b/qa/tests/eeschema/test_crossing_label.cpp @@ -0,0 +1,56 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +BOOST_AUTO_TEST_CASE( LabelDrivesCrossingWires ) +{ + + SETTINGS_MANAGER manager; + manager.LoadProject( "" ); + + SCHEMATIC schematic( &manager.Prj() ); + + SCH_SCREEN* screen = new SCH_SCREEN( nullptr ); + SCH_SHEET* sheet = new SCH_SHEET( nullptr, VECTOR2I( 0, 0 ), VECTOR2I( 1000, 1000 ) ); + sheet->SetScreen( screen ); + schematic.SetRoot( sheet ); + + CONNECTION_GRAPH graph; + graph.SetSchematic( &schematic ); + + SCH_SHEET_PATH sheetPath; + sheetPath.push_back( sheet ); + + SCH_LINE* h = new SCH_LINE( VECTOR2I( -1000, 0 ), LAYER_WIRE ); + h->SetEndPoint( VECTOR2I( 1000, 0 ) ); + SCH_LINE* v = new SCH_LINE( VECTOR2I( 0, -1000 ), LAYER_WIRE ); + v->SetEndPoint( VECTOR2I( 0, 1000 ) ); + SCH_LABEL* label = new SCH_LABEL( VECTOR2I( 0, 0 ), wxS( "N" ) ); + screen->Append( h, false ); + screen->Append( v, false ); + screen->Append( label, false ); + + std::vector items = { h, v, label }; + + label->GetOrInitConnection( sheetPath, &graph )->ConfigureFromLabel(wxS("N")); + + SCH_SHEET_LIST sheets = schematic.BuildSheetListSortedByPageNumbers(); + graph.Recalculate( sheets, true ); + + CONNECTION_SUBGRAPH* sg1 = graph.GetSubgraphForItem( h ); + CONNECTION_SUBGRAPH* sg2 = graph.GetSubgraphForItem( v ); + + BOOST_REQUIRE( sg1 ); + BOOST_REQUIRE( sg2 ); + BOOST_CHECK( sg1 == sg2 ); + BOOST_CHECK( sg1->GetDriver() == label ); + BOOST_CHECK( sg2->GetDriver() == label ); +}