56 if(
pad->IsAperturePad() ||
pad->IsNPTHWithNoCopper() )
94 bool aUseClearanceEpsilon =
true )
override
114 const bool sameNet = aA && aB && aA->
Net() && aA->
Net() == aB->
Net();
117 for(
int layer = layers.
Start(); layer <= layers.
End(); ++layer )
119 if( !sameNet && !freePad )
171 if( ( sameNet || freePad ) && rv == 0 )
195 return wxEmptyString;
228 default:
return false;
233 aConstraint->
m_Type = aType;
240 *aConstraint = it->second;
256 return a == other.
a &&
b == other.
b &&
type == other.
type;
265 else if (
a == other.
a )
269 else if (
b == other.
b )
280 const PNS::ITEM* aCollidingItem )
override
331 int aFlags = 0 )
override {};
373 obs.m_head, obs.m_head->KindStr().c_str(),
374 obs.m_item, obs.m_item->KindStr().c_str(),
384 std::unique_ptr<PNS::NODE> world (
new PNS::NODE );
389 world->SetMaxClearance( 10000000 );
390 world->SetRuleResolver( &m_ruleResolver );
398 int count = world->QueryColliding(
v1, obstacles );
407 m_ruleResolver.m_defaultClearance = 1000000;
408 world->QueryColliding(
v1, obstacles );
412 const auto& first = *obstacles.begin();
422 m_ruleResolver.m_defaultClearance = 200000;
423 m_ruleResolver.m_defaultHole2Hole = 1000000;
425 world->QueryColliding(
v1, obstacles );
429 auto iter = obstacles.begin();
430 const auto& first = *iter++;
440 m_ruleResolver.m_defaultHole2Hole = 220000;
441 m_ruleResolver.m_defaultHole2Copper = 1000000;
443 world->QueryColliding(
v1, obstacles );
447 auto iter = obstacles.begin();
448 const auto& first = *iter++;
451 BOOST_CHECK( ( first.m_head ==
v1 && first.m_item ==
v2->Hole() )
452 || ( first.m_head ==
v1->Hole() && first.m_item ==
v2 ) );
465 via.SetSecondaryDrill( std::optional<int>( 12000 ) );
470 std::unique_ptr<PNS::VIA> viaClone(
via.Clone() );
472 auto checkVia = [&](
const PNS::VIA& candidate )
476 BOOST_CHECK( candidate.HolePostMachining().has_value() );
478 BOOST_CHECK( candidate.SecondaryDrill().has_value() );
480 BOOST_CHECK( candidate.SecondaryHoleLayers().has_value() );
482 via.SecondaryHoleLayers()->Start() );
484 via.SecondaryHoleLayers()->End() );
485 BOOST_CHECK( candidate.SecondaryHolePostMachining().has_value() );
488 if( candidate.SecondaryHolePostMachining().has_value() )
489 BOOST_CHECK( candidate.SecondaryHolePostMachining().value() ==
via.SecondaryHolePostMachining().value() );
493 checkVia( *viaClone );
502 via.SetPrimaryDrillStartLayer(
F_Cu );
503 via.SetPrimaryDrillEndLayer(
B_Cu );
505 via.SetSecondaryDrillSize( std::optional<int>( 15000 ) );
506 via.SetSecondaryDrillStartLayer(
F_Cu );
510 via.SetTertiaryDrillSize( std::optional<int>( 8000 ) );
511 via.SetTertiaryDrillStartLayer(
B_Cu );
515 std::unique_ptr<PCB_VIA> viaClone(
static_cast<PCB_VIA*
>(
via.Clone() ) );
517 auto checkVia = [&](
const PCB_VIA& candidate )
521 BOOST_CHECK( candidate.GetFrontPostMachining().has_value() );
522 BOOST_CHECK_EQUAL(
static_cast<int>( candidate.GetFrontPostMachining().value() ),
523 static_cast<int>(
via.GetFrontPostMachining().value() ) );
524 BOOST_CHECK( candidate.GetSecondaryDrillSize().has_value() );
526 via.GetSecondaryDrillSize().value() );
528 via.GetSecondaryDrillStartLayer() );
530 via.GetSecondaryDrillEndLayer() );
532 BOOST_CHECK( candidate.GetBackPostMachining().has_value() );
534 static_cast<int>(
via.GetBackPostMachining().value() ) );
535 BOOST_CHECK( candidate.GetTertiaryDrillSize().has_value() );
537 via.GetTertiaryDrillSize().value() );
539 via.GetTertiaryDrillStartLayer() );
541 via.GetTertiaryDrillEndLayer() );
545 checkVia( *viaClone );
569 BOOST_CHECK( innerLayersRange2Layer.
Overlaps( 0 ) );
570 BOOST_CHECK( innerLayersRange2Layer.
Overlaps( 1 ) );
577 BOOST_CHECK( !innerLayersRange4Layer.
Overlaps( 0 ) );
578 BOOST_CHECK( innerLayersRange4Layer.
Overlaps( 1 ) );
579 BOOST_CHECK( innerLayersRange4Layer.
Overlaps( 2 ) );
580 BOOST_CHECK( !innerLayersRange4Layer.
Overlaps( 3 ) );
593 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
594 world->SetMaxClearance( 10000000 );
595 world->SetRuleResolver( &m_ruleResolver );
608 BOOST_CHECK( lockedSeg->
IsLocked() );
610 world->AddRaw( lockedSeg );
613 std::unique_ptr<PNS::SEGMENT> clone1(
PNS::Clone( *lockedSeg ) );
614 std::unique_ptr<PNS::SEGMENT> clone2(
PNS::Clone( *lockedSeg ) );
616 clone1->SetEnds( segStart, splitPt );
617 clone2->SetEnds( splitPt, segEnd );
620 "First half of split locked segment must retain locked state" );
622 "Second half of split locked segment must retain locked state" );
637 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
638 world->SetMaxClearance( 10000000 );
639 world->SetRuleResolver( &m_ruleResolver );
647 pad->SetPos( padPos );
650 world->AddRaw(
pad );
653 int narrowWidth = 250000;
657 world->AddRaw( narrowSeg );
660 int wideWidth = 500000;
664 world->AddRaw( wideSeg );
669 BOOST_CHECK( m_iface->TestInheritTrackWidth(
pad, &inherited ) );
674 BOOST_CHECK( m_iface->TestInheritTrackWidth(
pad, &inherited,
VECTOR2I( 2000000, 0 ) ) );
679 BOOST_CHECK( m_iface->TestInheritTrackWidth(
pad, &inherited,
VECTOR2I( 0, -2000000 ) ) );
684 BOOST_CHECK( m_iface->TestInheritTrackWidth(
pad, &inherited,
VECTOR2I( 100000, 50000 ) ) );
689 BOOST_CHECK( m_iface->TestInheritTrackWidth(
pad, &inherited,
VECTOR2I( 50000, -100000 ) ) );
705 auto compileAndCheck = [&](
const wxString& aExpr,
bool aExpectGeometry )
710 bool ok = compiler.
Compile( aExpr.ToUTF8().data(), &ucode, &ctx );
716 wxString::Format(
"Expression '%s': expected geometry=%s, got %s",
718 aExpectGeometry ?
"true" :
"false",
720 ?
"true" :
"false" ) );
725 compileAndCheck( wxT(
"A.NetClass == 'Power'" ),
false );
726 compileAndCheck( wxT(
"A.Type == 'via'" ),
false );
727 compileAndCheck( wxT(
"A.NetName == '/VCC'" ),
false );
730 compileAndCheck( wxT(
"A.intersectsCourtyard('U1')" ),
true );
731 compileAndCheck( wxT(
"A.intersectsArea('Zone1')" ),
true );
732 compileAndCheck( wxT(
"A.enclosedByArea('Zone1')" ),
true );
733 compileAndCheck( wxT(
"A.intersectsFrontCourtyard('U1')" ),
true );
734 compileAndCheck( wxT(
"A.intersectsBackCourtyard('U1')" ),
true );
737 compileAndCheck( wxT(
"A.insideCourtyard('U1')" ),
true );
738 compileAndCheck( wxT(
"A.insideArea('Zone1')" ),
true );
752 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
753 world->SetMaxClearance( 10000000 );
754 world->SetRuleResolver( &m_ruleResolver );
771 world->AddRaw( solid1 );
772 world->AddRaw( solid2 );
776 int count = world->QueryColliding( solid1, obstacles );
777 BOOST_CHECK( count > 0 );
785 nullShapeSolid.
SetNet( net2 );
787 bool collided = solid1->
Collide( &nullShapeSolid, world.get(),
F_Cu,
nullptr );
788 BOOST_CHECK( !collided );
802 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
803 world->SetMaxClearance( 10000000 );
804 world->SetRuleResolver( &m_ruleResolver );
817 VECTOR2I traceEnd( 2500000, 2500000 );
822 world->AddRaw( pad1 );
823 world->AddRaw( trace );
829 itemsToDrag.
Add( pad1 );
831 bool started = dragger.
Start( pad1Pos, itemsToDrag );
843 for(
const VECTOR2I& pos : dragPositions )
845 bool dragOk = dragger.
Drag( pos );
846 BOOST_CHECK( dragOk );
849 BOOST_CHECK( currentNode !=
nullptr );
854 BOOST_CHECK( traces.
Size() > 0 );
857 world->KillChildren();
870 chain.SetWidth( 250000 );
879 double oldRadius = line.
CLine().
CArcs()[0].GetRadius();
887 BOOST_CHECK( line.
CLine().
CArcs()[0].GetRadius() != oldRadius );
898 chain.SetWidth( 250000 );
921 m_router->LoadSettings( &settings );
935 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
936 world->SetMaxClearance( 10000000 );
937 world->SetRuleResolver( &m_ruleResolver );
940 world->AddRaw( arc );
949 m_router->SetFailureReason( wxEmptyString );
950 BOOST_CHECK( dragger.
Start( arc->
Anchor( 0 ), items ) );
951 BOOST_CHECK( m_router->FailureReason().IsEmpty() );
953 world->KillChildren();
958 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
959 world->SetMaxClearance( 10000000 );
960 world->SetRuleResolver( &m_ruleResolver );
963 world->AddRaw( arc );
972 m_router->SetFailureReason( wxEmptyString );
973 BOOST_CHECK( !dragger.
Start( arc->
Anchor( 0 ), items ) );
974 BOOST_CHECK( !m_router->FailureReason().IsEmpty() );
976 world->KillChildren();
982 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
983 world->SetMaxClearance( 10000000 );
984 world->SetRuleResolver( &m_ruleResolver );
987 world->AddRaw( arc );
996 m_router->SetFailureReason( wxEmptyString );
997 BOOST_CHECK( !dragger.
Start( arc->
Anchor( 0 ), items ) );
998 BOOST_CHECK( !m_router->FailureReason().IsEmpty() );
1000 world->KillChildren();
1034 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
1035 world->SetMaxClearance( 10000000 );
1036 world->SetRuleResolver( &m_ruleResolver );
1040 world->AddRaw(
v1 );
1041 world->AddRaw(
v2 );
1043 m_ruleResolver.m_defaultClearance = 1000000;
1046 world->QueryColliding(
v1, obstacles );
1048 BOOST_CHECK_GE( obstacles.size(), (
size_t) 1 );
1055 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
1056 world->SetMaxClearance( 10000000 );
1057 world->SetRuleResolver( &m_ruleResolver );
1060 world->AddRaw( makeVia(
VECTOR2I( 0, 0 ), net ) );
1062 world->AddRaw(
v1 );
1064 m_ruleResolver.m_hasUserPhysicalRules =
false;
1065 m_ruleResolver.m_defaultClearance = 1000000;
1068 world->QueryColliding(
v1, obstacles );
1078 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
1079 world->SetMaxClearance( 10000000 );
1080 world->SetRuleResolver( &m_ruleResolver );
1083 world->AddRaw( makeVia(
VECTOR2I( 0, 0 ), net ) );
1085 world->AddRaw(
v1 );
1087 m_ruleResolver.m_hasUserPhysicalRules =
true;
1088 m_ruleResolver.m_defaultPhysicalClearance = 1000000;
1091 world->QueryColliding(
v1, obstacles );
1093 BOOST_CHECK_GE( obstacles.size(), (
size_t) 1 );
1094 if( !obstacles.empty() )
1102 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
1103 world->SetMaxClearance( 10000000 );
1104 world->SetRuleResolver( &m_ruleResolver );
1108 world->AddRaw( freePad );
1111 m_ruleResolver.m_hasUserPhysicalRules =
false;
1112 m_ruleResolver.m_defaultClearance = 1000000;
1115 world->QueryColliding( v, obstacles );
1126 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
1127 world->SetMaxClearance( 10000000 );
1128 world->SetRuleResolver( &m_ruleResolver );
1132 world->AddRaw( freePad );
1135 m_ruleResolver.m_hasUserPhysicalRules =
true;
1136 m_ruleResolver.m_defaultPhysicalClearance = 0;
1137 m_ruleResolver.m_defaultClearance = 1000000;
1140 world->QueryColliding( v, obstacles );
1149 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
1150 world->SetMaxClearance( 10000000 );
1151 world->SetRuleResolver( &m_ruleResolver );
1155 world->AddRaw( freePad );
1158 m_ruleResolver.m_hasUserPhysicalRules =
true;
1159 m_ruleResolver.m_defaultPhysicalClearance = 1000000;
1162 world->QueryColliding( v, obstacles );
1164 BOOST_CHECK_GE( obstacles.size(), (
size_t) 1 );
1172 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
1173 world->SetMaxClearance( 10000000 );
1174 world->SetRuleResolver( &m_ruleResolver );
1179 world->AddRaw(
pad );
1180 world->AddRaw(
via );
1182 m_ruleResolver.m_hasUserPhysicalRules =
true;
1183 m_ruleResolver.m_defaultPhysicalHoleClearance = 1000000;
1186 world->QueryColliding(
via, obstacles );
1188 BOOST_CHECK_GE( obstacles.size(), (
size_t) 1 );
1194 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
1195 world->SetMaxClearance( 10000000 );
1196 world->SetRuleResolver( &m_ruleResolver );
1199 world->AddRaw( makeVia(
VECTOR2I( 0, 0 ), net ) );
1201 world->AddRaw(
v1 );
1203 m_ruleResolver.m_hasUserPhysicalRules =
true;
1204 m_ruleResolver.m_defaultPhysicalClearance = 0;
1207 world->QueryColliding(
v1, obstacles );
1217 std::unique_ptr<PNS::NODE> world(
new PNS::NODE );
1218 world->SetMaxClearance( 10000000 );
1219 world->SetRuleResolver( &m_ruleResolver );
1224 world->AddRaw(
pad );
1225 world->AddRaw(
via );
1227 m_ruleResolver.m_hasUserPhysicalRules =
true;
1228 m_ruleResolver.m_defaultPhysicalClearance = 100000;
1229 m_ruleResolver.m_defaultPhysicalHoleClearance = 2000000;
1232 world->QueryColliding(
via, obstacles );
1234 BOOST_CHECK_GE( obstacles.size(), (
size_t) 1 );
1239 int maxClearance = 0;
1241 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
virtual VECTOR2I Anchor(int n) const override
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 bool Start(const VECTOR2I &aP, ITEM_SET &aPrimitives) override
Function Start()
void SetMode(PNS::DRAG_MODE aDragMode) override
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)
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
void DragArc(const VECTOR2I &aP, int aIndex)
const SHAPE_LINE_CHAIN & CLine() const
SHAPE_LINE_CHAIN & Line()
void SetWidth(int aWidth)
Return line width.
Keep the router "world" - i.e.
std::set< OBSTACLE > OBSTACLES
Contain all persistent settings of the router, such as the mode, optimization effort,...
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.
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 std::vector< SHAPE_ARC > & CArcs() const
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)
const SHAPE_LINE_CHAIN chain
BOOST_CHECK_EQUAL(result, "25.4")
@ PCB_PAD_T
class PAD, a pad in a footprint
VECTOR2< int32_t > VECTOR2I