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 std::vector<const PAD*> overlappingSameNumPads;
178 for(
const PAD* p : sameNumPads )
180 if( p->IsOnLayer( aLayer )
181 &&
pad->GetBoundingBox().Intersects( p->GetBoundingBox() ) )
183 overlappingSameNumPads.push_back( p );
187 if( !handled || !overlappingSameNumPads.empty() )
191 std::shared_ptr<SHAPE_SEGMENT> slot =
pad->GetEffectiveHoleShape();
193 pad->TransformShapeToPolygon( padOutline, aLayer, 0,
pad->GetMaxError(),
ERROR_INSIDE );
195 if( sameNumPads.empty() )
197 if( !padOutline.
Collide(
pad->GetPosition() ) )
200 *ptA =
pad->GetPosition();
201 *ptB =
pad->GetPosition();
208 else if( constraint.Value().HasMin() )
214 slot->TransformToPolygon( slotPolygon, 0,
ERROR_INSIDE );
216 for(
const PAD* sameNumPad : sameNumPads )
219 sameNumPad->TransformShapeToPolygon( aggregatePadOutline, aLayer, 0,
pad->GetMaxError(),
222 sameNumPad->TransformHoleToPolygon( otherPadHoles, 0,
pad->GetMaxError(),
ERROR_INSIDE );
227 if( !aggregatePadOutline.
Collide(
pad->GetPosition() ) )
230 *ptA =
pad->GetPosition();
231 *ptB =
pad->GetPosition();
241 auto checkConstraint =
250 bool fail_min =
false;
251 bool fail_max =
false;
252 int width = ( ptA - ptB ).EuclideanNorm();
254 if( constraint.Value().HasMin() )
256 v_min = constraint.Value().Min();
257 fail_min = width < v_min;
260 if( constraint.Value().HasMax() )
262 v_max = constraint.Value().Max();
263 fail_max = width > v_max;
266 if( fail_min || fail_max )
272 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s min annular width %s; actual %s)" ),
273 constraint.GetName(),
280 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s max annular width %s; actual %s)" ),
281 constraint.GetName(),
286 drcItem->SetItems( item );
287 drcItem->SetViolatingRule( constraint.GetParentRule() );
292 auto checkAnnularWidth =
302 via->Padstack().ForEachUniqueLayer(
310 checkConstraint( constraint,
via, ptA, ptB, aLayer );
320 std::vector<const PAD*> sameNumPads;
323 sameNumPads = fp->GetPads(
pad->GetNumber(),
pad );
325 pad->Padstack().ForEachUniqueLayer(
333 getPadAnnulusPts(
pad, aLayer, constraint, sameNumPads, &ptA, &ptB );
334 checkConstraint( constraint,
pad, ptA, ptB, aLayer );
346 total += calcEffort( item );
350 for(
PAD*
pad : footprint->Pads() )
351 total += calcEffort(
pad );
356 ii += calcEffort( item );
361 if( !checkAnnularWidth( item ) )
367 for(
PAD*
pad : footprint->Pads() )
369 ii += calcEffort(
pad );
374 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.