Remove a long-standing hack to keep divots out of adjacent zones.
The new algorithm unions any adjacent zones before doing the chamfer/fillet and then subtracts the other zones back out afterwards. Fixes https://gitlab.com/kicad/code/kicad/issues/3812
This commit is contained in:
parent
a6d44676b3
commit
463100d67f
|
@ -774,7 +774,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
|||
auto layerContainer = m_layers_poly.find( layer );
|
||||
|
||||
if( layerContainer != m_layers_poly.end() )
|
||||
zone->TransformSolidAreasShapesToPolygonSet( layer, *layerContainer->second );
|
||||
zone->TransformSolidAreasShapesToPolygon( layer, *layerContainer->second );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1050,7 +1050,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
|||
if( !zone->IsOnLayer( curr_layer_id ) )
|
||||
continue;
|
||||
|
||||
zone->TransformSolidAreasShapesToPolygonSet( curr_layer_id, *layerPoly );
|
||||
zone->TransformSolidAreasShapesToPolygon( curr_layer_id, *layerPoly );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1151,11 +1151,9 @@ class SHAPE_POLY_SET : public SHAPE
|
|||
* returns a chamfered version of the aIndex-th polygon.
|
||||
* @param aDistance is the chamfering distance.
|
||||
* @param aIndex is the index of the polygon to be chamfered.
|
||||
* @param aPreserveCorners an optional set of corners which should not be chamfered.
|
||||
* @return POLYGON - A polygon containing the chamfered version of the aIndex-th polygon.
|
||||
*/
|
||||
POLYGON ChamferPolygon( unsigned int aDistance, int aIndex,
|
||||
std::set<VECTOR2I>* aPreserveCorners );
|
||||
POLYGON ChamferPolygon( unsigned int aDistance, int aIndex );
|
||||
|
||||
/**
|
||||
* Function Fillet
|
||||
|
@ -1163,32 +1161,26 @@ class SHAPE_POLY_SET : public SHAPE
|
|||
* @param aRadius is the fillet radius.
|
||||
* @param aErrorMax is the maximum allowable deviation of the polygon from the circle
|
||||
* @param aIndex is the index of the polygon to be filleted
|
||||
* @param aPreserveCorners an optional set of corners which should not be filleted.
|
||||
* @return POLYGON - A polygon containing the filleted version of the aIndex-th polygon.
|
||||
*/
|
||||
POLYGON FilletPolygon( unsigned int aRadius, int aErrorMax, int aIndex,
|
||||
std::set<VECTOR2I>* aPreserveCorners = nullptr );
|
||||
POLYGON FilletPolygon( unsigned int aRadius, int aErrorMax, int aIndex );
|
||||
|
||||
/**
|
||||
* Function Chamfer
|
||||
* returns a chamfered version of the polygon set.
|
||||
* @param aDistance is the chamfering distance.
|
||||
* @param aPreserveCorners an optional set of corners which should not be chamfered.
|
||||
* @return SHAPE_POLY_SET - A set containing the chamfered version of this set.
|
||||
*/
|
||||
SHAPE_POLY_SET Chamfer( int aDistance,
|
||||
std::set<VECTOR2I>* aPreserveCorners = nullptr );
|
||||
SHAPE_POLY_SET Chamfer( int aDistance );
|
||||
|
||||
/**
|
||||
* Function Fillet
|
||||
* returns a filleted version of the polygon set.
|
||||
* @param aRadius is the fillet radius.
|
||||
* @param aErrorMax is the maximum allowable deviation of the polygon from the circle
|
||||
* @param aPreserveCorners an optional set of corners which should not be filleted.
|
||||
* @return SHAPE_POLY_SET - A set containing the filleted version of this set.
|
||||
*/
|
||||
SHAPE_POLY_SET Fillet( int aRadius, int aErrorMax,
|
||||
std::set<VECTOR2I>* aPreserveCorners = nullptr );
|
||||
SHAPE_POLY_SET Fillet( int aRadius, int aErrorMax );
|
||||
|
||||
/**
|
||||
* Function DistanceToPolygon
|
||||
|
@ -1306,12 +1298,10 @@ class SHAPE_POLY_SET : public SHAPE
|
|||
* @param aIndex is the index of the polygon that will be chamfered/filleted.
|
||||
* @param aErrorMax is the maximum allowable deviation of the polygon from the circle
|
||||
* if aMode = FILLETED. If aMode = CHAMFERED, it is unused.
|
||||
* @param aPreserveCorners an optional set of corners which should be skipped.
|
||||
* @return POLYGON - the chamfered/filleted version of the polygon.
|
||||
*/
|
||||
POLYGON chamferFilletPolygon( CORNER_MODE aMode, unsigned int aDistance,
|
||||
int aIndex, int aErrorMax,
|
||||
std::set<VECTOR2I>* aPreserveCorners );
|
||||
int aIndex, int aErrorMax );
|
||||
|
||||
///> Returns true if the polygon set has any holes that touch share a vertex.
|
||||
bool hasTouchingHoles( const POLYGON& aPoly ) const;
|
||||
|
|
|
@ -1556,18 +1556,16 @@ int SHAPE_POLY_SET::TotalVertices() const
|
|||
}
|
||||
|
||||
|
||||
SHAPE_POLY_SET::POLYGON SHAPE_POLY_SET::ChamferPolygon( unsigned int aDistance, int aIndex,
|
||||
std::set<VECTOR2I>* aPreserveCorners )
|
||||
SHAPE_POLY_SET::POLYGON SHAPE_POLY_SET::ChamferPolygon( unsigned int aDistance, int aIndex )
|
||||
{
|
||||
return chamferFilletPolygon( CHAMFERED, aDistance, aIndex, 0, aPreserveCorners );
|
||||
return chamferFilletPolygon( CHAMFERED, aDistance, aIndex, 0 );
|
||||
}
|
||||
|
||||
|
||||
SHAPE_POLY_SET::POLYGON SHAPE_POLY_SET::FilletPolygon( unsigned int aRadius, int aErrorMax,
|
||||
int aIndex,
|
||||
std::set<VECTOR2I>* aPreserveCorners )
|
||||
int aIndex )
|
||||
{
|
||||
return chamferFilletPolygon( FILLETED, aRadius, aIndex, aErrorMax, aPreserveCorners );
|
||||
return chamferFilletPolygon( FILLETED, aRadius, aIndex, aErrorMax );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1676,32 +1674,30 @@ bool SHAPE_POLY_SET::IsVertexInHole( int aGlobalIdx )
|
|||
}
|
||||
|
||||
|
||||
SHAPE_POLY_SET SHAPE_POLY_SET::Chamfer( int aDistance, std::set<VECTOR2I>* aPreserveCorners )
|
||||
SHAPE_POLY_SET SHAPE_POLY_SET::Chamfer( int aDistance )
|
||||
{
|
||||
SHAPE_POLY_SET chamfered;
|
||||
|
||||
for( unsigned int idx = 0; idx < m_polys.size(); idx++ )
|
||||
chamfered.m_polys.push_back( ChamferPolygon( aDistance, idx, aPreserveCorners ) );
|
||||
chamfered.m_polys.push_back( ChamferPolygon( aDistance, idx ) );
|
||||
|
||||
return chamfered;
|
||||
}
|
||||
|
||||
|
||||
SHAPE_POLY_SET SHAPE_POLY_SET::Fillet( int aRadius, int aErrorMax,
|
||||
std::set<VECTOR2I>* aPreserveCorners )
|
||||
SHAPE_POLY_SET SHAPE_POLY_SET::Fillet( int aRadius, int aErrorMax )
|
||||
{
|
||||
SHAPE_POLY_SET filleted;
|
||||
|
||||
for( size_t idx = 0; idx < m_polys.size(); idx++ )
|
||||
filleted.m_polys.push_back( FilletPolygon( aRadius, aErrorMax, idx, aPreserveCorners ) );
|
||||
filleted.m_polys.push_back( FilletPolygon( aRadius, aErrorMax, idx ) );
|
||||
|
||||
return filleted;
|
||||
}
|
||||
|
||||
|
||||
SHAPE_POLY_SET::POLYGON SHAPE_POLY_SET::chamferFilletPolygon( CORNER_MODE aMode,
|
||||
unsigned int aDistance, int aIndex, int aErrorMax,
|
||||
std::set<VECTOR2I>* aPreserveCorners )
|
||||
unsigned int aDistance, int aIndex, int aErrorMax )
|
||||
{
|
||||
// Null segments create serious issues in calculations. Remove them:
|
||||
RemoveNullSegments();
|
||||
|
@ -1728,12 +1724,6 @@ SHAPE_POLY_SET::POLYGON SHAPE_POLY_SET::chamferFilletPolygon( CORNER_MODE aMode,
|
|||
int x1 = currContour.CPoint( currVertex ).x;
|
||||
int y1 = currContour.CPoint( currVertex ).y;
|
||||
|
||||
if( aPreserveCorners && aPreserveCorners->count( VECTOR2I( x1, y1 ) ) > 0 )
|
||||
{
|
||||
newContour.Append( x1, y1 );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Indices for previous and next vertices.
|
||||
int prevVertex;
|
||||
int nextVertex;
|
||||
|
|
|
@ -91,7 +91,7 @@ void BOARD::ConvertBrdLayerToPolygonalContours( PCB_LAYER_ID aLayer, SHAPE_POLY_
|
|||
ZONE_CONTAINER* zone = GetArea( ii );
|
||||
|
||||
if( zone->GetLayerSet().test( aLayer ) )
|
||||
zone->TransformSolidAreasShapesToPolygonSet( aLayer, aOutlines );
|
||||
zone->TransformSolidAreasShapesToPolygon( aLayer, aOutlines );
|
||||
}
|
||||
|
||||
// convert graphic items on copper layers (texts)
|
||||
|
@ -244,9 +244,9 @@ void MODULE::TransformGraphicShapesWithClearanceToPolygonSet( PCB_LAYER_ID aLaye
|
|||
}
|
||||
|
||||
|
||||
void ZONE_CONTAINER::TransformSolidAreasShapesToPolygonSet( PCB_LAYER_ID aLayer,
|
||||
SHAPE_POLY_SET& aCornerBuffer,
|
||||
int aError ) const
|
||||
void ZONE_CONTAINER::TransformSolidAreasShapesToPolygon( PCB_LAYER_ID aLayer,
|
||||
SHAPE_POLY_SET& aCornerBuffer,
|
||||
int aError ) const
|
||||
{
|
||||
if( !m_FilledPolysList.count( aLayer ) || m_FilledPolysList.at( aLayer ).IsEmpty() )
|
||||
return;
|
||||
|
|
|
@ -1164,65 +1164,55 @@ bool ZONE_CONTAINER::IsIsland( PCB_LAYER_ID aLayer, int aPolyIdx )
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Some intersecting zones, despite being on the same layer with the same net, cannot be
|
||||
* merged due to other parameters such as fillet radius. The copper pour will end up
|
||||
* effectively merged though, so we want to keep the corners of such intersections sharp.
|
||||
*/
|
||||
void ZONE_CONTAINER::GetColinearCorners( BOARD* aBoard, std::set<VECTOR2I>& aCorners )
|
||||
void ZONE_CONTAINER::GetInteractingZones( PCB_LAYER_ID aLayer,
|
||||
std::vector<ZONE_CONTAINER*>* aZones ) const
|
||||
{
|
||||
int epsilon = Millimeter2iu( 0.001 );
|
||||
|
||||
// Things get messy when zone of different nets intersect. To do it right we'd need to
|
||||
// run our colinear test with the final filled regions rather than the outline regions.
|
||||
// However, since there's no order dependance the only way to do that is to iterate
|
||||
// through successive zone fills until the results are no longer changing -- and that's
|
||||
// not going to happen. So we punt and ignore any "messy" corners.
|
||||
std::set<VECTOR2I> colinearCorners;
|
||||
std::set<VECTOR2I> messyCorners;
|
||||
|
||||
for( ZONE_CONTAINER* candidate : aBoard->Zones() )
|
||||
for( ZONE_CONTAINER* candidate : GetBoard()->Zones() )
|
||||
{
|
||||
if( candidate == this )
|
||||
continue;
|
||||
|
||||
if( candidate->GetLayerSet() != GetLayerSet() )
|
||||
if( !candidate->GetLayerSet().test( aLayer ) )
|
||||
continue;
|
||||
|
||||
if( candidate->GetIsKeepout() != GetIsKeepout() )
|
||||
if( candidate->GetIsKeepout() )
|
||||
continue;
|
||||
|
||||
if( candidate->GetNetCode() != GetNetCode() )
|
||||
continue;
|
||||
|
||||
for( auto iter = m_Poly->CIterate(); iter; iter++ )
|
||||
{
|
||||
if( candidate->m_Poly->Collide( iter.Get(), epsilon ) )
|
||||
{
|
||||
if( candidate->GetNetCode() == GetNetCode() )
|
||||
colinearCorners.insert( VECTOR2I( iter.Get() ) );
|
||||
else
|
||||
messyCorners.insert( VECTOR2I( iter.Get() ) );
|
||||
aZones->push_back( candidate );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( VECTOR2I corner : colinearCorners )
|
||||
{
|
||||
if( messyCorners.count( corner ) == 0 )
|
||||
aCorners.insert( corner );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ZONE_CONTAINER::BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly,
|
||||
std::set<VECTOR2I>* aPreserveCorners ) const
|
||||
bool ZONE_CONTAINER::BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly, PCB_LAYER_ID aLayer ) const
|
||||
{
|
||||
if( GetNumCorners() <= 2 ) // malformed zone. polygon calculations do not like it ...
|
||||
return false;
|
||||
|
||||
std::vector<ZONE_CONTAINER*> interactingZones;
|
||||
GetInteractingZones( aLayer, &interactingZones );
|
||||
|
||||
aSmoothedPoly = *m_Poly;
|
||||
|
||||
for( ZONE_CONTAINER* zone : interactingZones )
|
||||
aSmoothedPoly.BooleanAdd( *zone->Outline(), SHAPE_POLY_SET::PM_FAST );
|
||||
|
||||
// Make a smoothed polygon out of the user-drawn polygon if required
|
||||
switch( m_cornerSmoothingType )
|
||||
{
|
||||
case ZONE_SETTINGS::SMOOTHING_CHAMFER:
|
||||
aSmoothedPoly = m_Poly->Chamfer( m_cornerRadius, aPreserveCorners );
|
||||
aSmoothedPoly = aSmoothedPoly.Chamfer( m_cornerRadius );
|
||||
break;
|
||||
|
||||
case ZONE_SETTINGS::SMOOTHING_FILLET:
|
||||
|
@ -1233,7 +1223,7 @@ bool ZONE_CONTAINER::BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly,
|
|||
if( board )
|
||||
maxError = board->GetDesignSettings().m_MaxError;
|
||||
|
||||
aSmoothedPoly = m_Poly->Fillet( m_cornerRadius, maxError, aPreserveCorners );
|
||||
aSmoothedPoly = aSmoothedPoly.Fillet( m_cornerRadius, maxError );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -1242,10 +1232,13 @@ bool ZONE_CONTAINER::BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly,
|
|||
// We can avoid issues by creating a very small chamfer which remove acute angles,
|
||||
// or left it without chamfer and use only CPOLYGONS_LIST::InflateOutline to create
|
||||
// clearance areas
|
||||
aSmoothedPoly = m_Poly->Chamfer( Millimeter2iu( 0.0 ), aPreserveCorners );
|
||||
aSmoothedPoly = aSmoothedPoly.Chamfer( Millimeter2iu( 0.0 ) );
|
||||
break;
|
||||
}
|
||||
|
||||
if( interactingZones.size() )
|
||||
aSmoothedPoly.BooleanIntersection( *m_Poly, SHAPE_POLY_SET::PM_FAST );
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
@ -1283,11 +1276,11 @@ double ZONE_CONTAINER::CalculateFilledArea()
|
|||
* @param aPreserveCorners an optional set of corners which should not be chamfered/filleted
|
||||
*/
|
||||
void ZONE_CONTAINER::TransformOutlinesShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||
int aClearance, std::set<VECTOR2I>* aPreserveCorners ) const
|
||||
int aClearance ) const
|
||||
{
|
||||
// Creates the zone outline polygon (with holes if any)
|
||||
SHAPE_POLY_SET polybuffer;
|
||||
BuildSmoothedPoly( polybuffer, aPreserveCorners );
|
||||
BuildSmoothedPoly( polybuffer, GetLayer() );
|
||||
|
||||
// Calculate the polygon with clearance
|
||||
// holes are linked to the main outline, so only one polygon is created.
|
||||
|
|
|
@ -318,16 +318,15 @@ public:
|
|||
return HitTestCutout( VECTOR2I( aRefPos.x, aRefPos.y ), aOutlineIdx, aHoleIdx );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Some intersecting zones, despite being on the same layer with the same net, cannot be
|
||||
* merged due to other parameters such as fillet radius. The copper pour will end up
|
||||
* effectively merged though, so we want to keep the corners of such intersections sharp.
|
||||
* effectively merged though, so we need to do some calculations with them in mind.
|
||||
*/
|
||||
void GetColinearCorners( BOARD* aBoard, std::set<VECTOR2I>& colinearCorners );
|
||||
void GetInteractingZones( PCB_LAYER_ID aLayer, std::vector<ZONE_CONTAINER*>* aZones ) const;
|
||||
|
||||
/**
|
||||
* Function TransformSolidAreasShapesToPolygonSet
|
||||
* Function TransformSolidAreasShapesToPolygon
|
||||
* Convert solid areas full shapes to polygon set
|
||||
* (the full shape is the polygon area with a thick outline)
|
||||
* Used in 3D view
|
||||
|
@ -336,8 +335,8 @@ public:
|
|||
* @param aCornerBuffer = a buffer to store the polygons
|
||||
* @param aError = Maximum error allowed between true arc and polygon approx
|
||||
*/
|
||||
void TransformSolidAreasShapesToPolygonSet( PCB_LAYER_ID aLayer,
|
||||
SHAPE_POLY_SET& aCornerBuffer, int aError = ARC_HIGH_DEF ) const;
|
||||
void TransformSolidAreasShapesToPolygon( PCB_LAYER_ID aLayer, SHAPE_POLY_SET& aCornerBuffer,
|
||||
int aError = ARC_HIGH_DEF ) const;
|
||||
|
||||
/**
|
||||
* Function TransformOutlinesShapeWithClearanceToPolygon
|
||||
|
@ -348,14 +347,9 @@ public:
|
|||
* Circles (vias) and arcs (ends of tracks) are approximated by segments
|
||||
* @param aCornerBuffer = a buffer to store the polygon
|
||||
* @param aMinClearanceValue = the min clearance around outlines
|
||||
* @param aUseNetClearance = true to use a clearance which is the max value between
|
||||
* aMinClearanceValue and the net clearance
|
||||
* false to use aMinClearanceValue only
|
||||
* @param aPreserveCorners an optional set of corners which should not be smoothed.
|
||||
* if both aMinClearanceValue = 0 and aUseNetClearance = false: create the zone outline polygon.
|
||||
*/
|
||||
void TransformOutlinesShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||
int aMinClearanceValue, std::set<VECTOR2I>* aPreserveCorners = nullptr ) const;
|
||||
int aMinClearanceValue ) const;
|
||||
|
||||
/**
|
||||
* Function TransformShapeWithClearanceToPolygon
|
||||
|
@ -370,8 +364,8 @@ public:
|
|||
* for visualization
|
||||
*/
|
||||
void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||
int aClearanceValue, int aError = ARC_HIGH_DEF,
|
||||
bool ignoreLineWidth = false ) const override;
|
||||
int aClearanceValue, int aError = ARC_HIGH_DEF,
|
||||
bool ignoreLineWidth = false ) const override;
|
||||
|
||||
/**
|
||||
* Function HitTestForCorner
|
||||
|
@ -652,12 +646,8 @@ public:
|
|||
|
||||
/**
|
||||
* Function GetSmoothedPoly
|
||||
* returns a pointer to the corner-smoothed version of m_Poly.
|
||||
* @param aPreserveCorners - set of corners which should /not/ be smoothed
|
||||
* @return SHAPE_POLY_SET* - pointer to the polygon.
|
||||
*/
|
||||
bool BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly,
|
||||
std::set<VECTOR2I>* aPreserveCorners ) const;
|
||||
bool BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly, PCB_LAYER_ID aLayer ) const;
|
||||
|
||||
void SetCornerSmoothingType( int aType ) { m_cornerSmoothingType = aType; };
|
||||
|
||||
|
|
|
@ -684,11 +684,8 @@ void DRC::testZones( BOARD_COMMIT& aCommit )
|
|||
}
|
||||
}
|
||||
|
||||
ZONE_CONTAINER* zoneRef = m_pcb->GetArea( ii );
|
||||
std::set<VECTOR2I> colinearCorners;
|
||||
zoneRef->GetColinearCorners( m_pcb, colinearCorners );
|
||||
|
||||
zoneRef->BuildSmoothedPoly( smoothed_polys[ii], &colinearCorners );
|
||||
ZONE_CONTAINER* zoneRef = m_pcb->GetArea( ii );
|
||||
zoneRef->BuildSmoothedPoly( smoothed_polys[ii], zoneRef->GetLayer() );
|
||||
}
|
||||
|
||||
// iterate through all areas
|
||||
|
|
|
@ -868,18 +868,10 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask,
|
|||
if( zone->GetLayer() != layer )
|
||||
continue;
|
||||
|
||||
// Some intersecting zones, despite being on the same layer, cannot be
|
||||
// merged due to other parameters such as fillet radius. The filled areas will end up
|
||||
// effectively merged though, so we want to keep the corners of such intersections sharp.
|
||||
std::set<VECTOR2I> colinearCorners;
|
||||
zone->GetColinearCorners( aBoard, colinearCorners );
|
||||
|
||||
// add shapes inflated by aMinThickness/2 in areas
|
||||
zone->TransformOutlinesShapeWithClearanceToPolygon( areas, inflate + zone_margin,
|
||||
&colinearCorners );
|
||||
zone->TransformOutlinesShapeWithClearanceToPolygon( areas, inflate + zone_margin );
|
||||
// add shapes with their exact mask layer size in initialPolys
|
||||
zone->TransformOutlinesShapeWithClearanceToPolygon( initialPolys, zone_margin,
|
||||
&colinearCorners );
|
||||
zone->TransformOutlinesShapeWithClearanceToPolygon( initialPolys, zone_margin );
|
||||
}
|
||||
|
||||
int maxError = aBoard->GetDesignSettings().m_MaxError;
|
||||
|
|
|
@ -736,36 +736,30 @@ bool PNS_KICAD_IFACE_BASE::syncZone( PNS::NODE* aWorld, ZONE_CONTAINER* aZone )
|
|||
if( !aZone->GetIsKeepout() || !aZone->GetDoNotAllowTracks() )
|
||||
return false;
|
||||
|
||||
// Some intersecting zones, despite being on the same layer with the same net, cannot be
|
||||
// merged due to other parameters such as fillet radius. The copper pour will end up
|
||||
// effectively merged though, so we want to keep the corners of such intersections sharp.
|
||||
std::set<VECTOR2I> colinearCorners;
|
||||
aZone->GetColinearCorners( m_board, colinearCorners );
|
||||
|
||||
aZone->BuildSmoothedPoly( poly, &colinearCorners );
|
||||
poly.CacheTriangulation();
|
||||
|
||||
if( !poly.IsTriangulationUpToDate() )
|
||||
{
|
||||
KIDIALOG dlg( nullptr, wxString::Format( _( "Malformed keep-out zone at (%d, %d)" ),
|
||||
aZone->GetPosition().x, aZone->GetPosition().y ), KIDIALOG::KD_WARNING );
|
||||
dlg.ShowDetailedText(
|
||||
wxString::Format( _( "%s\nThis zone cannot be handled by the track layout tool.\n"
|
||||
"Please verify it is not a self-intersecting polygon." ),
|
||||
aZone->GetSelectMenuText( EDA_UNITS::MILLIMETRES ) ) );
|
||||
dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
|
||||
dlg.ShowModal();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
LSET layers = aZone->GetLayerSet();
|
||||
|
||||
for( int layer = F_Cu; layer <= B_Cu; layer++ )
|
||||
{
|
||||
if ( ! layers[layer] )
|
||||
if( ! layers[ layer ] )
|
||||
continue;
|
||||
|
||||
aZone->BuildSmoothedPoly( poly, ToLAYER_ID( layer ) );
|
||||
poly.CacheTriangulation();
|
||||
|
||||
if( !poly.IsTriangulationUpToDate() )
|
||||
{
|
||||
KIDIALOG dlg( nullptr, wxString::Format( _( "Malformed keep-out zone at (%d, %d)" ),
|
||||
aZone->GetPosition().x, aZone->GetPosition().y ), KIDIALOG::KD_WARNING );
|
||||
dlg.ShowDetailedText(
|
||||
wxString::Format( _( "%s\nThis zone cannot be handled by the track layout tool.\n"
|
||||
"Please verify it is not a self-intersecting polygon." ),
|
||||
aZone->GetSelectMenuText( EDA_UNITS::MILLIMETRES ) ) );
|
||||
dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
|
||||
dlg.ShowModal();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
for( int outline = 0; outline < poly.OutlineCount(); outline++ )
|
||||
{
|
||||
auto tri = poly.TriangulatedPolygon( outline );
|
||||
|
|
|
@ -741,7 +741,6 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE_CONTAINER* aZone, PCB_LA
|
|||
*/
|
||||
void ZONE_FILLER::computeRawFilledArea( const ZONE_CONTAINER* aZone, PCB_LAYER_ID aLayer,
|
||||
const SHAPE_POLY_SET& aSmoothedOutline,
|
||||
std::set<VECTOR2I>* aPreserveCorners,
|
||||
SHAPE_POLY_SET& aRawPolys,
|
||||
SHAPE_POLY_SET& aFinalPolys )
|
||||
{
|
||||
|
@ -928,15 +927,13 @@ bool ZONE_FILLER::fillSingleZone( ZONE_CONTAINER* aZone, PCB_LAYER_ID aLayer,
|
|||
SHAPE_POLY_SET& aRawPolys, SHAPE_POLY_SET& aFinalPolys )
|
||||
{
|
||||
SHAPE_POLY_SET smoothedPoly;
|
||||
std::set<VECTOR2I> colinearCorners;
|
||||
aZone->GetColinearCorners( m_board, colinearCorners );
|
||||
|
||||
/*
|
||||
* convert outlines + holes to outlines without holes (adding extra segments if necessary)
|
||||
* m_Poly data is expected normalized, i.e. NormalizeAreaOutlines was used after building
|
||||
* this zone
|
||||
*/
|
||||
if ( !aZone->BuildSmoothedPoly( smoothedPoly, &colinearCorners ) )
|
||||
if ( !aZone->BuildSmoothedPoly( smoothedPoly, aLayer ) )
|
||||
return false;
|
||||
|
||||
if( m_progressReporter && m_progressReporter->IsCancelled() )
|
||||
|
@ -944,8 +941,7 @@ bool ZONE_FILLER::fillSingleZone( ZONE_CONTAINER* aZone, PCB_LAYER_ID aLayer,
|
|||
|
||||
if( aZone->IsOnCopperLayer() )
|
||||
{
|
||||
computeRawFilledArea( aZone, aLayer, smoothedPoly, &colinearCorners, aRawPolys,
|
||||
aFinalPolys );
|
||||
computeRawFilledArea( aZone, aLayer, smoothedPoly, aRawPolys, aFinalPolys );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -70,7 +70,6 @@ private:
|
|||
*/
|
||||
void computeRawFilledArea( const ZONE_CONTAINER* aZone, PCB_LAYER_ID aLayer,
|
||||
const SHAPE_POLY_SET& aSmoothedOutline,
|
||||
std::set<VECTOR2I>* aPreserveCorners,
|
||||
SHAPE_POLY_SET& aRawPolys, SHAPE_POLY_SET& aFinalPolys );
|
||||
|
||||
/**
|
||||
|
|
|
@ -669,11 +669,9 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZones()
|
|||
for( int ii = 0; ii < m_board->GetAreaCount(); ii++ )
|
||||
{
|
||||
ZONE_CONTAINER* zone = m_board->GetArea( ii );
|
||||
ZONE_CONTAINER* zoneRef = m_board->GetArea( ii );
|
||||
std::set<VECTOR2I> colinearCorners;
|
||||
ZONE_CONTAINER* zoneRef = m_board->GetArea( ii );
|
||||
|
||||
zoneRef->GetColinearCorners( m_board, colinearCorners );
|
||||
zoneRef->BuildSmoothedPoly( smoothed_polys[ii], &colinearCorners );
|
||||
zoneRef->BuildSmoothedPoly( smoothed_polys[ii], zoneRef->GetLayer() );
|
||||
}
|
||||
|
||||
// iterate through all areas
|
||||
|
|
Loading…
Reference in New Issue