Be careful of interveneing priority zones when doing divot prevention.
Fixes https://gitlab.com/kicad/code/kicad/issues/12797
This commit is contained in:
parent
ed309e20da
commit
1f4e51b008
|
@ -1007,7 +1007,8 @@ bool ZONE::IsIsland( PCB_LAYER_ID aLayer, int aPolyIdx ) const
|
|||
}
|
||||
|
||||
|
||||
void ZONE::GetInteractingZones( PCB_LAYER_ID aLayer, std::vector<ZONE*>* aZones ) const
|
||||
void ZONE::GetInteractingZones( PCB_LAYER_ID aLayer, std::vector<ZONE*>* aSameNetCollidingZones,
|
||||
std::vector<ZONE*>* aOtherNetIntersectingZones ) const
|
||||
{
|
||||
int epsilon = pcbIUScale.mmToIU( 0.001 );
|
||||
BOX2I bbox = GetBoundingBox();
|
||||
|
@ -1022,23 +1023,27 @@ void ZONE::GetInteractingZones( PCB_LAYER_ID aLayer, std::vector<ZONE*>* aZones
|
|||
if( !candidate->GetLayerSet().test( aLayer ) )
|
||||
continue;
|
||||
|
||||
if( candidate->GetIsRuleArea() )
|
||||
continue;
|
||||
|
||||
if( candidate->GetNetCode() != GetNetCode() )
|
||||
if( candidate->GetIsRuleArea() || candidate->IsTeardropArea() )
|
||||
continue;
|
||||
|
||||
if( !candidate->GetBoundingBox().Intersects( bbox ) )
|
||||
continue;
|
||||
|
||||
for( auto iter = m_Poly->CIterate(); iter; iter++ )
|
||||
if( candidate->GetNetCode() == GetNetCode() )
|
||||
{
|
||||
if( candidate->m_Poly->Collide( iter.Get(), epsilon ) )
|
||||
for( auto iter = m_Poly->CIterate(); iter; iter++ )
|
||||
{
|
||||
aZones->push_back( candidate );
|
||||
break;
|
||||
if( candidate->m_Poly->Collide( iter.Get(), epsilon ) )
|
||||
{
|
||||
aSameNetCollidingZones->push_back( candidate );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
aOtherNetIntersectingZones->push_back( candidate );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1105,9 +1110,6 @@ bool ZONE::BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly, PCB_LAYER_ID aLayer
|
|||
}
|
||||
};
|
||||
|
||||
std::vector<ZONE*> interactingZones;
|
||||
GetInteractingZones( aLayer, &interactingZones );
|
||||
|
||||
SHAPE_POLY_SET* maxExtents = &flattened;
|
||||
SHAPE_POLY_SET withFillets;
|
||||
|
||||
|
@ -1124,11 +1126,34 @@ bool ZONE::BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly, PCB_LAYER_ID aLayer
|
|||
maxExtents = &withFillets;
|
||||
}
|
||||
|
||||
for( ZONE* zone : interactingZones )
|
||||
// We now add in the areas of any same-net, intersecting zones. This keeps us from smoothing
|
||||
// corners at an intersection (which often produces undesired divots between the intersecting
|
||||
// zones -- see #2752).
|
||||
//
|
||||
// After smoothing, we'll subtract back out everything outside of our zone.
|
||||
std::vector<ZONE*> sameNetCollidingZones;
|
||||
std::vector<ZONE*> otherNetIntersectingZones;
|
||||
GetInteractingZones( aLayer, &sameNetCollidingZones, &otherNetIntersectingZones );
|
||||
|
||||
for( ZONE* sameNetZone : sameNetCollidingZones )
|
||||
{
|
||||
SHAPE_POLY_SET flattened_outline = zone->Outline()->CloneDropTriangulation();
|
||||
flattened_outline.ClearArcs();
|
||||
aSmoothedPoly.BooleanAdd( flattened_outline, SHAPE_POLY_SET::PM_FAST );
|
||||
BOX2I sameNetBoundingBox = sameNetZone->GetBoundingBox();
|
||||
SHAPE_POLY_SET sameNetPoly = sameNetZone->Outline()->CloneDropTriangulation();
|
||||
|
||||
sameNetPoly.ClearArcs();
|
||||
|
||||
// Of course there's always a wrinkle. The same-net intersecting zone *might* get knocked
|
||||
// out along the border by a higher-priority, different-net zone. #12797
|
||||
for( ZONE* otherNetZone : otherNetIntersectingZones )
|
||||
{
|
||||
if( otherNetZone->HigherPriority( sameNetZone )
|
||||
&& otherNetZone->GetBoundingBox().Intersects( sameNetBoundingBox ) )
|
||||
{
|
||||
sameNetPoly.BooleanSubtract( *otherNetZone->Outline(), SHAPE_POLY_SET::PM_FAST );
|
||||
}
|
||||
}
|
||||
|
||||
aSmoothedPoly.BooleanAdd( sameNetPoly, SHAPE_POLY_SET::PM_FAST );
|
||||
}
|
||||
|
||||
if( aBoardOutline )
|
||||
|
|
|
@ -352,7 +352,8 @@ public:
|
|||
* merged due to other parameters such as fillet radius. The copper pour will end up
|
||||
* effectively merged though, so we need to do some calculations with them in mind.
|
||||
*/
|
||||
void GetInteractingZones( PCB_LAYER_ID aLayer, std::vector<ZONE*>* aZones ) const;
|
||||
void GetInteractingZones( PCB_LAYER_ID aLayer, std::vector<ZONE*>* aSameNetCollidingZones,
|
||||
std::vector<ZONE*>* aOtherNetIntersectingZones ) const;
|
||||
|
||||
/**
|
||||
* Convert solid areas full shapes to polygon set
|
||||
|
|
Loading…
Reference in New Issue