52 virtual bool Run()
override;
54 virtual const wxString
GetName()
const override {
return wxT(
"zone connections" ); };
65 std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->
GetConnectivity();
75 auto layerIter = zoneIter->second.find( aLayer );
77 if( layerIter != zoneIter->second.end() )
78 isolatedIslands = layerIter->second;
83 for(
PAD*
pad : footprint->Pads() )
98 BOX2I item_bbox =
pad->GetBoundingBox();
103 if( !
pad->FlashLayer( aLayer ) )
131 int ignoredSpokes = 0;
134 for(
int jj = 0; jj < zoneFill->OutlineCount(); ++jj )
136 std::vector<SHAPE_LINE_CHAIN::INTERSECTION> intersections;
138 zoneFill->Outline( jj ).Intersect( padOutline, intersections,
true, &padBBox );
140 std::vector<SHAPE_LINE_CHAIN::INTERSECTION> unique_intersections;
144 const auto found = std::find_if(
145 std::begin( unique_intersections ), std::end( unique_intersections ),
148 return ( j.
p == i.p );
151 if( found == std::end( unique_intersections ) )
152 unique_intersections.emplace_back( i );
158 if( unique_intersections.size() >= 2 )
162 ignoredSpokes += (int) unique_intersections.size() / 2;
163 ignoredSpokePos = ( unique_intersections[0].p + unique_intersections[1].p ) / 2;
167 spokes += (int) unique_intersections.size() / 2;
172 if( spokes == 0 && ignoredSpokes == 0 )
175 int customSpokes = 0;
179 for(
const std::shared_ptr<PCB_SHAPE>& primitive :
pad->GetPrimitives( aLayer ) )
186 if( customSpokes > 0 )
188 if( spokes < customSpokes )
195 drce->SetErrorDetail( wxString::Format(
_(
"(layer %s; %d spokes connected to isolated island)" ),
198 pos = ignoredSpokePos;
202 drce->SetErrorDetail( wxString::Format(
_(
"(layer %s; %s custom spoke count %d; actual %d)" ),
207 pos =
pad->GetPosition();
210 drce->SetItems( aZone,
pad );
219 if( spokes >= minCount )
226 for(
PCB_TRACK* track : connectivity->GetConnectedTracks(
pad ) )
233 else if( padOutline.
PointInside( track->GetEnd() ) )
244 if( !shape || !shape->
IsOnLayer( aLayer ) )
249 for(
const VECTOR2I& pt : connectionPts )
253 for(
const VECTOR2I& other : connectionPts )
255 if( other != pt && zoneFill->Collide( other ) )
275 spokes += ignoredSpokes;
283 if( spokes < minCount )
290 drce->SetErrorDetail( wxString::Format(
_(
"(layer %s; %d spokes connected to isolated island)" ),
293 pos = ignoredSpokePos;
297 drce->SetErrorDetail( wxString::Format(
_(
"(layer %s; %s min spoke count %d; actual %d)" ),
302 pos =
pad->GetPosition();
305 drce->SetItems( aZone,
pad );
318 std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->
GetConnectivity();
321 if( !
reportPhase(
_(
"Checking thermal reliefs..." ) ) )
324 std::vector< std::pair<ZONE*, PCB_LAYER_ID> > zoneLayers;
325 std::atomic<size_t> done( 1 );
326 size_t total_effort = 0;
334 zoneLayers.push_back( { zone, layer } );
340 total_effort = std::max( (
size_t) 1, total_effort );
343 auto returns =
tp.submit_loop( 0, zoneLayers.size(),
346 if( !m_drcEngine->IsCancelled() )
348 testZoneLayer( zoneLayers[ii].first, zoneLayers[ii].second );
349 done.fetch_add( zoneLayers[ii].first->GetFilledPolysList( zoneLayers[ii].second )->FullPointCount() );
353 for(
auto& ret : returns )
355 std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
357 while( status != std::future_status::ready )
359 reportProgress( done, total_effort );
360 status = ret.wait_for( std::chrono::milliseconds( 250 ) );
364 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.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
bool PointInside(const VECTOR2I &aPt, int aAccuracy=0, bool aUseBBoxCache=false) const override
Check if point aP lies inside a closed shape.
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.