71 BOOST_REQUIRE_MESSAGE( m_board,
"Failed to load board issue23389" );
75 std::shared_ptr<DRC_ITEM> item;
77 std::vector<PCB_SHAPE> pathShapes;
80 std::vector<ViolationInfo> violations;
83 BOOST_REQUIRE_MESSAGE( bds.
m_DRCEngine,
"DRC engine not initialized" );
91 [&](
const std::shared_ptr<DRC_ITEM>& aItem,
const VECTOR2I& aPos,
int aLayer,
92 const std::function<
void(
PCB_MARKER* )>& aPathGenerator )
104 aPathGenerator( &marker );
108 violations.push_back( vi );
115 BOOST_REQUIRE_GE( violations.size(), 1u );
118 std::map<KIID, BOARD_ITEM*> itemMap;
120 for(
PCB_TRACK* track : m_board->Tracks() )
121 itemMap[track->m_Uuid] = track;
123 for(
FOOTPRINT* fp : m_board->Footprints() )
125 itemMap[fp->m_Uuid] = fp;
127 for(
PAD*
pad : fp->Pads() )
128 itemMap[
pad->m_Uuid] =
pad;
131 for(
size_t i = 0; i < violations.size(); i++ )
133 const ViolationInfo& vi = violations[i];
136 vi.item->GetErrorMessage(
false ) ) );
138 vi.pos.x / 1e6, vi.pos.y / 1e6,
139 (
int) vi.pathShapes.size() ) );
141 for(
size_t j = 0; j < vi.pathShapes.size(); j++ )
148 " [%zu] SEG: (%.4f,%.4f)->(%.4f,%.4f) mm", j,
155 " [%zu] ARC: (%.4f,%.4f)->(%.4f,%.4f) c=(%.4f,%.4f) mm", j,
162 if( vi.pathShapes.empty() )
169 KIID idA = vi.item->GetMainItemID();
170 KIID idB = vi.item->GetAuxItemID();
172 auto itA = itemMap.find( idA );
173 auto itB = itemMap.find( idB );
175 if( itA != itemMap.end() )
178 if( itB != itemMap.end() )
206 auto validateOnOuterBoundary =
213 int anchorHalfWidth = anchorTrack->
GetWidth() / 2;
215 int tolerance = 10000;
218 int distToAnchor = anchorSeg.
Distance( pt );
221 " %s at (%.4f, %.4f): dist to anchor centerline=%d (hw=%d)",
222 label, pt.x / 1e6, pt.y / 1e6, distToAnchor, anchorHalfWidth ) );
225 std::abs( distToAnchor - anchorHalfWidth ) <= tolerance,
226 wxString::Format(
"Violation %zu %s: path endpoint is %d nm from "
227 "anchor track centerline, expected %d nm (halfWidth)",
228 i, label, distToAnchor, anchorHalfWidth ) );
231 for(
PCB_TRACK* other : m_board->Tracks() )
233 if( other == anchorTrack )
236 if( other->GetNetCode() != netCode )
239 if( !other->IsOnLayer( anchorTrack->
GetLayer() ) )
242 SEG otherSeg( other->GetStart(), other->GetEnd() );
243 int otherHalfWidth = other->GetWidth() / 2;
244 int distToOther = otherSeg.
Distance( pt );
251 distToOther >= otherHalfWidth - tolerance,
253 "Violation %zu %s: path endpoint (%.4f, %.4f) is "
254 "%d nm inside adjacent same-net track "
255 "(%.4f,%.4f)->(%.4f,%.4f) hw=%d. The path starts "
256 "at an interior point, not a physical copper edge.",
258 pt.x / 1e6, pt.y / 1e6,
259 otherHalfWidth - distToOther,
260 other->GetStart().x / 1e6,
261 other->GetStart().y / 1e6,
262 other->GetEnd().x / 1e6,
263 other->GetEnd().y / 1e6,
268 validateOnOuterBoundary( itemA, vi.pos,
"startPoint" );
276 int bestDist = std::numeric_limits<int>::max();
279 for(
const PCB_SHAPE& s : vi.pathShapes )
298 validateOnOuterBoundary( itemB, endPt,
"endPoint" );
DRC_CREEPAGE_PATH_FIXTURE()=default
std::unique_ptr< BOARD > m_board
BOOST_FIXTURE_TEST_CASE(CreepagePathStartPointIssue23576, DRC_CREEPAGE_PATH_FIXTURE)