KiCad PCB EDA Suite
CN_VISITOR Class Reference

#include <connectivity_algo.h>

Public Member Functions

 CN_VISITOR (CN_ITEM *aItem)
 
bool operator() (CN_ITEM *aCandidate)
 

Protected Member Functions

void checkZoneItemConnection (CN_ZONE_LAYER *aZoneLayer, CN_ITEM *aItem)
 
void checkZoneZoneConnection (CN_ZONE_LAYER *aZoneLayerA, CN_ZONE_LAYER *aZoneLayerB)
 

Protected Attributes

CN_ITEMm_item
 The item we are looking for connections to. More...
 

Detailed Description

Definition at line 289 of file connectivity_algo.h.

Constructor & Destructor Documentation

◆ CN_VISITOR()

CN_VISITOR::CN_VISITOR ( CN_ITEM aItem)
inline

Definition at line 292 of file connectivity_algo.h.

292 :
293 m_item( aItem )
294 {}
CN_ITEM * m_item
The item we are looking for connections to.

Member Function Documentation

◆ checkZoneItemConnection()

void CN_VISITOR::checkZoneItemConnection ( CN_ZONE_LAYER aZoneLayer,
CN_ITEM aItem 
)
protected

Definition at line 746 of file connectivity_algo.cpp.

747{
748 PCB_LAYER_ID layer = aZoneLayer->GetLayer();
749 BOARD_CONNECTED_ITEM* item = aItem->Parent();
750
751 if( !item->IsOnLayer( layer ) )
752 return;
753
754 auto connect =
755 [&]()
756 {
757 aZoneLayer->Connect( aItem );
758 aItem->Connect( aZoneLayer );
759 };
760
761 // Try quick checks first...
762 if( item->Type() == PCB_PAD_T )
763 {
764 PAD* pad = static_cast<PAD*>( item );
765
766 if( pad->GetRemoveUnconnected() && pad->ZoneConnectionCache( layer ) == ZLC_UNCONNECTED )
767 return;
768 }
769 else if( item->Type() == PCB_VIA_T )
770 {
771 PCB_VIA* via = static_cast<PCB_VIA*>( item );
772
773 if( via->GetRemoveUnconnected() && via->ZoneConnectionCache( layer ) == ZLC_UNCONNECTED )
774 return;
775 }
776
777 for( int i = 0; i < aItem->AnchorCount(); ++i )
778 {
779 if( aZoneLayer->ContainsPoint( aItem->GetAnchor( i ) ) )
780 {
781 connect();
782 return;
783 }
784 }
785
786 if( item->Type() == PCB_VIA_T || item->Type() == PCB_PAD_T )
787 {
788 // As long as the pad/via crosses the zone layer, check for the full effective shape
789 // We check for the overlapping layers above
790 if( aZoneLayer->Collide( item->GetEffectiveShape( layer, FLASHING::ALWAYS_FLASHED ).get() ) )
791 connect();
792
793 return;
794 }
795
796 if( aZoneLayer->Collide( item->GetEffectiveShape( layer ).get() ) )
797 connect();
798}
@ ZLC_UNCONNECTED
Definition: board_item.h:48
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
Definition: board_item.h:245
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.
Definition: board_item.cpp:222
void Connect(CN_ITEM *b)
virtual int AnchorCount() const
virtual const VECTOR2I GetAnchor(int n) const
BOARD_CONNECTED_ITEM * Parent() const
PCB_LAYER_ID GetLayer() const
bool Collide(SHAPE *aRefShape) const
bool ContainsPoint(const VECTOR2I &p) const
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
Definition: pad.h:59
@ ALWAYS_FLASHED
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:59
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:102
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition: typeinfo.h:87

References ALWAYS_FLASHED, CN_ITEM::AnchorCount(), CN_ZONE_LAYER::Collide(), CN_ITEM::Connect(), CN_ZONE_LAYER::ContainsPoint(), CN_ITEM::GetAnchor(), BOARD_ITEM::GetEffectiveShape(), CN_ZONE_LAYER::GetLayer(), BOARD_ITEM::IsOnLayer(), pad, CN_ITEM::Parent(), PCB_PAD_T, PCB_VIA_T, EDA_ITEM::Type(), via, and ZLC_UNCONNECTED.

