Don't use approximated shapes for router hulls.
We only do 45-degree routing anyway so we might as well build an octagonal-based hull from the get-go. Fixes https://gitlab.com/kicad/code/kicad/issues/7672 Fixes https://gitlab.com/kicad/code/kicad/issues/9544 Fixes https://gitlab.com/kicad/code/kicad/issues/9833
This commit is contained in:
parent
09ed60feb3
commit
3c0b10b022
|
@ -1116,9 +1116,7 @@ int BOARD_DESIGN_SETTINGS::GetLayerClass( PCB_LAYER_ID aLayer ) const
|
|||
|
||||
int BOARD_DESIGN_SETTINGS::GetDRCEpsilon() const
|
||||
{
|
||||
// You can loosen the max epsilon manually but we cap it at the board's inherent
|
||||
// accuracy given by the maximum error when approximating curves
|
||||
return std::max( m_MaxError, Millimeter2iu( ADVANCED_CFG::GetCfg().m_DRCEpsilon ) );
|
||||
return Millimeter2iu( ADVANCED_CFG::GetCfg().m_DRCEpsilon );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -953,36 +953,18 @@ std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE_BASE::syncPad( PAD* aPad )
|
|||
solid->SetHole( slot );
|
||||
}
|
||||
|
||||
auto shapes = std::dynamic_pointer_cast<SHAPE_COMPOUND>( aPad->GetEffectiveShape() );
|
||||
std::shared_ptr<SHAPE> shape = aPad->GetEffectiveShape();
|
||||
|
||||
if( shapes && shapes->Size() == 1 )
|
||||
if( shape->HasIndexableSubshapes() && shape->GetIndexableSubshapeCount() == 1 )
|
||||
{
|
||||
solid->SetShape( shapes->Shapes()[0]->Clone() );
|
||||
std::vector<SHAPE*> subshapes;
|
||||
shape->GetIndexableSubshapes( subshapes );
|
||||
|
||||
solid->SetShape( subshapes[0]->Clone() );
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Support PNS hull generation for compound shapes and use the actual shape here
|
||||
|
||||
// NOTE: Because PNS hulls can't handle compound shapes yet, there will always be a
|
||||
// discrepancy between the PNS and the DRC engine in some cases (such as custom shape pads
|
||||
// that use polygons with nonzero width). No matter where you put the error, this causes
|
||||
// issues, but the "lesser evil" is to allow routing in more cases (and have DRC errors that
|
||||
// need to be cleaned up) vs. having situations that are valid to DRC but can't be routed
|
||||
// because the extra error outside the pad is a clearance violation to the router.
|
||||
//
|
||||
// See https://gitlab.com/kicad/code/kicad/-/issues/9544
|
||||
// and https://gitlab.com/kicad/code/kicad/-/issues/7672
|
||||
|
||||
SHAPE_POLY_SET outline;
|
||||
aPad->TransformShapeWithClearanceToPolygon( outline, UNDEFINED_LAYER, 0, ARC_HIGH_DEF,
|
||||
ERROR_INSIDE );
|
||||
|
||||
SHAPE_SIMPLE* shape = new SHAPE_SIMPLE();
|
||||
|
||||
for( auto iter = outline.CIterate( 0 ); iter; iter++ )
|
||||
shape->Append( *iter );
|
||||
|
||||
solid->SetShape( shape );
|
||||
solid->SetShape( shape->Clone() );
|
||||
}
|
||||
|
||||
return solid;
|
||||
|
@ -1434,30 +1416,30 @@ void PNS_KICAD_IFACE::DisplayItem( const PNS::ITEM* aItem, int aClearance, bool
|
|||
|
||||
ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( aItem, m_view );
|
||||
|
||||
static KICAD_T tracksOrVias[] = { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T, EOT };
|
||||
static KICAD_T tracks[] = { PCB_TRACE_T, PCB_ARC_T, EOT };
|
||||
|
||||
if( aClearance >= 0 )
|
||||
{
|
||||
pitem->SetClearance( aClearance );
|
||||
|
||||
switch( m_dispOptions->m_ShowTrackClearanceMode )
|
||||
{
|
||||
case PCB_DISPLAY_OPTIONS::DO_NOT_SHOW_CLEARANCE:
|
||||
pitem->ShowTrackClearance( false );
|
||||
pitem->ShowViaClearance( false );
|
||||
break;
|
||||
case PCB_DISPLAY_OPTIONS::SHOW_TRACK_CLEARANCE_WITH_VIA_ALWAYS:
|
||||
case PCB_DISPLAY_OPTIONS::SHOW_WHILE_ROUTING_OR_DRAGGING:
|
||||
pitem->ShowTrackClearance( true );
|
||||
pitem->ShowViaClearance( true );
|
||||
pitem->ShowClearance( pitem->GetParent()->IsType( tracksOrVias ) );
|
||||
break;
|
||||
|
||||
case PCB_DISPLAY_OPTIONS::SHOW_TRACK_CLEARANCE_WITH_VIA_WHILE_ROUTING:
|
||||
pitem->ShowTrackClearance( !aEdit );
|
||||
pitem->ShowViaClearance( !aEdit );
|
||||
pitem->ShowClearance( pitem->GetParent()->IsType( tracksOrVias ) && !aEdit );
|
||||
break;
|
||||
|
||||
case PCB_DISPLAY_OPTIONS::SHOW_TRACK_CLEARANCE_WHILE_ROUTING:
|
||||
pitem->ShowTrackClearance( !aEdit );
|
||||
pitem->ShowViaClearance( false );
|
||||
pitem->ShowClearance( pitem->GetParent()->IsType( tracks ) && !aEdit );
|
||||
break;
|
||||
|
||||
default:
|
||||
pitem->ShowClearance( false );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <geometry/shape_circle.h>
|
||||
#include <geometry/shape_simple.h>
|
||||
#include <geometry/shape_compound.h>
|
||||
#include <geometry/shape_poly_set.h>
|
||||
|
||||
#include <wx/log.h>
|
||||
|
||||
|
@ -112,9 +113,16 @@ const SHAPE_LINE_CHAIN SOLID::Hull( int aClearance, int aWalkaroundThickness, in
|
|||
}
|
||||
else
|
||||
{
|
||||
// fixme - shouldn't happen but one day we should move
|
||||
// TransformShapeWithClearanceToPolygon() to the Geometry Library
|
||||
return SHAPE_LINE_CHAIN();
|
||||
SHAPE_POLY_SET hullSet;
|
||||
|
||||
for( SHAPE* shape : cmpnd->Shapes() )
|
||||
{
|
||||
hullSet.AddOutline( buildHullForPrimitiveShape( shape, aClearance,
|
||||
aWalkaroundThickness ) );
|
||||
}
|
||||
|
||||
hullSet.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
return hullSet.Outline( 0 );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -140,9 +148,16 @@ const SHAPE_LINE_CHAIN SOLID::HoleHull( int aClearance, int aWalkaroundThickness
|
|||
}
|
||||
else
|
||||
{
|
||||
// fixme - shouldn't happen but one day we should move
|
||||
// TransformShapeWithClearanceToPolygon() to the Geometry Library
|
||||
return SHAPE_LINE_CHAIN();
|
||||
SHAPE_POLY_SET hullSet;
|
||||
|
||||
for( SHAPE* shape : cmpnd->Shapes() )
|
||||
{
|
||||
hullSet.AddOutline( buildHullForPrimitiveShape( shape, aClearance,
|
||||
aWalkaroundThickness ) );
|
||||
}
|
||||
|
||||
hullSet.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
return hullSet.Outline( 0 );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue