55 virtual bool Run()
override;
57 virtual const wxString
GetName()
const override {
return wxT(
"zone connections" ); };
68 std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->
GetConnectivity();
78 auto layerIter = zoneIter->second.find( aLayer );
80 if( layerIter != zoneIter->second.end() )
81 isolatedIslands = layerIter->second;
86 for(
PAD*
pad : footprint->Pads() )
101 BOX2I item_bbox =
pad->GetBoundingBox();
106 if( !
pad->FlashLayer( aLayer ) )
134 int ignoredSpokes = 0;
137 for(
int jj = 0; jj < zoneFill->OutlineCount(); ++jj )
139 std::vector<SHAPE_LINE_CHAIN::INTERSECTION> intersections;
141 zoneFill->Outline( jj ).Intersect( padOutline, intersections,
true, &padBBox );
143 std::vector<SHAPE_LINE_CHAIN::INTERSECTION> unique_intersections;
147 const auto found = std::find_if(
148 std::begin( unique_intersections ), std::end( unique_intersections ),
151 return ( j.
p == i.p );
154 if( found == std::end( unique_intersections ) )
155 unique_intersections.emplace_back( i );
161 if( unique_intersections.size() >= 2 )
165 ignoredSpokes += (int) unique_intersections.size() / 2;
166 ignoredSpokePos = ( unique_intersections[0].p + unique_intersections[1].p ) / 2;
170 spokes += (int) unique_intersections.size() / 2;
175 if( spokes == 0 && ignoredSpokes == 0 )
178 int customSpokes = 0;
182 for(
const std::shared_ptr<PCB_SHAPE>& primitive :
pad->GetPrimitives( aLayer ) )
189 if( customSpokes > 0 )
191 if( spokes < customSpokes )
198 drce->SetErrorDetail( wxString::Format(
_(
"(layer %s; %d spokes connected to isolated island)" ),
201 pos = ignoredSpokePos;
205 drce->SetErrorDetail( wxString::Format(
_(
"(layer %s; %s custom spoke count %d; actual %d)" ),
210 pos =
pad->GetPosition();
213 drce->SetItems( aZone,
pad );
222 if( spokes >= minCount )
229 for(
PCB_TRACK* track : connectivity->GetConnectedTracks(
pad ) )
236 else if( padOutline.
PointInside( track->GetEnd() ) )
251 spokes += ignoredSpokes;
259 if( spokes < minCount )
266 drce->SetErrorDetail( wxString::Format(
_(
"(layer %s; %d spokes connected to isolated island)" ),
269 pos = ignoredSpokePos;
273 drce->SetErrorDetail( wxString::Format(
_(
"(layer %s; %s min spoke count %d; actual %d)" ),
278 pos =
pad->GetPosition();
281 drce->SetItems( aZone,
pad );
294 std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->
GetConnectivity();
297 if( !
reportPhase(
_(
"Checking thermal reliefs..." ) ) )
300 std::vector< std::pair<ZONE*, PCB_LAYER_ID> > zoneLayers;
301 std::atomic<size_t> done( 1 );
302 size_t total_effort = 0;
310 zoneLayers.push_back( { zone, layer } );
316 total_effort = std::max( (
size_t) 1, total_effort );
319 auto returns =
tp.submit_loop( 0, zoneLayers.size(),
322 if( !m_drcEngine->IsCancelled() )
324 testZoneLayer( zoneLayers[ii].first, zoneLayers[ii].second );
325 done.fetch_add( zoneLayers[ii].first->GetFilledPolysList( zoneLayers[ii].second )->FullPointCount() );
329 for(
auto& ret : returns )
331 std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
333 while( status != std::future_status::ready )
335 reportProgress( done, total_effort );
336 status = ret.wait_for( std::chrono::milliseconds( 250 ) );
340 return !m_drcEngine->IsCancelled();
constexpr int ARC_LOW_DEF
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 *){})
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.
const 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.