router: multiple fixes:
- PNS_ITEMSET now keeps ownership info (does not rely on PNS_ITEM::Owner(), avoiding the risk of dangling pointers) - fixed vias losing connected traces when dragging in mark obstacles mode - fixed rare segfault when board item returned null netclass
This commit is contained in:
parent
33a9f7ecc8
commit
95c59c8060
|
@ -142,21 +142,22 @@ bool PNS_DRAGGER::dragMarkObstacles( const VECTOR2I& aP )
|
|||
case CORNER:
|
||||
{
|
||||
int thresh = Settings().SmoothDraggedSegments() ? m_draggedLine.Width() / 4 : 0;
|
||||
PNS_LINE tmp( m_draggedLine );
|
||||
PNS_LINE dragged( m_draggedLine );
|
||||
|
||||
if( m_mode == SEGMENT )
|
||||
tmp.DragSegment( aP, m_draggedSegmentIndex, thresh );
|
||||
dragged.DragSegment( aP, m_draggedSegmentIndex, thresh );
|
||||
else
|
||||
tmp.DragCorner( aP, m_draggedSegmentIndex, thresh );
|
||||
dragged.DragCorner( aP, m_draggedSegmentIndex, thresh );
|
||||
|
||||
m_lastNode = m_shove->CurrentNode()->Branch();
|
||||
|
||||
m_lastValidDraggedLine = tmp;
|
||||
m_lastValidDraggedLine = dragged;
|
||||
m_lastValidDraggedLine.ClearSegmentLinks();
|
||||
m_lastValidDraggedLine.Unmark();
|
||||
|
||||
m_lastNode->Add( &m_lastValidDraggedLine );
|
||||
m_draggedItems = PNS_ITEMSET( &m_lastValidDraggedLine );
|
||||
m_draggedItems.Clear();
|
||||
m_draggedItems.Add( m_lastValidDraggedLine );
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -181,10 +182,12 @@ bool PNS_DRAGGER::dragMarkObstacles( const VECTOR2I& aP )
|
|||
|
||||
void PNS_DRAGGER::dumbDragVia( PNS_VIA* aVia, PNS_NODE* aNode, const VECTOR2I& aP )
|
||||
{
|
||||
m_draggedItems.Clear();
|
||||
|
||||
// fixme: this is awful.
|
||||
m_draggedVia = aVia->Clone();
|
||||
m_draggedVia->SetPos( aP );
|
||||
m_draggedItems.Clear();
|
||||
|
||||
m_draggedItems.Add( m_draggedVia );
|
||||
|
||||
m_lastNode->Remove( aVia );
|
||||
|
@ -197,7 +200,7 @@ void PNS_DRAGGER::dumbDragVia( PNS_VIA* aVia, PNS_NODE* aNode, const VECTOR2I& a
|
|||
PNS_LINE origLine( *l );
|
||||
PNS_LINE draggedLine( *l );
|
||||
|
||||
draggedLine.DragCorner( aP, 0 );
|
||||
draggedLine.DragCorner( aP, origLine.CLine().Find( aVia->Pos() ) );
|
||||
draggedLine.ClearSegmentLinks();
|
||||
|
||||
m_draggedItems.Add( draggedLine );
|
||||
|
@ -225,32 +228,33 @@ bool PNS_DRAGGER::dragShove( const VECTOR2I& aP )
|
|||
case CORNER:
|
||||
{
|
||||
int thresh = Settings().SmoothDraggedSegments() ? m_draggedLine.Width() / 4 : 0;
|
||||
PNS_LINE tmp( m_draggedLine );
|
||||
PNS_LINE dragged( m_draggedLine );
|
||||
|
||||
if( m_mode == SEGMENT )
|
||||
tmp.DragSegment( aP, m_draggedSegmentIndex, thresh );
|
||||
dragged.DragSegment( aP, m_draggedSegmentIndex, thresh );
|
||||
else
|
||||
tmp.DragCorner( aP, m_draggedSegmentIndex, thresh );
|
||||
dragged.DragCorner( aP, m_draggedSegmentIndex, thresh );
|
||||
|
||||
PNS_SHOVE::SHOVE_STATUS st = m_shove->ShoveLines( tmp );
|
||||
PNS_SHOVE::SHOVE_STATUS st = m_shove->ShoveLines( dragged );
|
||||
|
||||
if( st == PNS_SHOVE::SH_OK )
|
||||
ok = true;
|
||||
else if( st == PNS_SHOVE::SH_HEAD_MODIFIED )
|
||||
{
|
||||
tmp = m_shove->NewHead();
|
||||
dragged = m_shove->NewHead();
|
||||
ok = true;
|
||||
}
|
||||
|
||||
m_lastNode = m_shove->CurrentNode()->Branch();
|
||||
|
||||
if( ok )
|
||||
m_lastValidDraggedLine = tmp;
|
||||
m_lastValidDraggedLine = dragged;
|
||||
|
||||
m_lastValidDraggedLine.ClearSegmentLinks();
|
||||
m_lastValidDraggedLine.Unmark();
|
||||
m_lastNode->Add( &m_lastValidDraggedLine );
|
||||
m_draggedItems = PNS_ITEMSET( &m_lastValidDraggedLine );
|
||||
m_draggedItems.Clear();
|
||||
m_draggedItems.Add( m_lastValidDraggedLine );
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -96,9 +96,6 @@ public:
|
|||
virtual PNS_LOGGER* Logger();
|
||||
|
||||
private:
|
||||
typedef std::pair<PNS_LINE*, PNS_LINE*> LinePair;
|
||||
typedef std::vector<LinePair> LinePairVec;
|
||||
|
||||
enum DragMode {
|
||||
CORNER = 0,
|
||||
SEGMENT,
|
||||
|
@ -122,7 +119,6 @@ private:
|
|||
bool m_dragStatus;
|
||||
PNS_MODE m_currentMode;
|
||||
PNS_ITEMSET m_origViaConnections;
|
||||
PNS_ITEMSET m_draggedViaConnections;
|
||||
PNS_VIA* m_initialVia;
|
||||
PNS_ITEMSET m_draggedItems;
|
||||
};
|
||||
|
|
|
@ -41,60 +41,13 @@ enum LineMarker {
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class PNS_OBJECT
|
||||
*
|
||||
* Abstract base class to hold ownership information about items/nodes
|
||||
* used by the router.
|
||||
*/
|
||||
class PNS_OBJECT
|
||||
{
|
||||
public:
|
||||
PNS_OBJECT():
|
||||
m_owner( NULL ) {}
|
||||
|
||||
virtual ~PNS_OBJECT() {}
|
||||
|
||||
/**
|
||||
* Functon SetOwner()
|
||||
*
|
||||
* Sets the node that owns this item. An item can belong to a single
|
||||
* PNS_OBJECT or stay unowned.
|
||||
*/
|
||||
void SetOwner( PNS_OBJECT* aOwner )
|
||||
{
|
||||
m_owner = aOwner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function BelongsTo()
|
||||
*
|
||||
* @return true if the item is owned by aObj
|
||||
*/
|
||||
bool BelongsTo( const PNS_OBJECT* aObj ) const
|
||||
{
|
||||
return m_owner == aObj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function Owner()
|
||||
*
|
||||
* Returns the owner of this item, or NULL if there's none.
|
||||
*/
|
||||
PNS_OBJECT* Owner() const { return m_owner; }
|
||||
|
||||
protected:
|
||||
PNS_OBJECT* m_owner;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class PNS_ITEM
|
||||
*
|
||||
* Base class for PNS router board items. Implements the shared properties of all PCB items -
|
||||
* net, spanned layers, geometric shape & refererence to owning model.
|
||||
*/
|
||||
class PNS_ITEM : public PNS_OBJECT
|
||||
class PNS_ITEM
|
||||
{
|
||||
public:
|
||||
static const int UnusedNet = INT_MAX;
|
||||
|
@ -274,6 +227,34 @@ public:
|
|||
return Layers().Overlaps( aOther->Layers() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Functon SetOwner()
|
||||
*
|
||||
* Sets the node that owns this item. An item can belong to a single
|
||||
* PNS_NODE or stay unowned.
|
||||
*/
|
||||
void SetOwner( PNS_NODE* aOwner )
|
||||
{
|
||||
m_owner = aOwner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function BelongsTo()
|
||||
*
|
||||
* @return true if the item is owned by the node aNode.
|
||||
*/
|
||||
bool BelongsTo( PNS_NODE* aNode ) const
|
||||
{
|
||||
return m_owner == aNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function Owner()
|
||||
*
|
||||
* Returns the owner of this item, or NULL if there's none.
|
||||
*/
|
||||
PNS_NODE* Owner() const { return m_owner; }
|
||||
|
||||
/**
|
||||
* Function Collide()
|
||||
*
|
||||
|
@ -357,6 +338,7 @@ protected:
|
|||
PnsKind m_kind;
|
||||
|
||||
BOARD_CONNECTED_ITEM* m_parent;
|
||||
PNS_NODE* m_owner;
|
||||
PNS_LAYERSET m_layers;
|
||||
|
||||
bool m_movable;
|
||||
|
|
|
@ -24,43 +24,28 @@
|
|||
#include "pns_line.h"
|
||||
|
||||
|
||||
void PNS_ITEMSET::release()
|
||||
{
|
||||
BOOST_FOREACH( PNS_ITEM* item, m_items )
|
||||
{
|
||||
if( item->BelongsTo( this ) )
|
||||
delete item;
|
||||
}
|
||||
|
||||
m_items.clear();
|
||||
}
|
||||
|
||||
|
||||
PNS_ITEMSET::~PNS_ITEMSET()
|
||||
{
|
||||
release();
|
||||
}
|
||||
|
||||
|
||||
void PNS_ITEMSET::Add( const PNS_LINE& aLine )
|
||||
{
|
||||
PNS_LINE* copy = aLine.Clone();
|
||||
copy->SetOwner( this );
|
||||
m_items.push_back( copy );
|
||||
m_items.push_back( ENTRY( copy, true ) );
|
||||
}
|
||||
|
||||
|
||||
void PNS_ITEMSET::Prepend( const PNS_LINE& aLine )
|
||||
{
|
||||
PNS_LINE* copy = aLine.Clone();
|
||||
copy->SetOwner( this );
|
||||
m_items.push_front( copy );
|
||||
m_items.insert( m_items.begin(), ENTRY( copy, true ) );
|
||||
}
|
||||
|
||||
|
||||
PNS_ITEMSET& PNS_ITEMSET::FilterLayers( int aStart, int aEnd, bool aInvert )
|
||||
{
|
||||
ITEMS newItems;
|
||||
ENTRIES newItems;
|
||||
PNS_LAYERSET l;
|
||||
|
||||
if( aEnd < 0 )
|
||||
|
@ -68,16 +53,12 @@ PNS_ITEMSET& PNS_ITEMSET::FilterLayers( int aStart, int aEnd, bool aInvert )
|
|||
else
|
||||
l = PNS_LAYERSET( aStart, aEnd );
|
||||
|
||||
BOOST_FOREACH( PNS_ITEM* item, m_items )
|
||||
|
||||
if( item->Layers().Overlaps( l ) ^ aInvert )
|
||||
BOOST_FOREACH( const ENTRY& ent, m_items )
|
||||
{
|
||||
newItems.push_back( item );
|
||||
if( ent.item->Layers().Overlaps( l ) ^ aInvert )
|
||||
{
|
||||
newItems.push_back( ent );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( item->BelongsTo( this ) )
|
||||
item->SetOwner( NULL );
|
||||
}
|
||||
|
||||
m_items = newItems;
|
||||
|
@ -88,18 +69,13 @@ PNS_ITEMSET& PNS_ITEMSET::FilterLayers( int aStart, int aEnd, bool aInvert )
|
|||
|
||||
PNS_ITEMSET& PNS_ITEMSET::FilterKinds( int aKindMask, bool aInvert )
|
||||
{
|
||||
ITEMS newItems;
|
||||
ENTRIES newItems;
|
||||
|
||||
BOOST_FOREACH( PNS_ITEM* item, m_items )
|
||||
BOOST_FOREACH( const ENTRY& ent, m_items )
|
||||
{
|
||||
if( item->OfKind( aKindMask ) ^ aInvert )
|
||||
if( ent.item->OfKind( aKindMask ) ^ aInvert )
|
||||
{
|
||||
newItems.push_back( item );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( item->BelongsTo( this ) )
|
||||
item->SetOwner( NULL );
|
||||
newItems.push_back( ent );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,18 +87,13 @@ PNS_ITEMSET& PNS_ITEMSET::FilterKinds( int aKindMask, bool aInvert )
|
|||
|
||||
PNS_ITEMSET& PNS_ITEMSET::FilterMarker( int aMarker, bool aInvert )
|
||||
{
|
||||
ITEMS newItems;
|
||||
ENTRIES newItems;
|
||||
|
||||
BOOST_FOREACH( PNS_ITEM* item, m_items )
|
||||
BOOST_FOREACH( const ENTRY& ent, m_items )
|
||||
{
|
||||
if( item->Marker() & aMarker )
|
||||
if( ent.item->Marker() & aMarker )
|
||||
{
|
||||
newItems.push_back( item );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( item->BelongsTo( this ) )
|
||||
item->SetOwner( NULL );
|
||||
newItems.push_back( ent );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,18 +105,13 @@ PNS_ITEMSET& PNS_ITEMSET::FilterMarker( int aMarker, bool aInvert )
|
|||
|
||||
PNS_ITEMSET& PNS_ITEMSET::FilterNet( int aNet, bool aInvert )
|
||||
{
|
||||
ITEMS newItems;
|
||||
ENTRIES newItems;
|
||||
|
||||
BOOST_FOREACH( PNS_ITEM* item, m_items )
|
||||
BOOST_FOREACH( const ENTRY& ent, m_items )
|
||||
{
|
||||
if( ( item->Net() == aNet ) ^ aInvert )
|
||||
if( ( ent.item->Net() == aNet ) ^ aInvert )
|
||||
{
|
||||
newItems.push_back( item );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( item->BelongsTo( this ) )
|
||||
item->SetOwner( NULL );
|
||||
newItems.push_back( ent );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,19 +123,13 @@ PNS_ITEMSET& PNS_ITEMSET::FilterNet( int aNet, bool aInvert )
|
|||
|
||||
PNS_ITEMSET& PNS_ITEMSET::ExcludeItem( const PNS_ITEM* aItem )
|
||||
{
|
||||
ITEMS newItems;
|
||||
ENTRIES newItems;
|
||||
|
||||
BOOST_FOREACH( PNS_ITEM* item, m_items )
|
||||
BOOST_FOREACH( const ENTRY& ent, m_items )
|
||||
{
|
||||
if( item == aItem )
|
||||
{
|
||||
if( item->BelongsTo( this ) )
|
||||
item->SetOwner( NULL );
|
||||
if( ent.item != aItem )
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
newItems.push_back( item );
|
||||
newItems.push_back( ent );
|
||||
}
|
||||
|
||||
m_items = newItems;
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#ifndef __PNS_ITEMSET_H
|
||||
#define __PNS_ITEMSET_H
|
||||
|
||||
#include <deque>
|
||||
#include <vector>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "pns_item.h"
|
||||
|
@ -34,32 +34,83 @@
|
|||
**/
|
||||
class PNS_LINE;
|
||||
|
||||
class PNS_ITEMSET : public PNS_OBJECT
|
||||
class PNS_ITEMSET
|
||||
{
|
||||
public:
|
||||
typedef std::deque<PNS_ITEM*> ITEMS;
|
||||
struct ENTRY {
|
||||
|
||||
ENTRY( PNS_ITEM* aItem, bool aOwned = false ) :
|
||||
item( aItem ),
|
||||
owned( aOwned )
|
||||
{}
|
||||
|
||||
ENTRY( const ENTRY& aOther )
|
||||
{
|
||||
owned = aOther.owned;
|
||||
|
||||
if( aOther.owned )
|
||||
item = aOther.item->Clone();
|
||||
else
|
||||
item = aOther.item;
|
||||
}
|
||||
|
||||
~ENTRY()
|
||||
{
|
||||
if( owned )
|
||||
delete item;
|
||||
}
|
||||
|
||||
bool operator== ( const ENTRY& b ) const
|
||||
{
|
||||
return item == b.item;
|
||||
}
|
||||
|
||||
bool operator< ( const ENTRY& b ) const
|
||||
{
|
||||
return item < b.item;
|
||||
}
|
||||
|
||||
ENTRY& operator= ( const ENTRY& aOther )
|
||||
{
|
||||
owned = aOther.owned;
|
||||
|
||||
if( aOther.owned )
|
||||
item = aOther.item->Clone();
|
||||
else
|
||||
item = aOther.item;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator PNS_ITEM* () const
|
||||
{
|
||||
return item;
|
||||
}
|
||||
|
||||
PNS_ITEM *item;
|
||||
bool owned;
|
||||
};
|
||||
|
||||
typedef std::vector<ENTRY> ENTRIES;
|
||||
|
||||
PNS_ITEMSET( PNS_ITEM* aInitialItem = NULL, bool aBecomeOwner = false )
|
||||
{
|
||||
if( aInitialItem )
|
||||
{
|
||||
if( aBecomeOwner )
|
||||
aInitialItem->SetOwner( this );
|
||||
|
||||
m_items.push_back( aInitialItem );
|
||||
m_items.push_back( ENTRY( aInitialItem, aBecomeOwner ) );
|
||||
}
|
||||
}
|
||||
|
||||
PNS_ITEMSET( const PNS_ITEMSET& aOther )
|
||||
{
|
||||
copyFrom( aOther );
|
||||
m_items = aOther.m_items;
|
||||
}
|
||||
|
||||
~PNS_ITEMSET();
|
||||
|
||||
const PNS_ITEMSET& operator=( const PNS_ITEMSET& aOther )
|
||||
{
|
||||
copyFrom( aOther );
|
||||
m_items = aOther.m_items;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -81,8 +132,8 @@ public:
|
|||
return m_items.empty();
|
||||
}
|
||||
|
||||
ITEMS& Items() { return m_items; }
|
||||
const ITEMS& CItems() const { return m_items; }
|
||||
ENTRIES& Items() { return m_items; }
|
||||
const ENTRIES& CItems() const { return m_items; }
|
||||
|
||||
PNS_ITEMSET& FilterLayers( int aStart, int aEnd = -1, bool aInvert = false );
|
||||
PNS_ITEMSET& FilterKinds( int aKindMask, bool aInvert = false );
|
||||
|
@ -114,57 +165,39 @@ public:
|
|||
void Add( const PNS_LINE& aLine );
|
||||
void Prepend( const PNS_LINE& aLine );
|
||||
|
||||
PNS_ITEM* operator[] ( int index ) const
|
||||
{
|
||||
return m_items[index].item;
|
||||
}
|
||||
|
||||
void Add( PNS_ITEM* aItem, bool aBecomeOwner = false )
|
||||
{
|
||||
if( aBecomeOwner )
|
||||
aItem->SetOwner( this );
|
||||
|
||||
m_items.push_back( aItem );
|
||||
m_items.push_back( ENTRY( aItem, aBecomeOwner ) );
|
||||
}
|
||||
|
||||
void Prepend( PNS_ITEM* aItem, bool aBecomeOwner = false )
|
||||
{
|
||||
if( aBecomeOwner )
|
||||
aItem->SetOwner( this );
|
||||
|
||||
m_items.push_front( aItem );
|
||||
}
|
||||
|
||||
PNS_ITEM* Get( int index ) const
|
||||
{
|
||||
return m_items[index];
|
||||
}
|
||||
|
||||
PNS_ITEM* operator[] ( int index ) const
|
||||
{
|
||||
return m_items[index];
|
||||
m_items.insert( m_items.begin(), ENTRY( aItem, aBecomeOwner ) );
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
BOOST_FOREACH( PNS_ITEM* item, m_items )
|
||||
{
|
||||
if( item->BelongsTo( this ) )
|
||||
delete item;
|
||||
}
|
||||
|
||||
m_items.clear();
|
||||
}
|
||||
|
||||
bool Contains( const PNS_ITEM* aItem ) const
|
||||
bool Contains( PNS_ITEM* aItem ) const
|
||||
{
|
||||
return std::find( m_items.begin(), m_items.end(), aItem ) != m_items.end();
|
||||
const ENTRY ent( aItem );
|
||||
return std::find( m_items.begin(), m_items.end(), ent ) != m_items.end();
|
||||
}
|
||||
|
||||
void Erase( PNS_ITEM* aItem )
|
||||
{
|
||||
ITEMS::iterator f = std::find( m_items.begin(), m_items.end(), aItem );
|
||||
ENTRY ent( aItem );
|
||||
ENTRIES::iterator f = std::find( m_items.begin(), m_items.end(), ent );
|
||||
|
||||
if( f != m_items.end() )
|
||||
m_items.erase( f );
|
||||
|
||||
if( aItem->BelongsTo( this ) )
|
||||
delete aItem;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
|
@ -172,7 +205,7 @@ public:
|
|||
{
|
||||
int n = 0;
|
||||
|
||||
BOOST_FOREACH( PNS_ITEM* item, m_items )
|
||||
BOOST_FOREACH( const PNS_ITEM* item, m_items )
|
||||
{
|
||||
if( item->OfKind( kind ) )
|
||||
{
|
||||
|
@ -187,22 +220,8 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
void release();
|
||||
|
||||
void copyFrom( const PNS_ITEMSET& aOther )
|
||||
{
|
||||
release();
|
||||
|
||||
BOOST_FOREACH( PNS_ITEM* item, aOther.m_items )
|
||||
{
|
||||
if( item->BelongsTo( &aOther ) )
|
||||
m_items.push_back( item->Clone() );
|
||||
else
|
||||
m_items.push_back( item );
|
||||
}
|
||||
}
|
||||
|
||||
ITEMS m_items;
|
||||
ENTRIES m_items;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
class PNS_JOINT : public PNS_ITEM
|
||||
{
|
||||
public:
|
||||
typedef std::deque<PNS_ITEM*> LINKED_ITEMS;
|
||||
typedef PNS_ITEMSET::ENTRIES LINKED_ITEMS;
|
||||
|
||||
///> Joints are hashed by their position, layers and net.
|
||||
/// Linked items are, obviously, not hashed
|
||||
|
@ -87,10 +87,7 @@ public:
|
|||
if( m_locked )
|
||||
return false;
|
||||
|
||||
if( m_linkedItems.Size() != 2 )
|
||||
return false;
|
||||
|
||||
if( m_linkedItems[0]->Kind() != SEGMENT || m_linkedItems[1]->Kind() != SEGMENT )
|
||||
if( m_linkedItems.Size() != 2 || m_linkedItems.Count( SEGMENT ) != 2 )
|
||||
return false;
|
||||
|
||||
PNS_SEGMENT* seg1 = static_cast<PNS_SEGMENT*>( m_linkedItems[0] );
|
||||
|
@ -102,18 +99,10 @@ public:
|
|||
|
||||
bool IsNonFanoutVia() const
|
||||
{
|
||||
if( m_linkedItems.Size() != 3 )
|
||||
return false;
|
||||
int vias = m_linkedItems.Count( VIA );
|
||||
int segs = m_linkedItems.Count( SEGMENT );
|
||||
|
||||
int vias = 0, segs = 0;
|
||||
|
||||
for( int i = 0; i < 3; i++ )
|
||||
{
|
||||
vias += m_linkedItems[i]->Kind() == VIA ? 1 : 0;
|
||||
segs += m_linkedItems[i]->Kind() == SEGMENT ? 1 : 0;
|
||||
}
|
||||
|
||||
return ( vias == 1 && segs == 2 );
|
||||
return ( m_linkedItems.Size() == 3 && vias == 1 && segs == 2 );
|
||||
}
|
||||
|
||||
///> Links the joint to a given board item (when it's added to the PNS_NODE)
|
||||
|
|
|
@ -41,7 +41,6 @@ PNS_LINE::PNS_LINE( const PNS_LINE& aOther ) :
|
|||
m_net = aOther.m_net;
|
||||
m_movable = aOther.m_movable;
|
||||
m_layers = aOther.m_layers;
|
||||
m_owner = aOther.m_owner;
|
||||
m_via = aOther.m_via;
|
||||
m_hasVia = aOther.m_hasVia;
|
||||
m_marker = aOther.m_marker;
|
||||
|
@ -63,7 +62,6 @@ const PNS_LINE& PNS_LINE::operator=( const PNS_LINE& aOther )
|
|||
m_width = aOther.m_width;
|
||||
m_net = aOther.m_net;
|
||||
m_movable = aOther.m_movable;
|
||||
m_owner = aOther.m_owner;
|
||||
m_layers = aOther.m_layers;
|
||||
m_via = aOther.m_via;
|
||||
m_hasVia = aOther.m_hasVia;
|
||||
|
@ -146,7 +144,6 @@ PNS_SEGMENT* PNS_SEGMENT::Clone() const
|
|||
s->m_layers = m_layers;
|
||||
s->m_marker = m_marker;
|
||||
s->m_rank = m_rank;
|
||||
s->m_owner = NULL;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
@ -361,6 +358,13 @@ SHAPE_LINE_CHAIN dragCornerInternal( const SHAPE_LINE_CHAIN& aOrigin, const VECT
|
|||
int i;
|
||||
int d = 2;
|
||||
|
||||
if( aOrigin.SegmentCount() == 1)
|
||||
{
|
||||
DIRECTION_45 dir( aOrigin.CPoint( 0 ) - aOrigin.CPoint( 1 ) );
|
||||
|
||||
return DIRECTION_45().BuildInitialTrace( aOrigin.CPoint( 0 ), aP, dir.IsDiagonal() );
|
||||
}
|
||||
|
||||
if( aOrigin.CSegment( -1 ).Length() > 100000 * 30 ) // fixme: constant/parameter?
|
||||
d = 1;
|
||||
|
||||
|
@ -411,7 +415,9 @@ SHAPE_LINE_CHAIN dragCornerInternal( const SHAPE_LINE_CHAIN& aOrigin, const VECT
|
|||
return path;
|
||||
}
|
||||
|
||||
return DIRECTION_45().BuildInitialTrace( aOrigin.CPoint( 0 ), aP, true );
|
||||
DIRECTION_45 dir( aOrigin.CPoint( -1 ) - aOrigin.CPoint( -2 ) );
|
||||
|
||||
return DIRECTION_45().BuildInitialTrace( aOrigin.CPoint( -1 ), aP, dir.IsDiagonal() );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -152,7 +152,7 @@ bool PNS_MEANDER_PLACER::doMove( const VECTOR2I& aP, PNS_ITEM* aEndItem, int aTa
|
|||
{
|
||||
if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
|
||||
{
|
||||
Router()->DisplayDebugLine( l->CLine(), 5, 10000 );
|
||||
Router()->DisplayDebugLine( l->CLine(), 5, 30000 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -130,6 +130,18 @@ int PNS_MEANDER_SKEW_PLACER::currentSkew() const
|
|||
|
||||
bool PNS_MEANDER_SKEW_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
||||
{
|
||||
BOOST_FOREACH( const PNS_ITEM* item, m_tunedPathP.CItems() )
|
||||
{
|
||||
if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
|
||||
Router()->DisplayDebugLine( l->CLine(), 5, 10000 );
|
||||
}
|
||||
|
||||
BOOST_FOREACH( const PNS_ITEM* item, m_tunedPathN.CItems() )
|
||||
{
|
||||
if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
|
||||
Router()->DisplayDebugLine( l->CLine(), 4, 10000 );
|
||||
}
|
||||
|
||||
return doMove( aP, aEndItem, m_coupledLength + m_settings.m_targetSkew );
|
||||
}
|
||||
|
||||
|
|
|
@ -634,7 +634,6 @@ void PNS_NODE::removeLine( PNS_LINE* aLine )
|
|||
std::vector<PNS_SEGMENT*>* segRefs = aLine->LinkedSegments();
|
||||
|
||||
assert( segRefs != NULL );
|
||||
assert( aLine->Owner() );
|
||||
|
||||
BOOST_FOREACH( PNS_SEGMENT* seg, *segRefs )
|
||||
{
|
||||
|
@ -642,7 +641,6 @@ void PNS_NODE::removeLine( PNS_LINE* aLine )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void PNS_NODE::removeVia( PNS_VIA* aVia )
|
||||
{
|
||||
// We have to split a single joint (associated with a via, binding together multiple layers)
|
||||
|
|
|
@ -128,7 +128,7 @@ struct PNS_COLLISION_FILTER {
|
|||
* - lightweight cloning/branching (for recursive optimization and shove
|
||||
* springback)
|
||||
**/
|
||||
class PNS_NODE : public PNS_OBJECT
|
||||
class PNS_NODE
|
||||
{
|
||||
public:
|
||||
typedef boost::optional<PNS_OBSTACLE> OPT_OBSTACLE;
|
||||
|
|
|
@ -87,7 +87,6 @@ PNS_VIA* PNS_VIA::Clone() const
|
|||
v->m_pos = m_pos;
|
||||
v->m_diameter = m_diameter;
|
||||
v->m_drill = m_drill;
|
||||
v->m_owner = NULL;
|
||||
v->m_shape = SHAPE_CIRCLE( m_pos, m_diameter / 2 );
|
||||
v->m_rank = m_rank;
|
||||
v->m_marker = m_marker;
|
||||
|
|
|
@ -72,7 +72,6 @@ public:
|
|||
m_shape = SHAPE_CIRCLE( m_pos, m_diameter / 2 );
|
||||
m_marker = aB.m_marker;
|
||||
m_rank = aB.m_rank;
|
||||
m_owner = aB.m_owner;
|
||||
m_drill = aB.m_drill;
|
||||
m_viaType = aB.m_viaType;
|
||||
}
|
||||
|
|
|
@ -438,7 +438,11 @@ bool ROUTER_TOOL::prepareInteractive()
|
|||
|
||||
// fixme: switch on invisible layer
|
||||
|
||||
if( m_startItem && m_startItem->Net() >= 0 )
|
||||
// for some reason I don't understand, GetNetclass() may return null sometimes...
|
||||
if( m_startItem &&
|
||||
m_startItem->Net() >= 0 &&
|
||||
m_startItem->Parent() &&
|
||||
m_startItem->Parent()->GetNetClass() )
|
||||
{
|
||||
highlightNet( true, m_startItem->Net() );
|
||||
// Update track width and via size shown in main toolbar comboboxes
|
||||
|
|
Loading…
Reference in New Issue