Initial support for keepout zones in the P&S router.

This commit is contained in:
Tomasz Włostowski 2018-02-03 10:39:46 +01:00
parent d1a45d1476
commit 2faf1a1ed3
10 changed files with 129 additions and 17 deletions

View File

@ -785,7 +785,7 @@ void OPENGL_GAL::drawTriangulatedPolyset( const SHAPE_POLY_SET& aPolySet )
{
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;
triPoly->GetTriangle( i ,a,b,c);

View File

@ -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
{
return new SHAPE_POLY_SET( *this );
@ -1033,9 +1039,7 @@ void SHAPE_POLY_SET::unfractureSingle( SHAPE_POLY_SET::POLYGON& aPoly )
n++;
}
assert( outline >= 0 );
if( outline !=0 )
if( outline > 0 )
std::swap( result[0], result[outline] );
aPoly = result;
@ -1970,7 +1974,7 @@ private:
}
else
{
auto lastId = m_triPoly->VertexCount();
auto lastId = m_triPoly->GetVertexCount();
auto p = new p2t::Point( aP.x, aP.y, lastId );
m_triPoly->AddVertex( aP );
m_uniquePoints.insert ( p );

View File

@ -100,16 +100,16 @@ class SHAPE_POLY_SET : public SHAPE
return (m_vertexCount++);
}
int VertexCount() const
{
return m_vertexCount;
}
int TriangleCount() const
int GetTriangleCount() const
{
return m_triangleCount;
}
int GetVertexCount() const
{
return m_vertexCount;
}
private:
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();
/**
* Function GetRelativeIndices
*

View File

@ -184,6 +184,8 @@ INDEX::ITEM_SHAPE_INDEX* INDEX::getSubindex( const ITEM* aItem )
idx_n = SI_PadsTop;
else if( l.Start() == F_Cu )
idx_n = SI_PadsBottom;
else
idx_n = SI_Traces + 2 * l.Start() + SI_SegStraight;
}
break;

View File

@ -76,6 +76,7 @@ public:
m_owner = NULL;
m_marker = 0;
m_rank = -1;
m_routable = true;
}
ITEM( const ITEM& aOther )
@ -88,6 +89,7 @@ public:
m_owner = NULL;
m_marker = aOther.m_marker;
m_rank = aOther.m_rank;
m_routable = aOther.m_routable;
}
virtual ~ITEM();
@ -338,6 +340,16 @@ public:
return Marker() & MK_LOCKED;
}
void SetRoutable( bool aRoutable )
{
m_routable = aRoutable;
}
bool IsRoutable() const
{
return m_routable;
}
private:
bool collideSimple( const ITEM* aOther, int aClearance, bool aNeedMTV,
VECTOR2I& aMTV, bool aDifferentNetsOnly ) const;
@ -353,6 +365,7 @@ protected:
int m_net;
int m_marker;
int m_rank;
bool m_routable;
};
template< typename T, typename S >

View File

@ -24,6 +24,8 @@
#include <board_connected_item.h>
#include <class_module.h>
#include <class_track.h>
#include <class_zone.h>
#include <class_drawsegment.h>
#include <board_commit.h>
#include <layers_id_colors_and_visibility.h>
#include <geometry/convex_hull.h>
@ -84,7 +86,7 @@ private:
};
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;
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;
@ -474,7 +476,6 @@ PNS_KICAD_IFACE::PNS_KICAD_IFACE()
m_tool = nullptr;
m_view = nullptr;
m_previewItems = nullptr;
m_world = nullptr;
m_router = nullptr;
m_debugDecorator = nullptr;
m_dispOptions = nullptr;
@ -789,6 +790,57 @@ std::unique_ptr<PNS::VIA> PNS_KICAD_IFACE::syncVia( VIA* aVia )
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 )
{
@ -807,6 +859,19 @@ void PNS_KICAD_IFACE::SyncWorld( PNS::NODE *aWorld )
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 pad : module->Pads() )

View File

@ -67,15 +67,16 @@ private:
PNS_PCBNEW_RULE_RESOLVER* m_ruleResolver;
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::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_GROUP* m_previewItems;
std::unordered_set<BOARD_CONNECTED_ITEM*> m_hiddenItems;
PNS::NODE* m_world;
PNS::ROUTER* m_router;
BOARD* m_board;
PCB_TOOL* m_tool;

View File

@ -152,9 +152,30 @@ bool ROUTER::StartDragging( const VECTOR2I& aP, ITEM* aStartItem, int aDragMode
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 )
{
if( ! isStartingPointRoutable( aP, aLayer ) )
{
SetFailureReason( _("Cannot start routing inside a keepout area." ) );
return false;
}
m_forceMarkObstaclesMode = false;
switch( m_mode )

View File

@ -245,6 +245,7 @@ private:
void highlightCurrent( bool enabled );
void markViolations( NODE* aNode, ITEM_SET& aCurrent, NODE::ITEM_VECTOR& aRemoved );
bool isStartingPointRoutable( const VECTOR2I& aWhere, int aLayer );
VECTOR2I m_currentEnd;
RouterState m_state;

View File

@ -129,6 +129,9 @@ ITEM* TOOL_BASE::pickSingleItem( const VECTOR2I& aWhere, int aNet, int aLayer )
for( ITEM* item : candidates.Items() )
{
if( !item->IsRoutable() )
continue;
if( !IsCopperLayer( item->Layers().Start() ) )
continue;