More performance enhancements for DRC.
This commit is contained in:
parent
5da817649b
commit
82ebc247b8
|
@ -476,7 +476,17 @@ static inline bool Collide( const SHAPE_LINE_CHAIN_BASE& aA, const SHAPE_SEGMENT
|
|||
static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_RECT& aB, int aClearance,
|
||||
int* aActual, VECTOR2I* aLocation, VECTOR2I* aMTV )
|
||||
{
|
||||
return Collide( aA.Outline(), aB.Outline(), aClearance, aActual, aLocation, aMTV );
|
||||
if( aClearance || aActual || aLocation || aMTV )
|
||||
{
|
||||
return Collide( aA.Outline(), aB.Outline(), aClearance, aActual, aLocation, aMTV );
|
||||
}
|
||||
else
|
||||
{
|
||||
BOX2I bboxa = aA.BBox();
|
||||
BOX2I bboxb = aB.BBox();
|
||||
|
||||
return bboxa.Intersects( bboxb );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015 CERN
|
||||
* Copyright (C) 2015-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -25,10 +26,11 @@
|
|||
|
||||
#include <geometry/shape_rect.h>
|
||||
|
||||
bool SHAPE_RECT::Collide( const SEG& aSeg, int aClearance, int* aActual,
|
||||
VECTOR2I* aLocation ) const
|
||||
bool SHAPE_RECT::Collide( const SEG& aSeg, int aClearance, int* aActual, VECTOR2I* aLocation ) const
|
||||
{
|
||||
if( BBox( 0 ).Contains( aSeg.A ) )
|
||||
BOX2I bbox( BBox() );
|
||||
|
||||
if( bbox.Contains( aSeg.A ) )
|
||||
{
|
||||
if( aLocation )
|
||||
*aLocation = aSeg.A;
|
||||
|
@ -39,7 +41,7 @@ bool SHAPE_RECT::Collide( const SEG& aSeg, int aClearance, int* aActual,
|
|||
return true;
|
||||
}
|
||||
|
||||
if( BBox( 0 ).Contains( aSeg.B ) )
|
||||
if( bbox.Contains( aSeg.B ) )
|
||||
{
|
||||
if( aLocation )
|
||||
*aLocation = aSeg.B;
|
||||
|
|
|
@ -664,25 +664,29 @@ void CN_CONNECTIVITY_ALGO::FindIsolatedCopperIslands( ZONE* aZone, PCB_LAYER_ID
|
|||
wxLogTrace( wxT( "CN" ), wxT( "Found %u isolated islands\n" ), (unsigned) aIslands.size() );
|
||||
}
|
||||
|
||||
void CN_CONNECTIVITY_ALGO::FindIsolatedCopperIslands( std::vector<CN_ZONE_ISOLATED_ISLAND_LIST>& aZones )
|
||||
void CN_CONNECTIVITY_ALGO::FindIsolatedCopperIslands( std::vector<CN_ZONE_ISOLATED_ISLAND_LIST>& aZones,
|
||||
bool aConnectivityAlreadyRebuilt )
|
||||
{
|
||||
int delta = 10; // Number of additions between 2 calls to the progress bar
|
||||
int ii = 0;
|
||||
|
||||
for( CN_ZONE_ISOLATED_ISLAND_LIST& z : aZones )
|
||||
if( !aConnectivityAlreadyRebuilt )
|
||||
{
|
||||
Remove( z.m_zone );
|
||||
Add( z.m_zone );
|
||||
ii++;
|
||||
|
||||
if( m_progressReporter && ( ii % delta ) == 0 )
|
||||
for( CN_ZONE_ISOLATED_ISLAND_LIST& z : aZones )
|
||||
{
|
||||
m_progressReporter->SetCurrentProgress( (double) ii / (double) aZones.size() );
|
||||
m_progressReporter->KeepRefreshing( false );
|
||||
}
|
||||
Remove( z.m_zone );
|
||||
Add( z.m_zone );
|
||||
ii++;
|
||||
|
||||
if( m_progressReporter && m_progressReporter->IsCancelled() )
|
||||
return;
|
||||
if( m_progressReporter && ( ii % delta ) == 0 )
|
||||
{
|
||||
m_progressReporter->SetCurrentProgress( (double) ii / (double) aZones.size() );
|
||||
m_progressReporter->KeepRefreshing( false );
|
||||
}
|
||||
|
||||
if( m_progressReporter && m_progressReporter->IsCancelled() )
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_connClusters = SearchClusters( CSM_CONNECTIVITY_CHECK );
|
||||
|
|
|
@ -224,7 +224,8 @@ public:
|
|||
*
|
||||
* @param: aZones is the set of zones to search for islands.
|
||||
*/
|
||||
void FindIsolatedCopperIslands( std::vector<CN_ZONE_ISOLATED_ISLAND_LIST>& aZones );
|
||||
void FindIsolatedCopperIslands( std::vector<CN_ZONE_ISOLATED_ISLAND_LIST>& aZones,
|
||||
bool aConnectivityAlreadyRebuilt );
|
||||
|
||||
const CLUSTERS& GetClusters();
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include <ratsnest/ratsnest_data.h>
|
||||
#include <progress_reporter.h>
|
||||
#include <trigo.h>
|
||||
#include <drc/drc_rtree.h>
|
||||
|
||||
CONNECTIVITY_DATA::CONNECTIVITY_DATA()
|
||||
{
|
||||
|
@ -312,9 +313,10 @@ void CONNECTIVITY_DATA::FindIsolatedCopperIslands( ZONE* aZone, std::vector<int>
|
|||
#endif
|
||||
}
|
||||
|
||||
void CONNECTIVITY_DATA::FindIsolatedCopperIslands( std::vector<CN_ZONE_ISOLATED_ISLAND_LIST>& aZones )
|
||||
void CONNECTIVITY_DATA::FindIsolatedCopperIslands( std::vector<CN_ZONE_ISOLATED_ISLAND_LIST>& aZones,
|
||||
bool aConnectivityAlreadyRebuilt )
|
||||
{
|
||||
m_connAlgo->FindIsolatedCopperIslands( aZones );
|
||||
m_connAlgo->FindIsolatedCopperIslands( aZones, aConnectivityAlreadyRebuilt );
|
||||
}
|
||||
|
||||
|
||||
|
@ -740,14 +742,32 @@ bool CONNECTIVITY_DATA::TestTrackEndpointDangling( PCB_TRACK* aTrack, VECTOR2I*
|
|||
for( CN_ITEM* connected : citem->ConnectedItems() )
|
||||
{
|
||||
BOARD_CONNECTED_ITEM* item = connected->Parent();
|
||||
ZONE* zone = dynamic_cast<ZONE*>( item );
|
||||
DRC_RTREE* rtree = nullptr;
|
||||
bool hitStart = false;
|
||||
bool hitEnd = false;
|
||||
|
||||
if( item->GetFlags() & IS_DELETED )
|
||||
continue;
|
||||
|
||||
std::shared_ptr<SHAPE> shape = item->GetEffectiveShape( layer );
|
||||
if( zone )
|
||||
rtree = zone->GetBoard()->m_CopperZoneRTreeCache[ zone ].get();
|
||||
|
||||
bool hitStart = shape->Collide( aTrack->GetStart(), accuracy );
|
||||
bool hitEnd = shape->Collide( aTrack->GetEnd(), accuracy );
|
||||
if( rtree )
|
||||
{
|
||||
SHAPE_CIRCLE start( aTrack->GetStart(), accuracy );
|
||||
SHAPE_CIRCLE end( aTrack->GetEnd(), accuracy );
|
||||
|
||||
hitStart = rtree->QueryColliding( start.BBox(), &start, layer );
|
||||
hitEnd = rtree->QueryColliding( end.BBox(), &end, layer );
|
||||
}
|
||||
else
|
||||
{
|
||||
std::shared_ptr<SHAPE> shape = item->GetEffectiveShape( layer );
|
||||
|
||||
hitStart = shape->Collide( aTrack->GetStart(), accuracy );
|
||||
hitEnd = shape->Collide( aTrack->GetEnd(), accuracy );
|
||||
}
|
||||
|
||||
if( hitStart && hitEnd )
|
||||
{
|
||||
|
|
|
@ -185,7 +185,8 @@ public:
|
|||
* @param aIslands list of islands that have no connections (outline indices in the polygon set)
|
||||
*/
|
||||
void FindIsolatedCopperIslands( ZONE* aZone, std::vector<int>& aIslands );
|
||||
void FindIsolatedCopperIslands( std::vector<CN_ZONE_ISOLATED_ISLAND_LIST>& aZones );
|
||||
void FindIsolatedCopperIslands( std::vector<CN_ZONE_ISOLATED_ISLAND_LIST>& aZones,
|
||||
bool aConnectivityAlreadyRebuilt = false );
|
||||
|
||||
/**
|
||||
* Function RecalculateRatsnest()
|
||||
|
|
|
@ -85,7 +85,7 @@ bool DRC_TEST_PROVIDER_CONNECTIVITY::Run()
|
|||
// Rebuild just in case. This really needs to be reliable.
|
||||
connectivity->Clear();
|
||||
connectivity->Build( board, m_drcEngine->GetProgressReporter() );
|
||||
connectivity->FindIsolatedCopperIslands( islandsList );
|
||||
connectivity->FindIsolatedCopperIslands( islandsList, true );
|
||||
|
||||
int delta = 100; // This is the number of tests between 2 calls to the progress bar
|
||||
int ii = 0;
|
||||
|
|
|
@ -94,7 +94,6 @@ private:
|
|||
|
||||
std::unique_ptr<DRC_RTREE> m_tesselatedTree;
|
||||
std::unique_ptr<DRC_RTREE> m_itemTree;
|
||||
std::vector<ZONE*> m_copperZones;
|
||||
|
||||
std::map< std::tuple<BOARD_ITEM*, BOARD_ITEM*, PCB_LAYER_ID>, int> m_checkedPairs;
|
||||
|
||||
|
@ -121,9 +120,6 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::addItemToRTrees( BOARD_ITEM* item )
|
|||
SHAPE_POLY_SET::PM_FAST );
|
||||
}
|
||||
}
|
||||
|
||||
if( zone->IsOnCopperLayer() && !zone->GetIsRuleArea() )
|
||||
m_copperZones.push_back( zone );
|
||||
}
|
||||
else if( item->Type() == PCB_PAD_T )
|
||||
{
|
||||
|
@ -188,10 +184,6 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::buildRTrees()
|
|||
|
||||
m_tesselatedTree = std::make_unique<DRC_RTREE>();
|
||||
m_itemTree = std::make_unique<DRC_RTREE>();
|
||||
m_copperZones.clear();
|
||||
|
||||
// Unlikely to be correct, but better than starting at 0
|
||||
m_copperZones.reserve( m_board->Zones().size() );
|
||||
|
||||
forEachGeometryItem( s_allBasicItems, layers,
|
||||
[&]( BOARD_ITEM* item ) -> bool
|
||||
|
@ -495,7 +487,7 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::testMaskItemAgainstZones( BOARD_ITEM* aItem,
|
|||
PCB_LAYER_ID aMaskLayer,
|
||||
PCB_LAYER_ID aTargetLayer )
|
||||
{
|
||||
for( ZONE* zone : m_copperZones )
|
||||
for( ZONE* zone : m_board->m_DRCCopperZones )
|
||||
{
|
||||
if( !zone->GetLayerSet().test( aTargetLayer ) )
|
||||
continue;
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <board.h>
|
||||
#include <board_design_settings.h>
|
||||
#include <connectivity/connectivity_data.h>
|
||||
|
@ -65,132 +67,163 @@ public:
|
|||
{
|
||||
return wxT( "Checks thermal reliefs for a sufficient number of connecting spokes" );
|
||||
}
|
||||
|
||||
private:
|
||||
void testZoneLayer( ZONE* aZone, PCB_LAYER_ID aLayer );
|
||||
};
|
||||
|
||||
bool DRC_TEST_PROVIDER_ZONE_CONNECTIONS::Run()
|
||||
{
|
||||
const int delta = 5; // This is the number of tests between 2 calls to the progress bar
|
||||
int ii = 0;
|
||||
|
||||
void DRC_TEST_PROVIDER_ZONE_CONNECTIONS::testZoneLayer( ZONE* aZone, PCB_LAYER_ID aLayer )
|
||||
{
|
||||
BOARD* board = m_drcEngine->GetBoard();
|
||||
BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
|
||||
std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->GetConnectivity();
|
||||
DRC_CONSTRAINT constraint;
|
||||
|
||||
const std::shared_ptr<SHAPE_POLY_SET>& zoneFill = aZone->GetFilledPolysList( aLayer );
|
||||
|
||||
for( FOOTPRINT* footprint : board->Footprints() )
|
||||
{
|
||||
for( PAD* pad : footprint->Pads() )
|
||||
{
|
||||
if( m_drcEngine->IsErrorLimitExceeded( DRCE_STARVED_THERMAL ) )
|
||||
return;
|
||||
|
||||
if( m_drcEngine->IsCancelled() )
|
||||
return;
|
||||
|
||||
// Quick tests for "connected":
|
||||
//
|
||||
if( !pad->FlashLayer( aLayer ) )
|
||||
continue;
|
||||
|
||||
if( pad->GetNetCode() != aZone->GetNetCode() || pad->GetNetCode() <= 0 )
|
||||
continue;
|
||||
|
||||
EDA_RECT item_boundingbox = pad->GetBoundingBox();
|
||||
|
||||
if( !item_boundingbox.Intersects( aZone->GetCachedBoundingBox() ) )
|
||||
continue;
|
||||
|
||||
// If those passed, do a thorough test:
|
||||
//
|
||||
constraint = bds.m_DRCEngine->EvalZoneConnection( pad, aZone, aLayer );
|
||||
ZONE_CONNECTION conn = constraint.m_ZoneConnection;
|
||||
|
||||
if( conn != ZONE_CONNECTION::THERMAL )
|
||||
continue;
|
||||
|
||||
constraint = bds.m_DRCEngine->EvalRules( MIN_RESOLVED_SPOKES_CONSTRAINT, pad, aZone,
|
||||
aLayer );
|
||||
int minCount = constraint.m_Value.Min();
|
||||
|
||||
if( constraint.GetSeverity() == RPT_SEVERITY_IGNORE || minCount <= 0 )
|
||||
continue;
|
||||
|
||||
SHAPE_POLY_SET padPoly;
|
||||
pad->TransformShapeWithClearanceToPolygon( padPoly, aLayer, 0, ARC_LOW_DEF,
|
||||
ERROR_OUTSIDE );
|
||||
|
||||
SHAPE_LINE_CHAIN& padOutline = padPoly.Outline( 0 );
|
||||
std::vector<SHAPE_LINE_CHAIN::INTERSECTION> intersections;
|
||||
int spokes = 0;
|
||||
|
||||
for( int jj = 0; jj < zoneFill->OutlineCount(); ++jj )
|
||||
padOutline.Intersect( zoneFill->Outline( jj ), intersections, true );
|
||||
|
||||
spokes += intersections.size() / 2;
|
||||
|
||||
if( spokes <= 0 )
|
||||
continue;
|
||||
|
||||
// Now we know we're connected, so see if there are any other manual spokes
|
||||
// added:
|
||||
//
|
||||
for( PCB_TRACK* track : connectivity->GetConnectedTracks( pad ) )
|
||||
{
|
||||
if( padOutline.PointInside( track->GetStart() ) )
|
||||
{
|
||||
if( aZone->GetFilledPolysList( aLayer )->Collide( track->GetEnd() ) )
|
||||
spokes++;
|
||||
}
|
||||
else if( padOutline.PointInside( track->GetEnd() ) )
|
||||
{
|
||||
if( aZone->GetFilledPolysList( aLayer )->Collide( track->GetStart() ) )
|
||||
spokes++;
|
||||
}
|
||||
}
|
||||
|
||||
// And finally report it if there aren't enough:
|
||||
//
|
||||
if( spokes < minCount )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_STARVED_THERMAL );
|
||||
wxString msg;
|
||||
|
||||
msg.Printf( _( "(%s min spoke count %d; actual %d)" ),
|
||||
constraint.GetName(),
|
||||
minCount,
|
||||
spokes );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
||||
drce->SetItems( aZone, pad );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
reportViolation( drce, pad->GetPosition(), UNDEFINED_LAYER );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool DRC_TEST_PROVIDER_ZONE_CONNECTIONS::Run()
|
||||
{
|
||||
BOARD* board = m_drcEngine->GetBoard();
|
||||
BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
|
||||
std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->GetConnectivity();
|
||||
DRC_CONSTRAINT constraint;
|
||||
std::vector<ZONE*> zones;
|
||||
|
||||
if( !reportPhase( _( "Checking thermal reliefs..." ) ) )
|
||||
return false; // DRC cancelled
|
||||
|
||||
for( ZONE* zone : board->Zones() )
|
||||
zones.push_back( zone );
|
||||
std::vector< std::pair<ZONE*, PCB_LAYER_ID> > zoneLayers;
|
||||
|
||||
for( FOOTPRINT* footprint : board->Footprints() )
|
||||
for( ZONE* zone : board->m_DRCCopperZones )
|
||||
{
|
||||
for( ZONE* zone : footprint->Zones() )
|
||||
zones.push_back( zone );
|
||||
for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() )
|
||||
zoneLayers.push_back( { zone, layer } );
|
||||
}
|
||||
|
||||
for( ZONE* zone : zones )
|
||||
int zoneLayerCount = zoneLayers.size();
|
||||
std::atomic<size_t> next( 0 );
|
||||
std::atomic<size_t> done( 1 );
|
||||
std::atomic<size_t> threads_finished( 0 );
|
||||
size_t parallelThreadCount = std::max<size_t>( std::thread::hardware_concurrency(), 2 );
|
||||
|
||||
for( size_t ii = 0; ii < parallelThreadCount; ++ii )
|
||||
{
|
||||
if( !reportProgress( ii++, zones.size(), delta ) )
|
||||
return false;
|
||||
|
||||
for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() )
|
||||
{
|
||||
const std::shared_ptr<SHAPE_POLY_SET>& zoneFill = zone->GetFilledPolysList( layer );
|
||||
|
||||
for( FOOTPRINT* footprint : board->Footprints() )
|
||||
{
|
||||
for( PAD* pad : footprint->Pads() )
|
||||
std::thread t = std::thread(
|
||||
[&]( )
|
||||
{
|
||||
if( m_drcEngine->IsErrorLimitExceeded( DRCE_STARVED_THERMAL ) )
|
||||
return true;
|
||||
|
||||
if( m_drcEngine->IsCancelled() )
|
||||
return false;
|
||||
|
||||
// Quick tests for "connected":
|
||||
//
|
||||
if( !pad->FlashLayer( layer ) )
|
||||
continue;
|
||||
|
||||
if( pad->GetNetCode() != zone->GetNetCode() || pad->GetNetCode() <= 0 )
|
||||
continue;
|
||||
|
||||
EDA_RECT item_boundingbox = pad->GetBoundingBox();
|
||||
|
||||
if( !item_boundingbox.Intersects( zone->GetCachedBoundingBox() ) )
|
||||
continue;
|
||||
|
||||
// If those passed, do a thorough test:
|
||||
//
|
||||
constraint = bds.m_DRCEngine->EvalZoneConnection( pad, zone, layer );
|
||||
ZONE_CONNECTION conn = constraint.m_ZoneConnection;
|
||||
|
||||
if( conn != ZONE_CONNECTION::THERMAL )
|
||||
continue;
|
||||
|
||||
constraint = bds.m_DRCEngine->EvalRules( MIN_RESOLVED_SPOKES_CONSTRAINT,
|
||||
pad, zone, layer );
|
||||
int minCount = constraint.m_Value.Min();
|
||||
|
||||
if( constraint.GetSeverity() == RPT_SEVERITY_IGNORE || minCount <= 0 )
|
||||
continue;
|
||||
|
||||
SHAPE_POLY_SET padPoly;
|
||||
pad->TransformShapeWithClearanceToPolygon( padPoly, layer, 0, ARC_LOW_DEF,
|
||||
ERROR_OUTSIDE );
|
||||
|
||||
SHAPE_LINE_CHAIN& padOutline = padPoly.Outline( 0 );
|
||||
std::vector<SHAPE_LINE_CHAIN::INTERSECTION> intersections;
|
||||
int spokes = 0;
|
||||
|
||||
for( int jj = 0; jj < zoneFill->OutlineCount(); ++jj )
|
||||
padOutline.Intersect( zoneFill->Outline( jj ), intersections, true );
|
||||
|
||||
spokes += intersections.size() / 2;
|
||||
|
||||
if( spokes <= 0 )
|
||||
continue;
|
||||
|
||||
// Now we know we're connected, so see if there are any other manual spokes
|
||||
// added:
|
||||
//
|
||||
for( PCB_TRACK* track : connectivity->GetConnectedTracks( pad ) )
|
||||
for( int i = next.fetch_add( 1 ); i < zoneLayerCount; i = next.fetch_add( 1 ) )
|
||||
{
|
||||
if( padOutline.PointInside( track->GetStart() ) )
|
||||
{
|
||||
if( zone->GetFilledPolysList( layer )->Collide( track->GetEnd() ) )
|
||||
spokes++;
|
||||
}
|
||||
else if( padOutline.PointInside( track->GetEnd() ) )
|
||||
{
|
||||
if( zone->GetFilledPolysList( layer )->Collide( track->GetStart() ) )
|
||||
spokes++;
|
||||
}
|
||||
testZoneLayer( zoneLayers[i].first, zoneLayers[i].second );
|
||||
done.fetch_add( 1 );
|
||||
|
||||
if( m_drcEngine->IsCancelled() )
|
||||
break;
|
||||
}
|
||||
|
||||
// And finally report it if there aren't enough:
|
||||
//
|
||||
if( spokes < minCount )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_STARVED_THERMAL );
|
||||
wxString msg;
|
||||
threads_finished.fetch_add( 1 );
|
||||
} );
|
||||
|
||||
msg.Printf( _( "(%s min spoke count %d; actual %d)" ),
|
||||
constraint.GetName(),
|
||||
minCount,
|
||||
spokes );
|
||||
t.detach();
|
||||
}
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
||||
drce->SetItems( zone, pad );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
reportViolation( drce, pad->GetPosition(), UNDEFINED_LAYER );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while( threads_finished < parallelThreadCount )
|
||||
{
|
||||
m_drcEngine->ReportProgress( (double) done / (double) zoneLayerCount );
|
||||
std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) );
|
||||
}
|
||||
|
||||
return !m_drcEngine->IsCancelled();
|
||||
|
|
|
@ -2343,13 +2343,17 @@ void FOOTPRINT::CheckOverlappingPads( const std::function<void( const PAD*, cons
|
|||
{
|
||||
checkedPairs[ { a, b } ] = 1;
|
||||
|
||||
VECTOR2I pos;
|
||||
SHAPE* padShape = pad->GetEffectiveShape().get();
|
||||
SHAPE* otherShape = other->GetEffectiveShape().get();
|
||||
|
||||
if( padShape->Collide( otherShape, 0, nullptr, &pos ) )
|
||||
if( pad->GetBoundingBox().Intersects( other->GetBoundingBox() ) )
|
||||
{
|
||||
(aErrorHandler)( pad, other, pos );
|
||||
|
||||
VECTOR2I pos;
|
||||
SHAPE* padShape = pad->GetEffectiveShape().get();
|
||||
SHAPE* otherShape = other->GetEffectiveShape().get();
|
||||
|
||||
if( padShape->Collide( otherShape, 0, nullptr, &pos ) )
|
||||
{
|
||||
(aErrorHandler)( pad, other, pos );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1284,18 +1284,10 @@ double FP_ZONE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
|
|||
|
||||
std::shared_ptr<SHAPE> ZONE::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
|
||||
{
|
||||
std::shared_ptr<SHAPE> shape;
|
||||
|
||||
if( m_FilledPolysList.find( aLayer ) == m_FilledPolysList.end() )
|
||||
{
|
||||
shape = std::make_shared<SHAPE_NULL>();
|
||||
}
|
||||
return std::make_shared<SHAPE_NULL>();
|
||||
else
|
||||
{
|
||||
shape.reset( m_FilledPolysList.at( aLayer )->Clone() );
|
||||
}
|
||||
|
||||
return shape;
|
||||
return m_FilledPolysList.at( aLayer );
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue