Performance enhancements to zone filling & track DRC.
Significant improvement in fetch time for item clearances. On large boards with lots of nets, maybe 10% faster zone fills and about 2x speedup on track-to-track DRC.
This commit is contained in:
parent
d4054029cd
commit
7ce38ee6f8
|
@ -78,75 +78,30 @@ bool BOARD_CONNECTED_ITEM::SetNetCode( int aNetCode, bool aNoAssert )
|
|||
|
||||
int BOARD_CONNECTED_ITEM::GetClearance( BOARD_CONNECTED_ITEM* aItem ) const
|
||||
{
|
||||
NETCLASSPTR myclass = GetNetClass();
|
||||
int myClearance = m_netinfo->GetClearance();
|
||||
|
||||
// DO NOT use wxASSERT, because GetClearance is called inside an OnPaint event
|
||||
// and a call to wxASSERT can crash the application.
|
||||
if( myclass )
|
||||
{
|
||||
int myClearance = myclass->GetClearance();
|
||||
// @todo : after GetNetClass() is reliably not returning NULL, remove the
|
||||
// tests for if( myclass )
|
||||
if( m_netinfo->GetNet() == 0 )
|
||||
myClearance = GetBoard()->GetDesignSettings().GetDefault()->GetClearance();
|
||||
|
||||
if( aItem )
|
||||
{
|
||||
int hisClearance = aItem->GetClearance();
|
||||
return std::max( hisClearance, myClearance );
|
||||
}
|
||||
if( aItem )
|
||||
return std::max( myClearance, aItem->GetClearance() );
|
||||
|
||||
return myClearance;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogTrace( traceMask, "%s: NULL netclass,type %d", __func__, Type() );
|
||||
}
|
||||
|
||||
return 0;
|
||||
return myClearance;
|
||||
}
|
||||
|
||||
|
||||
NETCLASSPTR BOARD_CONNECTED_ITEM::GetNetClass() const
|
||||
{
|
||||
// It is important that this be implemented without any sequential searching.
|
||||
// Simple array lookups should be fine, performance-wise.
|
||||
BOARD* board = GetBoard();
|
||||
|
||||
// DO NOT use wxASSERT, because GetNetClass is called inside an OnPaint event
|
||||
// and a call to wxASSERT can crash the application.
|
||||
|
||||
if( board == NULL ) // Should not occur
|
||||
{
|
||||
wxLogTrace( traceMask, "%s: NULL board,type %d", __func__, Type() );
|
||||
|
||||
return NETCLASSPTR();
|
||||
}
|
||||
|
||||
NETCLASSPTR netclass;
|
||||
NETINFO_ITEM* net = board->FindNet( GetNetCode() );
|
||||
|
||||
if( net )
|
||||
{
|
||||
netclass = net->GetNetClass();
|
||||
|
||||
//DBG( if(!netclass) printf( "%s: NULL netclass,type %d", __func__, Type() );)
|
||||
}
|
||||
NETCLASSPTR netclass = m_netinfo->GetNetClass();
|
||||
|
||||
if( netclass )
|
||||
return netclass;
|
||||
else
|
||||
return board->GetDesignSettings().GetDefault();
|
||||
return GetBoard()->GetDesignSettings().GetDefault();
|
||||
}
|
||||
|
||||
|
||||
wxString BOARD_CONNECTED_ITEM::GetNetClassName() const
|
||||
{
|
||||
wxString name;
|
||||
NETCLASSPTR myclass = GetNetClass();
|
||||
|
||||
if( myclass )
|
||||
name = myclass->GetName();
|
||||
else
|
||||
name = NETCLASS::Default;
|
||||
|
||||
return name;
|
||||
return m_netinfo->GetClassName();
|
||||
}
|
||||
|
|
|
@ -202,9 +202,8 @@ public:
|
|||
|
||||
/**
|
||||
* Function GetClearance
|
||||
* returns the clearance when routing near aBoardItem
|
||||
*/
|
||||
int GetClearance( BOARD_ITEM* aBoardItem )
|
||||
int GetClearance()
|
||||
{
|
||||
wxASSERT( m_NetClass );
|
||||
return m_NetClass->GetClearance();
|
||||
|
|
|
@ -795,7 +795,7 @@ void DRC::testTracks( wxWindow *aActiveWindow, bool aShowProgressBar )
|
|||
}
|
||||
|
||||
// Test new segment against tracks and pads, optionally against copper zones
|
||||
if( !doTrackDrc( *seg_it, seg_it + 1, m_pcb->Tracks().end(), true, m_doZonesTest ) )
|
||||
if( !doTrackDrc( *seg_it, seg_it + 1, m_pcb->Tracks().end(), m_doZonesTest ) )
|
||||
{
|
||||
if( m_currentMarker )
|
||||
{
|
||||
|
|
|
@ -330,13 +330,12 @@ private:
|
|||
* @param aRefSeg The segment to test
|
||||
* @param aStartIt the iterator to the first track to test
|
||||
* @param aEndIt the marker for the iterator end
|
||||
* @param aTestPads true if should do pads test
|
||||
* @param aTestZones true if should do copper zones test. This can be very time consumming
|
||||
* @return bool - true if no problems, else false and m_currentMarker is
|
||||
* filled in with the problem information.
|
||||
*/
|
||||
bool doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterator aEndIt,
|
||||
bool aTestPads, bool aTestZones );
|
||||
bool aTestZones );
|
||||
|
||||
/**
|
||||
* Test for footprint courtyard overlaps.
|
||||
|
|
|
@ -111,12 +111,10 @@ bool poly2segmentDRC( wxPoint* aTref, int aTrefCount, wxPoint aSegStart, wxPoint
|
|||
|
||||
|
||||
bool DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterator aEndIt,
|
||||
bool aTestPads, bool aTestZones )
|
||||
bool aTestZones )
|
||||
{
|
||||
TRACK* track;
|
||||
wxPoint delta; // length on X and Y axis of segments
|
||||
LSET layerMask;
|
||||
int net_code_ref;
|
||||
wxPoint shape_pos;
|
||||
|
||||
std::vector<MARKER_PCB*> markers;
|
||||
|
@ -156,8 +154,11 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
m_segmEnd = delta = aRefSeg->GetEnd() - origin;
|
||||
m_segmAngle = 0;
|
||||
|
||||
layerMask = aRefSeg->GetLayerSet();
|
||||
net_code_ref = aRefSeg->GetNetCode();
|
||||
LSET layerMask = aRefSeg->GetLayerSet();
|
||||
int net_code_ref = aRefSeg->GetNetCode();
|
||||
int ref_seg_clearance = netclass->GetClearance();
|
||||
int ref_seg_width = aRefSeg->GetWidth();
|
||||
|
||||
|
||||
/******************************************/
|
||||
/* Phase 0 : via DRC tests : */
|
||||
|
@ -265,7 +266,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
}
|
||||
else // This is a track segment
|
||||
{
|
||||
if( aRefSeg->GetWidth() < dsnSettings.m_TrackMinWidth )
|
||||
if( ref_seg_width < dsnSettings.m_TrackMinWidth )
|
||||
{
|
||||
wxPoint refsegMiddle = ( aRefSeg->GetStart() + aRefSeg->GetEnd() ) / 2;
|
||||
|
||||
|
@ -308,28 +309,18 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
dummypad.SetLayerSet( LSET::AllCuMask() ); // Ensure the hole is on all layers
|
||||
|
||||
// Compute the min distance to pads
|
||||
if( aTestPads )
|
||||
for( MODULE* mod : m_pcb->Modules() )
|
||||
{
|
||||
unsigned pad_count = m_pcb->GetPadCount();
|
||||
|
||||
auto pads = m_pcb->GetPads();
|
||||
|
||||
for( unsigned ii = 0; ii < pad_count; ++ii )
|
||||
for( D_PAD* pad : mod->Pads() )
|
||||
{
|
||||
D_PAD* pad = pads[ii];
|
||||
SEG padSeg( pad->GetPosition(), pad->GetPosition() );
|
||||
|
||||
|
||||
/* No problem if pads are on another layer,
|
||||
* But if a drill hole exists (a pad on a single layer can have a hole!)
|
||||
* we must test the hole
|
||||
*/
|
||||
// No problem if pads are on another layer, but if a drill hole exists (a pad on
|
||||
// a single layer can have a hole!) we must test the hole
|
||||
if( !( pad->GetLayerSet() & layerMask ).any() )
|
||||
{
|
||||
/* We must test the pad hole. In order to use the function
|
||||
* checkClearanceSegmToPad(),a pseudo pad is used, with a shape and a
|
||||
* size like the hole
|
||||
*/
|
||||
// We must test the pad hole. In order to use checkClearanceSegmToPad(), a
|
||||
// pseudo pad is used, with a shape and a size like the hole
|
||||
if( pad->GetDrillSize().x == 0 )
|
||||
continue;
|
||||
|
||||
|
@ -341,8 +332,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
|
||||
m_padToTestPos = dummypad.GetPosition() - origin;
|
||||
|
||||
if( !checkClearanceSegmToPad( &dummypad, aRefSeg->GetWidth(),
|
||||
netclass->GetClearance() ) )
|
||||
if( !checkClearanceSegmToPad( &dummypad, ref_seg_width, ref_seg_clearance ) )
|
||||
{
|
||||
markers.PUSH_NEW_MARKER_4( aRefSeg, pad, padSeg, DRCE_TRACK_NEAR_THROUGH_HOLE );
|
||||
|
||||
|
@ -362,8 +352,9 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
// DRC for the pad
|
||||
shape_pos = pad->ShapePos();
|
||||
m_padToTestPos = shape_pos - origin;
|
||||
int segToPadClearance = std::max( ref_seg_clearance, pad->GetClearance() );
|
||||
|
||||
if( !checkClearanceSegmToPad( pad, aRefSeg->GetWidth(), aRefSeg->GetClearance( pad ) ) )
|
||||
if( !checkClearanceSegmToPad( pad, ref_seg_width, segToPadClearance ) )
|
||||
{
|
||||
markers.PUSH_NEW_MARKER_4( aRefSeg, pad, padSeg, DRCE_TRACK_NEAR_PAD );
|
||||
|
||||
|
@ -396,8 +387,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
|
||||
// the minimum distance = clearance plus half the reference track
|
||||
// width plus half the other track's width
|
||||
int w_dist = aRefSeg->GetClearance( track );
|
||||
w_dist += ( aRefSeg->GetWidth() + track->GetWidth() ) / 2;
|
||||
int w_dist = std::max( ref_seg_clearance, track->GetClearance() );
|
||||
w_dist += ( ref_seg_width + track->GetWidth() ) / 2;
|
||||
|
||||
// Due to many double to int conversions during calculations, which
|
||||
// create rounding issues,
|
||||
|
@ -680,10 +671,10 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
if( zone->GetNetCode() && zone->GetNetCode() == net_code_ref )
|
||||
continue;
|
||||
|
||||
int clearance = zone->GetClearance( aRefSeg );
|
||||
int clearance = std::max( ref_seg_clearance, zone->GetClearance() );
|
||||
SHAPE_POLY_SET* outline = const_cast<SHAPE_POLY_SET*>( &zone->GetFilledPolysList() );
|
||||
|
||||
if( outline->Distance( refSeg, aRefSeg->GetWidth() ) < clearance )
|
||||
if( outline->Distance( refSeg, ref_seg_width ) < clearance )
|
||||
addMarkerToPcb( m_markerFactory.NewMarker( aRefSeg, zone, DRCE_TRACK_NEAR_ZONE ) );
|
||||
}
|
||||
}
|
||||
|
@ -694,10 +685,10 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
{
|
||||
SEG test_seg( aRefSeg->GetStart(), aRefSeg->GetEnd() );
|
||||
|
||||
int clearance = std::max( aRefSeg->GetClearance(), dsnSettings.m_CopperEdgeClearance );
|
||||
int clearance = std::max( ref_seg_clearance, dsnSettings.m_CopperEdgeClearance );
|
||||
|
||||
// the minimum distance = clearance plus half the reference track width
|
||||
SEG::ecoord w_dist = clearance + aRefSeg->GetWidth() / 2;
|
||||
SEG::ecoord w_dist = clearance + ref_seg_width / 2;
|
||||
SEG::ecoord w_dist_sq = w_dist * w_dist;
|
||||
|
||||
for( auto it = m_board_outlines.IterateSegmentsWithHoles(); it; it++ )
|
||||
|
|
Loading…
Reference in New Issue