Improve feedback when routing in highlight collisions mode.
In particular, when Allow DRC violations is NOT turned on and we bump in to an obstacle.
This commit is contained in:
parent
44b2c907c6
commit
fc1b0ec11f
|
@ -60,13 +60,13 @@ bool ITEM::collideSimple( const ITEM* aOther, const NODE* aNode, bool aDifferent
|
||||||
|
|
||||||
if( holeA && holeA->Collide( shapeB, holeClearance + lineWidthB ) )
|
if( holeA && holeA->Collide( shapeB, holeClearance + lineWidthB ) )
|
||||||
{
|
{
|
||||||
Mark( MK_HOLE );
|
Mark( Marker() | MK_HOLE );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( holeB && holeB->Collide( shapeA, holeClearance + lineWidthA ) )
|
if( holeB && holeB->Collide( shapeA, holeClearance + lineWidthA ) )
|
||||||
{
|
{
|
||||||
aOther->Mark( MK_HOLE );
|
aOther->Mark( aOther->Marker() | MK_HOLE );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,8 +76,8 @@ bool ITEM::collideSimple( const ITEM* aOther, const NODE* aNode, bool aDifferent
|
||||||
|
|
||||||
if( holeA->Collide( holeB, holeToHoleClearance ) )
|
if( holeA->Collide( holeB, holeToHoleClearance ) )
|
||||||
{
|
{
|
||||||
Mark( MK_HOLE );
|
Mark( Marker() | MK_HOLE );
|
||||||
aOther->Mark( MK_HOLE );
|
aOther->Mark( aOther->Marker() | MK_HOLE );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ LINE::LINE( const LINE& aOther )
|
||||||
m_hasVia = aOther.m_hasVia;
|
m_hasVia = aOther.m_hasVia;
|
||||||
m_marker = aOther.m_marker;
|
m_marker = aOther.m_marker;
|
||||||
m_rank = aOther.m_rank;
|
m_rank = aOther.m_rank;
|
||||||
|
m_blockingObstacle = aOther.m_blockingObstacle;
|
||||||
|
|
||||||
copyLinks( &aOther );
|
copyLinks( &aOther );
|
||||||
}
|
}
|
||||||
|
@ -70,6 +71,7 @@ LINE& LINE::operator=( const LINE& aOther )
|
||||||
m_rank = aOther.m_rank;
|
m_rank = aOther.m_rank;
|
||||||
m_owner = aOther.m_owner;
|
m_owner = aOther.m_owner;
|
||||||
m_snapThreshhold = aOther.m_snapThreshhold;
|
m_snapThreshhold = aOther.m_snapThreshhold;
|
||||||
|
m_blockingObstacle = aOther.m_blockingObstacle;
|
||||||
|
|
||||||
copyLinks( &aOther );
|
copyLinks( &aOther );
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,8 @@ public:
|
||||||
* Makes an empty line.
|
* Makes an empty line.
|
||||||
*/
|
*/
|
||||||
LINE() :
|
LINE() :
|
||||||
LINK_HOLDER( LINE_T )
|
LINK_HOLDER( LINE_T ),
|
||||||
|
m_blockingObstacle( nullptr )
|
||||||
{
|
{
|
||||||
m_hasVia = false;
|
m_hasVia = false;
|
||||||
m_width = 1; // Dummy value
|
m_width = 1; // Dummy value
|
||||||
|
@ -86,7 +87,8 @@ public:
|
||||||
LINK_HOLDER( aBase ),
|
LINK_HOLDER( aBase ),
|
||||||
m_line( aLine ),
|
m_line( aLine ),
|
||||||
m_width( aBase.m_width ),
|
m_width( aBase.m_width ),
|
||||||
m_snapThreshhold( aBase.m_snapThreshhold )
|
m_snapThreshhold( aBase.m_snapThreshhold ),
|
||||||
|
m_blockingObstacle( nullptr )
|
||||||
{
|
{
|
||||||
m_net = aBase.m_net;
|
m_net = aBase.m_net;
|
||||||
m_layers = aBase.m_layers;
|
m_layers = aBase.m_layers;
|
||||||
|
@ -99,7 +101,8 @@ public:
|
||||||
* @param aVia
|
* @param aVia
|
||||||
*/
|
*/
|
||||||
LINE( const VIA& aVia ) :
|
LINE( const VIA& aVia ) :
|
||||||
LINK_HOLDER( LINE_T )
|
LINK_HOLDER( LINE_T ),
|
||||||
|
m_blockingObstacle( nullptr )
|
||||||
{
|
{
|
||||||
m_hasVia = true;
|
m_hasVia = true;
|
||||||
m_via = aVia;
|
m_via = aVia;
|
||||||
|
@ -204,6 +207,9 @@ public:
|
||||||
virtual void Unmark( int aMarker = -1 ) const override;
|
virtual void Unmark( int aMarker = -1 ) const override;
|
||||||
virtual int Marker() const override;
|
virtual int Marker() const override;
|
||||||
|
|
||||||
|
void SetBlockingObstacle( ITEM* aObstacle ) { m_blockingObstacle = aObstacle; }
|
||||||
|
ITEM* GetBlockingObstacle() const { return m_blockingObstacle; }
|
||||||
|
|
||||||
void DragSegment( const VECTOR2I& aP, int aIndex, bool aFreeAngle = false );
|
void DragSegment( const VECTOR2I& aP, int aIndex, bool aFreeAngle = false );
|
||||||
void DragCorner( const VECTOR2I& aP, int aIndex, bool aFreeAngle = false );
|
void DragCorner( const VECTOR2I& aP, int aIndex, bool aFreeAngle = false );
|
||||||
|
|
||||||
|
@ -214,7 +220,6 @@ public:
|
||||||
bool HasLockedSegments() const;
|
bool HasLockedSegments() const;
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
void Merge ( const LINE& aOther );
|
|
||||||
|
|
||||||
OPT_BOX2I ChangedArea( const LINE* aOther ) const;
|
OPT_BOX2I ChangedArea( const LINE* aOther ) const;
|
||||||
|
|
||||||
|
@ -240,14 +245,16 @@ private:
|
||||||
VECTOR2I snapDraggedCorner( const SHAPE_LINE_CHAIN& aPath, const VECTOR2I& aP,
|
VECTOR2I snapDraggedCorner( const SHAPE_LINE_CHAIN& aPath, const VECTOR2I& aP,
|
||||||
int aIndex ) const;
|
int aIndex ) const;
|
||||||
|
|
||||||
SHAPE_LINE_CHAIN m_line; ///> The actual shape of the line
|
SHAPE_LINE_CHAIN m_line; ///> The actual shape of the line.
|
||||||
int m_width; ///> our width
|
int m_width; ///> Our width.
|
||||||
|
|
||||||
|
|
||||||
int m_snapThreshhold; ///> Width to smooth out jagged segments
|
int m_snapThreshhold; ///> Width to smooth out jagged segments.
|
||||||
|
|
||||||
bool m_hasVia; ///> Optional via at the end point
|
bool m_hasVia; ///> Optional via at the end point.
|
||||||
VIA m_via;
|
VIA m_via;
|
||||||
|
|
||||||
|
ITEM* m_blockingObstacle; ///> For mark obstacle mode.
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -479,6 +479,7 @@ bool LINE_PLACER::rhWalkOnly( const VECTOR2I& aP, LINE& aNewHead )
|
||||||
bool LINE_PLACER::rhMarkObstacles( const VECTOR2I& aP, LINE& aNewHead )
|
bool LINE_PLACER::rhMarkObstacles( const VECTOR2I& aP, LINE& aNewHead )
|
||||||
{
|
{
|
||||||
buildInitialLine( aP, m_head );
|
buildInitialLine( aP, m_head );
|
||||||
|
m_head.SetBlockingObstacle( nullptr );
|
||||||
|
|
||||||
// If we are enforcing DRC violations, push back to the hull
|
// If we are enforcing DRC violations, push back to the hull
|
||||||
if( !Settings().CanViolateDRC() )
|
if( !Settings().CanViolateDRC() )
|
||||||
|
@ -486,7 +487,10 @@ bool LINE_PLACER::rhMarkObstacles( const VECTOR2I& aP, LINE& aNewHead )
|
||||||
NODE::OPT_OBSTACLE obs = m_currentNode->NearestObstacle( &m_head );
|
NODE::OPT_OBSTACLE obs = m_currentNode->NearestObstacle( &m_head );
|
||||||
|
|
||||||
if( obs && obs->m_distFirst != INT_MAX )
|
if( obs && obs->m_distFirst != INT_MAX )
|
||||||
|
{
|
||||||
buildInitialLine( obs->m_ipFirst, m_head );
|
buildInitialLine( obs->m_ipFirst, m_head );
|
||||||
|
m_head.SetBlockingObstacle( obs->m_item );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
aNewHead = m_head;
|
aNewHead = m_head;
|
||||||
|
@ -495,103 +499,6 @@ bool LINE_PLACER::rhMarkObstacles( const VECTOR2I& aP, LINE& aNewHead )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const LINE LINE_PLACER::reduceToNearestObstacle( const LINE& aOriginalLine )
|
|
||||||
{
|
|
||||||
const auto& l0 = aOriginalLine.CLine();
|
|
||||||
|
|
||||||
if ( !l0.PointCount() )
|
|
||||||
return aOriginalLine;
|
|
||||||
|
|
||||||
int l = l0.Length();
|
|
||||||
int step = l / 2;
|
|
||||||
VECTOR2I target;
|
|
||||||
|
|
||||||
LINE l_test( aOriginalLine );
|
|
||||||
|
|
||||||
while( step > 0 )
|
|
||||||
{
|
|
||||||
target = l0.PointAlong( l );
|
|
||||||
SHAPE_LINE_CHAIN l_cur( l0 );
|
|
||||||
|
|
||||||
int index = l_cur.Split( target );
|
|
||||||
|
|
||||||
l_test.SetShape( l_cur.Slice( 0, index ) );
|
|
||||||
|
|
||||||
if ( m_currentNode->CheckColliding( &l_test ) )
|
|
||||||
l -= step;
|
|
||||||
else
|
|
||||||
l += step;
|
|
||||||
|
|
||||||
step /= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
l = l_test.CLine().Length();
|
|
||||||
|
|
||||||
while( m_currentNode->CheckColliding( &l_test ) && l > 0 )
|
|
||||||
{
|
|
||||||
l--;
|
|
||||||
target = l0.PointAlong( l );
|
|
||||||
SHAPE_LINE_CHAIN l_cur( l0 );
|
|
||||||
|
|
||||||
int index = l_cur.Split( target );
|
|
||||||
|
|
||||||
l_test.SetShape( l_cur.Slice( 0, index ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
return l_test;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool LINE_PLACER::rhStopAtNearestObstacle( const VECTOR2I& aP, LINE& aNewHead )
|
|
||||||
{
|
|
||||||
LINE l0;
|
|
||||||
l0 = m_head;
|
|
||||||
|
|
||||||
buildInitialLine( aP, l0 );
|
|
||||||
|
|
||||||
LINE l_cur = reduceToNearestObstacle( l0 );
|
|
||||||
|
|
||||||
const SHAPE_LINE_CHAIN l_shape = l_cur.CLine();
|
|
||||||
|
|
||||||
if( l_shape.SegmentCount() == 0 )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if( l_shape.SegmentCount() == 1 )
|
|
||||||
{
|
|
||||||
SEG s = l_shape.CSegment( 0 );
|
|
||||||
|
|
||||||
VECTOR2I dL( DIRECTION_45( s ).Left().ToVector() );
|
|
||||||
VECTOR2I dR( DIRECTION_45( s ).Right().ToVector() );
|
|
||||||
|
|
||||||
SEG leadL( s.B, s.B + dL );
|
|
||||||
SEG leadR( s.B, s.B + dR );
|
|
||||||
|
|
||||||
SEG segL( s.B, leadL.LineProject( aP ) );
|
|
||||||
SEG segR( s.B, leadR.LineProject( aP ) );
|
|
||||||
|
|
||||||
LINE finishL( l0, SHAPE_LINE_CHAIN( { segL.A, segL.B } ) );
|
|
||||||
LINE finishR( l0, SHAPE_LINE_CHAIN( { segR.A, segR.B } ) );
|
|
||||||
|
|
||||||
LINE reducedL = reduceToNearestObstacle( finishL );
|
|
||||||
LINE reducedR = reduceToNearestObstacle( finishR );
|
|
||||||
|
|
||||||
int lL = reducedL.CLine().Length();
|
|
||||||
int lR = reducedR.CLine().Length();
|
|
||||||
|
|
||||||
if( lL > lR )
|
|
||||||
l_cur.Line().Append( reducedL.CLine() );
|
|
||||||
else
|
|
||||||
l_cur.Line().Append( reducedR.CLine() );
|
|
||||||
|
|
||||||
l_cur.Line().Simplify();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_head = l_cur;
|
|
||||||
aNewHead = m_head;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool LINE_PLACER::rhShoveOnly( const VECTOR2I& aP, LINE& aNewHead )
|
bool LINE_PLACER::rhShoveOnly( const VECTOR2I& aP, LINE& aNewHead )
|
||||||
{
|
{
|
||||||
LINE initTrack( m_head );
|
LINE initTrack( m_head );
|
||||||
|
|
|
@ -404,11 +404,6 @@ private:
|
||||||
*/
|
*/
|
||||||
void routeStep( const VECTOR2I& aP );
|
void routeStep( const VECTOR2I& aP );
|
||||||
|
|
||||||
const LINE reduceToNearestObstacle( const LINE& aOriginalLine );
|
|
||||||
|
|
||||||
bool rhStopAtNearestObstacle( const VECTOR2I& aP, LINE& aNewHead );
|
|
||||||
|
|
||||||
|
|
||||||
///> route step, walkaround mode
|
///> route step, walkaround mode
|
||||||
bool rhWalkOnly( const VECTOR2I& aP, LINE& aNewHead);
|
bool rhWalkOnly( const VECTOR2I& aP, LINE& aNewHead);
|
||||||
|
|
||||||
|
|
|
@ -333,8 +333,8 @@ NODE::OPT_OBSTACLE NODE::NearestObstacle( const LINE* aLine, int aKindMask,
|
||||||
if( aLine->EndsWithVia() )
|
if( aLine->EndsWithVia() )
|
||||||
{
|
{
|
||||||
const VIA& via = aLine->Via();
|
const VIA& via = aLine->Via();
|
||||||
int viaClearance = GetClearance( obstacle.m_item, &via );
|
int viaClearance = GetClearance( obstacle.m_item, &via );
|
||||||
int holeClearance = GetHoleClearance( obstacle.m_item, &via );
|
int holeClearance = GetHoleClearance( obstacle.m_item, &via );
|
||||||
|
|
||||||
if( holeClearance + via.Drill() / 2 > viaClearance + via.Diameter() / 2 )
|
if( holeClearance + via.Drill() / 2 > viaClearance + via.Diameter() / 2 )
|
||||||
viaClearance = holeClearance + via.Drill() / 2 - via.Diameter() / 2;
|
viaClearance = holeClearance + via.Drill() / 2 - via.Diameter() / 2;
|
||||||
|
@ -396,6 +396,7 @@ NODE::OPT_OBSTACLE NODE::NearestObstacle( const LINE* aLine, int aKindMask,
|
||||||
{
|
{
|
||||||
int dist = aLine->CLine().Length() + ( ip.p - via.Pos() ).EuclideanNorm();
|
int dist = aLine->CLine().Length() + ( ip.p - via.Pos() ).EuclideanNorm();
|
||||||
updateNearest( dist, ip.p, obstacle.m_item, obstacleHull );
|
updateNearest( dist, ip.p, obstacle.m_item, obstacleHull );
|
||||||
|
obstacle.m_item->Mark( obstacle.m_item->Marker() | MK_HOLE );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,6 +407,7 @@ NODE::OPT_OBSTACLE NODE::NearestObstacle( const LINE* aLine, int aKindMask,
|
||||||
{
|
{
|
||||||
int dist = aLine->CLine().PathLength( ip.p );
|
int dist = aLine->CLine().PathLength( ip.p );
|
||||||
updateNearest( dist, ip.p, obstacle.m_item, obstacleHull );
|
updateNearest( dist, ip.p, obstacle.m_item, obstacleHull );
|
||||||
|
obstacle.m_item->Mark( obstacle.m_item->Marker() | MK_HOLE );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -289,6 +289,24 @@ void ROUTER::moveDragging( const VECTOR2I& aP, ITEM* aEndItem )
|
||||||
|
|
||||||
void ROUTER::markViolations( NODE* aNode, ITEM_SET& aCurrent, NODE::ITEM_VECTOR& aRemoved )
|
void ROUTER::markViolations( NODE* aNode, ITEM_SET& aCurrent, NODE::ITEM_VECTOR& aRemoved )
|
||||||
{
|
{
|
||||||
|
auto updateItem =
|
||||||
|
[&]( ITEM* currentItem, ITEM* itemToMark )
|
||||||
|
{
|
||||||
|
std::unique_ptr<ITEM> tmp( itemToMark->Clone() );
|
||||||
|
int clearance;
|
||||||
|
|
||||||
|
if( itemToMark->Marker() & MK_HOLE )
|
||||||
|
clearance = aNode->GetHoleClearance( currentItem, itemToMark );
|
||||||
|
else
|
||||||
|
clearance = aNode->GetClearance( currentItem, itemToMark );
|
||||||
|
|
||||||
|
m_iface->DisplayItem( tmp.get(), -1, clearance );
|
||||||
|
|
||||||
|
// Remove the obstacle itself from the view unless we're just marking its hole
|
||||||
|
if( itemToMark->Marker() & MK_HOLE )
|
||||||
|
aRemoved.push_back( itemToMark );
|
||||||
|
};
|
||||||
|
|
||||||
for( ITEM* item : aCurrent.Items() )
|
for( ITEM* item : aCurrent.Items() )
|
||||||
{
|
{
|
||||||
NODE::OBSTACLES obstacles;
|
NODE::OBSTACLES obstacles;
|
||||||
|
@ -308,17 +326,17 @@ void ROUTER::markViolations( NODE* aNode, ITEM_SET& aCurrent, NODE::ITEM_VECTOR&
|
||||||
|
|
||||||
for( OBSTACLE& obs : obstacles )
|
for( OBSTACLE& obs : obstacles )
|
||||||
{
|
{
|
||||||
int clearance;
|
obs.m_item->Mark( obs.m_item->Marker() | MK_VIOLATION );
|
||||||
|
updateItem( item, obs.m_item );
|
||||||
|
}
|
||||||
|
|
||||||
if( ( obs.m_item->Marker() & MK_HOLE ) > 0 )
|
if( item->Kind() == ITEM::LINE_T )
|
||||||
clearance = aNode->GetHoleClearance( item, obs.m_item );
|
{
|
||||||
else
|
LINE* line = static_cast<LINE*>( item );
|
||||||
clearance = aNode->GetClearance( item, obs.m_item );
|
|
||||||
|
|
||||||
std::unique_ptr<ITEM> tmp( obs.m_item->Clone() );
|
// Show clearance on any blocking obstacles
|
||||||
tmp->Mark( tmp->Marker() | MK_VIOLATION );
|
if( line->GetBlockingObstacle() )
|
||||||
m_iface->DisplayItem( tmp.get(), -1, clearance );
|
updateItem( item, line->GetBlockingObstacle() );
|
||||||
aRemoved.push_back( obs.m_item );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ void ROUTER_PREVIEW_ITEM::Update( const PNS::ITEM* aItem )
|
||||||
m_color.a = 0.8;
|
m_color.a = 0.8;
|
||||||
m_depth = BaseOverlayDepth - aItem->Layers().Start();
|
m_depth = BaseOverlayDepth - aItem->Layers().Start();
|
||||||
|
|
||||||
if(( aItem->Marker() & PNS::MK_HOLE ) && aItem->Hole() )
|
if( ( aItem->Marker() & PNS::MK_HOLE ) && aItem->Hole() )
|
||||||
m_shape = aItem->Hole()->Clone();
|
m_shape = aItem->Hole()->Clone();
|
||||||
else
|
else
|
||||||
m_shape = aItem->Shape()->Clone();
|
m_shape = aItem->Shape()->Clone();
|
||||||
|
|
Loading…
Reference in New Issue