int SCH_SCREEN::CountConnectedItems( const wxPoint& aPos, bool aTestJunctions ) const { SCH_ITEM* item; int count = 0; for( item = m_drawList.begin(); item; item = item->Next() ) { if( item->Type() == SCH_JUNCTION_T && !aTestJunctions ) continue; if( item->IsConnected( aPos ) ) count++; } return count; }
void SCH_SCREEN::addConnectedItemsToBlock( const wxPoint& position ) { SCH_ITEM* item; ITEM_PICKER picker; bool addinlist = true; for( item = m_drawList.begin(); item; item = item->Next() ) { picker.SetItem( item ); if( !item->IsConnectable() || !item->IsConnected( position ) || (item->GetFlags() & SKIP_STRUCT) ) continue; if( item->IsSelected() && item->Type() != SCH_LINE_T ) continue; // A line having 2 ends, it can be tested twice: one time per end if( item->Type() == SCH_LINE_T ) { if( ! item->IsSelected() ) // First time this line is tested item->SetFlags( SELECTED | STARTPOINT | ENDPOINT ); else // second time (or more) this line is tested addinlist = false; SCH_LINE* line = (SCH_LINE*) item; if( line->GetStartPoint() == position ) item->ClearFlags( STARTPOINT ); else if( line->GetEndPoint() == position ) item->ClearFlags( ENDPOINT ); } else item->SetFlags( SELECTED ); if( addinlist ) { picker.SetFlags( item->GetFlags() ); m_BlockLocate.GetItems().PushItem( picker ); } } }
void SCH_SCREEN::addConnectedItemsToBlock( const SCH_ITEM* aItem, const wxPoint& position ) { SCH_ITEM* item; ITEM_PICKER picker; for( item = m_drawList.begin(); item; item = item->Next() ) { if( !item->IsConnectable() || ( item->GetFlags() & SKIP_STRUCT ) || !item->CanConnect( aItem ) || item == aItem ) continue; // A line having 2 ends, it can be tested twice: one time per end if( item->Type() == SCH_LINE_T ) { SCH_LINE* line = (SCH_LINE*) item; if( !item->HitTest( position ) ) continue; // First time through. Flags set to denote an end that is not moving if( !item->IsSelected() ) item->SetFlags( CANDIDATE | STARTPOINT | ENDPOINT ); if( line->GetStartPoint() == position ) item->ClearFlags( STARTPOINT ); else if( line->GetEndPoint() == position ) item->ClearFlags( ENDPOINT ); else // This picks up items such as labels that can connect to the middle of a line item->ClearFlags( STARTPOINT | ENDPOINT ); } // We want to move a mid-connected label or bus entry when the full line is being moved else if( !item->IsSelected() && aItem->Type() == SCH_LINE_T && !( aItem->GetFlags() & ( ENDPOINT | STARTPOINT ) ) ) { std::vector< wxPoint > connections; item->GetConnectionPoints( connections ); for( auto conn : connections ) { if( aItem->HitTest( conn ) ) { item->SetFlags( CANDIDATE ); break; } } } if( item->IsSelected() ) continue; if( ( item->GetFlags() & CANDIDATE ) || item->IsConnected( position ) ) // Deal with all non-line items { item->ClearFlags( CANDIDATE ); item->SetFlags( SELECTED ); picker.SetItem( item ); picker.SetFlags( item->GetFlags() ); m_BlockLocate.GetItems().PushItem( picker ); } } }
bool SCH_SCREEN::IsJunctionNeeded( const wxPoint& aPosition, bool aNew ) { bool has_nonparallel[2] = { false }; int end_count[2] = { 0 }; int pin_count = 0; std::vector<SCH_LINE*> lines[2]; for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() ) { if( item->GetFlags() & STRUCT_DELETED ) continue; if( aNew && ( item->Type() == SCH_JUNCTION_T ) && ( item->HitTest( aPosition ) ) ) return false; if( ( item->Type() == SCH_LINE_T ) && ( item->HitTest( aPosition, 0 ) ) ) { if( item->GetLayer() == LAYER_WIRE ) lines[0].push_back( (SCH_LINE*) item ); else if( item->GetLayer() == LAYER_BUS ) lines[1].push_back( (SCH_LINE*) item ); } if( ( item->Type() == SCH_COMPONENT_T ) && ( item->IsConnected( aPosition ) ) ) pin_count++; } for( int i = 0; i < 2; i++ ) { bool removed_overlapping = false; end_count[i] = lines[i].size(); for( auto line = lines[i].begin(); line < lines[i].end(); line++ ) { // Consider ending on a line to be equivalent to two endpoints because // we will want to split the line if anything else connects if( !(*line)->IsEndPoint( aPosition ) ) end_count[i]++; for( auto second_line = lines[i].end() - 1; second_line > line; second_line-- ) { if( !(*line)->IsParallel( *second_line ) ) has_nonparallel[i] = true; else if( !removed_overlapping && (*line)->IsSameQuadrant( *second_line, aPosition ) ) { /** * Overlapping lines that point in the same direction should not be counted * as extra end_points. We remove the overlapping lines, being careful to only * remove them once. */ removed_overlapping = true; end_count[i]--; } } } } // // If there are three or more endpoints if( pin_count + end_count[0] > 2 ) return true; // If there is at least one segment that ends on a non-parallel line or // junction of two other lines if( has_nonparallel[0] && end_count[0] > 2 ) return true; // Check for bus - bus junction requirements if( has_nonparallel[1] && end_count[1] > 2 ) return true; return false; }