49 switch( aItem->
Type() )
122 switch( aItem->
Type() )
182 ZONE* zone =
static_cast<ZONE*
>( aItem );
210 PROF_TIMER garbage_collection(
"garbage-collection" );
212 std::vector<CN_ITEM*> garbage;
213 garbage.reserve( 1024 );
221 garbage_collection.
Show();
226 std::vector<CN_ITEM*> dirtyItems;
230 return aItem->Dirty();
244 std::vector<std::future<size_t>> returns( dirtyItems.size() );
247 [&dirtyItems](
size_t aItem,
CN_LIST* aItemList,
250 if( aReporter && aReporter->IsCancelled() )
254 aItemList->FindNearby( dirtyItems[aItem], visitor );
257 aReporter->AdvanceProgress();
262 for(
size_t ii = 0; ii < dirtyItems.size(); ++ii )
265 for(
const std::future<size_t>& ret : returns )
268 std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
270 while( status != std::future_status::ready )
275 status = ret.wait_for( std::chrono::milliseconds( 250 ) );
310 const std::initializer_list<KICAD_T>& aTypes,
311 int aSingleNet,
CN_ITEM* rootItem )
315 std::deque<CN_ITEM*> Q;
316 std::set<CN_ITEM*> item_set;
323 auto addToSearchList =
324 [&item_set, withinAnyNet, aSingleNet, &aTypes, rootItem ](
CN_ITEM *aItem )
326 if( withinAnyNet && aItem->Net() <= 0 )
329 if( !aItem->Valid() )
332 if( aSingleNet >=0 && aItem->Net() != aSingleNet )
339 if( aItem->Parent()->Type() == type )
346 if( !found && aItem != rootItem )
349 aItem->SetVisited(
false );
351 item_set.insert( aItem );
359 while( !item_set.empty() )
361 std::shared_ptr<CN_CLUSTER> cluster = std::make_shared<CN_CLUSTER>();
363 auto it = item_set.begin();
365 while( it != item_set.end() && (*it)->Visited() )
366 it = item_set.erase( item_set.begin() );
368 if( it == item_set.end() )
382 cluster->Add( current );
386 if( withinAnyNet && n->Net() != root->
Net() )
389 if( !n->Visited() && n->Valid() )
397 clusters.push_back( cluster );
403 std::sort( clusters.begin(), clusters.end(),
404 [](
const std::shared_ptr<CN_CLUSTER>& a,
const std::shared_ptr<CN_CLUSTER>& b )
406 return a->OriginNet() < b->OriginNet();
417 std::vector<CN_ZONE_LAYER*> zitems;
421 if( zone->IsOnCopperLayer() )
430 for(
int j = 0; j < zone->GetFilledPolysList( layer )->OutlineCount(); j++ )
439 int progressDelta = 50;
442 size += zitems.size();
443 size += zitems.size();
444 size += aBoard->
Tracks().size();
447 size += footprint->Pads().size();
451 progressDelta = std::max( progressDelta, (
int) size / 4 );
456 if( aReporter && ( progress % progressDelta ) == 0 )
466 std::vector<std::future<size_t>> returns( zitems.size() );
474 aZoneLayer->BuildRTree();
482 for(
size_t ii = 0; ii < zitems.size(); ++ii )
483 returns[ii] =
tp.submit( cache_zones, zitems[ii] );
485 for(
const std::future<size_t>& ret : returns )
487 std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
489 while( status != std::future_status::ready )
494 status = ret.wait_for( std::chrono::milliseconds( 250 ) );
501 int ii = zitems.size();
506 m_itemMap[ zitem->Parent() ].Link( zitem );
518 for(
PAD*
pad : footprint->Pads() )
537 switch( item->Type() )
556 for(
const std::shared_ptr<CN_CLUSTER>& cluster :
m_connClusters )
558 if( cluster->IsConflicting() )
562 wxLogTrace( wxT(
"CN" ), wxT(
"Conflicting pads in cluster %p; skipping propagation" ),
565 else if( cluster->HasValidNet() )
571 for(
CN_ITEM* item : *cluster )
573 if( item->Valid() && item->CanChangeNet()
574 && item->Parent()->GetNetCode() != cluster->OriginNet() )
580 aCommit->
Modify( item->Parent() );
582 item->Parent()->SetNetCode( cluster->OriginNet() );
589 wxLogTrace( wxT(
"CN" ), wxT(
"Cluster %p: net: %d %s" ),
591 cluster->OriginNet(),
592 (
const char*) cluster->OriginNetName().c_str() );
596 wxLogTrace( wxT(
"CN" ), wxT(
"Cluster %p: no changeable items to propagate to" ),
602 wxLogTrace( wxT(
"CN" ), wxT(
"Cluster %p: connected to unused net" ),
617 std::vector<int>& aIslands )
629 for(
const std::shared_ptr<CN_CLUSTER>& cluster :
m_connClusters )
631 if( cluster->Contains( aZone ) && cluster->IsOrphaned() )
635 if( z->Parent() == aZone && z->Layer() == aLayer )
636 aIslands.push_back(
static_cast<CN_ZONE_LAYER*
>(z)->SubpolyIndex() );
641 wxLogTrace( wxT(
"CN" ), wxT(
"Found %u isolated islands\n" ), (
unsigned) aIslands.size() );
645 bool aConnectivityAlreadyRebuilt )
647 int progressDelta = 50;
650 progressDelta = std::max( progressDelta, (
int) aZones.size() / 4 );
652 if( !aConnectivityAlreadyRebuilt )
675 for(
PCB_LAYER_ID layer : zone.m_zone->GetLayerSet().Seq() )
677 if( zone.m_zone->GetFilledPolysList( layer )->IsEmpty() )
680 for(
const std::shared_ptr<CN_CLUSTER>& cluster :
m_connClusters )
682 if( cluster->Contains( zone.m_zone ) && cluster->IsOrphaned() )
686 if( z->Parent() == zone.m_zone && z->Layer() == layer )
688 zone.m_islands[layer].push_back(
720 for(
int i = lastNet; i < aNet + 1; i++ )
748 if(
pad->ConditionallyFlashed( layer )
758 if(
via->ConditionallyFlashed( layer )
790 const ZONE* zoneA =
static_cast<const ZONE*
>( aZoneLayerA->
Parent() );
791 const ZONE* zoneB =
static_cast<const ZONE*
>( aZoneLayerB->
Parent() );
798 if( aZoneLayerB->
GetLayer() != layer )
807 for(
int i = 0; i < outline.
PointCount(); i++ )
814 aZoneLayerA->
Connect( aZoneLayerB );
815 aZoneLayerB->
Connect( aZoneLayerA );
823 for(
int i = 0; i < outline2.
PointCount(); i++ )
830 aZoneLayerA->
Connect( aZoneLayerB );
831 aZoneLayerB->
Connect( aZoneLayerA );
846 if( parentA == parentB )
886 if(
const PAD*
pad = dyn_cast<const PAD*>( parentA ) )
888 if( !
pad->ConditionallyFlashed( layer ) )
891 else if(
const PCB_VIA*
via = dyn_cast<const PCB_VIA*>( parentA ) )
893 if( !
via->ConditionallyFlashed( layer ) )
897 if(
const PAD*
pad = dyn_cast<const PAD*>( parentB ) )
899 if( !
pad->ConditionallyFlashed( layer ) )
902 else if(
const PCB_VIA*
via = dyn_cast<const PCB_VIA*>( parentB ) )
904 if( !
via->ConditionallyFlashed( layer ) )
@ ZLO_FORCE_NO_ZONE_CONNECTION
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual bool IsConnected() const
Returns information if the object is derived from BOARD_CONNECTED_ITEM.
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.
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
BOARD_ITEM_CONTAINER * GetParentFootprint() const
virtual bool IsOnLayer(PCB_LAYER_ID aLayer, bool aIncludeCourtyards=false) const
Test to see if this object is on the given layer.
virtual bool IsOnCopperLayer() const
Information pertinent to a Pcbnew printed circuit board.
FOOTPRINTS & Footprints()
bool Intersects(const BOX2< Vec > &aRect) const
bool Contains(const Vec &aPoint) const
bool Remove(BOARD_ITEM *aItem)
void add(Container &c, BItem brditem)
PROGRESS_REPORTER * m_progressReporter
std::vector< std::shared_ptr< CN_CLUSTER > > m_connClusters
void propagateConnections(BOARD_COMMIT *aCommit=nullptr)
const CLUSTERS & GetClusters()
void FindIsolatedCopperIslands(ZONE *aZone, PCB_LAYER_ID aLayer, std::vector< int > &aIslands)
const CLUSTERS SearchClusters(CLUSTER_SEARCH_MODE aMode, const std::initializer_list< KICAD_T > &aTypes, int aSingleNet, CN_ITEM *rootItem=nullptr)
void Build(BOARD *aZoneLayer, PROGRESS_REPORTER *aReporter=nullptr)
void MarkNetAsDirty(int aNet)
void markItemNetAsDirty(const BOARD_ITEM *aItem)
std::vector< std::shared_ptr< CN_CLUSTER > > m_ratsnestClusters
void PropagateNets(BOARD_COMMIT *aCommit=nullptr)
Propagate nets from pads to other items in clusters.
std::vector< bool > m_dirtyNets
std::vector< std::shared_ptr< CN_CLUSTER > > CLUSTERS
void LocalBuild(const std::vector< BOARD_ITEM * > &aItems)
std::unordered_map< const BOARD_ITEM *, ITEM_MAP_ENTRY > m_itemMap
void SetProgressReporter(PROGRESS_REPORTER *aReporter)
bool Add(BOARD_ITEM *aItem)
CN_ITEM represents a BOARD_CONNETED_ITEM in the connectivity system (ie: a pad, track/arc/via,...
virtual int AnchorCount() const
const std::vector< CN_ITEM * > & ConnectedItems() const
int Net() const
allow parallel connection threads
virtual const VECTOR2I GetAnchor(int n) const
bool CanChangeNet() const
void SetVisited(bool aVisited)
BOARD_CONNECTED_ITEM * Parent() const
void SetDirty(bool aDirty=true)
void SetHasInvalid(bool aInvalid=true)
void RemoveInvalidItems(std::vector< CN_ITEM * > &aGarbage)
void checkZoneItemConnection(CN_ZONE_LAYER *aZoneLayer, CN_ITEM *aItem)
CN_ITEM * m_item
The item we are looking for connections to.
void checkZoneZoneConnection(CN_ZONE_LAYER *aZoneLayerA, CN_ZONE_LAYER *aZoneLayerB)
bool operator()(CN_ITEM *aCandidate)
PCB_LAYER_ID GetLayer() const
bool Collide(SHAPE *aRefShape) const
bool ContainsPoint(const VECTOR2I &p) const
COMMIT & Modify(EDA_ITEM *aItem)
Create an undo entry for an item that has been already modified.
KICAD_T Type() const
Returns the type of object.
LSET is a set of PCB_LAYER_IDs.
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Return an LSEQ from the union of this LSET and a desired sequence.
Handle the data for a net.
A small class to help profiling.
void Show(std::ostream &aStream=std::cerr)
Print the elapsed time (in a suitable unit) to a stream.
A progress reporter interface for use in multi-threaded environments.
virtual bool IsCancelled() const =0
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
virtual void AdvanceProgress()=0
Increment the progress bar length (inside the current virtual zone).
virtual void SetCurrentProgress(double aProgress)=0
Set the progress value to aProgress (0..1).
virtual void SetMaxProgress(int aMaxProgress)=0
Fix the value that gives the 100 percent progress bar length (inside the current virtual zone).
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
int PointCount() const
Return the number of points (vertices) in this line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
Handle a list of polygons defining a copper zone.
const std::shared_ptr< SHAPE_POLY_SET > & GetFilledPolysList(PCB_LAYER_ID aLayer) const
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
a few functions useful in geometry calculations.
FLASHING
Enum used during connectivity building to ensure we do not query connectivity while building the data...
bool IsCopperLayer(int aLayerId)
Tests whether a layer is a copper layer.
PCB_LAYER_ID
A quick note on layer IDs:
A structure used for calculating isolated islands on a given zone across all its layers.
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
BS::thread_pool thread_pool
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_ZONE_T
class ZONE, a copper pour area
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
@ PCB_PAD_T
class PAD, a pad in a footprint
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
@ PCB_NETINFO_T
class NETINFO_ITEM, a description of a net
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)