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 );
|
int epsilon = pcbIUScale.mmToIU( 0.001 );
|
||||||
BOX2I bbox = GetBoundingBox();
|
BOX2I bbox = GetBoundingBox();
|
||||||
|
@ -1022,23 +1023,27 @@ void ZONE::GetInteractingZones( PCB_LAYER_ID aLayer, std::vector<ZONE*>* aZones
|
||||||
if( !candidate->GetLayerSet().test( aLayer ) )
|
if( !candidate->GetLayerSet().test( aLayer ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( candidate->GetIsRuleArea() )
|
if( candidate->GetIsRuleArea() || candidate->IsTeardropArea() )
|
||||||
continue;
|
|
||||||
|
|
||||||
if( candidate->GetNetCode() != GetNetCode() )
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( !candidate->GetBoundingBox().Intersects( bbox ) )
|
if( !candidate->GetBoundingBox().Intersects( bbox ) )
|
||||||
continue;
|
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 );
|
if( candidate->m_Poly->Collide( iter.Get(), epsilon ) )
|
||||||
break;
|
{
|
||||||
|
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* maxExtents = &flattened;
|
||||||
SHAPE_POLY_SET withFillets;
|
SHAPE_POLY_SET withFillets;
|
||||||
|
|
||||||
|
@ -1124,11 +1126,34 @@ bool ZONE::BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly, PCB_LAYER_ID aLayer
|
||||||
maxExtents = &withFillets;
|
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();
|
BOX2I sameNetBoundingBox = sameNetZone->GetBoundingBox();
|
||||||
flattened_outline.ClearArcs();
|
SHAPE_POLY_SET sameNetPoly = sameNetZone->Outline()->CloneDropTriangulation();
|
||||||
aSmoothedPoly.BooleanAdd( flattened_outline, SHAPE_POLY_SET::PM_FAST );
|
|
||||||
|
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 )
|
if( aBoardOutline )
|
||||||
|
|
|
@ -352,7 +352,8 @@ public:
|
||||||
* merged due to other parameters such as fillet radius. The copper pour will end up
|
* 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.
|
* 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
|
* Convert solid areas full shapes to polygon set
|
||||||
|
|
Loading…
Reference in New Issue