Referenced by operator()().

◆ checkZoneZoneConnection()

void CN_VISITOR::checkZoneZoneConnection ( CN_ZONE_LAYER aZoneLayerA,
CN_ZONE_LAYER aZoneLayerB 
)
protected

Definition at line 800 of file connectivity_algo.cpp.

801{
802 const ZONE* zoneA = static_cast<const ZONE*>( aZoneLayerA->Parent() );
803 const ZONE* zoneB = static_cast<const ZONE*>( aZoneLayerB->Parent() );
804
805 const BOX2I& boxA = aZoneLayerA->BBox();
806 const BOX2I& boxB = aZoneLayerB->BBox();
807
808 PCB_LAYER_ID layer = aZoneLayerA->GetLayer();
809
810 if( aZoneLayerB->GetLayer() != layer )
811 return;
812
813 if( !boxA.Intersects( boxB ) )
814 return;
815
816 const SHAPE_LINE_CHAIN& outline =
817 zoneA->GetFilledPolysList( layer )->COutline( aZoneLayerA->SubpolyIndex() );
818
819 for( int i = 0; i < outline.PointCount(); i++ )
820 {
821 if( !boxB.Contains( outline.CPoint( i ) ) )
822 continue;
823
824 if( aZoneLayerB->ContainsPoint( outline.CPoint( i ) ) )
825 {
826 aZoneLayerA->Connect( aZoneLayerB );
827 aZoneLayerB->Connect( aZoneLayerA );
828 return;
829 }
830 }
831
832 const SHAPE_LINE_CHAIN& outline2 =
833 zoneB->GetFilledPolysList( layer )->COutline( aZoneLayerB->SubpolyIndex() );
834
835 for( int i = 0; i < outline2.PointCount(); i++ )
836 {
837 if( !boxA.Contains( outline2.CPoint( i ) ) )
838 continue;
839
840 if( aZoneLayerA->ContainsPoint( outline2.CPoint( i ) ) )
841 {
842 aZoneLayerA->Connect( aZoneLayerB );
843 aZoneLayerB->Connect( aZoneLayerA );
844 return;
845 }
846 }
847}
bool Intersects(const BOX2< Vec > &aRect) const
Definition: box2.h:269
bool Contains(const Vec &aPoint) const
Definition: box2.h:141
const BOX2I & BBox()
int SubpolyIndex() const
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.
Definition: zone.h:57
const std::shared_ptr< SHAPE_POLY_SET > & GetFilledPolysList(PCB_LAYER_ID aLayer) const
Definition: zone.h:601

References CN_ITEM::BBox(), CN_ITEM::Connect(), BOX2< Vec >::Contains(), CN_ZONE_LAYER::ContainsPoint(), SHAPE_LINE_CHAIN::CPoint(), ZONE::GetFilledPolysList(), CN_ZONE_LAYER::GetLayer(), BOX2< Vec >::Intersects(), CN_ITEM::Parent(), SHAPE_LINE_CHAIN::PointCount(), and CN_ZONE_LAYER::SubpolyIndex().

Referenced by operator()().

◆ operator()()

bool CN_VISITOR::operator() ( CN_ITEM aCandidate)

Definition at line 850 of file connectivity_algo.cpp.

