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
|
int BOARD_DESIGN_SETTINGS::GetDRCEpsilon() const
|
||||||
{
|
{
|
||||||
// You can loosen the max epsilon manually but we cap it at the board's inherent
|
return Millimeter2iu( ADVANCED_CFG::GetCfg().m_DRCEpsilon );
|
||||||
// accuracy given by the maximum error when approximating curves
|
|
||||||
return std::max( m_MaxError, 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 );
|
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
|
else
|
||||||
{
|
{
|
||||||
// TODO: Support PNS hull generation for compound shapes and use the actual shape here
|
solid->SetShape( shape->Clone() );
|
||||||
|
|
||||||
// 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 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return solid;
|
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 );
|
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 )
|
if( aClearance >= 0 )
|
||||||
{
|
{
|
||||||
pitem->SetClearance( aClearance );
|
pitem->SetClearance( aClearance );
|
||||||
|
|
||||||
switch( m_dispOptions->m_ShowTrackClearanceMode )
|
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_TRACK_CLEARANCE_WITH_VIA_ALWAYS:
|
||||||
case PCB_DISPLAY_OPTIONS::SHOW_WHILE_ROUTING_OR_DRAGGING:
|
case PCB_DISPLAY_OPTIONS::SHOW_WHILE_ROUTING_OR_DRAGGING:
|
||||||
pitem->ShowTrackClearance( true );
|
pitem->ShowClearance( pitem->GetParent()->IsType( tracksOrVias ) );
|
||||||
pitem->ShowViaClearance( true );
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCB_DISPLAY_OPTIONS::SHOW_TRACK_CLEARANCE_WITH_VIA_WHILE_ROUTING:
|
case PCB_DISPLAY_OPTIONS::SHOW_TRACK_CLEARANCE_WITH_VIA_WHILE_ROUTING:
|
||||||
pitem->ShowTrackClearance( !aEdit );
|
pitem->ShowClearance( pitem->GetParent()->IsType( tracksOrVias ) && !aEdit );
|
||||||
pitem->ShowViaClearance( !aEdit );
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCB_DISPLAY_OPTIONS::SHOW_TRACK_CLEARANCE_WHILE_ROUTING:
|
case PCB_DISPLAY_OPTIONS::SHOW_TRACK_CLEARANCE_WHILE_ROUTING:
|
||||||
pitem->ShowTrackClearance( !aEdit );
|
pitem->ShowClearance( pitem->GetParent()->IsType( tracks ) && !aEdit );
|
||||||
pitem->ShowViaClearance( false );
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
pitem->ShowClearance( false );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <geometry/shape_circle.h>
|
#include <geometry/shape_circle.h>
|
||||||
#include <geometry/shape_simple.h>
|
#include <geometry/shape_simple.h>
|
||||||
#include <geometry/shape_compound.h>
|
#include <geometry/shape_compound.h>
|
||||||
|
#include <geometry/shape_poly_set.h>
|
||||||
|
|
||||||
#include <wx/log.h>
|
#include <wx/log.h>
|
||||||
|
|
||||||
|
@ -112,9 +113,16 @@ const SHAPE_LINE_CHAIN SOLID::Hull( int aClearance, int aWalkaroundThickness, in
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// fixme - shouldn't happen but one day we should move
|
SHAPE_POLY_SET hullSet;
|
||||||
// TransformShapeWithClearanceToPolygon() to the Geometry Library
|
|
||||||
return SHAPE_LINE_CHAIN();
|
for( SHAPE* shape : cmpnd->Shapes() )
|
||||||
|
{
|
||||||
|
hullSet.AddOutline( buildHullForPrimitiveShape( shape, aClearance,
|
||||||
|
aWalkaroundThickness ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
hullSet.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||||
|
return hullSet.Outline( 0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -140,9 +148,16 @@ const SHAPE_LINE_CHAIN SOLID::HoleHull( int aClearance, int aWalkaroundThickness
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// fixme - shouldn't happen but one day we should move
|
SHAPE_POLY_SET hullSet;
|
||||||
// TransformShapeWithClearanceToPolygon() to the Geometry Library
|
|
||||||
return SHAPE_LINE_CHAIN();
|
for( SHAPE* shape : cmpnd->Shapes() )
|
||||||
|
{
|
||||||
|
hullSet.AddOutline( buildHullForPrimitiveShape( shape, aClearance,
|
||||||
|
aWalkaroundThickness ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
hullSet.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||||
|
return hullSet.Outline( 0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue