53 : m_skipRatsnest( aSkipRatsnest )
91 std::unique_lock<KISPINLOCK> lock(
m_lock, std::try_to_lock );
103 m_netclassMap[ net->GetNetCode() ] = net->GetNetClass()->GetName();
123 std::unique_lock<KISPINLOCK> lock(
m_lock, std::try_to_lock );
150 std::vector<RN_NET*> dirty_nets;
154 std::copy_if(
m_nets.begin() + 1,
m_nets.end(), std::back_inserter( dirty_nets ),
157 return aNet->IsDirty() && aNet->GetNodeCount() > 0;
161 size_t parallelThreadCount = std::min<size_t>( std::thread::hardware_concurrency(),
162 ( dirty_nets.size() + 7 ) / 8 );
164 std::atomic<size_t> nextNet( 0 );
165 std::vector<std::future<size_t>> returns( parallelThreadCount );
168 [&nextNet, &dirty_nets]() ->
size_t 170 for(
size_t i = nextNet++; i < dirty_nets.size(); i = nextNet++ )
176 if( parallelThreadCount <= 1 )
182 for(
size_t ii = 0; ii < parallelThreadCount; ++ii )
183 returns[ii] = std::async( std::launch::async, update_lambda );
186 for(
size_t ii = 0; ii < parallelThreadCount; ++ii )
210 if( lastNet >= (
int)
m_nets.size() )
212 unsigned int prevSize =
m_nets.size();
213 m_nets.resize( lastNet + 1 );
215 for(
unsigned int i = prevSize; i <
m_nets.size(); i++ )
219 const std::vector<CN_CLUSTER_PTR>& clusters =
m_connAlgo->GetClusters();
223 for(
int net = 0; net < lastNet; net++ )
234 int net = c->OriginNet();
237 if( c->IsOrphaned() && c->Size() == 1 )
239 if( dynamic_cast<CN_ZONE_LAYER*>( *c->begin() ) )
258 std::vector<BOARD_CONNECTED_ITEM*> citems;
264 for(
PAD*
pad : static_cast<FOOTPRINT*>(item)->Pads() )
265 citems.push_back(
pad );
270 citems.push_back( citem );
282 for(
const std::shared_ptr<CN_ANCHOR>&
anchor : cnItem->Anchors() )
283 anchor->SetNoLine(
true );
300 m_connAlgo->FindIsolatedCopperIslands( aZone, aIslands );
306 m_connAlgo->FindIsolatedCopperIslands( aZones );
321 for(
unsigned int nc = 1; nc < aDynamicData->
m_nets.size(); nc++ )
323 auto dynNet = aDynamicData->
m_nets[nc];
325 if( dynNet->GetNodeCount() != 0 )
345 for(
const CN_EDGE& edge : edges )
352 l.
a = nodeA->Parent()->GetPosition() + (wxPoint) aInternalOffset;
353 l.
b = nodeB->Parent()->GetPosition() + (wxPoint) aInternalOffset;
364 anchor.SetNoLine(
false );
383 std::vector<KICAD_T> aTypes,
384 bool aCheckOptionalFlashing )
const 394 return std::count( aTypes.begin(), aTypes.end(), aItemType ) > 0;
401 if( connected->Valid()
402 && connected->Layers().Overlaps( aLayer )
403 && matchType( connected->Parent()->Type() ) )
407 const PAD*
pad = static_cast<const PAD*>( aItem );
415 return connected->Parent()->GetEffectiveShape( layer )->Collide( &hole );
417 else if(
CN_ZONE_LAYER* zoneLayer = dynamic_cast<CN_ZONE_LAYER*>( connected ) )
419 ZONE* zone = static_cast<ZONE*>( zoneLayer->Parent() );
420 int islandIdx = zoneLayer->SubpolyIndex();
425 const auto& padOutline =
pad->GetEffectivePolygon()->Outline( 0 );
427 for(
const VECTOR2I& pt : fill.COutline( islandIdx ).CPoints() )
429 if( !padOutline.PointInside( pt ) )
439 else if( aCheckOptionalFlashing && aItem->
Type() ==
PCB_VIA_T )
441 const PCB_VIA*
via = static_cast<const PCB_VIA*>( aItem );
449 return connected->Parent()->GetEffectiveShape( layer )->Collide( &hole );
451 else if(
CN_ZONE_LAYER* zoneLayer = dynamic_cast<CN_ZONE_LAYER*>( connected ) )
453 ZONE* zone = static_cast<ZONE*>( zoneLayer->Parent() );
454 int islandIdx = zoneLayer->SubpolyIndex();
461 for(
const VECTOR2I& pt : fill.COutline( islandIdx ).CPoints() )
463 if( !viaCircle.SHAPE::Collide( pt ) )
474 return connected->Net() == aItem->
GetNetCode();
485 unsigned int unconnected = 0;
492 const std::vector<CN_EDGE>& edges = net->GetUnconnected();
497 unconnected += edges.size();
516 bool aIgnoreNetcodes )
const 518 std::vector<BOARD_CONNECTED_ITEM*> rv;
519 const auto clusters =
m_connAlgo->SearchClusters(
525 for(
auto cl : clusters )
527 if( cl->Contains( aItem ) )
529 for(
const auto item : *cl )
532 rv.push_back( item->Parent() );
544 std::vector<BOARD_CONNECTED_ITEM*> items;
547 std::bitset<MAX_STRUCT_TYPE_ID> type_bits;
549 for(
unsigned int i = 0; aTypes[i] !=
EOT; ++i )
552 type_bits.set( aTypes[i] );
556 if( aItem.
Valid() && ( aItem.
Net() == aNetCode ) && type_bits[aItem.
Parent()->
Type()] )
557 items.push_back( aItem.
Parent() );
560 std::sort( items.begin(), items.end() );
561 items.erase( std::unique( items.begin(), items.end() ), items.end() );
574 for(
const auto& edge : net->GetEdges() )
577 ent.
net = edge.GetSourceNode()->Parent()->GetNetCode();
578 ent.
a = edge.GetSourceNode()->Parent();
579 ent.
b = edge.GetTargetNode()->Parent();
580 ent.
anchorA = edge.GetSourceNode()->Pos();
581 ent.
anchorB = edge.GetTargetNode()->Pos();
582 aReport.push_back( ent );
587 return aReport.empty();
596 std::set<PCB_TRACK*> tracks;
597 std::vector<PCB_TRACK*> rv;
599 for(
CN_ITEM* citem : entry.GetItems() )
603 if( connected->Valid() &&
605 connected->Parent()->Type() ==
PCB_VIA_T ||
606 connected->Parent()->Type() ==
PCB_ARC_T ) )
607 tracks.insert( static_cast<PCB_TRACK*> ( connected->Parent() ) );
611 std::copy( tracks.begin(), tracks.end(), std::back_inserter( rv ) );
617 std::set<PAD*>* pads )
const 623 if( connected->Valid() && connected->Parent()->Type() ==
PCB_PAD_T )
624 pads->insert( static_cast<PAD*> ( connected->Parent() ) );
634 std::vector<PAD*> rv;
638 std::copy( pads.begin(), pads.end(), std::back_inserter( rv ) );
650 sum += net->GetNodeCount();
652 else if( aNet < (
int)
m_nets.size() )
654 sum =
m_nets[aNet]->GetNodeCount();
670 PAD* dpad = static_cast<PAD*>(
pad->Parent() );
672 if( aNet < 0 || aNet == dpad->GetNetCode() )
686 for(
const CN_EDGE& edge : rnNet->GetEdges() )
687 aEdges.push_back( edge );
695 switch( aItem->
Type() )
700 PCB_TRACK* track = static_cast<PCB_TRACK*>( aItem );
719 wxFAIL_MSG( wxT(
"track not in connectivity system" ) );
723 CN_ITEM* citem = items.front();
725 if( !citem->
Valid() )
749 bool hitStart = shape->Collide( aTrack->
GetStart(), accuracy );
750 bool hitEnd = shape->Collide( aTrack->
GetEnd(), accuracy );
752 if( hitStart && hitEnd )
768 if( start_count > 0 && end_count > 0 )
773 *aPos = (start_count == 0 ) ? aTrack->
GetStart() : aTrack->
GetEnd();
783 if( connected.empty() )
794 for(
CN_ITEM* item : connected )
800 first_layer = item->Layer();
801 else if( item->Layer() != first_layer )
812 wxFAIL_MSG( wxT(
"CONNECTIVITY_DATA::TestTrackEndpointDangling: unknown track type" ) );
823 const int& aMaxError )
const 826 std::vector<BOARD_CONNECTED_ITEM*> rv;
829 for(
auto cnItem : entry.GetItems() )
831 for(
auto connected : cnItem->ConnectedItems() )
833 for(
auto anchor : connected->Anchors() )
835 if( (
anchor->Pos() - aAnchor ).SquaredEuclideanNorm() <= maxErrorSq )
837 for(
int i = 0; aTypes[i] > 0; i++ )
839 if( connected->Valid() && connected->Parent()->Type() == aTypes[i] )
841 rv.push_back( connected->Parent() );
858 if ( aNet < 0 || aNet >= (
int)
m_nets.size() )
871 for(
PAD*
pad : static_cast<FOOTPRINT*>( aItem )->Pads() )
876 m_connAlgo->MarkNetAsDirty( static_cast<BOARD_CONNECTED_ITEM*>( aItem )->GetNetCode() );
891 std::vector<CN_EDGE> edges;
892 std::set<BOARD_CONNECTED_ITEM*> item_set;
898 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( item );
902 nets.insert(
pad->GetNetCode() );
903 item_set.insert(
pad );
906 else if(
auto conn_item = dyn_cast<BOARD_CONNECTED_ITEM*>( item ) )
908 item_set.insert( conn_item );
909 nets.insert( conn_item->GetNetCode() );
913 for(
int netcode : nets )
919 std::shared_ptr<CN_ANCHOR> srcNode = edge.GetSourceNode();
920 std::shared_ptr<CN_ANCHOR> dstNode = edge.GetTargetNode();
925 bool srcFound = ( item_set.find( srcParent ) != item_set.end() );
926 bool dstFound = ( item_set.find( dstParent ) != item_set.end() );
928 if ( srcFound && dstFound )
929 edges.push_back( edge );
939 std::vector<CN_EDGE> edges;
944 if( edge.GetSourceNode()->Parent() == aPad || edge.GetTargetNode()->Parent() == aPad )
945 edges.push_back( edge );
955 std::set<const PAD*> pads;
956 std::vector<CN_EDGE> edges;
958 for(
auto pad : aComponent->
Pads() )
960 nets.insert(
pad->GetNetCode() );
964 for(
const auto& netcode : nets )
968 for(
const auto& edge : net->GetEdges() )
970 auto srcNode = edge.GetSourceNode();
971 auto dstNode = edge.GetTargetNode();
973 const PAD* srcParent = static_cast<const PAD*>( srcNode->Parent() );
974 const PAD* dstParent = static_cast<const PAD*>( dstNode->Parent() );
976 bool srcFound = ( pads.find(srcParent) != pads.end() );
977 bool dstFound = ( pads.find(dstParent) != pads.end() );
979 if ( srcFound && dstFound && !aSkipInternalConnections )
981 edges.push_back( edge );
983 else if ( srcFound || dstFound )
985 edges.push_back( edge );
bool IsConnectedOnLayer(const BOARD_CONNECTED_ITEM *aItem, int aLayer, std::vector< KICAD_T > aTypes={}, bool aCheckOptionalFlashing=false) const
const CONNECTED_ITEMS & ConnectedItems() const
void Clear()
Function Clear() Erases the connectivity database.
const std::vector< CN_EDGE > GetRatsnestForComponent(FOOTPRINT *aComponent, bool aSkipInternalConnections=false)
unsigned int GetNodeCount(int aNet=-1) const
double GetLineLength(const wxPoint &aPointA, const wxPoint &aPointB)
Return the length of a line segment defined by aPointA and aPointB.
PROPAGATE_MODE
Controls how nets are propagated through clusters.
const std::vector< PCB_TRACK * > GetConnectedTracks(const BOARD_CONNECTED_ITEM *aItem) const
wxPoint GetPosition() const override
const wxPoint & GetEnd() const
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
A progress reporter interface for use in multi-threaded environments.
std::shared_ptr< CN_CONNECTIVITY_ALGO > m_connAlgo
Class that computes missing connections on a PCB.
PROGRESS_REPORTER * m_progressReporter
const std::list< CN_ITEM * > GetItems() const
VECTOR2I::extended_type ecoord
std::shared_ptr< CN_CONNECTIVITY_ALGO > GetConnectivityAlgo() const
bool Update(BOARD_ITEM *aItem)
Function Update() Updates the connectivity data for an item.
const std::vector< BOARD_CONNECTED_ITEM * > GetNetItems(int aNetCode, const KICAD_T aTypes[]) const
Function GetNetItems() Returns the list of items that belong to a certain net.
void RecalculateRatsnest(BOARD_COMMIT *aCommit=nullptr)
Function RecalculateRatsnest() Updates the ratsnest for the board.
std::shared_ptr< FROM_TO_CACHE > m_fromToCache
class PCB_ARC, an arc track segment on a copper layer
void PropagateNets(BOARD_COMMIT *aCommit=nullptr, PROPAGATE_MODE aMode=PROPAGATE_MODE::SKIP_CONFLICTS)
Propagates the net codes from the source pads to the tracks/vias.
const NETINFO_LIST & GetNetInfo() const
class PAD, a pad in a footprint
const SHAPE_POLY_SET & GetFilledPolysList(PCB_LAYER_ID aLayer) const
BOARD_CONNECTED_ITEM * Parent() const
virtual wxPoint GetPosition() const
CN_ANCHOR represents a physical location that can be connected: a pad or a track/arc/via endpoint.
A thread-safe event counter.
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
std::vector< RN_DYNAMIC_LINE > m_dynamicRatsnest
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
void ComputeDynamicRatsnest(const std::vector< BOARD_ITEM * > &aItems, const CONNECTIVITY_DATA *aDynamicData, VECTOR2I aInternalOffset={ 0, 0 })
Function ComputeDynamicRatsnest() Calculates the temporary dynamic ratsnest (i.e.
search types array terminator (End Of Types)
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
class PCB_TRACK, a track segment (segment on a copper layer)
unsigned int GetPadCount(int aNet=-1) const
void Build(BOARD *aBoard, PROGRESS_REPORTER *aReporter=nullptr)
Function Build() Builds the connectivity database for the board aBoard.
const std::vector< BOARD_CONNECTED_ITEM * > GetConnectedItemsAtAnchor(const BOARD_CONNECTED_ITEM *aItem, const VECTOR2I &aAnchor, const KICAD_T aTypes[], const int &aMaxError=0) const
Function GetConnectedItemsAtAnchor() Returns a list of items connected to a source item aItem at posi...
static const char Default[]
the name of the default NETCLASS
const std::vector< BOARD_CONNECTED_ITEM * > GetConnectedItems(const BOARD_CONNECTED_ITEM *aItem, const KICAD_T aTypes[], bool aIgnoreNetcodes=false) const
Function GetConnectedItems() Returns a list of items connected to a source item aItem.
std::map< int, wxString > m_netclassMap
Map of netcode -> netclass the net is a member of; used for ratsnest painting.
unsigned int GetUnconnectedCount() const
Function GetUnconnectedCount() Returns the number of remaining edges in the ratsnest.
Handle a list of polygons defining a copper zone.
void ClearDynamicRatsnest()
Function ClearDynamicRatsnest() Erases the temporary dynamic ratsnest (i.e.
void SetProgressReporter(PROGRESS_REPORTER *aReporter)
bool Remove(BOARD_ITEM *aItem)
Function Remove() Removes an item from the connectivity data.
void MarkItemNetAsDirty(BOARD_ITEM *aItem)
const std::vector< CN_EDGE > & GetEdges() const
static int getMinDist(BOARD_CONNECTED_ITEM *aItem, const wxPoint &aPoint)
std::vector< RN_NET * > m_nets
EDA_ITEM_FLAGS GetFlags() const
bool NearestBicoloredPair(const RN_NET &aOtherNet, CN_ANCHOR_PTR &aNode1, CN_ANCHOR_PTR &aNode2) const
class FOOTPRINT, a footprint
void GetUnconnectedEdges(std::vector< CN_EDGE > &aEdges) const
bool Add(BOARD_ITEM *aItem)
Function Add() Adds an item to the connectivity data.
void BlockRatsnestItems(const std::vector< BOARD_ITEM * > &aItems)
void AddCluster(std::shared_ptr< CN_CLUSTER > aCluster)
RN_NET * GetRatsnestForNet(int aNet)
Function GetRatsnestForNet() Returns the ratsnest, expressed as a set of graph edges for a given net.
Handle the data for a net.
const std::vector< CN_EDGE > GetRatsnestForPad(const PAD *aPad)
bool CheckConnectivity(std::vector< CN_DISJOINT_NET_ENTRY > &aReport)
CN_EDGE represents a point-to-point connection, whether realized or unrealized (ie: tracks etc.
void FindIsolatedCopperIslands(ZONE *aZone, std::vector< int > &aIslands)
Function FindIsolatedCopperIslands() Searches for copper islands in zone aZone that are not connected...
Information pertinent to a Pcbnew printed circuit board.
PCB_LAYER_ID
A quick note on layer IDs:
CN_ITEM represents a BOARD_CONNETED_ITEM in the connectivity system (ie: a pad, track/arc/via,...
std::shared_ptr< CN_CLUSTER > CN_CLUSTER_PTR
std::shared_ptr< CN_ANCHOR > CN_ANCHOR_PTR
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
int GetNetCount() const
Function GetNetCount() Returns the total number of nets in the connectivity database.
bool TestTrackEndpointDangling(PCB_TRACK *aTrack, wxPoint *aPos=nullptr)
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)
Describe ratsnest for a single net.
void Show(std::ostream &aStream=std::cerr)
const std::vector< PAD * > GetConnectedPads(const BOARD_CONNECTED_ITEM *aItem) const
void HideDynamicRatsnest()
Hides the temporary dynamic ratsnest lines.
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
void addRatsnestCluster(const std::shared_ptr< CN_CLUSTER > &aCluster)
PCB_LAYER_ID ToLAYER_ID(int aLayer)
void Move(const VECTOR2I &aDelta)
Moves the connectivity list anchors.
const wxPoint & GetStart() const
const std::vector< CN_EDGE > GetRatsnestForItems(const std::vector< BOARD_ITEM * > aItems)
KICAD_T Type() const
Returns the type of object.
virtual void SetCurrentProgress(double aProgress)=0
Set the progress value to aProgress (0..1).
bool m_skipRatsnest
Used to suppress ratsnest calculations on dynamic ratsnests.