Extract SCH_SCREEN::GetNeededJunctions from AddJunctionsIfNeeded

This commit is contained in:
Roberto Fernandez Bautista 2022-08-18 20:52:31 +01:00
parent 22cc861c9b
commit c7f33e21f8
3 changed files with 60 additions and 41 deletions

View File

@ -1431,6 +1431,56 @@ std::vector<VECTOR2I> SCH_SCREEN::GetConnections() const
}
std::vector<VECTOR2I> SCH_SCREEN::GetNeededJunctions( const std::deque<EDA_ITEM*>& aItems ) const
{
std::vector<VECTOR2I> pts;
std::vector<VECTOR2I> connections = GetConnections();
for( const EDA_ITEM* edaItem : aItems )
{
const SCH_ITEM* item = dynamic_cast<const SCH_ITEM*>( edaItem );
if( !item || !item->IsConnectable() )
continue;
std::vector<VECTOR2I> new_pts = item->GetConnectionPoints();
pts.insert( pts.end(), new_pts.begin(), new_pts.end() );
// If the item is a line, we also add any connection points from the rest of the schematic
// that terminate on the line after it is moved.
if( item->Type() == SCH_LINE_T )
{
SCH_LINE* line = (SCH_LINE*) item;
for( const VECTOR2I& pt : connections )
{
if( IsPointOnSegment( line->GetStartPoint(), line->GetEndPoint(), pt ) )
pts.push_back( pt );
}
}
}
// We always have some overlapping connection points. Drop duplicates here
std::sort( pts.begin(), pts.end(),
[]( const VECTOR2I& a, const VECTOR2I& b ) -> bool
{
return a.x < b.x || ( a.x == b.x && a.y < b.y );
} );
pts.erase( unique( pts.begin(), pts.end() ), pts.end() );
// We only want the needed junction points, remove all the others
pts.erase( std::remove_if( pts.begin(), pts.end(),
[this]( const VECTOR2I& a ) -> bool
{
return !IsExplicitJunctionNeeded( a );
} ),
pts.end() );
return pts;
}
SCH_LABEL_BASE* SCH_SCREEN::GetLabel( const VECTOR2I& aPosition, int aAccuracy ) const
{
for( SCH_ITEM* item : Items().Overlapping( aPosition, aAccuracy ) )

View File

@ -452,6 +452,14 @@ public:
*/
std::vector<VECTOR2I> GetConnections() const;
/**
* Return the unique set of points belonging to aItems where a junction is needed.
*
* @param aItems List of objects to check
* @return Points where a junction is needed
*/
std::vector<VECTOR2I> GetNeededJunctions( const std::deque<EDA_ITEM*>& aItems ) const;
/**
* Return a label item located at \a aPosition.
*

View File

@ -1288,47 +1288,8 @@ int SCH_LINE_WIRE_BUS_TOOL::AddJunctionsIfNeeded( EE_SELECTION* aSelection )
{
SCH_SCREEN* screen = m_frame->GetScreen();
std::vector<VECTOR2I> pts;
std::vector<VECTOR2I> connections = screen->GetConnections();
for( unsigned ii = 0; ii < aSelection->GetSize(); ii++ )
{
SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( aSelection->GetItem( ii ) );
if( !item || !item->IsConnectable() )
continue;
std::vector<VECTOR2I> new_pts = item->GetConnectionPoints();
pts.insert( pts.end(), new_pts.begin(), new_pts.end() );
// If the item is a line, we also add any connection points from the rest of the schematic
// that terminate on the line after it is moved.
if( item->Type() == SCH_LINE_T )
{
SCH_LINE* line = (SCH_LINE*) item;
for( const VECTOR2I& pt : connections )
{
if( IsPointOnSegment( line->GetStartPoint(), line->GetEndPoint(), pt ) )
pts.push_back( pt );
}
}
}
// We always have some overlapping connection points. Drop duplicates here
std::sort( pts.begin(), pts.end(),
[]( const VECTOR2I& a, const VECTOR2I& b ) -> bool
{
return a.x < b.x || ( a.x == b.x && a.y < b.y );
} );
pts.erase( unique( pts.begin(), pts.end() ), pts.end() );
for( const VECTOR2I& point : pts )
{
if( screen->IsExplicitJunctionNeeded( point ) )
m_frame->AddJunction( m_frame->GetScreen(), point, true, false );
}
for( const VECTOR2I& point : screen->GetNeededJunctions( aSelection->Items() ) )
m_frame->AddJunction( m_frame->GetScreen(), point, true, false );
return 0;
}