When dragging a via, we need to get all obstacles
The clearance epsilon should not be used to limit which force elements
we return in the query. Otherwise, we can drag elements into a
DRC-violating space
Fixes https://gitlab.com/kicad/code/kicad/-/issues/16293
(cherry picked from commit 5e850911c5
)
This commit is contained in:
parent
892c5726f5
commit
6b5acdea1f
|
@ -191,6 +191,9 @@ bool ITEM::collideSimple( const ITEM* aHead, const NODE* aNode,
|
|||
}
|
||||
else
|
||||
{
|
||||
if( aCtx && !aCtx->options.m_useClearanceEpsilon )
|
||||
clearanceEpsilon = 0;
|
||||
|
||||
clearance = aNode->GetClearance( this, aHead, aCtx ? aCtx->options.m_useClearanceEpsilon
|
||||
: false );
|
||||
}
|
||||
|
|
|
@ -409,12 +409,18 @@ NODE::OPT_OBSTACLE NODE::CheckColliding( const ITEM_SET& aSet, int aKindMask )
|
|||
|
||||
NODE::OPT_OBSTACLE NODE::CheckColliding( const ITEM* aItemA, int aKindMask )
|
||||
{
|
||||
OBSTACLES obs;
|
||||
COLLISION_SEARCH_OPTIONS opts;
|
||||
|
||||
opts.m_kindMask = aKindMask;
|
||||
opts.m_limitCount = 1;
|
||||
|
||||
return CheckColliding( aItemA, opts );
|
||||
}
|
||||
|
||||
NODE::OPT_OBSTACLE NODE::CheckColliding( const ITEM* aItemA, const COLLISION_SEARCH_OPTIONS& aOpts )
|
||||
{
|
||||
OBSTACLES obs;
|
||||
|
||||
if( aItemA->Kind() == ITEM::LINE_T )
|
||||
{
|
||||
int n = 0;
|
||||
|
@ -428,7 +434,7 @@ NODE::OPT_OBSTACLE NODE::CheckColliding( const ITEM* aItemA, int aKindMask )
|
|||
// Disabling the cache will lead to slowness.
|
||||
|
||||
const SEGMENT s( *line, l.CSegment( i ) );
|
||||
n += QueryColliding( &s, obs, opts );
|
||||
n += QueryColliding( &s, obs, aOpts );
|
||||
|
||||
if( n )
|
||||
return OPT_OBSTACLE( *obs.begin() );
|
||||
|
@ -436,13 +442,13 @@ NODE::OPT_OBSTACLE NODE::CheckColliding( const ITEM* aItemA, int aKindMask )
|
|||
|
||||
if( line->EndsWithVia() )
|
||||
{
|
||||
n += QueryColliding( &line->Via(), obs, opts );
|
||||
n += QueryColliding( &line->Via(), obs, aOpts );
|
||||
|
||||
if( n )
|
||||
return OPT_OBSTACLE( *obs.begin() );
|
||||
}
|
||||
}
|
||||
else if( QueryColliding( aItemA, obs, opts ) > 0 )
|
||||
else if( QueryColliding( aItemA, obs, aOpts ) > 0 )
|
||||
{
|
||||
return OPT_OBSTACLE( *obs.begin() );
|
||||
}
|
||||
|
|
|
@ -279,8 +279,7 @@ public:
|
|||
* starting point.
|
||||
*
|
||||
* @param aLine the item to find collisions with
|
||||
* @param aKindMask mask of obstacle types to take into account
|
||||
* @param aRestrictedSet is an optional set of items that should be considered as obstacles
|
||||
* @param aOpts options for the search
|
||||
* @return the obstacle, if found, otherwise empty.
|
||||
*/
|
||||
OPT_OBSTACLE NearestObstacle( const LINE* aLine,
|
||||
|
@ -307,6 +306,16 @@ public:
|
|||
*/
|
||||
OPT_OBSTACLE CheckColliding( const ITEM_SET& aSet, int aKindMask = ITEM::ANY_T );
|
||||
|
||||
/**
|
||||
* Check if the item collides with anything else in the world, and if found, returns the
|
||||
* obstacle.
|
||||
*
|
||||
* @param aItem the item to find collisions with
|
||||
* @param aOpts options for the search
|
||||
* @return the obstacle, if found, otherwise empty.
|
||||
*/
|
||||
OPT_OBSTACLE CheckColliding( const ITEM* aItem, const COLLISION_SEARCH_OPTIONS& aOpts );
|
||||
|
||||
/**
|
||||
* Find all items that contain the point \a aPoint.
|
||||
*
|
||||
|
|
|
@ -61,7 +61,12 @@ bool VIA::PushoutForce( NODE* aNode, const VECTOR2I& aDirection, VECTOR2I& aForc
|
|||
|
||||
while( iter < aMaxIterations )
|
||||
{
|
||||
NODE::OPT_OBSTACLE obs = aNode->CheckColliding( &mv, aCollisionMask );
|
||||
COLLISION_SEARCH_OPTIONS opt;
|
||||
opt.m_limitCount = 1;
|
||||
opt.m_kindMask = aCollisionMask;
|
||||
opt.m_useClearanceEpsilon = false;
|
||||
|
||||
NODE::OPT_OBSTACLE obs = aNode->CheckColliding( &mv, opt );
|
||||
|
||||
if( !obs )
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue