Initial support for keepout zones in the P&S router.
This commit is contained in:
parent
d1a45d1476
commit
2faf1a1ed3
|
@ -785,7 +785,7 @@ void OPENGL_GAL::drawTriangulatedPolyset( const SHAPE_POLY_SET& aPolySet )
|
||||||
{
|
{
|
||||||
auto triPoly = aPolySet.TriangulatedPolygon( j );
|
auto triPoly = aPolySet.TriangulatedPolygon( j );
|
||||||
|
|
||||||
for ( int i = 0; i < triPoly->TriangleCount(); i++ )
|
for ( int i = 0; i < triPoly->GetTriangleCount(); i++ )
|
||||||
{
|
{
|
||||||
VECTOR2I a, b, c;
|
VECTOR2I a, b, c;
|
||||||
triPoly->GetTriangle( i ,a,b,c);
|
triPoly->GetTriangle( i ,a,b,c);
|
||||||
|
|
|
@ -57,6 +57,12 @@ SHAPE_POLY_SET::SHAPE_POLY_SET( const SHAPE_POLY_SET& aOther ) :
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHAPE_POLY_SET::~SHAPE_POLY_SET()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SHAPE* SHAPE_POLY_SET::Clone() const
|
SHAPE* SHAPE_POLY_SET::Clone() const
|
||||||
{
|
{
|
||||||
return new SHAPE_POLY_SET( *this );
|
return new SHAPE_POLY_SET( *this );
|
||||||
|
@ -1033,9 +1039,7 @@ void SHAPE_POLY_SET::unfractureSingle( SHAPE_POLY_SET::POLYGON& aPoly )
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert( outline >= 0 );
|
if( outline > 0 )
|
||||||
|
|
||||||
if( outline !=0 )
|
|
||||||
std::swap( result[0], result[outline] );
|
std::swap( result[0], result[outline] );
|
||||||
|
|
||||||
aPoly = result;
|
aPoly = result;
|
||||||
|
@ -1970,7 +1974,7 @@ private:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto lastId = m_triPoly->VertexCount();
|
auto lastId = m_triPoly->GetVertexCount();
|
||||||
auto p = new p2t::Point( aP.x, aP.y, lastId );
|
auto p = new p2t::Point( aP.x, aP.y, lastId );
|
||||||
m_triPoly->AddVertex( aP );
|
m_triPoly->AddVertex( aP );
|
||||||
m_uniquePoints.insert ( p );
|
m_uniquePoints.insert ( p );
|
||||||
|
|
|
@ -100,16 +100,16 @@ class SHAPE_POLY_SET : public SHAPE
|
||||||
return (m_vertexCount++);
|
return (m_vertexCount++);
|
||||||
}
|
}
|
||||||
|
|
||||||
int VertexCount() const
|
int GetTriangleCount() const
|
||||||
{
|
|
||||||
return m_vertexCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
int TriangleCount() const
|
|
||||||
{
|
{
|
||||||
return m_triangleCount;
|
return m_triangleCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GetVertexCount() const
|
||||||
|
{
|
||||||
|
return m_vertexCount;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
TRI* m_triangles = nullptr;
|
TRI* m_triangles = nullptr;
|
||||||
|
@ -427,6 +427,8 @@ class SHAPE_POLY_SET : public SHAPE
|
||||||
*/
|
*/
|
||||||
SHAPE_POLY_SET( const SHAPE_POLY_SET& aOther );
|
SHAPE_POLY_SET( const SHAPE_POLY_SET& aOther );
|
||||||
|
|
||||||
|
~SHAPE_POLY_SET();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetRelativeIndices
|
* Function GetRelativeIndices
|
||||||
*
|
*
|
||||||
|
|
|
@ -184,6 +184,8 @@ INDEX::ITEM_SHAPE_INDEX* INDEX::getSubindex( const ITEM* aItem )
|
||||||
idx_n = SI_PadsTop;
|
idx_n = SI_PadsTop;
|
||||||
else if( l.Start() == F_Cu )
|
else if( l.Start() == F_Cu )
|
||||||
idx_n = SI_PadsBottom;
|
idx_n = SI_PadsBottom;
|
||||||
|
else
|
||||||
|
idx_n = SI_Traces + 2 * l.Start() + SI_SegStraight;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,7 @@ public:
|
||||||
m_owner = NULL;
|
m_owner = NULL;
|
||||||
m_marker = 0;
|
m_marker = 0;
|
||||||
m_rank = -1;
|
m_rank = -1;
|
||||||
|
m_routable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ITEM( const ITEM& aOther )
|
ITEM( const ITEM& aOther )
|
||||||
|
@ -88,6 +89,7 @@ public:
|
||||||
m_owner = NULL;
|
m_owner = NULL;
|
||||||
m_marker = aOther.m_marker;
|
m_marker = aOther.m_marker;
|
||||||
m_rank = aOther.m_rank;
|
m_rank = aOther.m_rank;
|
||||||
|
m_routable = aOther.m_routable;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~ITEM();
|
virtual ~ITEM();
|
||||||
|
@ -338,6 +340,16 @@ public:
|
||||||
return Marker() & MK_LOCKED;
|
return Marker() & MK_LOCKED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetRoutable( bool aRoutable )
|
||||||
|
{
|
||||||
|
m_routable = aRoutable;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsRoutable() const
|
||||||
|
{
|
||||||
|
return m_routable;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool collideSimple( const ITEM* aOther, int aClearance, bool aNeedMTV,
|
bool collideSimple( const ITEM* aOther, int aClearance, bool aNeedMTV,
|
||||||
VECTOR2I& aMTV, bool aDifferentNetsOnly ) const;
|
VECTOR2I& aMTV, bool aDifferentNetsOnly ) const;
|
||||||
|
@ -353,6 +365,7 @@ protected:
|
||||||
int m_net;
|
int m_net;
|
||||||
int m_marker;
|
int m_marker;
|
||||||
int m_rank;
|
int m_rank;
|
||||||
|
bool m_routable;
|
||||||
};
|
};
|
||||||
|
|
||||||
template< typename T, typename S >
|
template< typename T, typename S >
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
#include <board_connected_item.h>
|
#include <board_connected_item.h>
|
||||||
#include <class_module.h>
|
#include <class_module.h>
|
||||||
#include <class_track.h>
|
#include <class_track.h>
|
||||||
|
#include <class_zone.h>
|
||||||
|
#include <class_drawsegment.h>
|
||||||
#include <board_commit.h>
|
#include <board_commit.h>
|
||||||
#include <layers_id_colors_and_visibility.h>
|
#include <layers_id_colors_and_visibility.h>
|
||||||
#include <geometry/convex_hull.h>
|
#include <geometry/convex_hull.h>
|
||||||
|
@ -84,7 +86,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
int localPadClearance( const PNS::ITEM* aItem ) const;
|
int localPadClearance( const PNS::ITEM* aItem ) const;
|
||||||
int matchDpSuffix( const wxString& aNetName, wxString& aComplementNet, wxString& aBaseDpName );
|
int matchDpSuffix( wxString aNetName, wxString& aComplementNet, wxString& aBaseDpName );
|
||||||
|
|
||||||
PNS::ROUTER* m_router;
|
PNS::ROUTER* m_router;
|
||||||
BOARD* m_board;
|
BOARD* m_board;
|
||||||
|
@ -225,7 +227,7 @@ void PNS_PCBNEW_RULE_RESOLVER::OverrideClearance( bool aEnable, int aNetA, int a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int PNS_PCBNEW_RULE_RESOLVER::matchDpSuffix( const wxString& aNetName, wxString& aComplementNet, wxString& aBaseDpName )
|
int PNS_PCBNEW_RULE_RESOLVER::matchDpSuffix( wxString aNetName, wxString& aComplementNet, wxString& aBaseDpName )
|
||||||
{
|
{
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
|
||||||
|
@ -474,7 +476,6 @@ PNS_KICAD_IFACE::PNS_KICAD_IFACE()
|
||||||
m_tool = nullptr;
|
m_tool = nullptr;
|
||||||
m_view = nullptr;
|
m_view = nullptr;
|
||||||
m_previewItems = nullptr;
|
m_previewItems = nullptr;
|
||||||
m_world = nullptr;
|
|
||||||
m_router = nullptr;
|
m_router = nullptr;
|
||||||
m_debugDecorator = nullptr;
|
m_debugDecorator = nullptr;
|
||||||
m_dispOptions = nullptr;
|
m_dispOptions = nullptr;
|
||||||
|
@ -789,6 +790,57 @@ std::unique_ptr<PNS::VIA> PNS_KICAD_IFACE::syncVia( VIA* aVia )
|
||||||
return via;
|
return via;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PNS_KICAD_IFACE::syncZone( PNS::NODE* aWorld, ZONE_CONTAINER* aZone )
|
||||||
|
{
|
||||||
|
SHAPE_POLY_SET poly;
|
||||||
|
|
||||||
|
if( !aZone->GetIsKeepout() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
aZone->BuildSmoothedPoly( poly );
|
||||||
|
poly.CacheTriangulation();
|
||||||
|
|
||||||
|
LSET layers = aZone->GetLayerSet();
|
||||||
|
|
||||||
|
for ( int layer = F_Cu; layer <= B_Cu; layer++ )
|
||||||
|
{
|
||||||
|
if ( ! layers[layer] )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for ( int outline = 0; outline < poly.OutlineCount(); outline++ )
|
||||||
|
{
|
||||||
|
auto tri = poly.TriangulatedPolygon( outline );
|
||||||
|
|
||||||
|
for( int i = 0; i < tri->GetTriangleCount(); i++)
|
||||||
|
{
|
||||||
|
VECTOR2I a, b, c;
|
||||||
|
tri->GetTriangle( i, a, b, c );
|
||||||
|
auto triShape = new SHAPE_CONVEX;
|
||||||
|
|
||||||
|
triShape->Append( a );
|
||||||
|
triShape->Append( b );
|
||||||
|
triShape->Append( c );
|
||||||
|
|
||||||
|
std::unique_ptr< PNS::SOLID > solid( new PNS::SOLID );
|
||||||
|
|
||||||
|
solid->SetLayer( layer );
|
||||||
|
solid->SetNet( 0 );
|
||||||
|
solid->SetParent( aZone );
|
||||||
|
solid->SetShape( triShape );
|
||||||
|
solid->SetRoutable( false );
|
||||||
|
|
||||||
|
aWorld->Add( std::move( solid ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE::syncGraphicalItem( DRAWSEGMENT* aItem )
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void PNS_KICAD_IFACE::SetBoard( BOARD* aBoard )
|
void PNS_KICAD_IFACE::SetBoard( BOARD* aBoard )
|
||||||
{
|
{
|
||||||
|
@ -807,6 +859,19 @@ void PNS_KICAD_IFACE::SyncWorld( PNS::NODE *aWorld )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for( auto gitem : m_board->Drawings() )
|
||||||
|
{
|
||||||
|
auto solid = syncGraphicalItem( static_cast<DRAWSEGMENT*>( gitem ) );
|
||||||
|
|
||||||
|
if ( solid )
|
||||||
|
aWorld->Add( std::move( solid ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
for( auto zone : m_board->Zones() )
|
||||||
|
{
|
||||||
|
syncZone( aWorld, zone );
|
||||||
|
}
|
||||||
|
|
||||||
for( auto module : m_board->Modules() )
|
for( auto module : m_board->Modules() )
|
||||||
{
|
{
|
||||||
for( auto pad : module->Pads() )
|
for( auto pad : module->Pads() )
|
||||||
|
|
|
@ -67,15 +67,16 @@ private:
|
||||||
PNS_PCBNEW_RULE_RESOLVER* m_ruleResolver;
|
PNS_PCBNEW_RULE_RESOLVER* m_ruleResolver;
|
||||||
PNS_PCBNEW_DEBUG_DECORATOR* m_debugDecorator;
|
PNS_PCBNEW_DEBUG_DECORATOR* m_debugDecorator;
|
||||||
|
|
||||||
std::unique_ptr<PNS::SOLID> syncPad( D_PAD* aPad );
|
std::unique_ptr<PNS::SOLID> syncPad( D_PAD* aPad );
|
||||||
std::unique_ptr<PNS::SEGMENT> syncTrack( TRACK* aTrack );
|
std::unique_ptr<PNS::SEGMENT> syncTrack( TRACK* aTrack );
|
||||||
std::unique_ptr<PNS::VIA> syncVia( VIA* aVia );
|
std::unique_ptr<PNS::VIA> syncVia( VIA* aVia );
|
||||||
|
std::unique_ptr<PNS::SOLID> syncGraphicalItem( DRAWSEGMENT* aItem );
|
||||||
|
bool syncZone( PNS::NODE* aWorld, ZONE_CONTAINER* aZone );
|
||||||
|
|
||||||
KIGFX::VIEW* m_view;
|
KIGFX::VIEW* m_view;
|
||||||
KIGFX::VIEW_GROUP* m_previewItems;
|
KIGFX::VIEW_GROUP* m_previewItems;
|
||||||
std::unordered_set<BOARD_CONNECTED_ITEM*> m_hiddenItems;
|
std::unordered_set<BOARD_CONNECTED_ITEM*> m_hiddenItems;
|
||||||
|
|
||||||
PNS::NODE* m_world;
|
|
||||||
PNS::ROUTER* m_router;
|
PNS::ROUTER* m_router;
|
||||||
BOARD* m_board;
|
BOARD* m_board;
|
||||||
PCB_TOOL* m_tool;
|
PCB_TOOL* m_tool;
|
||||||
|
|
|
@ -152,9 +152,30 @@ bool ROUTER::StartDragging( const VECTOR2I& aP, ITEM* aStartItem, int aDragMode
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ROUTER::isStartingPointRoutable( const VECTOR2I& aWhere, int aLayer )
|
||||||
|
{
|
||||||
|
auto candidates = QueryHoverItems( aWhere );
|
||||||
|
|
||||||
|
for( ITEM* item : candidates.Items() )
|
||||||
|
{
|
||||||
|
if( ! item->IsRoutable() && item->Layers().Overlaps( aLayer ) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ROUTER::StartRouting( const VECTOR2I& aP, ITEM* aStartItem, int aLayer )
|
bool ROUTER::StartRouting( const VECTOR2I& aP, ITEM* aStartItem, int aLayer )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if( ! isStartingPointRoutable( aP, aLayer ) )
|
||||||
|
{
|
||||||
|
SetFailureReason( _("Cannot start routing inside a keepout area." ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
m_forceMarkObstaclesMode = false;
|
m_forceMarkObstaclesMode = false;
|
||||||
|
|
||||||
switch( m_mode )
|
switch( m_mode )
|
||||||
|
|
|
@ -245,6 +245,7 @@ private:
|
||||||
void highlightCurrent( bool enabled );
|
void highlightCurrent( bool enabled );
|
||||||
|
|
||||||
void markViolations( NODE* aNode, ITEM_SET& aCurrent, NODE::ITEM_VECTOR& aRemoved );
|
void markViolations( NODE* aNode, ITEM_SET& aCurrent, NODE::ITEM_VECTOR& aRemoved );
|
||||||
|
bool isStartingPointRoutable( const VECTOR2I& aWhere, int aLayer );
|
||||||
|
|
||||||
VECTOR2I m_currentEnd;
|
VECTOR2I m_currentEnd;
|
||||||
RouterState m_state;
|
RouterState m_state;
|
||||||
|
|
|
@ -129,6 +129,9 @@ ITEM* TOOL_BASE::pickSingleItem( const VECTOR2I& aWhere, int aNet, int aLayer )
|
||||||
|
|
||||||
for( ITEM* item : candidates.Items() )
|
for( ITEM* item : candidates.Items() )
|
||||||
{
|
{
|
||||||
|
if( !item->IsRoutable() )
|
||||||
|
continue;
|
||||||
|
|
||||||
if( !IsCopperLayer( item->Layers().Start() ) )
|
if( !IsCopperLayer( item->Layers().Start() ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue