Performance SCH_EDIT_FRAME::SchematicCleanUp
Avoid O(N^2) comparisonis by spatial presorting. If bounding boxes don't overlap there's no need to run expensive checks.
This commit is contained in:
parent
5900f6baa4
commit
f3c2083018
|
@ -186,6 +186,28 @@ void SCH_EDIT_FRAME::SchematicCleanUp( SCH_COMMIT* aCommit, SCH_SCREEN* aScreen
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
|
||||||
|
auto minX = []( const SCH_LINE* l )
|
||||||
|
{
|
||||||
|
return std::min( l->GetStartPoint().x, l->GetEndPoint().x );
|
||||||
|
};
|
||||||
|
|
||||||
|
auto maxX = []( const SCH_LINE* l )
|
||||||
|
{
|
||||||
|
return std::max( l->GetStartPoint().x, l->GetEndPoint().x );
|
||||||
|
};
|
||||||
|
|
||||||
|
auto minY = []( const SCH_LINE* l )
|
||||||
|
{
|
||||||
|
return std::min( l->GetStartPoint().y, l->GetEndPoint().y );
|
||||||
|
};
|
||||||
|
|
||||||
|
auto maxY = []( const SCH_LINE* l )
|
||||||
|
{
|
||||||
|
return std::max( l->GetStartPoint().y, l->GetEndPoint().y );
|
||||||
|
};
|
||||||
|
|
||||||
|
// Would be nice to put lines in a canonical form here by swapping
|
||||||
|
// start <-> end as needed but I don't know what swapping breaks.
|
||||||
while( changed )
|
while( changed )
|
||||||
{
|
{
|
||||||
changed = false;
|
changed = false;
|
||||||
|
@ -197,6 +219,13 @@ void SCH_EDIT_FRAME::SchematicCleanUp( SCH_COMMIT* aCommit, SCH_SCREEN* aScreen
|
||||||
lines.push_back( static_cast<SCH_LINE*>( item ) );
|
lines.push_back( static_cast<SCH_LINE*>( item ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sort by minimum X position
|
||||||
|
std::sort( lines.begin(), lines.end(),
|
||||||
|
[&]( const SCH_LINE* a, const SCH_LINE* b )
|
||||||
|
{
|
||||||
|
return minX( a ) < minX( b );
|
||||||
|
} );
|
||||||
|
|
||||||
for( auto it1 = lines.begin(); it1 != lines.end(); ++it1 )
|
for( auto it1 = lines.begin(); it1 != lines.end(); ++it1 )
|
||||||
{
|
{
|
||||||
SCH_LINE* firstLine = *it1;
|
SCH_LINE* firstLine = *it1;
|
||||||
|
@ -210,11 +239,24 @@ void SCH_EDIT_FRAME::SchematicCleanUp( SCH_COMMIT* aCommit, SCH_SCREEN* aScreen
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int firstRightXEdge = maxX( firstLine );
|
||||||
auto it2 = it1;
|
auto it2 = it1;
|
||||||
|
|
||||||
for( ++it2; it2 != lines.end(); ++it2 )
|
for( ++it2; it2 != lines.end(); ++it2 )
|
||||||
{
|
{
|
||||||
SCH_LINE* secondLine = *it2;
|
SCH_LINE* secondLine = *it2;
|
||||||
|
int secondLeftXEdge = minX( secondLine );
|
||||||
|
|
||||||
|
// impossible to overlap remaining lines
|
||||||
|
if( secondLeftXEdge > firstRightXEdge )
|
||||||
|
break;
|
||||||
|
|
||||||
|
// No Y axis overlap
|
||||||
|
if( !( std::max( minY( firstLine ), minY( secondLine ) )
|
||||||
|
<= std::min( maxY( firstLine ), maxY( secondLine ) ) ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if( secondLine->GetFlags() & STRUCT_DELETED )
|
if( secondLine->GetFlags() & STRUCT_DELETED )
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Reference in New Issue