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 ) )
|
||||
{
|
||||
Mark( MK_HOLE );
|
||||
Mark( Marker() | MK_HOLE );
|
||||
return true;
|
||||
}
|
||||
|
||||
if( holeB && holeB->Collide( shapeA, holeClearance + lineWidthA ) )
|
||||
{
|
||||
aOther->Mark( MK_HOLE );
|
||||
aOther->Mark( aOther->Marker() | MK_HOLE );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -76,8 +76,8 @@ bool ITEM::collideSimple( const ITEM* aOther, const NODE* aNode, bool aDifferent
|
|||
|
||||
if( holeA->Collide( holeB, holeToHoleClearance ) )
|
||||
{
|
||||
Mark( MK_HOLE );
|
||||
aOther->Mark( MK_HOLE );
|
||||
Mark( Marker() | MK_HOLE );
|
||||
aOther->Mark( aOther->Marker() | MK_HOLE );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ LINE::LINE( const LINE& aOther )
|
|||
m_hasVia = aOther.m_hasVia;
|
||||
m_marker = aOther.m_marker;
|
||||
m_rank = aOther.m_rank;
|
||||
m_blockingObstacle = aOther.m_blockingObstacle;
|
||||
|
||||
copyLinks( &aOther );
|
||||
}
|
||||
|
@ -70,6 +71,7 @@ LINE& LINE::operator=( const LINE& aOther )
|
|||
m_rank = aOther.m_rank;
|
||||
m_owner = aOther.m_owner;
|
||||
m_snapThreshhold = aOther.m_snapThreshhold;
|
||||
m_blockingObstacle = aOther.m_blockingObstacle;
|
||||
|
||||
copyLinks( &aOther );
|
||||
|
||||
|
|
|
@ -68,7 +68,8 @@ public:
|
|||
* Makes an empty line.
|
||||
*/
|
||||
LINE() :
|
||||
LINK_HOLDER( LINE_T )
|
||||
LINK_HOLDER( LINE_T ),
|
||||
m_blockingObstacle( nullptr )
|
||||
{
|
||||
m_hasVia = false;
|
||||
m_width = 1; // Dummy value
|
||||
|
@ -86,7 +87,8 @@ public:
|
|||
LINK_HOLDER( aBase ),
|
||||
m_line( aLine ),
|
||||
m_width( aBase.m_width ),
|
||||
m_snapThreshhold( aBase.m_snapThreshhold )
|
||||
m_snapThreshhold( aBase.m_snapThreshhold ),
|
||||
m_blockingObstacle( nullptr )
|
||||
{
|
||||
m_net = aBase.m_net;
|
||||
m_layers = aBase.m_layers;
|
||||
|
@ -99,7 +101,8 @@ public:
|
|||
* @param aVia
|
||||
*/
|
||||
LINE( const VIA& aVia ) :
|
||||
LINK_HOLDER( LINE_T )
|
||||
LINK_HOLDER( LINE_T ),
|
||||
m_blockingObstacle( nullptr )
|
||||
{
|
||||
m_hasVia = true;
|
||||
m_via = aVia;
|
||||
|
@ -204,6 +207,9 @@ public:
|
|||
virtual void Unmark( int aMarker = -1 ) 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 DragCorner( const VECTOR2I& aP, int aIndex, bool aFreeAngle = false );
|
||||
|
||||
|
@ -214,7 +220,6 @@ public:
|
|||
bool HasLockedSegments() const;
|
||||
|
||||
void Clear();
|
||||
void Merge ( const LINE& aOther );
|
||||
|
||||
OPT_BOX2I ChangedArea( const LINE* aOther ) const;
|
||||
|
||||
|
@ -240,14 +245,16 @@ private:
|
|||
VECTOR2I snapDraggedCorner( const SHAPE_LINE_CHAIN& aPath, const VECTOR2I& aP,
|
||||
int aIndex ) const;
|
||||
|
||||
SHAPE_LINE_CHAIN m_line; ///> The actual shape of the line
|
||||
int m_width; ///> our width
|
||||
SHAPE_LINE_CHAIN m_line; ///> The actual shape of the line.
|
||||
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;
|
||||
|
||||
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 )
|
||||
{
|
||||
buildInitialLine( aP, m_head );
|
||||
m_head.SetBlockingObstacle( nullptr );
|
||||
|
||||
// If we are enforcing DRC violations, push back to the hull
|
||||
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 );
|
||||
|
||||
if( obs && obs->m_distFirst != INT_MAX )
|
||||
{
|
||||
buildInitialLine( obs->m_ipFirst, m_head );
|
||||
m_head.SetBlockingObstacle( obs->m_item );
|
||||
}
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
LINE initTrack( m_head );
|
||||
|
|
|
@ -404,11 +404,6 @@ private:
|
|||
*/
|
||||
void routeStep( const VECTOR2I& aP );
|
||||
|
||||
const LINE reduceToNearestObstacle( const LINE& aOriginalLine );
|
||||
|
||||
bool rhStopAtNearestObstacle( const VECTOR2I& aP, LINE& aNewHead );
|
||||
|
||||
|
||||
///> route step, walkaround mode
|
||||
bool rhWalkOnly( const VECTOR2I& aP, LINE& aNewHead);
|
||||
|
||||
|
|
|
@ -333,8 +333,8 @@ NODE::OPT_OBSTACLE NODE::NearestObstacle( const LINE* aLine, int aKindMask,
|
|||
if( aLine->EndsWithVia() )
|
||||
{
|
||||
const VIA& via = aLine->Via();
|
||||
int viaClearance = GetClearance( obstacle.m_item, &via );
|
||||
int holeClearance = GetHoleClearance( obstacle.m_item, &via );
|
||||
int viaClearance = GetClearance( obstacle.m_item, &via );
|
||||
int holeClearance = GetHoleClearance( obstacle.m_item, &via );
|
||||
|
||||
if( holeClearance + via.Drill() / 2 > viaClearance + 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();
|
||||
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 );
|
||||
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 )
|
||||
{
|
||||
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() )
|
||||
{
|
||||
NODE::OBSTACLES obstacles;
|
||||
|
@ -308,17 +326,17 @@ void ROUTER::markViolations( NODE* aNode, ITEM_SET& aCurrent, NODE::ITEM_VECTOR&
|
|||
|
||||
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 )
|
||||
clearance = aNode->GetHoleClearance( item, obs.m_item );
|
||||
else
|
||||
clearance = aNode->GetClearance( item, obs.m_item );
|
||||
if( item->Kind() == ITEM::LINE_T )
|
||||
{
|
||||
LINE* line = static_cast<LINE*>( item );
|
||||
|
||||
std::unique_ptr<ITEM> tmp( obs.m_item->Clone() );
|
||||
tmp->Mark( tmp->Marker() | MK_VIOLATION );
|
||||
m_iface->DisplayItem( tmp.get(), -1, clearance );
|
||||
aRemoved.push_back( obs.m_item );
|
||||
// Show clearance on any blocking obstacles
|
||||
if( line->GetBlockingObstacle() )
|
||||
updateItem( item, line->GetBlockingObstacle() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ void ROUTER_PREVIEW_ITEM::Update( const PNS::ITEM* aItem )
|
|||
m_color.a = 0.8;
|
||||
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();
|
||||
else
|
||||
m_shape = aItem->Shape()->Clone();
|
||||
|
|
Loading…
Reference in New Issue