64 REPORT_AUX( wxT(
"Annular width violations ignored. Skipping check." ) );
68 const int progressDelta = 500;
72 REPORT_AUX( wxT(
"No annular width constraints found. Tests not run." ) );
76 if( !
reportPhase(
_(
"Checking pad & via annular rings..." ) ) )
82 switch( item->Type() )
96 pad->Padstack().ForEachUniqueLayer(
101 switch(
pad->GetShape( aLayer ) )
104 if(
pad->GetChamferRectRatio( aLayer ) > 0.30 )
132 auto getPadAnnulusPts =
136 bool handled =
false;
140 int xDist =
KiROUND( (
pad->GetSizeX() -
pad->GetDrillSizeX() ) / 2.0 );
141 int yDist =
KiROUND( (
pad->GetSizeY() -
pad->GetDrillSizeY() ) / 2.0 );
145 *ptA =
pad->GetPosition() -
VECTOR2I( 0,
pad->GetDrillSizeY() / 2 );
150 *ptA =
pad->GetPosition() -
VECTOR2I(
pad->GetDrillSizeX() / 2, 0 );
157 switch(
pad->GetShape( aLayer ) )
160 handled =
pad->GetChamferRectRatio( aLayer ) <= 0.30;
176 if( !handled || !sameNumPads.empty() )
180 std::shared_ptr<SHAPE_SEGMENT> slot =
pad->GetEffectiveHoleShape();
182 pad->TransformShapeToPolygon( padOutline, aLayer, 0,
pad->GetMaxError(),
ERROR_INSIDE );
184 if( sameNumPads.empty() )
186 if( !padOutline.
Collide(
pad->GetPosition() ) )
189 *ptA =
pad->GetPosition();
190 *ptB =
pad->GetPosition();
197 else if( constraint.Value().HasMin() )
203 slot->TransformToPolygon( slotPolygon, 0,
ERROR_INSIDE );
205 for(
const PAD* sameNumPad : sameNumPads )
208 sameNumPad->TransformShapeToPolygon( aggregatePadOutline, aLayer, 0,
211 sameNumPad->TransformHoleToPolygon( otherPadHoles, 0,
pad->GetMaxError(),
217 if( !aggregatePadOutline.
Collide(
pad->GetPosition() ) )
220 *ptA =
pad->GetPosition();
221 *ptB =
pad->GetPosition();
231 auto checkConstraint =
240 bool fail_min =
false;
241 bool fail_max =
false;
242 int width = ( ptA - ptB ).EuclideanNorm();
244 if( constraint.Value().HasMin() )
246 v_min = constraint.Value().Min();
247 fail_min = width < v_min;
250 if( constraint.Value().HasMax() )
252 v_max = constraint.Value().Max();
253 fail_max = width > v_max;
256 if( fail_min || fail_max )
263 msg =
formatMsg(
_(
"(%s min annular width %s; actual %s)" ),
264 constraint.GetName(),
271 msg =
formatMsg(
_(
"(%s max annular width %s; actual %s)" ),
272 constraint.GetName(),
277 drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS(
" " ) + msg );
278 drcItem->SetItems( item );
279 drcItem->SetViolatingRule( constraint.GetParentRule() );
284 auto checkAnnularWidth =
294 via->Padstack().ForEachUniqueLayer(
302 checkConstraint( constraint,
via, ptA, ptB, aLayer );
312 std::vector<const PAD*> sameNumPads;
315 sameNumPads = fp->GetPads(
pad->GetNumber(),
pad );
317 pad->Padstack().ForEachUniqueLayer(
325 getPadAnnulusPts(
pad, aLayer, constraint, sameNumPads, &ptA, &ptB );
326 checkConstraint( constraint,
pad, ptA, ptB, aLayer );
338 total += calcEffort( item );
342 for(
PAD*
pad : footprint->Pads() )
343 total += calcEffort(
pad );
348 ii += calcEffort( item );
353 if( !checkAnnularWidth( item ) )
359 for(
PAD*
pad : footprint->Pads() )
361 ii += calcEffort(
pad );
366 if( !checkAnnularWidth(
pad ) )
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.