Force overlapping wires to share labels
Crossing wires with pathological label in the center are actually connected for the netlist. This is an ERC error but we should keep things consistent. Fixes https://gitlab.com/kicad/code/kicad/-/issues/21494
This commit is contained in:
@@ -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<SCH_LABEL_BASE*>( item ) )
|
||||
{
|
||||
VECTOR2I point = item->GetPosition();
|
||||
SCH_SCREEN* screen = aSheet.LastScreen();
|
||||
auto items = screen->Items().Overlapping( point );
|
||||
std::vector<SCH_ITEM*> 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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
#include <qa_utils/wx_utils/unit_test_utils.h>
|
||||
|
||||
#include <connection_graph.h>
|
||||
#include <sch_line.h>
|
||||
#include <sch_label.h>
|
||||
#include <sch_sheet.h>
|
||||
#include <sch_sheet_path.h>
|
||||
#include <sch_screen.h>
|
||||
#include <schematic.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <project.h>
|
||||
|
||||
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<SCH_ITEM*> 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 );
|
||||
}
|
||||
Reference in New Issue
Block a user