56 virtual bool Run()
override;
58 virtual const wxString
GetName()
const override {
return wxT(
"zone connections" ); };
69 std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->
GetConnectivity();
79 auto layerIter = zoneIter->second.find( aLayer );
81 if( layerIter != zoneIter->second.end() )
82 isolatedIslands = layerIter->second;
87 for(
PAD*
pad : footprint->Pads() )
102 BOX2I item_bbox =
pad->GetBoundingBox();
107 if( !
pad->FlashLayer( aLayer ) )
135 int ignoredSpokes = 0;
138 for(
int jj = 0; jj < zoneFill->OutlineCount(); ++jj )
140 std::vector<SHAPE_LINE_CHAIN::INTERSECTION> intersections;
142 zoneFill->Outline( jj ).Intersect( padOutline, intersections,
true, &padBBox );
144 std::vector<SHAPE_LINE_CHAIN::INTERSECTION> unique_intersections;
148 const auto found = std::find_if(
149 std::begin( unique_intersections ), std::end( unique_intersections ),
152 return ( j.
p == i.p );
155 if( found == std::end( unique_intersections ) )
156 unique_intersections.emplace_back( i );
162 if( unique_intersections.size() >= 2 )
166 ignoredSpokes += (int) unique_intersections.size() / 2;
167 ignoredSpokePos = ( unique_intersections[0].p + unique_intersections[1].p ) / 2;
171 spokes += (int) unique_intersections.size() / 2;
176 if( spokes == 0 && ignoredSpokes == 0 )
179 int customSpokes = 0;
183 for(
const std::shared_ptr<PCB_SHAPE>& primitive :
pad->GetPrimitives( aLayer ) )
190 if( customSpokes > 0 )
192 if( spokes < customSpokes )
199 drce->SetErrorDetail( wxString::Format(
_(
"(layer %s; %d spokes connected to isolated island)" ),
202 pos = ignoredSpokePos;
206 drce->SetErrorDetail( wxString::Format(
_(
"(layer %s; %s custom spoke count %d; actual %d)" ),
211 pos =
pad->GetPosition();
214 drce->SetItems( aZone,
pad );
223 if( spokes >= minCount )
230 for(
PCB_TRACK* track : connectivity->GetConnectedTracks(
pad ) )
237 else if( padOutline.
PointInside( track->GetEnd() ) )
248 if( !shape || !shape->
IsOnLayer( aLayer ) )
253 for(
const VECTOR2I& pt : connectionPts )
257 for(
const VECTOR2I& other : connectionPts )
259 if( other != pt && zoneFill->Collide( other ) )
279 spokes += ignoredSpokes;
287 if( spokes < minCount )
294 drce->SetErrorDetail( wxString::Format(
_(
"(layer %s; %d spokes connected to isolated island)" ),
297 pos = ignoredSpokePos;
301 drce->SetErrorDetail( wxString::Format(
_(
"(layer %s; %s min spoke count %d; actual %d)" ),
306 pos =
pad->GetPosition();
309 drce->SetItems( aZone,
pad );
322 std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->
GetConnectivity();
325 if( !
reportPhase(
_(
"Checking thermal reliefs..." ) ) )
328 std::vector< std::pair<ZONE*, PCB_LAYER_ID> > zoneLayers;
329 std::atomic<size_t> done( 1 );
330 size_t total_effort = 0;
338 zoneLayers.push_back( { zone, layer } );
344 total_effort = std::max( (
size_t) 1, total_effort );
347 auto returns =
tp.submit_loop( 0, zoneLayers.size(),
350 if( !m_drcEngine->IsCancelled() )
352 testZoneLayer( zoneLayers[ii].first, zoneLayers[ii].second );
353 done.fetch_add( zoneLayers[ii].first->GetFilledPolysList( zoneLayers[ii].second )->FullPointCount() );
357 for(
auto& ret : returns )
359 std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
361 while( status != std::future_status::ready )
363 reportProgress( done, total_effort );
364 status = ret.wait_for( std::chrono::milliseconds( 250 ) );
368 return !m_drcEngine->IsCancelled();
constexpr int ARC_LOW_DEF
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
Container for design settings for a BOARD object.
std::shared_ptr< DRC_ENGINE > m_DRCEngine
Information pertinent to a Pcbnew printed circuit board.
std::map< ZONE *, std::map< PCB_LAYER_ID, ISOLATED_ISLANDS > > m_ZoneIsolatedIslandsMap
std::vector< ZONE * > m_DRCCopperZones
const FOOTPRINTS & Footprints() const
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
constexpr bool Intersects(const BOX2< Vec > &aRect) const
SEVERITY GetSeverity() const
ZONE_CONNECTION m_ZoneConnection
DRC_RULE * GetParentRule() const
DRC_CONSTRAINT EvalRules(DRC_CONSTRAINT_T aConstraintType, const BOARD_ITEM *a, const BOARD_ITEM *b, PCB_LAYER_ID aLayer, REPORTER *aReporter=nullptr)
DRC_CONSTRAINT EvalZoneConnection(const BOARD_ITEM *a, const BOARD_ITEM *b, PCB_LAYER_ID aLayer, REPORTER *aReporter=nullptr)
static std::shared_ptr< DRC_ITEM > Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
virtual bool Run() override
Run this provider against the given PCB with configured options (if any).
virtual const wxString GetName() const override
void testZoneLayer(ZONE *aZone, PCB_LAYER_ID aLayer)
virtual ~DRC_TEST_PROVIDER_ZONE_CONNECTIONS()=default
DRC_TEST_PROVIDER_ZONE_CONNECTIONS()
virtual bool reportPhase(const wxString &aStageName)
void reportViolation(std::shared_ptr< DRC_ITEM > &item, const VECTOR2I &aMarkerPos, int aMarkerLayer, const std::function< void(PCB_MARKER *)> &aPathGenerator=[](PCB_MARKER *){})
std::vector< VECTOR2I > GetConnectionPoints() const
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Test to see if this object is on the given layer.
bool PointInside(const VECTOR2I &aPt, int aAccuracy=0, bool aUseBBoxCache=false) const override
Check if point aP lies inside a closed shape.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
Represent a set of closed polygons.
bool Collide(const SHAPE *aShape, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Check if the boundary of shape (this) lies closer to the shape aShape than aClearance,...
int FullPointCount() const
Return the number of points in the shape poly set.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
Handle a list of polygons defining a copper zone.
std::shared_ptr< SHAPE_POLY_SET > GetFilledPolysList(PCB_LAYER_ID aLayer) const
const BOX2I GetBoundingBox() const override
bool IsTeardropArea() const
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
@ MIN_RESOLVED_SPOKES_CONSTRAINT
@ THERMAL_RELIEF_GAP_CONSTRAINT
PCB_LAYER_ID
A quick note on layer IDs:
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
static DRC_REGISTER_TEST_PROVIDER< DRC_TEST_PROVIDER_ANNULAR_WIDTH > dummy
A struct recording the isolated and single-pad islands within a zone.
std::vector< int > m_SingleConnectionOutlines
Represent an intersection between two line segments.
VECTOR2I p
Point of intersection between our and their.
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
BS::priority_thread_pool thread_pool
VECTOR2< int32_t > VECTOR2I
ZONE_CONNECTION
How pads are covered by copper in zone.
@ THERMAL
Use thermal relief for pads.