From 6992afeb3894a1e7255eadc4fbf3d9751f5ca3bc Mon Sep 17 00:00:00 2001 From: John Beard Date: Fri, 17 May 2024 21:04:59 +0800 Subject: [PATCH] Consider a bus entry hitting a wire corner or tee to be dot-worthy This doesn't change the connectivity, it just makes putting the dot more closely match what the connectivity already does. Fixes: https://gitlab.com/kicad/code/kicad/-/issues/18046 --- eeschema/junction_helpers.cpp | 14 ++++++- eeschema/junction_helpers.h | 5 +++ eeschema/sch_screen.cpp | 7 ++-- qa/tests/eeschema/test_junction_helpers.cpp | 42 ++++++++++++++++++++- 4 files changed, 62 insertions(+), 6 deletions(-) diff --git a/eeschema/junction_helpers.cpp b/eeschema/junction_helpers.cpp index 372b531531..a7e3adf37f 100644 --- a/eeschema/junction_helpers.cpp +++ b/eeschema/junction_helpers.cpp @@ -13,10 +13,11 @@ POINT_INFO JUNCTION_HELPERS::AnalyzePoint( const EE_RTREE& aItems, const VECTOR2 BUSES }; - POINT_INFO info {}; + POINT_INFO info{}; info.hasBusEntry = false; info.hasExplicitJunctionDot = false; info.isJunction = false; + info.hasBusEntryToMultipleWires = false; bool breakLines[2] = { false }; std::unordered_set exitAngles[2]; @@ -106,6 +107,17 @@ POINT_INFO JUNCTION_HELPERS::AnalyzePoint( const EE_RTREE& aItems, const VECTOR2 } } + if( info.hasBusEntry ) + { + // The bus entry and one wire is 2 wires, and the one entry is exactly one bus + // Any more wires must be multiple wires, but any more buses means a wire + // crossing at the bus entry root. + info.hasBusEntryToMultipleWires = + exitAngles[WIRES].size() > 2 && exitAngles[BUSES].size() == 1; + } + + // Any three things of the same type is a junction of some sort info.isJunction = exitAngles[WIRES].size() >= 3 || exitAngles[BUSES].size() >= 3; + return info; } \ No newline at end of file diff --git a/eeschema/junction_helpers.h b/eeschema/junction_helpers.h index 5256bd14bb..8b2cf9147c 100644 --- a/eeschema/junction_helpers.h +++ b/eeschema/junction_helpers.h @@ -10,9 +10,14 @@ namespace JUNCTION_HELPERS */ struct POINT_INFO { + ///< True if the point has 3+ wires and/or 3+ buses meeting there bool isJunction; + ///< True if there is already junction dot at the point bool hasExplicitJunctionDot; + ///< True if there is a bus entry at the point (either end) bool hasBusEntry; + ///< True if there is a bus entry at the point and it connects to more than one wire + bool hasBusEntryToMultipleWires; }; /** diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp index 8b2f90c46d..dedd452f3f 100644 --- a/eeschema/sch_screen.cpp +++ b/eeschema/sch_screen.cpp @@ -488,7 +488,7 @@ bool SCH_SCREEN::IsExplicitJunction( const VECTOR2I& aPosition ) const const JUNCTION_HELPERS::POINT_INFO info = JUNCTION_HELPERS::AnalyzePoint( Items(), aPosition, false ); - return info.isJunction && !info.hasBusEntry; + return info.isJunction && ( !info.hasBusEntry || info.hasBusEntryToMultipleWires ); } @@ -497,7 +497,8 @@ bool SCH_SCREEN::IsExplicitJunctionNeeded( const VECTOR2I& aPosition ) const const JUNCTION_HELPERS::POINT_INFO info = JUNCTION_HELPERS::AnalyzePoint( Items(), aPosition, false ); - return info.isJunction && !info.hasBusEntry && !info.hasExplicitJunctionDot; + return info.isJunction && ( !info.hasBusEntry || info.hasBusEntryToMultipleWires ) + && !info.hasExplicitJunctionDot; } @@ -506,7 +507,7 @@ bool SCH_SCREEN::IsExplicitJunctionAllowed( const VECTOR2I& aPosition ) const const JUNCTION_HELPERS::POINT_INFO info = JUNCTION_HELPERS::AnalyzePoint( Items(), aPosition, true ); - return info.isJunction && !info.hasBusEntry; + return info.isJunction && (!info.hasBusEntry || info.hasBusEntryToMultipleWires ); } diff --git a/qa/tests/eeschema/test_junction_helpers.cpp b/qa/tests/eeschema/test_junction_helpers.cpp index 20087dfefb..2660ecc06a 100644 --- a/qa/tests/eeschema/test_junction_helpers.cpp +++ b/qa/tests/eeschema/test_junction_helpers.cpp @@ -109,6 +109,8 @@ BOOST_AUTO_TEST_CASE( WireTee ) const POINT_INFO info = AnalyzePoint( items, { 0, 0 }, false ); BOOST_CHECK( info.isJunction ); + BOOST_CHECK( !info.hasBusEntry ); + BOOST_CHECK( !info.hasBusEntryToMultipleWires ); } BOOST_AUTO_TEST_CASE( BusEntryOnBus ) @@ -139,6 +141,8 @@ BOOST_AUTO_TEST_CASE( BusEntryOnBus ) const POINT_INFO info_end = AnalyzePoint( items, { BE_SIZE, BE_SIZE }, false ); BOOST_CHECK( !info_end.isJunction ); BOOST_CHECK( info_end.hasBusEntry ); + // There is no wire here + BOOST_CHECK( !info_end.hasBusEntryToMultipleWires ); } BOOST_AUTO_TEST_CASE( BusEntryToWire ) @@ -155,6 +159,8 @@ BOOST_AUTO_TEST_CASE( BusEntryToWire ) const POINT_INFO info = AnalyzePoint( items, { BE_SIZE, BE_SIZE }, false ); BOOST_CHECK( !info.isJunction ); BOOST_CHECK( info.hasBusEntry ); + // This is a single wire to a bus entry, not multiple + BOOST_CHECK( !info.hasBusEntryToMultipleWires ); } BOOST_AUTO_TEST_CASE( WireDirectToBus ) @@ -169,6 +175,8 @@ BOOST_AUTO_TEST_CASE( WireDirectToBus ) const POINT_INFO info = AnalyzePoint( items, { 0, 0 }, false ); BOOST_CHECK( !info.isJunction ); BOOST_CHECK( !info.hasBusEntry ); + // It's a single wire, and not a bus entry + BOOST_CHECK( !info.hasBusEntryToMultipleWires ); } BOOST_AUTO_TEST_CASE( WireCrossingBus ) @@ -188,13 +196,14 @@ BOOST_AUTO_TEST_CASE( WireCrossingBus ) // Two wires and two buses meet, which isn't a junction BOOST_CHECK( !info.isJunction ); BOOST_CHECK( !info.hasBusEntry ); + BOOST_CHECK( !info.hasBusEntryToMultipleWires ); } BOOST_AUTO_TEST_CASE( WireToBusEntryRoot ) { /* - * /--- <-- not a junction (also an ERC error!) - * ______________ + * /--- <-- not a junction + * _____________ * ||\ * || \ * || \ @@ -206,6 +215,8 @@ BOOST_AUTO_TEST_CASE( WireToBusEntryRoot ) const POINT_INFO info = AnalyzePoint( items, { 0, 0 }, false ); BOOST_CHECK( !info.isJunction ); BOOST_CHECK( info.hasBusEntry ); + // The bus/bus-entry point isn't valid + BOOST_CHECK( !info.hasBusEntryToMultipleWires ); } BOOST_AUTO_TEST_CASE( WireCrossingBusEntryRoot ) @@ -228,6 +239,8 @@ BOOST_AUTO_TEST_CASE( WireCrossingBusEntryRoot ) // Three buses meet here, so this is a junction BOOST_CHECK( info.isJunction ); BOOST_CHECK( info.hasBusEntry ); + // There are multiple wires but they don't count here + BOOST_CHECK( !info.hasBusEntryToMultipleWires ); } BOOST_AUTO_TEST_CASE( WireCornerToBusEntry ) @@ -250,6 +263,31 @@ BOOST_AUTO_TEST_CASE( WireCornerToBusEntry ) const POINT_INFO info = AnalyzePoint( items, { BE_SIZE, BE_SIZE }, false ); BOOST_CHECK( info.isJunction ); BOOST_CHECK( info.hasBusEntry ); + BOOST_CHECK( info.hasBusEntryToMultipleWires ); +} + +BOOST_AUTO_TEST_CASE( WireTeeToBusEntry ) +{ + /* + * || + * || + * || | + * \ | /--- junction here + * \| / + * O------------- + * | + * | + */ + items.insert( make_bus( { 0, 0 }, { 0, BE_SIZE } ) ); + items.insert( make_wire( { BE_SIZE, BE_SIZE }, { 2 * BE_SIZE, BE_SIZE } ) ); // right + items.insert( make_wire( { BE_SIZE, BE_SIZE }, { BE_SIZE, 0 } ) ); //up + items.insert( make_wire( { BE_SIZE, BE_SIZE }, { BE_SIZE, 2 * BE_SIZE } ) ); // down + items.insert( new SCH_BUS_WIRE_ENTRY( { 0, 0 }, false ) ); + + const POINT_INFO info = AnalyzePoint( items, { BE_SIZE, BE_SIZE }, false ); + BOOST_CHECK( info.isJunction ); + BOOST_CHECK( info.hasBusEntry ); + BOOST_CHECK( info.hasBusEntryToMultipleWires ); } BOOST_AUTO_TEST_CASE( SheetPinToOneWire )