Add curved track support to track-to-zone DRC.

Fixes https://gitlab.com/kicad/code/kicad/issues/6039
This commit is contained in:
Jeff Young 2020-10-20 11:33:20 +01:00
parent d142075417
commit 18f9f3cf0b
2 changed files with 35 additions and 15 deletions

View File

@ -978,27 +978,20 @@ bool TRACK::cmp_tracks::operator() ( const TRACK* a, const TRACK* b ) const
std::shared_ptr<SHAPE> TRACK::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
{
std::shared_ptr<SHAPE_SEGMENT> shape( new SHAPE_SEGMENT( m_Start, m_End, m_Width ) );
return shape;
return std::make_shared<SHAPE_SEGMENT>( m_Start, m_End, m_Width );
}
std::shared_ptr<SHAPE> VIA::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
{
// fixme: pad stack support (depending on aLayer )
std::shared_ptr<SHAPE_CIRCLE> shape( new SHAPE_CIRCLE( m_Start, m_Width / 2 ) );
return shape;
return std::make_shared<SHAPE_CIRCLE>( m_Start, m_Width / 2 );
}
std::shared_ptr<SHAPE> ARC::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
{
std::shared_ptr<SHAPE_ARC> shape( new SHAPE_ARC( GetStart(), GetMid(), GetEnd(),
GetWidth() ) );
return shape;
return std::make_shared<SHAPE_ARC>( GetStart(), GetMid(), GetEnd(), GetWidth() );
}

View File

@ -27,7 +27,7 @@
#include <class_pad.h>
#include <class_track.h>
//#include <geometry/polygon_test_point_inside.h>
#include <geometry/shape_arc.h>
#include <geometry/seg.h>
#include <geometry/shape_poly_set.h>
#include <geometry/shape_rect.h>
@ -508,8 +508,6 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, PCB_LAYER_I
|| static_cast<VIA*>( aRefSeg )->FlashLayer( aLayer )
|| static_cast<VIA*>( aRefSeg )->GetDrill() > 0 ) )
{
SEG testSeg( aRefSeg->GetStart(), aRefSeg->GetEnd() );
for( ZONE_CONTAINER* zone : m_board->Zones() )
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_CLEARANCE ) )
@ -543,12 +541,41 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, PCB_LAYER_I
int allowedDist = minClearance + halfWidth - bds.GetDRCEpsilon();
const SHAPE_POLY_SET& zonePoly = zone->GetFilledPolysList( aLayer );
int actual;
int actual = INT_MAX;
VECTOR2I location;
accountCheck( constraint );
if( zonePoly.Collide( testSeg, allowedDist, &actual, &location ) )
if( aRefSeg->Type() == PCB_ARC_T )
{
std::shared_ptr<SHAPE> refShape = aRefSeg->GetEffectiveShape();
SHAPE_ARC* refArc = dynamic_cast<SHAPE_ARC*>( refShape.get() );
SHAPE_LINE_CHAIN refArcSegs = refArc->ConvertToPolyline( bds.m_MaxError );
for( int i = 0; i < refArcSegs.SegmentCount(); ++i )
{
SEG refArcSeg = refArcSegs.Segment( i );
int segActual;
VECTOR2I segLocation;
if( zonePoly.Collide( refArcSeg, allowedDist, &segActual, &segLocation ) )
{
if( segActual < actual )
{
actual = segActual;
location = segLocation;
}
}
}
}
else
{
SEG testSeg( aRefSeg->GetStart(), aRefSeg->GetEnd() );
zonePoly.Collide( testSeg, allowedDist, &actual, &location );
}
if( actual != INT_MAX )
{
actual = std::max( 0, actual - halfWidth );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_CLEARANCE );