Example #1
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;
}
Example #2
0
// Delete null length segments, and intermediate points ..
bool TRACKS_CLEANER::clean_segments()
{
    bool modified = false;
    TRACK*          segment, * nextsegment;
    TRACK*          other;
    int             flag, no_inc;


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

        if( segment->IsNull() )     // Length segment = 0; delete it
            segment->DeleteStructure();
    }

    // Delete redundant segments, i.e. segments having the same end points
    // and layers
    for( segment  = m_Brd->m_Track; segment; segment = segment->Next() )
    {
        for( other = segment->Next(); other; other = nextsegment )
        {
            nextsegment = other->Next();
            bool erase = false;

            if( segment->Type() != other->Type() )
                continue;

            if( segment->GetLayer() != other->GetLayer() )
                continue;

            if( segment->GetNetCode() != other->GetNetCode() )
                break;

            if( ( segment->GetStart() == other->GetStart() ) &&
                ( segment->GetEnd() == other->GetEnd() ) )
                erase = true;

            if( ( segment->GetStart() == other->GetEnd() ) &&
                ( segment->GetEnd() == other->GetStart() ) )
                erase = true;

            // Delete redundant point
            if( erase )
            {
                other->DeleteStructure();
                modified = true;
            }
        }
    }

    // merge collinear segments:
    for( segment = m_Brd->m_Track; segment; segment = nextsegment )
    {
        TRACK*  segStart;
        TRACK*  segEnd;
        TRACK*  segDelete;

        nextsegment = segment->Next();

        if( segment->Type() != PCB_TRACE_T )
            continue;

        flag = no_inc = 0;

        // search for a possible point connected to the START point of the current segment
        for( segStart = segment->Next(); ; )
        {
            segStart = segment->GetTrace( segStart, NULL, FLG_START );

            if( segStart )
            {
                // the two segments must have the same width
                if( segment->GetWidth() != segStart->GetWidth() )
                    break;

                // it cannot be a via
                if( segStart->Type() != PCB_TRACE_T )
                    break;

                // We must have only one segment connected
                segStart->SetState( BUSY, true );
                other = segment->GetTrace( m_Brd->m_Track, NULL, FLG_START );
                segStart->SetState( BUSY, false );

                if( other == NULL )
                    flag = 1;           // OK

                break;
            }
            break;
        }

        if( flag )   // We have the starting point of the segment is connected to an other segment
        {
            segDelete = mergeCollinearSegmentIfPossible( segment, segStart, FLG_START );

            if( segDelete )
            {
                no_inc = 1;
                segDelete->DeleteStructure();
                modified = true;
            }
        }

        // search for a possible point connected to the END point of the current segment:
        for( segEnd = segment->Next(); ; )
        {
            segEnd = segment->GetTrace( segEnd, NULL, FLG_END );

            if( segEnd )
            {
                if( segment->GetWidth() != segEnd->GetWidth() )
                    break;

                if( segEnd->Type() != PCB_TRACE_T )
                    break;

                // We must have only one segment connected
                segEnd->SetState( BUSY, true );
                other = segment->GetTrace( m_Brd->m_Track, NULL, FLG_END );
                segEnd->SetState( BUSY, false );

                if( other == NULL )
                    flag |= 2;          // Ok

                break;
            }
            else
            {
                break;
            }
        }

        if( flag & 2 )  // We have the ending point of the segment is connected to an other segment
        {
            segDelete = mergeCollinearSegmentIfPossible( segment, segEnd, FLG_END );

            if( segDelete )
            {
                no_inc = 1;
                segDelete->DeleteStructure();
                modified = true;
            }
        }

        if( no_inc ) // The current segment was modified, retry to merge it
            nextsegment = segment->Next();
    }

    return modified;
}