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 );
        }
    }
}
Exemple #3
0
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 );
        }
    }
}
Exemple #4
0
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;
}