mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-04-19 14:11:41 +00:00
Speed up creepage
Make sure of sets where possible Don't do checks in nested loops -- prune first Thread when possible Ensure we are updating the dialog as we go Fix some coding convention issues Fixes https://gitlab.com/kicad/code/kicad/-/issues/19488
This commit is contained in:
parent
ae4ef7c062
commit
8ccf8c1138
@ -23,6 +23,7 @@
|
||||
|
||||
#include <drc/drc_creepage_utils.h>
|
||||
#include <geometry/intersection.h>
|
||||
#include <thread_pool.h>
|
||||
|
||||
|
||||
extern bool segmentIntersectsArc( const VECTOR2I& p1, const VECTOR2I& p2, const VECTOR2I& center,
|
||||
@ -467,7 +468,7 @@ std::vector<PATH_CONNECTION> BE_SHAPE_CIRCLE::Paths( const BE_SHAPE_CIRCLE& aS2,
|
||||
}
|
||||
|
||||
|
||||
void CreepageGraph::TransformCreepShapesToNodes( std::vector<CREEP_SHAPE*>& aShapes )
|
||||
void CREEPAGE_GRAPH::TransformCreepShapesToNodes( std::vector<CREEP_SHAPE*>& aShapes )
|
||||
{
|
||||
for( CREEP_SHAPE* p1 : aShapes )
|
||||
{
|
||||
@ -476,15 +477,15 @@ void CreepageGraph::TransformCreepShapesToNodes( std::vector<CREEP_SHAPE*>& aSha
|
||||
|
||||
switch( p1->GetType() )
|
||||
{
|
||||
case CREEP_SHAPE::TYPE::POINT: AddNode( GraphNode::TYPE::POINT, p1, p1->GetPos() ); break;
|
||||
case CREEP_SHAPE::TYPE::CIRCLE: AddNode( GraphNode::TYPE::CIRCLE, p1, p1->GetPos() ); break;
|
||||
case CREEP_SHAPE::TYPE::ARC: AddNode( GraphNode::TYPE::ARC, p1, p1->GetPos() ); break;
|
||||
case CREEP_SHAPE::TYPE::POINT: AddNode( GRAPH_NODE::TYPE::POINT, p1, p1->GetPos() ); break;
|
||||
case CREEP_SHAPE::TYPE::CIRCLE: AddNode( GRAPH_NODE::TYPE::CIRCLE, p1, p1->GetPos() ); break;
|
||||
case CREEP_SHAPE::TYPE::ARC: AddNode( GRAPH_NODE::TYPE::ARC, p1, p1->GetPos() ); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CreepageGraph::RemoveDuplicatedShapes()
|
||||
void CREEPAGE_GRAPH::RemoveDuplicatedShapes()
|
||||
{
|
||||
// Sort the vector
|
||||
sort( m_shapeCollection.begin(), m_shapeCollection.end(), compareShapes );
|
||||
@ -514,7 +515,7 @@ void CreepageGraph::RemoveDuplicatedShapes()
|
||||
std::swap( m_shapeCollection, newVector );
|
||||
}
|
||||
|
||||
void CreepageGraph::TransformEdgeToCreepShapes()
|
||||
void CREEPAGE_GRAPH::TransformEdgeToCreepShapes()
|
||||
{
|
||||
for( BOARD_ITEM* drawing : m_boardEdge )
|
||||
{
|
||||
@ -589,7 +590,7 @@ void CreepageGraph::TransformEdgeToCreepShapes()
|
||||
}
|
||||
|
||||
|
||||
std::vector<PCB_SHAPE> GraphConnection::GetShapes()
|
||||
std::vector<PCB_SHAPE> GRAPH_CONNECTION::GetShapes()
|
||||
{
|
||||
std::vector<PCB_SHAPE> shapes = std::vector<PCB_SHAPE>();
|
||||
int lineWidth = 0;
|
||||
@ -600,12 +601,12 @@ std::vector<PCB_SHAPE> GraphConnection::GetShapes()
|
||||
if( !n1 || !n2 )
|
||||
return shapes;
|
||||
|
||||
if( n1->m_type == GraphNode::TYPE::VIRTUAL || n2->m_type == GraphNode::TYPE::VIRTUAL )
|
||||
if( n1->m_type == GRAPH_NODE::TYPE::VIRTUAL || n2->m_type == GRAPH_NODE::TYPE::VIRTUAL )
|
||||
{
|
||||
return shapes;
|
||||
}
|
||||
|
||||
if( !forceStraightLigne && n1->m_parent && ( n1->m_parent == n2->m_parent )
|
||||
if( !m_forceStraightLine && n1->m_parent && ( n1->m_parent == n2->m_parent )
|
||||
&& ( n1->m_parent->GetType() == CREEP_SHAPE::TYPE::CIRCLE ) )
|
||||
{
|
||||
VECTOR2I center = n1->m_parent->GetPos();
|
||||
@ -633,7 +634,7 @@ std::vector<PCB_SHAPE> GraphConnection::GetShapes()
|
||||
return shapes;
|
||||
}
|
||||
|
||||
else if( !forceStraightLigne && n1->m_parent && ( n1->m_parent == n2->m_parent )
|
||||
else if( !m_forceStraightLine && n1->m_parent && ( n1->m_parent == n2->m_parent )
|
||||
&& n1->m_parent->GetType() == CREEP_SHAPE::TYPE::ARC )
|
||||
{
|
||||
BE_SHAPE_ARC* arc = dynamic_cast<BE_SHAPE_ARC*>( n1->m_parent );
|
||||
@ -701,19 +702,19 @@ std::vector<PCB_SHAPE> GraphConnection::GetShapes()
|
||||
return shapes;
|
||||
}
|
||||
|
||||
void CREEP_SHAPE::ConnectChildren( std::shared_ptr<GraphNode>& a1, std::shared_ptr<GraphNode>&,
|
||||
CreepageGraph& aG ) const
|
||||
void CREEP_SHAPE::ConnectChildren( std::shared_ptr<GRAPH_NODE>& a1, std::shared_ptr<GRAPH_NODE>&,
|
||||
CREEPAGE_GRAPH& aG ) const
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void BE_SHAPE_POINT::ConnectChildren( std::shared_ptr<GraphNode>& a1, std::shared_ptr<GraphNode>&,
|
||||
CreepageGraph& aG ) const
|
||||
void BE_SHAPE_POINT::ConnectChildren( std::shared_ptr<GRAPH_NODE>& a1, std::shared_ptr<GRAPH_NODE>&,
|
||||
CREEPAGE_GRAPH& aG ) const
|
||||
{
|
||||
}
|
||||
|
||||
void BE_SHAPE_CIRCLE::ShortenChildDueToGV( std::shared_ptr<GraphNode>& a1,
|
||||
std::shared_ptr<GraphNode>& a2, CreepageGraph& aG,
|
||||
void BE_SHAPE_CIRCLE::ShortenChildDueToGV( std::shared_ptr<GRAPH_NODE>& a1,
|
||||
std::shared_ptr<GRAPH_NODE>& a2, CREEPAGE_GRAPH& aG,
|
||||
double aNormalWeight ) const
|
||||
{
|
||||
EDA_ANGLE angle1 = EDA_ANGLE( a1->m_pos - m_pos );
|
||||
@ -740,7 +741,7 @@ void BE_SHAPE_CIRCLE::ShortenChildDueToGV( std::shared_ptr<GraphNode>& a1,
|
||||
skipPoint.y += m_radius * sin( pointAngle.AsRadians() );
|
||||
|
||||
|
||||
std::shared_ptr<GraphNode> gnt = aG.AddNode( GraphNode::POINT, a1->m_parent, skipPoint );
|
||||
std::shared_ptr<GRAPH_NODE> gnt = aG.AddNode( GRAPH_NODE::POINT, a1->m_parent, skipPoint );
|
||||
|
||||
PATH_CONNECTION pc;
|
||||
|
||||
@ -753,15 +754,15 @@ void BE_SHAPE_CIRCLE::ShortenChildDueToGV( std::shared_ptr<GraphNode>& a1,
|
||||
pc.a2 = maxAngle == angle2 ? a2->m_pos : a1->m_pos;
|
||||
pc.weight = aG.m_minGrooveWidth;
|
||||
|
||||
std::shared_ptr<GraphConnection> gc = aG.AddConnection( gnt, maxAngle == angle2 ? a2 : a1, pc );
|
||||
std::shared_ptr<GRAPH_CONNECTION> gc = aG.AddConnection( gnt, maxAngle == angle2 ? a2 : a1, pc );
|
||||
|
||||
if( gc )
|
||||
gc->forceStraightLigne = true;
|
||||
gc->m_forceStraightLine = true;
|
||||
return;
|
||||
}
|
||||
|
||||
void BE_SHAPE_CIRCLE::ConnectChildren( std::shared_ptr<GraphNode>& a1,
|
||||
std::shared_ptr<GraphNode>& a2, CreepageGraph& aG ) const
|
||||
void BE_SHAPE_CIRCLE::ConnectChildren( std::shared_ptr<GRAPH_NODE>& a1,
|
||||
std::shared_ptr<GRAPH_NODE>& a2, CREEPAGE_GRAPH& aG ) const
|
||||
{
|
||||
if( !a1 || !a2 )
|
||||
return;
|
||||
@ -797,8 +798,8 @@ void BE_SHAPE_CIRCLE::ConnectChildren( std::shared_ptr<GraphNode>& a1,
|
||||
}
|
||||
|
||||
|
||||
void BE_SHAPE_ARC::ConnectChildren( std::shared_ptr<GraphNode>& a1, std::shared_ptr<GraphNode>& a2,
|
||||
CreepageGraph& aG ) const
|
||||
void BE_SHAPE_ARC::ConnectChildren( std::shared_ptr<GRAPH_NODE>& a1, std::shared_ptr<GRAPH_NODE>& a2,
|
||||
CREEPAGE_GRAPH& aG ) const
|
||||
{
|
||||
if( !a1 || !a2 )
|
||||
return;
|
||||
@ -828,7 +829,7 @@ void BE_SHAPE_ARC::ConnectChildren( std::shared_ptr<GraphNode>& a1, std::shared_
|
||||
}
|
||||
}
|
||||
|
||||
void CreepageGraph::SetTarget( double aTarget )
|
||||
void CREEPAGE_GRAPH::SetTarget( double aTarget )
|
||||
{
|
||||
m_creepageTarget = aTarget;
|
||||
m_creepageTargetSquared = aTarget * aTarget;
|
||||
@ -2030,9 +2031,9 @@ std::vector<PATH_CONNECTION> GetPaths( CREEP_SHAPE* aS1, CREEP_SHAPE* aS2, doubl
|
||||
return result;
|
||||
}
|
||||
|
||||
double CreepageGraph::Solve(
|
||||
std::shared_ptr<GraphNode>& aFrom, std::shared_ptr<GraphNode>& aTo,
|
||||
std::vector<std::shared_ptr<GraphConnection>>& aResult ) // Change to vector of pointers
|
||||
double CREEPAGE_GRAPH::Solve(
|
||||
std::shared_ptr<GRAPH_NODE>& aFrom, std::shared_ptr<GRAPH_NODE>& aTo,
|
||||
std::vector<std::shared_ptr<GRAPH_CONNECTION>>& aResult ) // Change to vector of pointers
|
||||
{
|
||||
if( !aFrom || !aTo )
|
||||
return 0;
|
||||
@ -2041,19 +2042,19 @@ double CreepageGraph::Solve(
|
||||
return 0;
|
||||
|
||||
// Dijkstra's algorithm for shortest path
|
||||
std::unordered_map<GraphNode*, double> distances;
|
||||
std::unordered_map<GraphNode*, GraphNode*> previous;
|
||||
std::unordered_map<GRAPH_NODE*, double> distances;
|
||||
std::unordered_map<GRAPH_NODE*, GRAPH_NODE*> previous;
|
||||
|
||||
auto cmp = [&distances]( GraphNode* left, GraphNode* right )
|
||||
auto cmp = [&distances]( GRAPH_NODE* left, GRAPH_NODE* right )
|
||||
{
|
||||
if( distances[left] == distances[right] )
|
||||
return left > right; // Compare addresses to avoid ties.
|
||||
return distances[left] > distances[right];
|
||||
};
|
||||
std::priority_queue<GraphNode*, std::vector<GraphNode*>, decltype( cmp )> pq( cmp );
|
||||
std::priority_queue<GRAPH_NODE*, std::vector<GRAPH_NODE*>, decltype( cmp )> pq( cmp );
|
||||
|
||||
// Initialize distances to infinity for all nodes except the starting node
|
||||
for( std::shared_ptr<GraphNode> node : m_nodes )
|
||||
for( std::shared_ptr<GRAPH_NODE> node : m_nodes )
|
||||
{
|
||||
if( node != nullptr )
|
||||
distances[node.get()] = std::numeric_limits<double>::infinity(); // Set to infinity
|
||||
@ -2065,7 +2066,7 @@ double CreepageGraph::Solve(
|
||||
// Dijkstra's main loop
|
||||
while( !pq.empty() )
|
||||
{
|
||||
GraphNode* current = pq.top();
|
||||
GRAPH_NODE* current = pq.top();
|
||||
pq.pop();
|
||||
|
||||
if( current == aTo.get() )
|
||||
@ -2074,9 +2075,9 @@ double CreepageGraph::Solve(
|
||||
}
|
||||
|
||||
// Traverse neighbors
|
||||
for( std::shared_ptr<GraphConnection> connection : current->m_connections )
|
||||
for( std::shared_ptr<GRAPH_CONNECTION> connection : current->m_node_conns )
|
||||
{
|
||||
GraphNode* neighbor = ( connection->n1 ).get() == current ? ( connection->n2 ).get()
|
||||
GRAPH_NODE* neighbor = ( connection->n1 ).get() == current ? ( connection->n2 ).get()
|
||||
: ( connection->n1 ).get();
|
||||
|
||||
if( !neighbor )
|
||||
@ -2103,17 +2104,18 @@ double CreepageGraph::Solve(
|
||||
}
|
||||
|
||||
// Trace back the path from aTo to aFrom
|
||||
GraphNode* step = aTo.get();
|
||||
GRAPH_NODE* step = aTo.get();
|
||||
|
||||
while( step != aFrom.get() )
|
||||
{
|
||||
GraphNode* prevNode = previous[step];
|
||||
for( std::shared_ptr<GraphConnection> connection : step->m_connections )
|
||||
GRAPH_NODE* prevNode = previous[step];
|
||||
|
||||
for( std::shared_ptr<GRAPH_CONNECTION> node_conn : step->m_node_conns )
|
||||
{
|
||||
if( ( ( connection->n1 ).get() == prevNode && ( connection->n2 ).get() == step )
|
||||
|| ( ( connection->n1 ).get() == step && ( connection->n2 ).get() == prevNode ) )
|
||||
if( ( ( node_conn->n1 ).get() == prevNode && ( node_conn->n2 ).get() == step )
|
||||
|| ( ( node_conn->n1 ).get() == step && ( node_conn->n2 ).get() == prevNode ) )
|
||||
{
|
||||
aResult.push_back( connection );
|
||||
aResult.push_back( node_conn );
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2123,7 +2125,7 @@ double CreepageGraph::Solve(
|
||||
return pathWeight;
|
||||
}
|
||||
|
||||
void CreepageGraph::Addshape( const SHAPE& aShape, std::shared_ptr<GraphNode>& aConnectTo,
|
||||
void CREEPAGE_GRAPH::Addshape( const SHAPE& aShape, std::shared_ptr<GRAPH_NODE>& aConnectTo,
|
||||
BOARD_ITEM* aParent )
|
||||
{
|
||||
CREEP_SHAPE* newshape = nullptr;
|
||||
@ -2238,15 +2240,15 @@ void CreepageGraph::Addshape( const SHAPE& aShape, std::shared_ptr<GraphNode>& a
|
||||
if( !newshape )
|
||||
return;
|
||||
|
||||
std::shared_ptr<GraphNode> gnShape = nullptr;
|
||||
std::shared_ptr<GRAPH_NODE> gnShape = nullptr;
|
||||
|
||||
newshape->SetParent( aParent );
|
||||
|
||||
switch( aShape.Type() )
|
||||
{
|
||||
case SH_SEGMENT: gnShape = AddNode( GraphNode::SEGMENT, newshape, newshape->GetPos() ); break;
|
||||
case SH_CIRCLE: gnShape = AddNode( GraphNode::CIRCLE, newshape, newshape->GetPos() ); break;
|
||||
case SH_ARC: gnShape = AddNode( GraphNode::ARC, newshape, newshape->GetPos() ); break;
|
||||
case SH_SEGMENT: gnShape = AddNode( GRAPH_NODE::SEGMENT, newshape, newshape->GetPos() ); break;
|
||||
case SH_CIRCLE: gnShape = AddNode( GRAPH_NODE::CIRCLE, newshape, newshape->GetPos() ); break;
|
||||
case SH_ARC: gnShape = AddNode( GRAPH_NODE::ARC, newshape, newshape->GetPos() ); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
@ -2254,7 +2256,7 @@ void CreepageGraph::Addshape( const SHAPE& aShape, std::shared_ptr<GraphNode>& a
|
||||
{
|
||||
m_shapeCollection.push_back( newshape );
|
||||
gnShape->m_net = aConnectTo->m_net;
|
||||
std::shared_ptr<GraphConnection> gc = AddConnection( gnShape, aConnectTo );
|
||||
std::shared_ptr<GRAPH_CONNECTION> gc = AddConnection( gnShape, aConnectTo );
|
||||
|
||||
if( gc )
|
||||
gc->m_path.m_show = false;
|
||||
@ -2266,113 +2268,121 @@ void CreepageGraph::Addshape( const SHAPE& aShape, std::shared_ptr<GraphNode>& a
|
||||
}
|
||||
}
|
||||
|
||||
void CreepageGraph::GeneratePaths( double aMaxWeight, PCB_LAYER_ID aLayer,
|
||||
bool aGenerateBoardEdges )
|
||||
void CREEPAGE_GRAPH::GeneratePaths( double aMaxWeight, PCB_LAYER_ID aLayer, bool aClearance )
|
||||
{
|
||||
std::vector<std::shared_ptr<GraphNode>> nodes1 = m_nodes;
|
||||
std::vector<std::shared_ptr<GraphNode>> nodes2 = m_nodes;
|
||||
std::vector<std::shared_ptr<GRAPH_NODE>> nodes;
|
||||
std::mutex nodes_lock;
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
|
||||
std::copy_if( m_nodes.begin(), m_nodes.end(), std::back_inserter( nodes ),
|
||||
[&]( std::shared_ptr<GRAPH_NODE> gn )
|
||||
{
|
||||
return !!gn && gn->m_parent && gn->m_connectDirectly
|
||||
&& ( gn->m_type != GRAPH_NODE::TYPE::VIRTUAL );
|
||||
} );
|
||||
|
||||
for( std::shared_ptr<GraphNode> gn1 : nodes1 )
|
||||
auto processNodes = [&]( size_t i, size_t j ) -> bool
|
||||
{
|
||||
nodes2.erase( nodes2.begin() );
|
||||
|
||||
if( !gn1 )
|
||||
continue;
|
||||
|
||||
if( !gn1->m_parent )
|
||||
continue;
|
||||
|
||||
if( !gn1->m_connectDirectly )
|
||||
continue;
|
||||
|
||||
if( gn1->m_type == GraphNode::TYPE::VIRTUAL )
|
||||
continue;
|
||||
|
||||
|
||||
for( std::shared_ptr<GraphNode> gn2 : nodes2 )
|
||||
{
|
||||
if( !gn2 )
|
||||
continue;
|
||||
|
||||
if( !gn2->m_parent )
|
||||
continue;
|
||||
|
||||
if( gn1->m_parent == gn2->m_parent )
|
||||
continue;
|
||||
|
||||
if( !gn2->m_connectDirectly )
|
||||
continue;
|
||||
|
||||
if( gn2->m_type == GraphNode::TYPE::VIRTUAL )
|
||||
continue;
|
||||
|
||||
if( !aGenerateBoardEdges && !gn1->m_parent->IsConductive()
|
||||
&& !gn2->m_parent->IsConductive() )
|
||||
continue;
|
||||
|
||||
if( ( gn1->m_net == gn2->m_net ) && ( gn1->m_parent->IsConductive() )
|
||||
&& ( gn2->m_parent->IsConductive() ) )
|
||||
continue;
|
||||
|
||||
for( PATH_CONNECTION pc : GetPaths( gn1->m_parent, gn2->m_parent, aMaxWeight ) )
|
||||
for( size_t ii = i; ii < j; ii++ )
|
||||
{
|
||||
std::vector<const BOARD_ITEM*> IgnoreForTest;
|
||||
IgnoreForTest.push_back( gn1->m_parent->GetParent() );
|
||||
IgnoreForTest.push_back( gn2->m_parent->GetParent() );
|
||||
std::shared_ptr<GRAPH_NODE> gn1 = nodes[ii];
|
||||
|
||||
if( !pc.isValid( m_board, aLayer, m_boardEdge, IgnoreForTest, m_boardOutline,
|
||||
{ false, true }, m_minGrooveWidth ) )
|
||||
continue;
|
||||
|
||||
std::shared_ptr<GraphNode>* connect1 = &gn1;
|
||||
std::shared_ptr<GraphNode>* connect2 = &gn2;
|
||||
std::shared_ptr<GraphNode> gnt1 = nullptr;
|
||||
std::shared_ptr<GraphNode> gnt2 = nullptr;
|
||||
|
||||
if ( gn1->m_parent->GetType() != CREEP_SHAPE::TYPE::POINT )
|
||||
for( size_t jj = ii + 1; jj < nodes.size(); jj++ )
|
||||
{
|
||||
gnt1 = AddNode( GraphNode::POINT, gn1->m_parent, pc.a1 );
|
||||
gnt1->m_connectDirectly = false;
|
||||
std::shared_ptr<GRAPH_NODE> gn2 = nodes[jj];
|
||||
|
||||
if( gn1->m_parent->IsConductive() )
|
||||
if( gn1->m_parent->GetParent() == gn2->m_parent->GetParent() )
|
||||
continue;
|
||||
|
||||
if( ( gn1->m_net == gn2->m_net ) && ( gn1->m_parent->IsConductive() )
|
||||
&& ( gn2->m_parent->IsConductive() ) )
|
||||
continue;
|
||||
|
||||
for( PATH_CONNECTION pc : GetPaths( gn1->m_parent, gn2->m_parent, aMaxWeight ) )
|
||||
{
|
||||
std::shared_ptr<GraphConnection> gc = AddConnection( gn1, gnt1 );
|
||||
std::vector<const BOARD_ITEM*> IgnoreForTest;
|
||||
IgnoreForTest.push_back( gn1->m_parent->GetParent() );
|
||||
IgnoreForTest.push_back( gn2->m_parent->GetParent() );
|
||||
|
||||
if( gc )
|
||||
gc->m_path.m_show = false;
|
||||
if( !pc.isValid( m_board, aLayer, m_boardEdge, IgnoreForTest, m_boardOutline,
|
||||
{ false, true }, m_minGrooveWidth ) )
|
||||
continue;
|
||||
|
||||
std::shared_ptr<GRAPH_NODE>* connect1 = &gn1;
|
||||
std::shared_ptr<GRAPH_NODE>* connect2 = &gn2;
|
||||
std::shared_ptr<GRAPH_NODE> gnt1 = nullptr;
|
||||
std::shared_ptr<GRAPH_NODE> gnt2 = nullptr;
|
||||
std::lock_guard<std::mutex> lock( nodes_lock );
|
||||
|
||||
if( gn1->m_parent->GetType() != CREEP_SHAPE::TYPE::POINT )
|
||||
{
|
||||
gnt1 = AddNode( GRAPH_NODE::POINT, gn1->m_parent, pc.a1 );
|
||||
gnt1->m_connectDirectly = false;
|
||||
|
||||
if( gn1->m_parent->IsConductive() )
|
||||
{
|
||||
std::shared_ptr<GRAPH_CONNECTION> gc = AddConnection( gn1, gnt1 );
|
||||
|
||||
if( gc )
|
||||
gc->m_path.m_show = false;
|
||||
}
|
||||
connect1 = &gnt1;
|
||||
}
|
||||
|
||||
if( gn2->m_parent->GetType() != CREEP_SHAPE::TYPE::POINT )
|
||||
{
|
||||
gnt2 = AddNode( GRAPH_NODE::POINT, gn2->m_parent, pc.a2 );
|
||||
gnt2->m_connectDirectly = false;
|
||||
|
||||
if( gn2->m_parent->IsConductive() )
|
||||
{
|
||||
std::shared_ptr<GRAPH_CONNECTION> gc = AddConnection( gn2, gnt2 );
|
||||
|
||||
if( gc )
|
||||
gc->m_path.m_show = false;
|
||||
}
|
||||
connect2 = &gnt2;
|
||||
}
|
||||
|
||||
AddConnection( *connect1, *connect2, pc );
|
||||
}
|
||||
connect1 = &gnt1;
|
||||
}
|
||||
} // for jj
|
||||
} // for ii
|
||||
|
||||
if( gn2->m_parent->GetType() != CREEP_SHAPE::TYPE::POINT )
|
||||
return true;
|
||||
};
|
||||
|
||||
// Running in the clearance test, we are already in a parallelized loop, so parallelizing again
|
||||
// will run into deadlock as all threads start waiting
|
||||
if( aClearance )
|
||||
processNodes( 0, nodes.size() );
|
||||
else
|
||||
{
|
||||
auto ret = tp.parallelize_loop( nodes.size(), processNodes );
|
||||
|
||||
for( size_t ii = 0; ii < ret.size(); ii++ )
|
||||
{
|
||||
std::future<bool>& r = ret[ii];
|
||||
|
||||
if( r.valid() )
|
||||
{
|
||||
std::future_status status = r.wait_for( std::chrono::seconds( 0 ) );
|
||||
|
||||
while( status != std::future_status::ready )
|
||||
{
|
||||
gnt2 = AddNode( GraphNode::POINT, gn2->m_parent, pc.a2 );
|
||||
gnt2->m_connectDirectly = false;
|
||||
|
||||
if( gn2->m_parent->IsConductive() )
|
||||
{
|
||||
std::shared_ptr<GraphConnection> gc = AddConnection( gn2, gnt2 );
|
||||
|
||||
if( gc )
|
||||
gc->m_path.m_show = false;
|
||||
}
|
||||
connect2 = &gnt2;
|
||||
status = r.wait_for( std::chrono::milliseconds( 100 ) );
|
||||
}
|
||||
|
||||
AddConnection( *connect1, *connect2, pc );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CreepageGraph::Trim( double aWeightLimit )
|
||||
void CREEPAGE_GRAPH::Trim( double aWeightLimit )
|
||||
{
|
||||
std::vector<std::shared_ptr<GraphConnection>> toRemove;
|
||||
std::vector<std::shared_ptr<GRAPH_CONNECTION>> toRemove;
|
||||
|
||||
// Collect connections to remove
|
||||
for( std::shared_ptr<GraphConnection>& gc : m_connections )
|
||||
for( std::shared_ptr<GRAPH_CONNECTION>& gc : m_connections )
|
||||
{
|
||||
if( gc && ( gc->m_path.weight > aWeightLimit ) )
|
||||
{
|
||||
@ -2381,35 +2391,35 @@ void CreepageGraph::Trim( double aWeightLimit )
|
||||
}
|
||||
|
||||
// Remove collected connections
|
||||
for( const std::shared_ptr<GraphConnection>& gc : toRemove )
|
||||
for( const std::shared_ptr<GRAPH_CONNECTION>& gc : toRemove )
|
||||
{
|
||||
RemoveConnection( gc );
|
||||
}
|
||||
}
|
||||
|
||||
void CreepageGraph::RemoveConnection( std::shared_ptr<GraphConnection> aGc, bool aDelete )
|
||||
void CREEPAGE_GRAPH::RemoveConnection( std::shared_ptr<GRAPH_CONNECTION> aGc, bool aDelete )
|
||||
{
|
||||
if( !aGc )
|
||||
return;
|
||||
|
||||
for( std::shared_ptr<GraphNode> gn : { aGc->n1, aGc->n2 } )
|
||||
for( std::shared_ptr<GRAPH_NODE> gn : { aGc->n1, aGc->n2 } )
|
||||
{
|
||||
if( gn )
|
||||
{
|
||||
auto& nConns = gn->m_connections;
|
||||
nConns.erase( std::remove( nConns.begin(), nConns.end(), aGc ), nConns.end() );
|
||||
gn->m_node_conns.erase( aGc );
|
||||
|
||||
if( nConns.empty() && aDelete )
|
||||
if( gn->m_node_conns.empty() && aDelete )
|
||||
{
|
||||
auto it = std::find_if( m_nodes.begin(), m_nodes.end(),
|
||||
[&gn]( const std::shared_ptr<GraphNode> node )
|
||||
[&gn]( const std::shared_ptr<GRAPH_NODE> node )
|
||||
{
|
||||
return node.get() == gn.get();
|
||||
} );
|
||||
|
||||
if( it != m_nodes.end() )
|
||||
{
|
||||
m_nodes.erase( it );
|
||||
}
|
||||
|
||||
m_nodeset.erase( gn );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2423,30 +2433,32 @@ void CreepageGraph::RemoveConnection( std::shared_ptr<GraphConnection> aGc, bool
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<GraphNode> CreepageGraph::AddNode( GraphNode::TYPE aType, CREEP_SHAPE* parent,
|
||||
std::shared_ptr<GRAPH_NODE> CREEPAGE_GRAPH::AddNode( GRAPH_NODE::TYPE aType, CREEP_SHAPE* parent,
|
||||
VECTOR2I pos )
|
||||
{
|
||||
std::shared_ptr<GraphNode> gn = FindNode( aType, parent, pos );
|
||||
std::shared_ptr<GRAPH_NODE> gn = FindNode( aType, parent, pos );
|
||||
if( gn )
|
||||
return gn;
|
||||
|
||||
gn = std::make_shared<GraphNode>( aType, parent, pos );
|
||||
gn = std::make_shared<GRAPH_NODE>( aType, parent, pos );
|
||||
m_nodes.push_back( gn );
|
||||
m_nodeset.insert( gn );
|
||||
return gn;
|
||||
}
|
||||
|
||||
std::shared_ptr<GraphNode> CreepageGraph::AddNodeVirtual()
|
||||
std::shared_ptr<GRAPH_NODE> CREEPAGE_GRAPH::AddNodeVirtual()
|
||||
{
|
||||
//Virtual nodes are always unique, do not try to find them
|
||||
std::shared_ptr<GraphNode> gn =
|
||||
std::make_shared<GraphNode>( GraphNode::TYPE::VIRTUAL, nullptr );
|
||||
std::shared_ptr<GRAPH_NODE> gn =
|
||||
std::make_shared<GRAPH_NODE>( GRAPH_NODE::TYPE::VIRTUAL, nullptr );
|
||||
m_nodes.push_back( gn );
|
||||
m_nodeset.insert( gn );
|
||||
return gn;
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<GraphConnection> CreepageGraph::AddConnection( std::shared_ptr<GraphNode>& aN1,
|
||||
std::shared_ptr<GraphNode>& aN2,
|
||||
std::shared_ptr<GRAPH_CONNECTION> CREEPAGE_GRAPH::AddConnection( std::shared_ptr<GRAPH_NODE>& aN1,
|
||||
std::shared_ptr<GRAPH_NODE>& aN2,
|
||||
const PATH_CONNECTION& aPc )
|
||||
{
|
||||
if( !aN1 || !aN2 )
|
||||
@ -2454,16 +2466,16 @@ std::shared_ptr<GraphConnection> CreepageGraph::AddConnection( std::shared_ptr<G
|
||||
|
||||
wxASSERT_MSG( ( aN1 != aN2 ), "Creepage: a connection connects a node to itself" );
|
||||
|
||||
std::shared_ptr<GraphConnection> gc = std::make_shared<GraphConnection>( aN1, aN2, aPc );
|
||||
std::shared_ptr<GRAPH_CONNECTION> gc = std::make_shared<GRAPH_CONNECTION>( aN1, aN2, aPc );
|
||||
m_connections.push_back( gc );
|
||||
aN1->m_connections.push_back( gc );
|
||||
aN2->m_connections.push_back( gc );
|
||||
aN1->m_node_conns.insert( gc );
|
||||
aN2->m_node_conns.insert( gc );
|
||||
|
||||
return gc;
|
||||
}
|
||||
|
||||
std::shared_ptr<GraphConnection> CreepageGraph::AddConnection( std::shared_ptr<GraphNode>& aN1,
|
||||
std::shared_ptr<GraphNode>& aN2 )
|
||||
std::shared_ptr<GRAPH_CONNECTION> CREEPAGE_GRAPH::AddConnection( std::shared_ptr<GRAPH_NODE>& aN1,
|
||||
std::shared_ptr<GRAPH_NODE>& aN2 )
|
||||
{
|
||||
if( !aN1 || !aN2 )
|
||||
return nullptr;
|
||||
@ -2476,24 +2488,22 @@ std::shared_ptr<GraphConnection> CreepageGraph::AddConnection( std::shared_ptr<G
|
||||
return AddConnection( aN1, aN2, pc );
|
||||
}
|
||||
|
||||
std::shared_ptr<GraphNode> CreepageGraph::FindNode( GraphNode::TYPE aType, CREEP_SHAPE* aParent,
|
||||
std::shared_ptr<GRAPH_NODE> CREEPAGE_GRAPH::FindNode( GRAPH_NODE::TYPE aType, CREEP_SHAPE* aParent,
|
||||
VECTOR2I aPos )
|
||||
{
|
||||
for( std::shared_ptr<GraphNode> gn : m_nodes )
|
||||
{
|
||||
if( aPos == gn->m_pos && aParent == gn->m_parent && aType == gn->m_type )
|
||||
{
|
||||
return gn;
|
||||
}
|
||||
}
|
||||
auto it = m_nodeset.find( std::make_shared<GRAPH_NODE>( aType, aParent, aPos ) );
|
||||
|
||||
if( it != m_nodeset.end() )
|
||||
return *it;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<GraphNode> CreepageGraph::AddNetElements( int aNetCode, PCB_LAYER_ID aLayer,
|
||||
std::shared_ptr<GRAPH_NODE> CREEPAGE_GRAPH::AddNetElements( int aNetCode, PCB_LAYER_ID aLayer,
|
||||
int aMaxCreepage )
|
||||
{
|
||||
std::shared_ptr<GraphNode> virtualNode = AddNodeVirtual();
|
||||
std::shared_ptr<GRAPH_NODE> virtualNode = AddNodeVirtual();
|
||||
virtualNode->m_net = aNetCode;
|
||||
|
||||
for( FOOTPRINT* footprint : m_board.Footprints() )
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
* Copyright The KiCad Developers.
|
||||
* Copyright (C) 2024 Fabien Corona f.corona<at>laposte.net
|
||||
@ -25,6 +24,8 @@
|
||||
#ifndef _DRC_CREEPAGE_UTILS_H
|
||||
#define _DRC_CREEPAGE_UTILS_H
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
#include <common.h>
|
||||
#include <macros.h>
|
||||
#include <board_design_settings.h>
|
||||
@ -141,9 +142,9 @@ struct PATH_CONNECTION
|
||||
};
|
||||
|
||||
|
||||
class GraphConnection;
|
||||
class GraphNode;
|
||||
class CreepageGraph;
|
||||
class GRAPH_CONNECTION;
|
||||
class GRAPH_NODE;
|
||||
class CREEPAGE_GRAPH;
|
||||
class CREEP_SHAPE;
|
||||
class BE_SHAPE;
|
||||
class BE_SHAPE_POINT;
|
||||
@ -168,7 +169,14 @@ public:
|
||||
CIRCLE,
|
||||
ARC
|
||||
};
|
||||
CREEP_SHAPE() {};
|
||||
|
||||
CREEP_SHAPE()
|
||||
{
|
||||
m_conductive = false;
|
||||
m_parent = nullptr;
|
||||
m_pos = VECTOR2I( 0, 0 );
|
||||
m_type = CREEP_SHAPE::TYPE::UNDEFINED;
|
||||
};
|
||||
|
||||
virtual ~CREEP_SHAPE() {}
|
||||
|
||||
@ -183,8 +191,8 @@ public:
|
||||
const BOARD_ITEM* GetParent() const { return m_parent; };
|
||||
void SetParent( BOARD_ITEM* aParent ) { m_parent = aParent; };
|
||||
|
||||
virtual void ConnectChildren( std::shared_ptr<GraphNode>& a1, std::shared_ptr<GraphNode>& a2,
|
||||
CreepageGraph& aG ) const;
|
||||
virtual void ConnectChildren( std::shared_ptr<GRAPH_NODE>& a1, std::shared_ptr<GRAPH_NODE>& a2,
|
||||
CREEPAGE_GRAPH& aG ) const;
|
||||
|
||||
std::vector<PATH_CONNECTION> ReversePaths( const std::vector<PATH_CONNECTION>& aV ) const
|
||||
{
|
||||
@ -206,36 +214,42 @@ public:
|
||||
std::vector<PATH_CONNECTION> a;
|
||||
return a;
|
||||
};
|
||||
|
||||
virtual std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_POINT& aS2, double aMaxWeight,
|
||||
double aMaxSquaredWeight ) const
|
||||
{
|
||||
std::vector<PATH_CONNECTION> a;
|
||||
return a;
|
||||
};
|
||||
|
||||
virtual std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_CIRCLE& aS2, double aMaxWeight,
|
||||
double aMaxSquaredWeight ) const
|
||||
{
|
||||
std::vector<PATH_CONNECTION> a;
|
||||
return a;
|
||||
};
|
||||
|
||||
virtual std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_ARC& aS2, double aMaxWeight,
|
||||
double aMaxSquaredWeight ) const
|
||||
{
|
||||
std::vector<PATH_CONNECTION> a;
|
||||
return a;
|
||||
};
|
||||
|
||||
virtual std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_SEGMENT& aS2, double aMaxWeight,
|
||||
double aMaxSquaredWeight ) const
|
||||
{
|
||||
std::vector<PATH_CONNECTION> a;
|
||||
return a;
|
||||
};
|
||||
|
||||
virtual std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_CIRCLE& aS2, double aMaxWeight,
|
||||
double aMaxSquaredWeight ) const
|
||||
{
|
||||
std::vector<PATH_CONNECTION> a;
|
||||
return a;
|
||||
};
|
||||
|
||||
virtual std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_ARC& aS2, double aMaxWeight,
|
||||
double aMaxSquaredWeight ) const
|
||||
{
|
||||
@ -248,10 +262,10 @@ public:
|
||||
|
||||
|
||||
protected:
|
||||
bool m_conductive = false;
|
||||
BOARD_ITEM* m_parent = nullptr;
|
||||
VECTOR2I m_pos = VECTOR2I( 0, 0 );
|
||||
CREEP_SHAPE::TYPE m_type = CREEP_SHAPE::TYPE::UNDEFINED;
|
||||
bool m_conductive;
|
||||
BOARD_ITEM* m_parent;
|
||||
VECTOR2I m_pos;
|
||||
CREEP_SHAPE::TYPE m_type;
|
||||
};
|
||||
|
||||
|
||||
@ -346,7 +360,7 @@ public:
|
||||
std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_ARC& aS2, double aMaxWeight,
|
||||
double aMaxSquaredWeight ) const override;
|
||||
|
||||
private:
|
||||
protected:
|
||||
VECTOR2I m_pos = VECTOR2I( 0, 0 );
|
||||
double m_radius = 1;
|
||||
};
|
||||
@ -359,33 +373,36 @@ class CU_SHAPE_ARC : public CU_SHAPE_CIRCLE
|
||||
{
|
||||
public:
|
||||
CU_SHAPE_ARC( VECTOR2I aPos, double aRadius, EDA_ANGLE aStartAngle, EDA_ANGLE aEndAngle,
|
||||
VECTOR2D aStartPoint, VECTOR2D aEndPoint ) : CU_SHAPE_CIRCLE( aPos, aRadius )
|
||||
VECTOR2D aStartPoint, VECTOR2D aEndPoint ) :
|
||||
CU_SHAPE_CIRCLE( aPos, aRadius ),
|
||||
m_startAngle( aStartAngle ), m_endAngle( aEndAngle ),
|
||||
m_startPoint( aStartPoint ), m_endPoint( aEndPoint )
|
||||
{
|
||||
m_pos = aPos;
|
||||
m_type = CREEP_SHAPE::TYPE::ARC;
|
||||
m_startAngle = aStartAngle;
|
||||
m_endAngle = aEndAngle;
|
||||
m_startPoint = aStartPoint;
|
||||
m_endPoint = aEndPoint;
|
||||
m_radius = aRadius;
|
||||
m_width = 0;
|
||||
}
|
||||
|
||||
std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_POINT& aS2, double aMaxWeight,
|
||||
double aMaxSquaredWeight ) const override;
|
||||
|
||||
std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_CIRCLE& aS2, double aMaxWeight,
|
||||
double aMaxSquaredWeight ) const override;
|
||||
|
||||
std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_ARC& aS2, double aMaxWeight,
|
||||
double aMaxSquaredWeight ) const override;
|
||||
|
||||
std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_SEGMENT& aS2, double aMaxWeight,
|
||||
double aMaxSquaredWeight ) const override
|
||||
{
|
||||
return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
|
||||
};
|
||||
|
||||
std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_CIRCLE& aS2, double aMaxWeight,
|
||||
double aMaxSquaredWeight ) const override
|
||||
{
|
||||
return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
|
||||
};
|
||||
|
||||
std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_ARC& aS2, double aMaxWeight,
|
||||
double aMaxSquaredWeight ) const override;
|
||||
|
||||
@ -397,34 +414,36 @@ public:
|
||||
|
||||
VECTOR2I GetStartPoint() const override { return m_startPoint; }
|
||||
VECTOR2I GetEndPoint() const override { return m_endPoint; }
|
||||
|
||||
EDA_ANGLE AngleBetweenStartAndEnd( const VECTOR2I aPoint ) const
|
||||
{
|
||||
EDA_ANGLE angle( aPoint - m_pos );
|
||||
|
||||
while( angle < GetStartAngle() )
|
||||
angle += ANGLE_360;
|
||||
|
||||
while( angle > GetEndAngle() + ANGLE_360 )
|
||||
angle -= ANGLE_360;
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
double GetWidth() const { return m_width; };
|
||||
void SetWidth( double aW ) { m_width = aW; };
|
||||
|
||||
private:
|
||||
int m_width = 0;
|
||||
VECTOR2I m_pos = VECTOR2I( 0, 0 );
|
||||
double m_radius = 1;
|
||||
EDA_ANGLE m_startAngle = EDA_ANGLE( 0 );
|
||||
EDA_ANGLE m_endAngle = EDA_ANGLE( 180 );
|
||||
VECTOR2I m_startPoint = VECTOR2I( 1, 0 );
|
||||
VECTOR2I m_endPoint = VECTOR2I( -1, 0 );
|
||||
int m_width;
|
||||
EDA_ANGLE m_startAngle;
|
||||
EDA_ANGLE m_endAngle;
|
||||
VECTOR2I m_startPoint;
|
||||
VECTOR2I m_endPoint;
|
||||
};
|
||||
|
||||
/** @class Graphnode
|
||||
*
|
||||
* @brief a node in a @class CreepageGraph
|
||||
*/
|
||||
class GraphNode
|
||||
class GRAPH_NODE
|
||||
{
|
||||
public:
|
||||
enum TYPE
|
||||
@ -437,48 +456,50 @@ public:
|
||||
VIRTUAL
|
||||
};
|
||||
|
||||
GraphNode( GraphNode::TYPE aType, CREEP_SHAPE* aParent, VECTOR2I aPos = VECTOR2I() )
|
||||
GRAPH_NODE( GRAPH_NODE::TYPE aType, CREEP_SHAPE* aParent, VECTOR2I aPos = VECTOR2I() )
|
||||
: m_parent( aParent ), m_pos( aPos ), m_type( aType )
|
||||
{
|
||||
m_parent = aParent;
|
||||
m_pos = aPos;
|
||||
m_type = aType;
|
||||
m_node_conns = {};
|
||||
m_virtual = false;
|
||||
m_connectDirectly = true;
|
||||
m_connections = {};
|
||||
m_net = -1;
|
||||
};
|
||||
|
||||
~GraphNode() {};
|
||||
~GRAPH_NODE() {};
|
||||
|
||||
|
||||
CREEP_SHAPE* m_parent = nullptr;
|
||||
std::vector<std::shared_ptr<GraphConnection>> m_connections = {};
|
||||
VECTOR2I m_pos = VECTOR2I( 0, 0 );
|
||||
CREEP_SHAPE* m_parent;
|
||||
std::set<std::shared_ptr<GRAPH_CONNECTION>> m_node_conns;
|
||||
VECTOR2I m_pos;
|
||||
|
||||
// Virtual nodes are connected with a 0 weight connection to equivalent net ( same net or netclass )
|
||||
bool m_virtual = false;
|
||||
bool m_connectDirectly = true;
|
||||
int m_net = -1;
|
||||
bool m_virtual ;
|
||||
bool m_connectDirectly;
|
||||
int m_net;
|
||||
|
||||
GraphNode::TYPE m_type;
|
||||
GRAPH_NODE::TYPE m_type;
|
||||
};
|
||||
|
||||
/** @class GraphConnection
|
||||
*
|
||||
* @brief a connection in a @class CreepageGraph
|
||||
*/
|
||||
class GraphConnection
|
||||
class GRAPH_CONNECTION
|
||||
{
|
||||
public:
|
||||
GraphConnection( std::shared_ptr<GraphNode>& aN1, std::shared_ptr<GraphNode>& aN2,
|
||||
const PATH_CONNECTION& aPc ) : n1( aN1 ), n2( aN2 )
|
||||
GRAPH_CONNECTION( std::shared_ptr<GRAPH_NODE>& aN1, std::shared_ptr<GRAPH_NODE>& aN2,
|
||||
const PATH_CONNECTION& aPc ) : n1( aN1 ), n2( aN2 )
|
||||
{
|
||||
m_path = aPc;
|
||||
m_forceStraightLine = false;
|
||||
};
|
||||
|
||||
std::shared_ptr<GraphNode> n1 = nullptr;
|
||||
std::shared_ptr<GraphNode> n2 = nullptr;
|
||||
PATH_CONNECTION m_path;
|
||||
|
||||
std::vector<PCB_SHAPE> GetShapes();
|
||||
bool forceStraightLigne = false;
|
||||
|
||||
std::shared_ptr<GRAPH_NODE> n1;
|
||||
std::shared_ptr<GRAPH_NODE> n2;
|
||||
PATH_CONNECTION m_path;
|
||||
bool m_forceStraightLine;
|
||||
};
|
||||
|
||||
|
||||
@ -497,20 +518,25 @@ public:
|
||||
|
||||
std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_POINT& aS2, double aMaxWeight,
|
||||
double aMaxSquaredWeight ) const override;
|
||||
|
||||
std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_CIRCLE& aS2, double aMaxWeight,
|
||||
double aMaxSquaredWeight ) const override;
|
||||
|
||||
std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_ARC& aS2, double aMaxWeight,
|
||||
double aMaxSquaredWeight ) const override;
|
||||
|
||||
std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_SEGMENT& aS2, double aMaxWeight,
|
||||
double aMaxSquaredWeight ) const override
|
||||
{
|
||||
return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
|
||||
};
|
||||
|
||||
std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_CIRCLE& aS2, double aMaxWeight,
|
||||
double aMaxSquaredWeight ) const override
|
||||
{
|
||||
return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
|
||||
}
|
||||
|
||||
std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_ARC& aS2, double aMaxWeight,
|
||||
double aMaxSquaredWeight ) const override
|
||||
{
|
||||
@ -518,8 +544,8 @@ public:
|
||||
};
|
||||
|
||||
|
||||
void ConnectChildren( std::shared_ptr<GraphNode>& a1, std::shared_ptr<GraphNode>& a2,
|
||||
CreepageGraph& aG ) const override;
|
||||
void ConnectChildren( std::shared_ptr<GRAPH_NODE>& a1, std::shared_ptr<GRAPH_NODE>& a2,
|
||||
CREEPAGE_GRAPH& aG ) const override;
|
||||
};
|
||||
|
||||
/** @class BE_SHAPE_CIRCLE
|
||||
@ -541,15 +567,19 @@ public:
|
||||
{
|
||||
return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
|
||||
};
|
||||
|
||||
std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_CIRCLE& aS2, double aMaxWeight,
|
||||
double aMaxSquaredWeight ) const override;
|
||||
|
||||
std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_ARC& aS2, double aMaxWeight,
|
||||
double aMaxSquaredWeight ) const override;
|
||||
|
||||
std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_SEGMENT& aS2, double aMaxWeight,
|
||||
double aMaxSquaredWeight ) const override
|
||||
{
|
||||
return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
|
||||
};
|
||||
|
||||
std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_CIRCLE& aS2, double aMaxWeight,
|
||||
double aMaxSquaredWeight ) const override
|
||||
{
|
||||
@ -558,10 +588,12 @@ public:
|
||||
|
||||
|
||||
int GetRadius() const override { return m_radius; }
|
||||
void ConnectChildren( std::shared_ptr<GraphNode>& a1, std::shared_ptr<GraphNode>& a2,
|
||||
CreepageGraph& aG ) const override;
|
||||
void ShortenChildDueToGV( std::shared_ptr<GraphNode>& a1, std::shared_ptr<GraphNode>& a2,
|
||||
CreepageGraph& aG, double aNormalWeight ) const;
|
||||
|
||||
void ConnectChildren( std::shared_ptr<GRAPH_NODE>& a1, std::shared_ptr<GRAPH_NODE>& a2,
|
||||
CREEPAGE_GRAPH& aG ) const override;
|
||||
|
||||
void ShortenChildDueToGV( std::shared_ptr<GRAPH_NODE>& a1, std::shared_ptr<GRAPH_NODE>& a2,
|
||||
CREEPAGE_GRAPH& aG, double aNormalWeight ) const;
|
||||
|
||||
|
||||
protected:
|
||||
@ -576,18 +608,16 @@ class BE_SHAPE_ARC : public BE_SHAPE_CIRCLE
|
||||
{
|
||||
public:
|
||||
BE_SHAPE_ARC( VECTOR2I aPos, int aRadius, EDA_ANGLE aStartAngle, EDA_ANGLE aEndAngle,
|
||||
VECTOR2D aStartPoint, VECTOR2D aEndPoint ) : BE_SHAPE_CIRCLE( aPos, aRadius )
|
||||
VECTOR2D aStartPoint, VECTOR2D aEndPoint ) :
|
||||
BE_SHAPE_CIRCLE( aPos, aRadius ),
|
||||
m_startAngle( aStartAngle ), m_endAngle( aEndAngle ),
|
||||
m_startPoint( aStartPoint ), m_endPoint( aEndPoint )
|
||||
{
|
||||
m_type = CREEP_SHAPE::TYPE::ARC;
|
||||
m_startAngle = aStartAngle;
|
||||
m_endAngle = aEndAngle;
|
||||
m_startPoint = aStartPoint;
|
||||
m_endPoint = aEndPoint;
|
||||
m_radius = aRadius;
|
||||
}
|
||||
|
||||
void ConnectChildren( std::shared_ptr<GraphNode>& a1, std::shared_ptr<GraphNode>& a2,
|
||||
CreepageGraph& aG ) const override;
|
||||
void ConnectChildren( std::shared_ptr<GRAPH_NODE>& a1, std::shared_ptr<GRAPH_NODE>& a2,
|
||||
CREEPAGE_GRAPH& aG ) const override;
|
||||
|
||||
|
||||
std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_POINT& aS2, double aMaxWeight,
|
||||
@ -642,7 +672,6 @@ public:
|
||||
std::pair<bool, bool> IsThereATangentPassingThroughPoint( const BE_SHAPE_POINT aPoint ) const;
|
||||
|
||||
protected:
|
||||
int m_radius;
|
||||
EDA_ANGLE m_startAngle;
|
||||
EDA_ANGLE m_endAngle;
|
||||
VECTOR2I m_startPoint;
|
||||
@ -654,16 +683,18 @@ protected:
|
||||
*
|
||||
* @brief A graph with nodes and connections for creepage calculation
|
||||
*/
|
||||
class CreepageGraph
|
||||
class CREEPAGE_GRAPH
|
||||
{
|
||||
public:
|
||||
CreepageGraph( BOARD& aBoard ) : m_board( aBoard )
|
||||
CREEPAGE_GRAPH( BOARD& aBoard ) : m_board( aBoard )
|
||||
{
|
||||
m_boardOutline = nullptr;
|
||||
m_minGrooveWidth = 0;
|
||||
m_creepageTarget = -1;
|
||||
m_creepageTargetSquared = -1;
|
||||
};
|
||||
~CreepageGraph()
|
||||
|
||||
~CREEPAGE_GRAPH()
|
||||
{
|
||||
for( CREEP_SHAPE* cs : m_shapeCollection )
|
||||
if( cs )
|
||||
@ -673,46 +704,73 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
BOARD& m_board;
|
||||
std::vector<BOARD_ITEM*> m_boardEdge;
|
||||
SHAPE_POLY_SET* m_boardOutline;
|
||||
|
||||
std::vector<std::shared_ptr<GraphNode>> m_nodes;
|
||||
std::vector<std::shared_ptr<GraphConnection>> m_connections;
|
||||
|
||||
|
||||
void TransformEdgeToCreepShapes();
|
||||
void TransformCreepShapesToNodes( std::vector<CREEP_SHAPE*>& aShapes );
|
||||
void TransformCreepShapesToNodes(std::vector<CREEP_SHAPE*>& aShapes);
|
||||
void RemoveDuplicatedShapes();
|
||||
|
||||
// Add a node to the graph. If an equivalent node exists, returns the pointer of the existing node instead
|
||||
std::shared_ptr<GraphNode> AddNode( GraphNode::TYPE aType, CREEP_SHAPE* aParent = nullptr,
|
||||
std::shared_ptr<GRAPH_NODE> AddNode( GRAPH_NODE::TYPE aType, CREEP_SHAPE* aParent = nullptr,
|
||||
VECTOR2I aPos = VECTOR2I() );
|
||||
std::shared_ptr<GraphNode> AddNodeVirtual();
|
||||
std::shared_ptr<GraphConnection> AddConnection( std::shared_ptr<GraphNode>& aN1,
|
||||
std::shared_ptr<GraphNode>& aN2,
|
||||
|
||||
std::shared_ptr<GRAPH_NODE> AddNodeVirtual();
|
||||
|
||||
std::shared_ptr<GRAPH_CONNECTION> AddConnection( std::shared_ptr<GRAPH_NODE>& aN1,
|
||||
std::shared_ptr<GRAPH_NODE>& aN2,
|
||||
const PATH_CONNECTION& aPc );
|
||||
std::shared_ptr<GraphConnection> AddConnection( std::shared_ptr<GraphNode>& aN1,
|
||||
std::shared_ptr<GraphNode>& aN2 );
|
||||
std::shared_ptr<GraphNode> FindNode( GraphNode::TYPE aType, CREEP_SHAPE* aParent,
|
||||
|
||||
std::shared_ptr<GRAPH_CONNECTION> AddConnection( std::shared_ptr<GRAPH_NODE>& aN1,
|
||||
std::shared_ptr<GRAPH_NODE>& aN2 );
|
||||
|
||||
std::shared_ptr<GRAPH_NODE> FindNode( GRAPH_NODE::TYPE aType, CREEP_SHAPE* aParent,
|
||||
VECTOR2I aPos );
|
||||
|
||||
void RemoveConnection( std::shared_ptr<GraphConnection>, bool aDelete = false );
|
||||
void RemoveConnection( std::shared_ptr<GRAPH_CONNECTION>, bool aDelete = false );
|
||||
|
||||
void Trim( double aWeightLimit );
|
||||
void Addshape( const SHAPE& aShape, std::shared_ptr<GraphNode>& aConnectTo,
|
||||
|
||||
void Addshape( const SHAPE& aShape, std::shared_ptr<GRAPH_NODE>& aConnectTo,
|
||||
BOARD_ITEM* aParent = nullptr );
|
||||
|
||||
double Solve( std::shared_ptr<GraphNode>& aFrom, std::shared_ptr<GraphNode>& aTo,
|
||||
std::vector<std::shared_ptr<GraphConnection>>& aResult );
|
||||
double Solve( std::shared_ptr<GRAPH_NODE>& aFrom, std::shared_ptr<GRAPH_NODE>& aTo,
|
||||
std::vector<std::shared_ptr<GRAPH_CONNECTION>>& aResult );
|
||||
|
||||
void GeneratePaths( double aMaxWeight, PCB_LAYER_ID aLayer, bool aGenerateBoardEdges = true );
|
||||
std::shared_ptr<GraphNode> AddNetElements( int aNetCode, PCB_LAYER_ID aLayer,
|
||||
void GeneratePaths( double aMaxWeight, PCB_LAYER_ID aLayer, bool aClearance );
|
||||
|
||||
std::shared_ptr<GRAPH_NODE> AddNetElements( int aNetCode, PCB_LAYER_ID aLayer,
|
||||
int aMaxCreepage );
|
||||
|
||||
void SetTarget( double aTarget );
|
||||
double GetTarget() { return m_creepageTarget; };
|
||||
int m_minGrooveWidth = 0;
|
||||
|
||||
std::vector<CREEP_SHAPE*> m_shapeCollection;
|
||||
|
||||
struct GraphNodeHash
|
||||
{
|
||||
std::size_t operator()(const std::shared_ptr<GRAPH_NODE>& node) const
|
||||
{
|
||||
return hash_val(node->m_type, node->m_parent, node->m_pos.x, node->m_pos.y);
|
||||
}
|
||||
};
|
||||
|
||||
struct GraphNodeEqual
|
||||
{
|
||||
bool operator()(const std::shared_ptr<GRAPH_NODE>& lhs, const std::shared_ptr<GRAPH_NODE>& rhs) const
|
||||
{
|
||||
return lhs->m_type == rhs->m_type && lhs->m_parent == rhs->m_parent && lhs->m_pos == rhs->m_pos;
|
||||
}
|
||||
};
|
||||
|
||||
BOARD& m_board;
|
||||
std::vector<BOARD_ITEM*> m_boardEdge;
|
||||
SHAPE_POLY_SET* m_boardOutline;
|
||||
std::vector<std::shared_ptr<GRAPH_NODE>> m_nodes;
|
||||
std::vector<std::shared_ptr<GRAPH_CONNECTION>> m_connections;
|
||||
std::vector<CREEP_SHAPE*> m_shapeCollection;
|
||||
|
||||
// This is a duplicate of m_nodes, but it is used to quickly find a node rather than iterating through m_nodes
|
||||
std::unordered_set<std::shared_ptr<GRAPH_NODE>, GraphNodeHash, GraphNodeEqual> m_nodeset;
|
||||
|
||||
int m_minGrooveWidth;
|
||||
|
||||
private:
|
||||
double m_creepageTarget;
|
||||
|
@ -92,9 +92,9 @@ void DRC_TEST_PROVIDER_CLEARANCE_BASE::ReportAndShowPathCuToCu(
|
||||
std::shared_ptr<DRC_ITEM>& aDrce, const VECTOR2I& aMarkerPos, int aMarkerLayer,
|
||||
const BOARD_ITEM* aItem1, const BOARD_ITEM* aItem2, PCB_LAYER_ID layer, int aDistance )
|
||||
{
|
||||
CreepageGraph graph( *m_board );
|
||||
std::shared_ptr<GraphNode> NetA = graph.AddNodeVirtual();
|
||||
std::shared_ptr<GraphNode> NetB = graph.AddNodeVirtual();
|
||||
CREEPAGE_GRAPH graph( *m_board );
|
||||
std::shared_ptr<GRAPH_NODE> NetA = graph.AddNodeVirtual();
|
||||
std::shared_ptr<GRAPH_NODE> NetB = graph.AddNodeVirtual();
|
||||
|
||||
// They need to be different or the algorithm won't compute the path.
|
||||
NetA->m_net = 1;
|
||||
@ -103,12 +103,12 @@ void DRC_TEST_PROVIDER_CLEARANCE_BASE::ReportAndShowPathCuToCu(
|
||||
graph.Addshape( *( aItem1->GetEffectiveShape( layer ) ), NetA, nullptr );
|
||||
graph.Addshape( *( aItem2->GetEffectiveShape( layer ) ), NetB, nullptr );
|
||||
|
||||
graph.GeneratePaths( aDistance * 2, layer );
|
||||
graph.GeneratePaths( aDistance * 2, layer, true );
|
||||
|
||||
double minValue = aDistance * 2;
|
||||
GraphConnection* minGc = nullptr;
|
||||
GRAPH_CONNECTION* minGc = nullptr;
|
||||
|
||||
for( std::shared_ptr<GraphConnection> gc : graph.m_connections )
|
||||
for( std::shared_ptr<GRAPH_CONNECTION> gc : graph.m_connections )
|
||||
{
|
||||
if( ( gc->m_path.weight < minValue ) && ( gc->m_path.weight > 0 ) )
|
||||
{
|
||||
@ -119,7 +119,7 @@ void DRC_TEST_PROVIDER_CLEARANCE_BASE::ReportAndShowPathCuToCu(
|
||||
|
||||
if( minGc )
|
||||
{
|
||||
PATH_CONNECTION pc = minGc->m_path;
|
||||
PATH_CONNECTION pc = minGc->m_path;
|
||||
DRC_CUSTOM_MARKER_HANDLER handler =
|
||||
GetGraphicsHandler( minGc->GetShapes(), pc.a1, pc.a2, aDistance );
|
||||
reportViolation( aDrce, aMarkerPos, aMarkerLayer, &handler );
|
||||
|
@ -64,10 +64,12 @@ public:
|
||||
|
||||
private:
|
||||
int testCreepage();
|
||||
int testCreepage( CreepageGraph& aGraph, int aNetCodeA, int aNetCodeB, PCB_LAYER_ID aLayer );
|
||||
int testCreepage( CREEPAGE_GRAPH& aGraph, int aNetCodeA, int aNetCodeB, PCB_LAYER_ID aLayer );
|
||||
|
||||
void CollectBoardEdges( std::vector<BOARD_ITEM*>& aVector );
|
||||
void CollectNetCodes( std::vector<int>& aVector );
|
||||
|
||||
std::set<std::pair<const BOARD_ITEM*, const BOARD_ITEM*>> m_reportedPairs;
|
||||
};
|
||||
|
||||
|
||||
@ -75,8 +77,6 @@ bool DRC_TEST_PROVIDER_CREEPAGE::Run()
|
||||
{
|
||||
m_board = m_drcEngine->GetBoard();
|
||||
|
||||
//int errorMax = m_board->GetDesignSettings().m_MaxError;
|
||||
|
||||
if( !m_drcEngine->IsErrorLimitExceeded( DRCE_CREEPAGE ) )
|
||||
{
|
||||
if( !reportPhase( _( "Checking creepage..." ) ) )
|
||||
@ -88,13 +88,13 @@ bool DRC_TEST_PROVIDER_CREEPAGE::Run()
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<GraphNode> FindInGraphNodes( std::shared_ptr<GraphNode> aNode,
|
||||
std::vector<std::shared_ptr<GraphNode>>& aGraph )
|
||||
std::shared_ptr<GRAPH_NODE> FindInGraphNodes( std::shared_ptr<GRAPH_NODE> aNode,
|
||||
std::vector<std::shared_ptr<GRAPH_NODE>>& aGraph )
|
||||
{
|
||||
if( !aNode )
|
||||
return nullptr;
|
||||
|
||||
for( std::shared_ptr<GraphNode> gn : aGraph )
|
||||
for( std::shared_ptr<GRAPH_NODE> gn : aGraph )
|
||||
{
|
||||
if( aNode->m_pos == gn->m_pos )
|
||||
{
|
||||
@ -105,7 +105,7 @@ std::shared_ptr<GraphNode> FindInGraphNodes( std::shared_ptr<GraphNode>
|
||||
}
|
||||
|
||||
|
||||
int DRC_TEST_PROVIDER_CREEPAGE::testCreepage( CreepageGraph& aGraph, int aNetCodeA, int aNetCodeB,
|
||||
int DRC_TEST_PROVIDER_CREEPAGE::testCreepage( CREEPAGE_GRAPH& aGraph, int aNetCodeA, int aNetCodeB,
|
||||
PCB_LAYER_ID aLayer )
|
||||
{
|
||||
PCB_TRACK bci1( m_board );
|
||||
@ -134,17 +134,23 @@ int DRC_TEST_PROVIDER_CREEPAGE::testCreepage( CreepageGraph& aGraph, int aNetCod
|
||||
if ( netA->GetBoundingBox().Distance( netB->GetBoundingBox() ) > creepageValue )
|
||||
return 0;
|
||||
|
||||
std::shared_ptr<GraphNode> NetA = aGraph.AddNetElements( aNetCodeA, aLayer, creepageValue );
|
||||
std::shared_ptr<GraphNode> NetB = aGraph.AddNetElements( aNetCodeB, aLayer, creepageValue );
|
||||
std::shared_ptr<GRAPH_NODE> NetA = aGraph.AddNetElements( aNetCodeA, aLayer, creepageValue );
|
||||
std::shared_ptr<GRAPH_NODE> NetB = aGraph.AddNetElements( aNetCodeB, aLayer, creepageValue );
|
||||
|
||||
|
||||
aGraph.GeneratePaths( creepageValue, aLayer );
|
||||
aGraph.GeneratePaths( creepageValue, aLayer, false );
|
||||
|
||||
std::vector<std::shared_ptr<GraphNode>> nodes1 = aGraph.m_nodes;
|
||||
std::vector<std::shared_ptr<GraphNode>> nodes2 = aGraph.m_nodes;
|
||||
std::vector<std::shared_ptr<GRAPH_NODE>> temp_nodes;
|
||||
|
||||
alg::for_all_pairs( aGraph.m_nodes.begin(), aGraph.m_nodes.end(),
|
||||
[&]( std::shared_ptr<GraphNode> aN1, std::shared_ptr<GraphNode> aN2 )
|
||||
std::copy_if( aGraph.m_nodes.begin(), aGraph.m_nodes.end(), std::back_inserter( temp_nodes ),
|
||||
[]( std::shared_ptr<GRAPH_NODE> aNode )
|
||||
{
|
||||
return !!aNode && aNode->m_parent && aNode->m_parent->IsConductive()
|
||||
&& aNode->m_connectDirectly && aNode->m_type == GRAPH_NODE::POINT;
|
||||
} );
|
||||
|
||||
alg::for_all_pairs( temp_nodes.begin(), temp_nodes.end(),
|
||||
[&]( std::shared_ptr<GRAPH_NODE> aN1, std::shared_ptr<GRAPH_NODE> aN2 )
|
||||
{
|
||||
if( aN1 == aN2 )
|
||||
return;
|
||||
@ -167,21 +173,20 @@ int DRC_TEST_PROVIDER_CREEPAGE::testCreepage( CreepageGraph& aGraph, int aNetCod
|
||||
|
||||
// We are only looking for points on circles and arcs
|
||||
|
||||
if( aN1->m_type != GraphNode::POINT )
|
||||
if( aN1->m_type != GRAPH_NODE::POINT )
|
||||
return;
|
||||
|
||||
if( aN2->m_type != GraphNode::POINT )
|
||||
if( aN2->m_type != GRAPH_NODE::POINT )
|
||||
return;
|
||||
|
||||
aN1->m_parent->ConnectChildren( aN1, aN2, aGraph );
|
||||
} );
|
||||
|
||||
std::vector<std::shared_ptr<GraphConnection>> shortestPath;
|
||||
std::vector<std::shared_ptr<GRAPH_CONNECTION>> shortestPath;
|
||||
shortestPath.clear();
|
||||
double distance = aGraph.Solve( NetA, NetB, shortestPath );
|
||||
|
||||
|
||||
if( ( shortestPath.size() > 0 ) && ( distance - creepageValue < 0 ) )
|
||||
if( !shortestPath.empty() && ( shortestPath.size() >= 4 ) && ( distance - creepageValue < 0 ) )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CREEPAGE );
|
||||
wxString msg = formatMsg( _( "(%s creepage %s; actual %s)" ), constraint.GetName(),
|
||||
@ -189,22 +194,27 @@ int DRC_TEST_PROVIDER_CREEPAGE::testCreepage( CreepageGraph& aGraph, int aNetCod
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
if( shortestPath.size() >= 4 && shortestPath[1]->n1 && shortestPath[1]->n2 )
|
||||
drce->SetItems( shortestPath[1]->n1->m_parent->GetParent(),
|
||||
shortestPath[shortestPath.size() - 2]->n2->m_parent->GetParent() );
|
||||
std::shared_ptr<GRAPH_CONNECTION> gc1 = shortestPath[1];
|
||||
std::shared_ptr<GRAPH_CONNECTION> gc2 = shortestPath[shortestPath.size() - 2];
|
||||
|
||||
if( gc1->n1 && gc2->n2 )
|
||||
{
|
||||
const BOARD_ITEM* item1 = gc1->n1->m_parent->GetParent();
|
||||
const BOARD_ITEM* item2 = gc2->n2->m_parent->GetParent();
|
||||
|
||||
if( m_reportedPairs.insert( std::make_pair( item1, item2 ) ).second )
|
||||
drce->SetItems( item1, item2 );
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::vector<PCB_SHAPE> shortestPathShapes1, shortestPathShapes2;
|
||||
|
||||
VECTOR2I startPoint = shortestPath[1]->m_path.a2;
|
||||
VECTOR2I endPoint = shortestPath[shortestPath.size() - 2]->m_path.a2;
|
||||
|
||||
PCB_SHAPE s;
|
||||
s.SetStart( startPoint );
|
||||
s.SetEnd( endPoint );
|
||||
|
||||
|
||||
VECTOR2I startPoint = gc1->m_path.a2;
|
||||
VECTOR2I endPoint = gc2->m_path.a2;
|
||||
std::vector<PCB_SHAPE> path;
|
||||
for( std::shared_ptr<GraphConnection> gc : shortestPath )
|
||||
|
||||
for( std::shared_ptr<GRAPH_CONNECTION> gc : shortestPath )
|
||||
{
|
||||
if( !gc )
|
||||
continue;
|
||||
@ -217,11 +227,10 @@ int DRC_TEST_PROVIDER_CREEPAGE::testCreepage( CreepageGraph& aGraph, int aNetCod
|
||||
}
|
||||
}
|
||||
|
||||
DRC_CUSTOM_MARKER_HANDLER graphicsHandler =
|
||||
GetGraphicsHandler( path, startPoint, endPoint, distance );
|
||||
reportViolation( drce, shortestPath[1]->m_path.a2, aLayer, &graphicsHandler );
|
||||
DRC_CUSTOM_MARKER_HANDLER handler = GetGraphicsHandler( path, startPoint, endPoint, distance );
|
||||
reportViolation( drce, gc1->m_path.a2, aLayer, &handler );
|
||||
|
||||
}
|
||||
shortestPath.clear();
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -336,7 +345,7 @@ int DRC_TEST_PROVIDER_CREEPAGE::testCreepage()
|
||||
return -1;
|
||||
|
||||
const DRAWINGS drawings = m_board->Drawings();
|
||||
CreepageGraph graph( *m_board );
|
||||
CREEPAGE_GRAPH graph( *m_board );
|
||||
|
||||
|
||||
if( ADVANCED_CFG::GetCfg().m_EnableCreepageSlot )
|
||||
@ -355,23 +364,30 @@ int DRC_TEST_PROVIDER_CREEPAGE::testCreepage()
|
||||
graph.RemoveDuplicatedShapes();
|
||||
graph.TransformCreepShapesToNodes( graph.m_shapeCollection );
|
||||
|
||||
graph.GeneratePaths( maxConstraint, Edge_Cuts );
|
||||
graph.GeneratePaths( maxConstraint, Edge_Cuts, false );
|
||||
|
||||
|
||||
int beNodeSize = graph.m_nodes.size();
|
||||
int beConnectionsSize = graph.m_connections.size();
|
||||
int beNodeSize = graph.m_nodes.size();
|
||||
int beConnectionsSize = graph.m_connections.size();
|
||||
bool prevTestChangedGraph = false;
|
||||
|
||||
size_t current = 0;
|
||||
size_t total =
|
||||
( netcodes.size() * ( netcodes.size() - 1 ) ) / 2 * m_board->GetCopperLayerCount();
|
||||
|
||||
alg::for_all_pairs( netcodes.begin(), netcodes.end(),
|
||||
[&]( int aNet1, int aNet2 )
|
||||
{
|
||||
if( aNet1 == aNet2 )
|
||||
return;
|
||||
|
||||
for( PCB_LAYER_ID layer : LSET::AllCuMask().CuStack() )
|
||||
for( auto it = m_board->GetLayerSet().copper_layers_begin();
|
||||
it != m_board->GetLayerSet().copper_layers_end();
|
||||
++it )
|
||||
{
|
||||
if( !m_board->IsLayerEnabled( layer ) )
|
||||
continue;
|
||||
PCB_LAYER_ID layer = *it;
|
||||
|
||||
reportProgress( current++, total );
|
||||
|
||||
if ( prevTestChangedGraph )
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user