Пример #1
0
bool TRACKS_CLEANER::remove_duplicates_of_track( const TRACK *aTrack )
{
    bool modified = false;

    TRACK *nextsegment;
    for( TRACK *other = aTrack->Next(); other; other = nextsegment )
    {
        nextsegment = other->Next();

        // New netcode, break out (can't be there any other)
        if( aTrack->GetNetCode() != other->GetNetCode() )
            break;

        // Must be of the same type, on the same layer and the endpoints
        // must be the same (maybe swapped)
        if( (aTrack->Type() != other->Type()) &&
            (aTrack->GetLayer() != other->GetLayer()) )
        {
            if( ((aTrack->GetStart() == other->GetStart()) &&
                 (aTrack->GetEnd() == other->GetEnd())) ||
                ((aTrack->GetStart() == other->GetEnd()) &&
                 (aTrack->GetEnd() == other->GetStart())))
            {
                m_Brd->GetRatsnest()->Remove( other );
                other->ViewRelease();
                other->DeleteStructure();
                modified = true;
            }
        }
    }
    return modified;
}
Пример #2
0
bool TRACKS_CLEANER::merge_collinear_of_track( TRACK *aSegment )
{
    bool merged_this = false;

    // *WHY* doesn't C++ have prec and succ (or ++ --) like PASCAL?
    for( ENDPOINT_T endpoint = ENDPOINT_START; endpoint <= ENDPOINT_END;
            endpoint = ENDPOINT_T( endpoint + 1 ) )
    {
        // search for a possible segment connected to the current endpoint of the current one
        TRACK *other = aSegment->Next();
        if( other )
        {
            other = aSegment->GetTrack( other, NULL, endpoint, true, false );

            if( other )
            {
                // the two segments must have the same width and the other
                // cannot be a via
                if( (aSegment->GetWidth() == other->GetWidth()) &&
                        (other->Type() == PCB_TRACE_T) )
                {
                    // There can be only one segment connected
                    other->SetState( BUSY, true );
                    TRACK *yet_another = aSegment->GetTrack( m_Brd->m_Track, NULL,
                            endpoint, true, false );
                    other->SetState( BUSY, false );

                    if( !yet_another )
                    {
                        // Try to merge them
                        TRACK *segDelete = mergeCollinearSegmentIfPossible( aSegment,
                                other, endpoint );

                        // Merge succesful, the other one has to go away
                        if( segDelete )
                        {
                            m_Brd->GetRatsnest()->Remove( segDelete );
                            segDelete->ViewRelease();
                            segDelete->DeleteStructure();
                            merged_this = true;
                        }
                    }
                }
            }
        }
    }

    return merged_this;
}
Пример #3
0
/*
 *  Delete dangling tracks
 *  Vias:
 *  If a via is only connected to a dangling track, it also will be removed
 */
