75 BOOST_REQUIRE_MESSAGE( m_board,
"Failed to load board issue23389" );
79 std::shared_ptr<DRC_ITEM> item;
81 std::vector<PCB_SHAPE> pathShapes;
84 std::vector<ViolationInfo> violations;
87 BOOST_REQUIRE_MESSAGE( bds.
m_DRCEngine,
"DRC engine not initialized" );
95 [&](
const std::shared_ptr<DRC_ITEM>& aItem,
const VECTOR2I& aPos,
int aLayer,
96 const std::function<
void(
PCB_MARKER* )>& aPathGenerator )
108 aPathGenerator( &marker );
112 violations.push_back( vi );
119 BOOST_REQUIRE_GE( violations.size(), 1u );
122 std::map<KIID, BOARD_ITEM*> itemMap;
124 for(
PCB_TRACK* track : m_board->Tracks() )
125 itemMap[track->m_Uuid] = track;
127 for(
FOOTPRINT* fp : m_board->Footprints() )
129 itemMap[fp->m_Uuid] = fp;
131 for(
PAD*
pad : fp->Pads() )
132 itemMap[
pad->m_Uuid] =
pad;
135 for(
size_t i = 0; i < violations.size(); i++ )
137 const ViolationInfo& vi = violations[i];
140 vi.item->GetErrorMessage(
false ) ) );
142 vi.pos.x / 1e6, vi.pos.y / 1e6,
143 (
int) vi.pathShapes.size() ) );
145 for(
size_t j = 0; j < vi.pathShapes.size(); j++ )
152 " [%zu] SEG: (%.4f,%.4f)->(%.4f,%.4f) mm", j,
159 " [%zu] ARC: (%.4f,%.4f)->(%.4f,%.4f) c=(%.4f,%.4f) mm", j,
166 if( vi.pathShapes.empty() )
173 KIID idA = vi.item->GetMainItemID();
174 KIID idB = vi.item->GetAuxItemID();
176 auto itA = itemMap.find( idA );
177 auto itB = itemMap.find( idB );
179 if( itA != itemMap.end() )
182 if( itB != itemMap.end() )
210 auto validateOnOuterBoundary =
217 int anchorHalfWidth = anchorTrack->
GetWidth() / 2;
219 int tolerance = 10000;
222 int distToAnchor = anchorSeg.
Distance( pt );
225 " %s at (%.4f, %.4f): dist to anchor centerline=%d (hw=%d)",
226 label, pt.x / 1e6, pt.y / 1e6, distToAnchor, anchorHalfWidth ) );
229 std::abs( distToAnchor - anchorHalfWidth ) <= tolerance,
230 wxString::Format(
"Violation %zu %s: path endpoint is %d nm from "
231 "anchor track centerline, expected %d nm (halfWidth)",
232 i, label, distToAnchor, anchorHalfWidth ) );
235 for(
PCB_TRACK* other : m_board->Tracks() )
237 if( other == anchorTrack )
240 if( other->GetNetCode() != netCode )
243 if( !other->IsOnLayer( anchorTrack->
GetLayer() ) )
246 SEG otherSeg( other->GetStart(), other->GetEnd() );
247 int otherHalfWidth = other->GetWidth() / 2;
248 int distToOther = otherSeg.
Distance( pt );
255 distToOther >= otherHalfWidth - tolerance,
257 "Violation %zu %s: path endpoint (%.4f, %.4f) is "
258 "%d nm inside adjacent same-net track "
259 "(%.4f,%.4f)->(%.4f,%.4f) hw=%d. The path starts "
260 "at an interior point, not a physical copper edge.",
262 pt.x / 1e6, pt.y / 1e6,
263 otherHalfWidth - distToOther,
264 other->GetStart().x / 1e6,
265 other->GetStart().y / 1e6,
266 other->GetEnd().x / 1e6,
267 other->GetEnd().y / 1e6,
272 validateOnOuterBoundary( itemA, vi.pos,
"startPoint" );
280 int bestDist = std::numeric_limits<int>::max();
283 for(
const PCB_SHAPE& s : vi.pathShapes )
302 validateOnOuterBoundary( itemB, endPt,
"endPoint" );
DRC_CREEPAGE_PATH_FIXTURE()=default
std::unique_ptr< BOARD > m_board
BOOST_FIXTURE_TEST_CASE(CreepagePathStartPointIssue23576, DRC_CREEPAGE_PATH_FIXTURE)