54 if(
pad->IsAperturePad() ||
pad->IsNPTHWithNoCopper() )
92 bool aUseClearanceEpsilon =
true )
override
112 const bool sameNet = aA && aB && aA->
Net() && aA->
Net() == aB->
Net();
115 for(
int layer = layers.
Start(); layer <= layers.
End(); ++layer )
117 if( !sameNet && !freePad )
169 if( ( sameNet || freePad ) && rv == 0 )
193 return wxEmptyString;
226 default:
return false;
231 aConstraint->
m_Type = aType;
238 *aConstraint = it->second;
254 return a == other.
a &&
b == other.
b &&
type == other.
type;
263 else if (
a == other.
a )
267 else if (
b == other.
b )
278 const PNS::ITEM* aCollidingItem )
override
329 int aFlags = 0 )
override {};
371 obs.m_head, obs.m_head->KindStr().c_str(),
372 obs.m_item, obs.m_item->KindStr().c_str(),
382 std::unique_ptr<PNS::NODE> world (
new PNS::NODE );
387 world->SetMaxClearance( 10000000 );
388 world->SetRuleResolver( &m_ruleResolver );
396 int count = world->QueryColliding(
v1, obstacles );
405 m_ruleResolver.m_defaultClearance = 1000000;
406 world->QueryColliding(
v1, obstacles );
410 const auto& first = *obstacles.begin();
420 m_ruleResolver.m_defaultClearance = 200000;
421 m_ruleResolver.m_defaultHole2Hole = 1000000;
423 world->QueryColliding(
v1, obstacles );
427 auto iter = obstacles.begin();
428 const auto& first = *iter++;
438 m_ruleResolver.m_defaultHole2Hole = 220000;
439 m_ruleResolver.m_defaultHole2Copper = 1000000;
441 world->QueryColliding(
v1, obstacles );
445 auto iter = obstacles.begin();
446 const auto& first = *iter++;
449 BOOST_CHECK( ( first.m_head ==
v1 && first.m_item ==
v2->Hole() )
450 || ( first.m_head ==
v1->Hole() && first.m_item ==
v2 ) );
463 via.SetSecondaryDrill( std::optional<int>( 12000 ) );
468 std::unique_ptr<PNS::VIA> viaClone(
via.Clone() );
470 auto checkVia = [&](
const PNS::VIA& candidate )
474 BOOST_CHECK( candidate.HolePostMachining().has_value() );
476 BOOST_CHECK( candidate.SecondaryDrill().has_value() );
478 BOOST_CHECK( candidate.SecondaryHoleLayers().has_value() );
480 via.SecondaryHoleLayers()->Start() );
482 via.SecondaryHoleLayers()->End() );
483 BOOST_CHECK( candidate.SecondaryHolePostMachining().has_value() );
486 if( candidate.SecondaryHolePostMachining().has_value() )
487 BOOST_CHECK( candidate.SecondaryHolePostMachining().value() ==
via.SecondaryHolePostMachining().value() );
491 checkVia( *viaClone );
500 via.SetPrimaryDrillStartLayer(
F_Cu );
501 via.SetPrimaryDrillEndLayer(
B_Cu );
503 via.SetSecondaryDrillSize( std::optional<int>( 15000 ) );
504 via.SetSecondaryDrillStartLayer(
F_Cu );
508 via.SetTertiaryDrillSize( std::optional<int>( 8000 ) );
509 via.SetTertiaryDrillStartLayer(
B_Cu );
513 std::unique_ptr<PCB_VIA> viaClone(
static_cast<PCB_VIA*
>(
via.Clone() ) );
515 auto checkVia = [&](
const PCB_VIA& candidate )
519 BOOST_CHECK( candidate.GetFrontPostMachining().has_value() );
520 BOOST_CHECK_EQUAL(
static_cast<int>( candidate.GetFrontPostMachining().value() ),
521 static_cast<int>(
via.GetFrontPostMachining().value() ) );
522 BOOST_CHECK( candidate.GetSecondaryDrillSize().has_value() );
524 via.GetSecondaryDrillSize().value() );
526 via.GetSecondaryDrillStartLayer() );
528 via.GetSecondaryDrillEndLayer() );
530 BOOST_CHECK( candidate.GetBackPostMachining().has_value() );
532 static_cast<int>(
via.GetBackPostMachining().value() ) );
533 BOOST_CHECK( candidate.GetTertiaryDrillSize().has_value() );
535 via.GetTertiaryDrillSize().value() );
537 via.GetTertiaryDrillStartLayer() );
539 via.GetTertiaryDrillEndLayer() );
543 checkVia( *viaClone );
567 BOOST_CHECK( innerLayersRange2Layer.
Overlaps( 0 ) );
568 BOOST_CHECK( innerLayersRange2Layer.
Overlaps( 1 ) );
575 BOOST_CHECK( !innerLayersRange4Layer.
Overlaps( 0 ) );
576 BOOST_CHECK( innerLayersRange4Layer.
Overlaps( 1 ) );
577 BOOST_CHECK( innerLayersRange4Layer.
Overlaps( 2 ) );
578 BOOST_CHECK( !innerLayersRange4Layer.
Overlaps( 3 ) );
591 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
592 world->SetMaxClearance( 10000000 );
593 world->SetRuleResolver( &m_ruleResolver );
606 BOOST_CHECK( lockedSeg->
IsLocked() );
608 world->AddRaw( lockedSeg );
611 std::unique_ptr<PNS::SEGMENT> clone1(
PNS::Clone( *lockedSeg ) );
612 std::unique_ptr<PNS::SEGMENT> clone2(
PNS::Clone( *lockedSeg ) );
614 clone1->SetEnds( segStart, splitPt );
615 clone2->SetEnds( splitPt, segEnd );
618 "First half of split locked segment must retain locked state" );
620 "Second half of split locked segment must retain locked state" );
635 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
636 world->SetMaxClearance( 10000000 );
637 world->SetRuleResolver( &m_ruleResolver );
645 pad->SetPos( padPos );
648 world->AddRaw(
pad );
651 int narrowWidth = 250000;
655 world->AddRaw( narrowSeg );
658 int wideWidth = 500000;
662 world->AddRaw( wideSeg );
667 BOOST_CHECK( m_iface->TestInheritTrackWidth(
pad, &inherited ) );
672 BOOST_CHECK( m_iface->TestInheritTrackWidth(
pad, &inherited,
VECTOR2I( 2000000, 0 ) ) );
677 BOOST_CHECK( m_iface->TestInheritTrackWidth(
pad, &inherited,
VECTOR2I( 0, -2000000 ) ) );
682 BOOST_CHECK( m_iface->TestInheritTrackWidth(
pad, &inherited,
VECTOR2I( 100000, 50000 ) ) );
687 BOOST_CHECK( m_iface->TestInheritTrackWidth(
pad, &inherited,
VECTOR2I( 50000, -100000 ) ) );
703 auto compileAndCheck = [&](
const wxString& aExpr,
bool aExpectGeometry )
708 bool ok = compiler.
Compile( aExpr.ToUTF8().data(), &ucode, &ctx );
714 wxString::Format(
"Expression '%s': expected geometry=%s, got %s",
716 aExpectGeometry ?
"true" :
"false",
718 ?
"true" :
"false" ) );
723 compileAndCheck( wxT(
"A.NetClass == 'Power'" ),
false );
724 compileAndCheck( wxT(
"A.Type == 'via'" ),
false );
725 compileAndCheck( wxT(
"A.NetName == '/VCC'" ),
false );
728 compileAndCheck( wxT(
"A.intersectsCourtyard('U1')" ),
true );
729 compileAndCheck( wxT(
"A.intersectsArea('Zone1')" ),
true );
730 compileAndCheck( wxT(
"A.enclosedByArea('Zone1')" ),
true );
731 compileAndCheck( wxT(
"A.intersectsFrontCourtyard('U1')" ),
true );
732 compileAndCheck( wxT(
"A.intersectsBackCourtyard('U1')" ),
true );
735 compileAndCheck( wxT(
"A.insideCourtyard('U1')" ),
true );
736 compileAndCheck( wxT(
"A.insideArea('Zone1')" ),
true );
750 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
751 world->SetMaxClearance( 10000000 );
752 world->SetRuleResolver( &m_ruleResolver );
769 world->AddRaw( solid1 );
770 world->AddRaw( solid2 );
774 int count = world->QueryColliding( solid1, obstacles );
775 BOOST_CHECK( count > 0 );
783 nullShapeSolid.
SetNet( net2 );
785 bool collided = solid1->
Collide( &nullShapeSolid, world.get(),
F_Cu,
nullptr );
786 BOOST_CHECK( !collided );
800 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
801 world->SetMaxClearance( 10000000 );
802 world->SetRuleResolver( &m_ruleResolver );
815 VECTOR2I traceEnd( 2500000, 2500000 );
820 world->AddRaw( pad1 );
821 world->AddRaw( trace );
827 itemsToDrag.
Add( pad1 );
829 bool started = dragger.
Start( pad1Pos, itemsToDrag );
841 for(
const VECTOR2I& pos : dragPositions )
843 bool dragOk = dragger.
Drag( pos );
844 BOOST_CHECK( dragOk );
847 BOOST_CHECK( currentNode !=
nullptr );
852 BOOST_CHECK( traces.
Size() > 0 );
855 world->KillChildren();
888 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
889 world->SetMaxClearance( 10000000 );
890 world->SetRuleResolver( &m_ruleResolver );
897 m_ruleResolver.m_defaultClearance = 1000000;
900 world->QueryColliding(
v1, obstacles );
902 BOOST_CHECK_GE( obstacles.size(), (
size_t) 1 );
909 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
910 world->SetMaxClearance( 10000000 );
911 world->SetRuleResolver( &m_ruleResolver );
914 world->AddRaw( makeVia(
VECTOR2I( 0, 0 ), net ) );
918 m_ruleResolver.m_hasUserPhysicalRules =
false;
919 m_ruleResolver.m_defaultClearance = 1000000;
922 world->QueryColliding(
v1, obstacles );
932 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
933 world->SetMaxClearance( 10000000 );
934 world->SetRuleResolver( &m_ruleResolver );
937 world->AddRaw( makeVia(
VECTOR2I( 0, 0 ), net ) );
941 m_ruleResolver.m_hasUserPhysicalRules =
true;
942 m_ruleResolver.m_defaultPhysicalClearance = 1000000;
945 world->QueryColliding(
v1, obstacles );
947 BOOST_CHECK_GE( obstacles.size(), (
size_t) 1 );
948 if( !obstacles.empty() )
956 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
957 world->SetMaxClearance( 10000000 );
958 world->SetRuleResolver( &m_ruleResolver );
962 world->AddRaw( freePad );
965 m_ruleResolver.m_hasUserPhysicalRules =
false;
966 m_ruleResolver.m_defaultClearance = 1000000;
969 world->QueryColliding( v, obstacles );
980 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
981 world->SetMaxClearance( 10000000 );
982 world->SetRuleResolver( &m_ruleResolver );
986 world->AddRaw( freePad );
989 m_ruleResolver.m_hasUserPhysicalRules =
true;
990 m_ruleResolver.m_defaultPhysicalClearance = 0;
991 m_ruleResolver.m_defaultClearance = 1000000;
994 world->QueryColliding( v, obstacles );
1003 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
1004 world->SetMaxClearance( 10000000 );
1005 world->SetRuleResolver( &m_ruleResolver );
1009 world->AddRaw( freePad );
1012 m_ruleResolver.m_hasUserPhysicalRules =
true;
1013 m_ruleResolver.m_defaultPhysicalClearance = 1000000;
1016 world->QueryColliding( v, obstacles );
1018 BOOST_CHECK_GE( obstacles.size(), (
size_t) 1 );
1026 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
1027 world->SetMaxClearance( 10000000 );
1028 world->SetRuleResolver( &m_ruleResolver );
1033 world->AddRaw(
pad );
1034 world->AddRaw(
via );
1036 m_ruleResolver.m_hasUserPhysicalRules =
true;
1037 m_ruleResolver.m_defaultPhysicalHoleClearance = 1000000;
1040 world->QueryColliding(
via, obstacles );
1042 BOOST_CHECK_GE( obstacles.size(), (
size_t) 1 );
1048 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
1049 world->SetMaxClearance( 10000000 );
1050 world->SetRuleResolver( &m_ruleResolver );
1053 world->AddRaw( makeVia(
VECTOR2I( 0, 0 ), net ) );
1055 world->AddRaw(
v1 );
1057 m_ruleResolver.m_hasUserPhysicalRules =
true;
1058 m_ruleResolver.m_defaultPhysicalClearance = 0;
1061 world->QueryColliding(
v1, obstacles );
1071 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
1072 world->SetMaxClearance( 10000000 );
1073 world->SetRuleResolver( &m_ruleResolver );
1078 world->AddRaw(
pad );
1079 world->AddRaw(
via );
1081 m_ruleResolver.m_hasUserPhysicalRules =
true;
1082 m_ruleResolver.m_defaultPhysicalClearance = 100000;
1083 m_ruleResolver.m_defaultPhysicalHoleClearance = 2000000;
1086 world->QueryColliding(
via, obstacles );
1088 BOOST_CHECK_GE( obstacles.size(), (
size_t) 1 );
1093 int maxClearance = 0;
1095 maxClearance = std::max( maxClearance, obs.m_clearance );
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
Information pertinent to a Pcbnew printed circuit board.
KICAD_T Type() const
Returns the type of object.
bool Compile(const wxString &aString, UCODE *aCode, CONTEXT *aPreflightContext)
PNS::RULE_RESOLVER * GetRuleResolver() override
void DisplayItem(const PNS::ITEM *aItem, int aClearance, bool aEdit=false, int aFlags=0) override
void HideItem(PNS::ITEM *aItem) override
~MOCK_PNS_KICAD_IFACE() override
MOCK_PNS_KICAD_IFACE(PNS_TEST_FIXTURE *aFixture)
PNS_TEST_FIXTURE * m_testFixture
bool TestInheritTrackWidth(PNS::ITEM *aItem, int *aInheritedWidth, const VECTOR2I &aStartPosition=VECTOR2I())
virtual int NetCode(PNS::NET_HANDLE aNet) override
bool IsNetTieExclusion(const PNS::ITEM *aItem, const VECTOR2I &aCollisionPos, const PNS::ITEM *aCollidingItem) override
bool IsKeepout(const PNS::ITEM *aObstacle, const PNS::ITEM *aItem, bool *aEnforce) override
int m_defaultPhysicalHoleClearance
virtual int Clearance(const PNS::ITEM *aA, const PNS::ITEM *aB, bool aUseClearanceEpsilon=true) override
virtual bool QueryConstraint(PNS::CONSTRAINT_TYPE aType, const PNS::ITEM *aItemA, const PNS::ITEM *aItemB, int aLayer, PNS::CONSTRAINT *aConstraint) override
int m_defaultPhysicalClearance
bool IsInNetTie(const PNS::ITEM *aA) override
std::map< ITEM_KEY, PNS::CONSTRAINT > m_ruleMap
virtual PNS::NET_HANDLE DpCoupledNet(PNS::NET_HANDLE aNet) override
bool IsDrilledHole(const PNS::ITEM *aItem) override
void AddMockRule(PNS::CONSTRAINT_TYPE aType, const PNS::ITEM *aItemA, const PNS::ITEM *aItemB, PNS::CONSTRAINT &aConstraint)
bool IsNonPlatedSlot(const PNS::ITEM *aItem) override
bool HasUserDefinedPhysicalConstraint() override
virtual bool DpNetPair(const PNS::ITEM *aItem, PNS::NET_HANDLE &aNetP, PNS::NET_HANDLE &aNetN) override
virtual wxString NetName(PNS::NET_HANDLE aNet) override
virtual ~MOCK_RULE_RESOLVER()
bool m_hasUserPhysicalRules
int ClearanceEpsilon() const override
virtual int DpNetPolarity(PNS::NET_HANDLE aNet) override
bool HasGeometryDependentFunctions() const
const ITEM_SET Traces() override
Function Traces()
NODE * CurrentNode() const override
Function CurrentNode()
bool Start(const VECTOR2I &aP, ITEM_SET &aPrimitives) override
Function Start()
bool Drag(const VECTOR2I &aP) override
Function Drag()
virtual void SetWorld(NODE *aWorld)
Function SetWorld()
void Add(const LINE &aLine)
Base class for PNS router board items.
BOARD_ITEM * Parent() const
void SetLayers(const PNS_LAYER_RANGE &aLayers)
void SetIsFreePad(bool aIsFreePad=true)
const PNS_LAYER_RANGE & Layers() const
virtual NET_HANDLE Net() const
void SetNet(NET_HANDLE aNet)
virtual int Layer() const
bool Collide(const ITEM *aHead, const NODE *aNode, int aLayer, COLLISION_SEARCH_CONTEXT *aCtx=nullptr) const
Check for a collision (clearance violation) with between us and item aOther.
bool OfKind(int aKindMask) const
virtual void Mark(int aMarker) const
virtual BOARD_ITEM * BoardItem() const
void SetRoutable(bool aRoutable)
Keep the router "world" - i.e.
std::set< OBSTACLE > OBSTACLES
int Width() const override
void SetWidth(int aWidth) override
void SetPos(const VECTOR2I &aCenter)
void SetShape(SHAPE *shape)
bool inheritTrackWidth(PNS::ITEM *aItem, int *aInheritedWidth, const VECTOR2I &aStartPosition)
Represent a contiguous set of PCB layers.
bool Overlaps(const PNS_LAYER_RANGE &aOther) const
PNS_LAYER_RANGE Intersection(const PNS_LAYER_RANGE &aOther) const
Shortcut for comparisons/overlap tests.
constexpr PCB_LAYER_ID PCBNEW_LAYER_ID_START
@ CT_PHYSICAL_HOLE_CLEARANCE
std::unique_ptr< typename std::remove_const< T >::type > Clone(const T &aItem)
PNS::CONSTRAINT_TYPE type
bool operator<(const ITEM_KEY &other) const
bool operator==(const ITEM_KEY &other) const
An abstract function object, returning a design rule (clearance, diff pair gap, etc) required between...
Hold an object colliding with another object, along with some useful data about the collision.
SETTINGS_MANAGER m_settingsManager
MOCK_RULE_RESOLVER m_ruleResolver
MOCK_PNS_KICAD_IFACE * m_iface
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_CHECK_MESSAGE(totalMismatches==0, std::to_string(totalMismatches)+" board(s) with strategy disagreements")
BOOST_TEST_MESSAGE("\n=== Real-World Polygon PIP Benchmark ===\n"<< formatTable(table))
static bool isEdge(const PNS::ITEM *aItem)
static bool isHole(const PNS::ITEM *aItem)
static void dumpObstacles(const PNS::NODE::OBSTACLES &obstacles)
BOOST_FIXTURE_TEST_CASE(PNSHoleCollisions, PNS_TEST_FIXTURE)
static bool isCopper(const PNS::ITEM *aItem)
BOOST_AUTO_TEST_CASE(PCBViaBackdrillCloneRetainsData)
BOOST_CHECK_EQUAL(result, "25.4")
@ PCB_PAD_T
class PAD, a pad in a footprint
VECTOR2< int32_t > VECTOR2I