You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
3.6 KiB

  1. #include "junction_helpers.h"
  2. #include <sch_line.h>
  3. using namespace JUNCTION_HELPERS;
  4. POINT_INFO JUNCTION_HELPERS::AnalyzePoint( const EE_RTREE& aItems, const VECTOR2I& aPosition,
  5. bool aBreakCrossings )
  6. {
  7. enum layers
  8. {
  9. WIRES = 0,
  10. BUSES
  11. };
  12. POINT_INFO info{};
  13. info.hasBusEntry = false;
  14. info.hasExplicitJunctionDot = false;
  15. info.isJunction = false;
  16. info.hasBusEntryToMultipleWires = false;
  17. bool breakLines[2] = { false };
  18. std::unordered_set<int> exitAngles[2];
  19. std::vector<const SCH_LINE*> midPointLines[2];
  20. // A pin at 90° still shouldn't match a line at 90° so just give pins unique numbers
  21. int uniqueAngle = 10000;
  22. for( const SCH_ITEM* item : aItems.Overlapping( aPosition ) )
  23. {
  24. if( item->GetEditFlags() & STRUCT_DELETED )
  25. continue;
  26. switch( item->Type() )
  27. {
  28. case SCH_JUNCTION_T:
  29. if( item->HitTest( aPosition, -1 ) )
  30. info.hasExplicitJunctionDot = true;
  31. break;
  32. case SCH_LINE_T:
  33. {
  34. const SCH_LINE* line = static_cast<const SCH_LINE*>( item );
  35. int layer;
  36. if( line->GetStartPoint() == line->GetEndPoint() )
  37. break;
  38. else if( line->GetLayer() == LAYER_WIRE )
  39. layer = WIRES;
  40. else if( line->GetLayer() == LAYER_BUS )
  41. layer = BUSES;
  42. else
  43. break;
  44. if( line->IsConnected( aPosition ) )
  45. {
  46. breakLines[layer] = true;
  47. exitAngles[layer].insert( line->GetAngleFrom( aPosition ) );
  48. }
  49. else if( line->HitTest( aPosition, -1 ) )
  50. {
  51. if( aBreakCrossings )
  52. breakLines[layer] = true;
  53. // Defer any line midpoints until we know whether or not we're breaking them
  54. midPointLines[layer].push_back( line );
  55. }
  56. }
  57. break;
  58. case SCH_BUS_WIRE_ENTRY_T:
  59. if( item->IsConnected( aPosition ) )
  60. {
  61. breakLines[BUSES] = true;
  62. exitAngles[BUSES].insert( uniqueAngle++ );
  63. breakLines[WIRES] = true;
  64. exitAngles[WIRES].insert( uniqueAngle++ );
  65. info.hasBusEntry = true;
  66. }
  67. break;
  68. case SCH_SYMBOL_T:
  69. case SCH_SHEET_T:
  70. if( item->IsConnected( aPosition ) )
  71. {
  72. breakLines[WIRES] = true;
  73. exitAngles[WIRES].insert( uniqueAngle++ );
  74. }
  75. break;
  76. default: break;
  77. }
  78. }
  79. for( int layer : { WIRES, BUSES } )
  80. {
  81. if( breakLines[layer] )
  82. {
  83. for( const SCH_LINE* line : midPointLines[layer] )
  84. {
  85. exitAngles[layer].insert( line->GetAngleFrom( aPosition ) );
  86. exitAngles[layer].insert( line->GetReverseAngleFrom( aPosition ) );
  87. }
  88. }
  89. }
  90. if( info.hasBusEntry )
  91. {
  92. // The bus entry and one wire is 2 wires, and the one entry is exactly one bus
  93. // Any more wires must be multiple wires, but any more buses means a wire
  94. // crossing at the bus entry root.
  95. info.hasBusEntryToMultipleWires =
  96. exitAngles[WIRES].size() > 2 && exitAngles[BUSES].size() == 1;
  97. }
  98. // Any three things of the same type is a junction of some sort
  99. info.isJunction = exitAngles[WIRES].size() >= 3 || exitAngles[BUSES].size() >= 3;
  100. return info;
  101. }