bool TRACKS_CLEANER::deleteUnconnectedTracks()
{
    if( m_Brd->m_Track == NULL )
        return false;

    bool modified = false;
    bool item_erased;
    do // Iterate when at least one track is deleted
    {
        item_erased = false;
        TRACK* next_track;
        for( TRACK *track = m_Brd->m_Track; track != NULL; track = next_track )
        {
            next_track = track->Next();

            bool flag_erase = false; // Start without a good reason to erase it

            /* if a track endpoint is not connected to a pad, test if
             * the endpoint is connected to another track or to a zone.
             * For via test, an enhancement could be to test if
             * connected to 2 items on different layers. Currently
             * a via must be connected to 2 items, that can be on the
             * same layer */

            // Check if there is nothing attached on the start
            if( !(track->GetState( START_ON_PAD )) )
                flag_erase |= testTrackEndpointDangling( track, ENDPOINT_START );

            // Check if there is nothing attached on the end
            if( !(track->GetState( END_ON_PAD )) )
                flag_erase |= testTrackEndpointDangling( track, ENDPOINT_END );

            if( flag_erase )
            {
                // remove segment from board
                m_Brd->GetRatsnest()->Remove( track );
                track->ViewRelease();
                track->DeleteStructure();

                /* keep iterating, because a track connected to the deleted track
                 * now perhaps is not connected and should be deleted */
                item_erased = true;
                modified = true;
            }
        }
    } while( item_erased );

    return modified;
}
Пример #4
0
// Delete null length track segments
bool TRACKS_CLEANER::delete_null_segments()
{
    TRACK *nextsegment;
    bool modified = false;

    // Delete null segments
    for( TRACK *segment = m_Brd->m_Track; segment; segment = nextsegment )
    {
        nextsegment = segment->Next();

        if( segment->IsNull() )     // Length segment = 0; delete it
        {
            m_Brd->GetRatsnest()->Remove( segment );
            segment->ViewRelease();
            segment->DeleteStructure();
            modified = true;
        }
    }
    return modified;
}
void DIALOG_GLOBAL_DELETION::AcceptPcbDelete( )
{
    bool gen_rastnest = false;

    m_Parent->SetCurItem( NULL );

    if( m_DelAlls->GetValue() )
    {
        m_Parent->Clear_Pcb( true );
    }
    else
    {
        if( !IsOK( this, _( "Are you sure you want to delete the selected items?" ) ) )
            return;

        BOARD*            pcb = m_Parent->GetBoard();
        PICKED_ITEMS_LIST pickersList;
        ITEM_PICKER       itemPicker( NULL, UR_DELETED );
        BOARD_ITEM*       item;
        BOARD_ITEM*       nextitem;
        RN_DATA*          ratsnest = pcb->GetRatsnest();

        LSET layers_filter = LSET().set();

        if( m_rbLayersOption->GetSelection() != 0 )     // Use current layer only
            layers_filter = LSET( ToLAYER_ID( m_currentLayer ) );

        if( m_DelZones->GetValue() )
        {
            int area_index = 0;
            item = pcb->GetArea( area_index );

            while( item )
            {
                if( layers_filter[item->GetLayer()] )
                {
                    itemPicker.SetItem( item );
                    pickersList.PushItem( itemPicker );
                    pcb->Remove( item );
                    item->ViewRelease();
                    ratsnest->Remove( item );
                    gen_rastnest = true;
                }
                else
                {
                    area_index++;
                }

                item = pcb->GetArea( area_index );
            }
        }

        if( m_DelDrawings->GetValue() || m_DelBoardEdges->GetValue() )
        {
            LSET masque_layer;

            if( m_DelDrawings->GetValue() )
                 masque_layer = LSET::AllNonCuMask().set( Edge_Cuts, false );

            if( m_DelBoardEdges->GetValue() )
                 masque_layer.set( Edge_Cuts );

            masque_layer &= layers_filter;

            for( item = pcb->m_Drawings; item; item = nextitem )
            {
                nextitem = item->Next();

                if( item->Type() == PCB_LINE_T  &&  masque_layer[item->GetLayer()] )
                {
                    itemPicker.SetItem( item );
                    pickersList.PushItem( itemPicker );
                    item->ViewRelease();
                    item->UnLink();
                }
            }
        }

        if( m_DelTexts->GetValue() )
        {
            LSET del_text_layers = layers_filter;

            for( item = pcb->m_Drawings; item; item = nextitem )
            {
                nextitem = item->Next();

                if( item->Type() == PCB_TEXT_T  &&  del_text_layers[item->GetLayer()] )
                {
                    itemPicker.SetItem( item );
                    pickersList.PushItem( itemPicker );
                    item->ViewRelease();
                    item->UnLink();
                }
            }
        }

        if( m_DelModules->GetValue() )
        {
            for( item = pcb->m_Modules; item; item = nextitem )
            {
                nextitem = item->Next();

                if( layers_filter[item->GetLayer()] &&
                    ( ( m_ModuleFilterNormal->GetValue() && !item->IsLocked() ) ||
                      ( m_ModuleFilterLocked->GetValue() && item->IsLocked() ) ) )
                {
                    itemPicker.SetItem( item );
                    pickersList.PushItem( itemPicker );
                    static_cast<MODULE*>( item )->RunOnChildren(
                            boost::bind( &KIGFX::VIEW_ITEM::ViewRelease, _1 ) );
                    ratsnest->Remove( item );
                    item->ViewRelease();
                    item->UnLink();
                    gen_rastnest = true;
                }
            }
        }

        if( m_DelTracks->GetValue() )
        {
            STATUS_FLAGS track_mask_filter = 0;

            if( !m_TrackFilterLocked->GetValue() )
                track_mask_filter |= TRACK_LOCKED;

            if( !m_TrackFilterAR->GetValue() )
                track_mask_filter |= TRACK_AR;

            TRACK* nexttrack;

            for( TRACK *track = pcb->m_Track; track; track = nexttrack )
            {
                nexttrack = track->Next();

                if( ( track->GetState( TRACK_LOCKED | TRACK_AR ) & track_mask_filter ) != 0 )
                    continue;

                if( ( track->GetState( TRACK_LOCKED | TRACK_AR ) == 0 ) &&
                    !m_TrackFilterNormal->GetValue() )
                    continue;

                if( ( track->Type() == PCB_VIA_T ) && !m_TrackFilterVias->GetValue() )
                    continue;

                if( ( track->GetLayerSet() & layers_filter ) == 0 )
                    continue;

                itemPicker.SetItem( track );
                pickersList.PushItem( itemPicker );
                track->ViewRelease();
                ratsnest->Remove( track );
                track->UnLink();
                gen_rastnest = true;
            }
        }

        if( pickersList.GetCount() )
            m_Parent->SaveCopyInUndoList( pickersList, UR_DELETED );

        if( m_DelMarkers->GetValue() )
            pcb->DeleteMARKERs();

        if( gen_rastnest )
            m_Parent->Compile_Ratsnest( NULL, true );

        if( m_Parent->IsGalCanvasActive() )
            pcb->GetRatsnest()->Recalculate();

    }

    m_Parent->GetCanvas()->Refresh();
    m_Parent->OnModify();

    EndModal( 1 );
}