851{
852 const BOARD_CONNECTED_ITEM* parentA = aCandidate->Parent();
853 const BOARD_CONNECTED_ITEM* parentB = m_item->Parent();
854
855 if( !aCandidate->Valid() || !m_item->Valid() )
856 return true;
857
858 if( parentA == parentB )
859 return true;
860
861 // Don't connect items in different nets that can't be changed
862 if( !aCandidate->CanChangeNet() && !m_item->CanChangeNet() && aCandidate->Net() != m_item->Net() )
863 return true;
864
865 // If both m_item and aCandidate are marked dirty, they will both be searched
866 // Since we are reciprocal in our connection, we arbitrarily pick one of the connections
867 // to conduct the expensive search
868 if( aCandidate->Dirty() && aCandidate < m_item )
869 return true;
870
871 // We should handle zone-zone connection separately
872 if ( parentA->Type() == PCB_ZONE_T && parentB->Type() == PCB_ZONE_T )
873 {
875 static_cast<CN_ZONE_LAYER*>( aCandidate ) );
876 return true;
877 }
878
879 if( parentA->Type() == PCB_ZONE_T )
880 {
881 checkZoneItemConnection( static_cast<CN_ZONE_LAYER*>( aCandidate ), m_item );
882 return true;
883 }
884
885 if( parentB->Type() == PCB_ZONE_T )
886 {
887 checkZoneItemConnection( static_cast<CN_ZONE_LAYER*>( m_item ), aCandidate );
888 return true;
889 }
890
891 LSET commonLayers = parentA->GetLayerSet() & parentB->GetLayerSet();
892
893 for( PCB_LAYER_ID layer : commonLayers.Seq() )
894 {
897
898 if( const PAD* pad = dyn_cast<const PAD*>( parentA ) )
899 {
900 if( !pad->GetRemoveUnconnected() || ( ( layer == F_Cu || layer == B_Cu ) && pad->GetKeepTopBottom() ) )
901 flashingA = FLASHING::ALWAYS_FLASHED;
902 }
903 else if( const PCB_VIA* via = dyn_cast<const PCB_VIA*>( parentA ) )
904 {
905 if( !via->GetRemoveUnconnected() || ( ( layer == F_Cu || layer == B_Cu ) && via->GetKeepTopBottom() ) )
906 flashingA = FLASHING::ALWAYS_FLASHED;
907 }
908
909 if( const PAD* pad = dyn_cast<const PAD*>( parentB ) )
910 {
911 if( !pad->GetRemoveUnconnected() || ( ( layer == F_Cu || layer == B_Cu ) && pad->GetKeepTopBottom() ) )
912 flashingB = FLASHING::ALWAYS_FLASHED;
913 }
914 else if( const PCB_VIA* via = dyn_cast<const PCB_VIA*>( parentB ) )
915 {
916 if( !via->GetRemoveUnconnected() || ( ( layer == F_Cu || layer == B_Cu ) && via->GetKeepTopBottom() ) )
917 flashingB = FLASHING::ALWAYS_FLASHED;
918 }
919
920 if( parentA->GetEffectiveShape( layer, flashingA )->Collide(
921 parentB->GetEffectiveShape( layer, flashingB ).get() ) )
922 {
923 m_item->Connect( aCandidate );
924 aCandidate->Connect( m_item );
925 return true;
926 }
927 }
928
929 return true;
930};
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition: board_item.h:185
int Net() const
allow parallel connection threads
bool Valid() const
bool CanChangeNet() const
bool Dirty() const
void checkZoneItemConnection(CN_ZONE_LAYER *aZoneLayer, CN_ITEM *aItem)
void checkZoneZoneConnection(CN_ZONE_LAYER *aZoneLayerA, CN_ZONE_LAYER *aZoneLayerB)
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:530
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:411
FLASHING
Enum used during connectivity building to ensure we do not query connectivity while building the data...
Definition: layer_ids.h:147
@ B_Cu
Definition: layer_ids.h:95
@ F_Cu
Definition: layer_ids.h:64
@ PCB_ZONE_T
class ZONE, a copper pour area
Definition: typeinfo.h:112

References ALWAYS_FLASHED, B_Cu, CN_ITEM::CanChangeNet(), checkZoneItemConnection(), checkZoneZoneConnection(), CN_ITEM::Connect(), CN_ITEM::Dirty(), F_Cu, BOARD_ITEM::GetEffectiveShape(), BOARD_ITEM::GetLayerSet(), m_item, CN_ITEM::Net(), NEVER_FLASHED, pad, CN_ITEM::Parent(), PCB_ZONE_T, LSET::Seq(), EDA_ITEM::Type(), CN_ITEM::Valid(), and via.

Member Data Documentation

◆ m_item

CN_ITEM* CN_VISITOR::m_item
protected

The item we are looking for connections to.

Definition at line 304 of file connectivity_algo.h.

Referenced by operator()().


The documentation for this class was generated from the following files: