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; }
// 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; }