48 switch( aItem->
Type() )
51 for(
PAD*
pad : static_cast<FOOTPRINT*>( aItem )->Pads() )
100 auto citem = static_cast<const BOARD_CONNECTED_ITEM*>( aItem );
107 const FOOTPRINT* footprint = static_cast<const FOOTPRINT*>( aItem );
121 switch( aItem->
Type() )
124 MarkNetAsDirty( static_cast<NETINFO_ITEM*>( aItem )->GetNetCode() );
129 if( static_cast<FOOTPRINT*>( aItem )->GetAttributes() &
FP_JUST_ADDED )
132 for(
PAD*
pad : static_cast<FOOTPRINT*>( aItem )->Pads() )
181 ZONE* zone = static_cast<ZONE*>( aItem );
209 PROF_COUNTER garbage_collection(
"garbage-collection" );
211 std::vector<CN_ITEM*> garbage;
212 garbage.reserve( 1024 );
216 for(
auto item : garbage )
220 garbage_collection.
Show();
224 std::vector<CN_ITEM*> dirtyItems;
228 return aItem->Dirty();
241 size_t parallelThreadCount = std::min<size_t>( std::thread::hardware_concurrency(),
242 ( dirtyItems.size() + 7 ) / 8 );
244 std::atomic<size_t> nextItem( 0 );
245 std::vector<std::future<size_t>> returns( parallelThreadCount );
248 [&nextItem, &dirtyItems](
CN_LIST* aItemList,
251 for(
size_t i = nextItem++; i < dirtyItems.size(); i = nextItem++ )
254 aItemList->FindNearby( dirtyItems[i], visitor );
258 if( aReporter->IsCancelled() )
261 aReporter->AdvanceProgress();
268 if( parallelThreadCount <= 1 )
272 for(
size_t ii = 0; ii < parallelThreadCount; ++ii )
274 returns[ii] = std::async( std::launch::async, conn_lambda, &
m_itemList,
278 for(
size_t ii = 0; ii < parallelThreadCount; ++ii )
281 std::future_status status;
287 status = returns[ii].wait_for( std::chrono::milliseconds( 100 ) );
288 }
while( status != std::future_status::ready );
324 std::deque<CN_ITEM*> Q;
325 std::set<CN_ITEM*> item_set;
332 auto addToSearchList =
333 [&item_set, withinAnyNet, aSingleNet, aTypes](
CN_ITEM *aItem )
335 if( withinAnyNet && aItem->Net() <= 0 )
338 if( !aItem->Valid() )
341 if( aSingleNet >=0 && aItem->Net() != aSingleNet )
346 for(
int i = 0; aTypes[i] !=
EOT; i++ )
348 if( aItem->Parent()->Type() == aTypes[i] )
358 aItem->SetVisited(
false );
360 item_set.insert( aItem );
368 while( !item_set.empty() )
372 auto it = item_set.begin();
374 while( it != item_set.end() && (*it)->Visited() )
375 it = item_set.erase( item_set.begin() );
377 if( it == item_set.end() )
391 cluster->Add( current );
395 if( withinAnyNet && n->Net() != root->
Net() )
398 if( !n->Visited() && n->Valid() )
406 clusters.push_back( cluster );
412 std::sort( clusters.begin(), clusters.end(),
415 return a->OriginNet() < b->OriginNet();
424 if( aReporter && ( ( aCount % aDelta ) == 0 || aCount == aSize - 1 ) )
438 size += aBoard->
Zones().size();
439 size += aBoard->
Tracks().size();
442 size += footprint->Pads().size();
462 for(
PAD*
pad : footprint->Pads() )
473 for(
auto item : aItems )
475 switch( item->Type() )
485 for(
PAD*
pad : static_cast<FOOTPRINT*>( item )->Pads() )
501 wxLogTrace( wxT(
"CN" ), wxT(
"propagateConnections: propagate skip conflicts? %d" ),
506 if( skipConflicts && cluster->IsConflicting() )
508 wxLogTrace( wxT(
"CN" ), wxT(
"Conflicting nets in cluster %p; skipping update" ),
511 else if( cluster->IsOrphaned() )
513 wxLogTrace( wxT(
"CN" ), wxT(
"Skipping orphaned cluster %p [net: %s]" ),
515 (
const char*) cluster->OriginNetName().c_str() );
517 else if( cluster->HasValidNet() )
519 if( cluster->IsConflicting() )
521 wxLogTrace( wxT(
"CN" ), wxT(
"Conflicting nets in cluster %p; chose %d (%s)" ),
523 cluster->OriginNet(),
524 cluster->OriginNetName() );
530 for(
auto item : *cluster )
532 if( item->CanChangeNet() )
534 if( item->Valid() && item->Parent()->GetNetCode() != cluster->OriginNet() )
540 aCommit->
Modify( item->Parent() );
542 item->Parent()->SetNetCode( cluster->OriginNet() );
550 wxLogTrace( wxT(
"CN" ), wxT(
"Cluster %p : net : %d %s" ),
552 cluster->OriginNet(),
553 (
const char*) cluster->OriginNetName().c_str() );
556 wxLogTrace( wxT(
"CN" ), wxT(
"Cluster %p : nothing to propagate" ),
561 wxLogTrace( wxT(
"CN" ), wxT(
"Cluster %p : connected to unused net" ),
576 std::vector<int>& aIslands )
590 if( cluster->Contains( aZone ) && cluster->IsOrphaned() )
592 for(
auto z : *cluster )
594 if( z->Parent() == aZone && z->Layer() == aLayer )
596 aIslands.push_back( static_cast<CN_ZONE_LAYER*>(z)->SubpolyIndex() );
602 wxLogTrace( wxT(
"CN" ), wxT(
"Found %u isolated islands\n" ), (
unsigned) aIslands.size() );
607 for(
auto& z : aZones )
617 for(
PCB_LAYER_ID layer : zone.m_zone->GetLayerSet().Seq() )
619 if( zone.m_zone->GetFilledPolysList( layer ).IsEmpty() )
624 if( cluster->Contains( zone.m_zone ) && cluster->IsOrphaned() )
628 if( z->Parent() == zone.m_zone && z->Layer() == layer )
630 zone.m_islands[layer].push_back(
631 static_cast<CN_ZONE_LAYER*>( z )->SubpolyIndex() );
662 for(
int i = lastNet; i < aNet + 1; i++ )
684 accuracy = ( static_cast<PCB_TRACK*>( aItem->
Parent() )->GetWidth() + 1 ) / 2;
700 const ZONE* zoneA = static_cast<const ZONE*>( aZoneLayerA->
Parent() );
701 const ZONE* zoneB = static_cast<const ZONE*>( aZoneLayerB->
Parent() );
703 if( aZoneLayerA->
Layer() != aZoneLayerB->
Layer() )
706 if( aZoneLayerB->
Net() != aZoneLayerA->
Net() )
718 if( zoneB->GetFilledPolysUseThickness() )
719 radiusB = ( zoneB->GetMinThickness() + 1 ) / 2;
726 for(
int i = 0; i < outline.PointCount(); i++ )
728 if( !boxB.
Contains( outline.CPoint( i ) ) )
731 if( aZoneLayerB->
ContainsPoint( outline.CPoint( i ), radiusA ) )
733 aZoneLayerA->
Connect( aZoneLayerB );
734 aZoneLayerB->
Connect( aZoneLayerA );
740 zoneB->GetFilledPolysList( layer ).COutline( aZoneLayerB->
SubpolyIndex() );
742 for(
int i = 0; i < outline2.
PointCount(); i++ )
749 aZoneLayerA->
Connect( aZoneLayerB );
750 aZoneLayerB->
Connect( aZoneLayerA );
765 if( parentA == parentB )
770 if( !commonLayers.any() )
783 static_cast<CN_ZONE_LAYER*>( aCandidate ) );
804 if(
const PAD*
pad = dyn_cast<const PAD*>( parentA ) )
806 if( !
pad->GetRemoveUnconnected() || ( ( layer ==
F_Cu || layer ==
B_Cu ) &&
pad->GetKeepTopBottom() ) )
809 else if(
const PCB_VIA*
via = dyn_cast<const PCB_VIA*>( parentA ) )
811 if( !
via->GetRemoveUnconnected() || ( ( layer ==
F_Cu || layer ==
B_Cu ) &&
via->GetKeepTopBottom() ) )
815 if(
const PAD*
pad = dyn_cast<const PAD*>( parentB ) )
817 if( !
pad->GetRemoveUnconnected() || ( ( layer ==
F_Cu || layer ==
B_Cu ) &&
pad->GetKeepTopBottom() ) )
820 else if(
const PCB_VIA*
via = dyn_cast<const PCB_VIA*>( parentB ) )
822 if( !
via->GetRemoveUnconnected() || ( ( layer ==
F_Cu || layer ==
B_Cu ) &&
via->GetKeepTopBottom() ) )
void RemoveInvalidItems(std::vector< CN_ITEM * > &aGarbage)
const CONNECTED_ITEMS & ConnectedItems() const
COMMIT & Modify(EDA_ITEM *aItem)
Create an undo entry for an item that has been already modified.
virtual void SetMaxProgress(int aMaxProgress)=0
Fix the value that gives the 100 percent progress bar length (inside the current virtual zone).
bool Remove(BOARD_ITEM *aItem)
void SetHasInvalid(bool aInvalid=true)
PROPAGATE_MODE
Controls how nets are propagated through clusters.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
void checkZoneItemConnection(CN_ZONE_LAYER *aZoneLayer, CN_ITEM *aItem)
A progress reporter interface for use in multi-threaded environments.
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
bool ContainsPoint(const VECTOR2I &p, int aAccuracy=0) const
void SetVisited(bool aVisited)
class PCB_ARC, an arc track segment on a copper layer
void MarkNetAsDirty(int aNet)
class PAD, a pad in a footprint
bool Add(BOARD_ITEM *aItem)
const SHAPE_POLY_SET & GetFilledPolysList(PCB_LAYER_ID aLayer) const
BOARD_CONNECTED_ITEM * Parent() const
void FindIsolatedCopperIslands(ZONE *aZone, PCB_LAYER_ID aLayer, std::vector< int > &aIslands)
void add(Container &c, BItem brditem)
int PointCount() const
Return the number of points (vertices) in this line chain.
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Return an LSEQ from the union of this LSET and a desired sequence.
A thread-safe event counter.
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
void SetDirty(bool aDirty=true)
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
int Net() const
allow parallel connection threads
search types array terminator (End Of Types)
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
std::vector< bool > m_dirtyNets
class PCB_TRACK, a track segment (segment on a copper layer)
virtual int AnchorCount() const
void PropagateNets(BOARD_COMMIT *aCommit=nullptr, PROPAGATE_MODE aMode=PROPAGATE_MODE::SKIP_CONFLICTS)
Propagate nets from pads to other items in clusters.
const CLUSTERS SearchClusters(CLUSTER_SEARCH_MODE aMode, const KICAD_T aTypes[], int aSingleNet)
bool Intersects(const BOX2< Vec > &aRect) const
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
void markItemNetAsDirty(const BOARD_ITEM *aItem)
LSET is a set of PCB_LAYER_IDs.
int GetMinThickness() const
void propagateConnections(BOARD_COMMIT *aCommit=nullptr, PROPAGATE_MODE aMode=PROPAGATE_MODE::SKIP_CONFLICTS)
FOOTPRINTS & Footprints()
bool Contains(const Vec &aPoint) const
a few functions useful in geometry calculations.
void checkZoneZoneConnection(CN_ZONE_LAYER *aZoneLayerA, CN_ZONE_LAYER *aZoneLayerB)
Handle a list of polygons defining a copper zone.
class ZONE, a copper pour area
void reportProgress(PROGRESS_REPORTER *aReporter, int aCount, int aSize, int aDelta)
FLASHING
Enum used during connectivity building to ensure we do not query connectivity while building the data...
virtual const VECTOR2I GetAnchor(int n) const
class FOOTPRINT, a footprint
bool CanChangeNet() const
CLUSTERS m_ratsnestClusters
bool operator()(CN_ITEM *aCandidate)
const CLUSTERS & GetClusters()
void Build(BOARD *aBoard, PROGRESS_REPORTER *aReporter=nullptr)
Information pertinent to a Pcbnew printed circuit board.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
PCB_LAYER_ID
A quick note on layer IDs:
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
CN_ITEM represents a BOARD_CONNETED_ITEM in the connectivity system (ie: a pad, track/arc/via,...
class NETINFO_ITEM, a description of a net
std::shared_ptr< CN_CLUSTER > CN_CLUSTER_PTR
virtual int Layer() const
Return the item's layer, for single-layered items only.
virtual bool IsConnected() const
Returns information if the object is derived from BOARD_CONNECTED_ITEM.
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
class PCB_VIA, a via (like a track segment on a copper layer)
void Show(std::ostream &aStream=std::cerr)
virtual bool IsCancelled() const =0
CN_ITEM * m_item
The item we are looking for connections to.
std::vector< CN_CLUSTER_PTR > CLUSTERS
virtual bool IsOnCopperLayer() const
std::unordered_map< const BOARD_ITEM *, ITEM_MAP_ENTRY > m_itemMap
A structure used for calculating isolated islands on a given zone across all its layers.
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
KICAD_T Type() const
Returns the type of object.
BOARD_ITEM_CONTAINER * GetParentFootprint() const
bool GetFilledPolysUseThickness() const
void SetProgressReporter(PROGRESS_REPORTER *aReporter)
PROGRESS_REPORTER * m_progressReporter
virtual void SetCurrentProgress(double aProgress)=0
Set the progress value to aProgress (0..1).