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:
Tomasz Wlostowski 2015-08-19 17:27:23 +02:00 committed by Maciej Suminski
parent 33a9f7ecc8
commit 95c59c8060
14 changed files with 185 additions and 217 deletions

View File

@ -142,21 +142,22 @@ bool PNS_DRAGGER::dragMarkObstacles( const VECTOR2I& aP )
case CORNER: case CORNER:
{ {
int thresh = Settings().SmoothDraggedSegments() ? m_draggedLine.Width() / 4 : 0; int thresh = Settings().SmoothDraggedSegments() ? m_draggedLine.Width() / 4 : 0;
PNS_LINE tmp( m_draggedLine ); PNS_LINE dragged( m_draggedLine );
if( m_mode == SEGMENT ) if( m_mode == SEGMENT )
tmp.DragSegment( aP, m_draggedSegmentIndex, thresh ); dragged.DragSegment( aP, m_draggedSegmentIndex, thresh );
else else
tmp.DragCorner( aP, m_draggedSegmentIndex, thresh ); dragged.DragCorner( aP, m_draggedSegmentIndex, thresh );
m_lastNode = m_shove->CurrentNode()->Branch(); m_lastNode = m_shove->CurrentNode()->Branch();
m_lastValidDraggedLine = tmp; m_lastValidDraggedLine = dragged;
m_lastValidDraggedLine.ClearSegmentLinks(); m_lastValidDraggedLine.ClearSegmentLinks();
m_lastValidDraggedLine.Unmark(); m_lastValidDraggedLine.Unmark();
m_lastNode->Add( &m_lastValidDraggedLine ); m_lastNode->Add( &m_lastValidDraggedLine );
m_draggedItems = PNS_ITEMSET( &m_lastValidDraggedLine ); m_draggedItems.Clear();
m_draggedItems.Add( m_lastValidDraggedLine );
break; 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 ) void PNS_DRAGGER::dumbDragVia( PNS_VIA* aVia, PNS_NODE* aNode, const VECTOR2I& aP )
{ {
m_draggedItems.Clear();
// fixme: this is awful. // fixme: this is awful.
m_draggedVia = aVia->Clone(); m_draggedVia = aVia->Clone();
m_draggedVia->SetPos( aP ); m_draggedVia->SetPos( aP );
m_draggedItems.Clear();
m_draggedItems.Add( m_draggedVia ); m_draggedItems.Add( m_draggedVia );
m_lastNode->Remove( aVia ); m_lastNode->Remove( aVia );
@ -192,12 +195,12 @@ void PNS_DRAGGER::dumbDragVia( PNS_VIA* aVia, PNS_NODE* aNode, const VECTOR2I& a
BOOST_FOREACH( PNS_ITEM* item, m_origViaConnections.Items() ) BOOST_FOREACH( PNS_ITEM* item, m_origViaConnections.Items() )
{ {
if ( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) ) if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
{ {
PNS_LINE origLine( *l ); PNS_LINE origLine( *l );
PNS_LINE draggedLine( *l ); PNS_LINE draggedLine( *l );
draggedLine.DragCorner( aP, 0 ); draggedLine.DragCorner( aP, origLine.CLine().Find( aVia->Pos() ) );
draggedLine.ClearSegmentLinks(); draggedLine.ClearSegmentLinks();
m_draggedItems.Add( draggedLine ); m_draggedItems.Add( draggedLine );
@ -225,32 +228,33 @@ bool PNS_DRAGGER::dragShove( const VECTOR2I& aP )
case CORNER: case CORNER:
{ {
int thresh = Settings().SmoothDraggedSegments() ? m_draggedLine.Width() / 4 : 0; int thresh = Settings().SmoothDraggedSegments() ? m_draggedLine.Width() / 4 : 0;
PNS_LINE tmp( m_draggedLine ); PNS_LINE dragged( m_draggedLine );
if( m_mode == SEGMENT ) if( m_mode == SEGMENT )
tmp.DragSegment( aP, m_draggedSegmentIndex, thresh ); dragged.DragSegment( aP, m_draggedSegmentIndex, thresh );
else 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 ) if( st == PNS_SHOVE::SH_OK )
ok = true; ok = true;
else if( st == PNS_SHOVE::SH_HEAD_MODIFIED ) else if( st == PNS_SHOVE::SH_HEAD_MODIFIED )
{ {
tmp = m_shove->NewHead(); dragged = m_shove->NewHead();
ok = true; ok = true;
} }
m_lastNode = m_shove->CurrentNode()->Branch(); m_lastNode = m_shove->CurrentNode()->Branch();
if( ok ) if( ok )
m_lastValidDraggedLine = tmp; m_lastValidDraggedLine = dragged;
m_lastValidDraggedLine.ClearSegmentLinks(); m_lastValidDraggedLine.ClearSegmentLinks();
m_lastValidDraggedLine.Unmark(); m_lastValidDraggedLine.Unmark();
m_lastNode->Add( &m_lastValidDraggedLine ); m_lastNode->Add( &m_lastValidDraggedLine );
m_draggedItems = PNS_ITEMSET( &m_lastValidDraggedLine ); m_draggedItems.Clear();
m_draggedItems.Add( m_lastValidDraggedLine );
break; break;
} }

View File

@ -96,9 +96,6 @@ public:
virtual PNS_LOGGER* Logger(); virtual PNS_LOGGER* Logger();
private: private:
typedef std::pair<PNS_LINE*, PNS_LINE*> LinePair;
typedef std::vector<LinePair> LinePairVec;
enum DragMode { enum DragMode {
CORNER = 0, CORNER = 0,
SEGMENT, SEGMENT,
@ -122,9 +119,8 @@ private:
bool m_dragStatus; bool m_dragStatus;
PNS_MODE m_currentMode; PNS_MODE m_currentMode;
PNS_ITEMSET m_origViaConnections; PNS_ITEMSET m_origViaConnections;
PNS_ITEMSET m_draggedViaConnections; PNS_VIA* m_initialVia;
PNS_VIA* m_initialVia; PNS_ITEMSET m_draggedItems;
PNS_ITEMSET m_draggedItems;
}; };
#endif #endif

View File

@ -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 * Class PNS_ITEM
* *
* Base class for PNS router board items. Implements the shared properties of all PCB items - * Base class for PNS router board items. Implements the shared properties of all PCB items -
* net, spanned layers, geometric shape & refererence to owning model. * net, spanned layers, geometric shape & refererence to owning model.
*/ */
class PNS_ITEM : public PNS_OBJECT class PNS_ITEM
{ {
public: public:
static const int UnusedNet = INT_MAX; static const int UnusedNet = INT_MAX;
@ -274,6 +227,34 @@ public:
return Layers().Overlaps( aOther->Layers() ); 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() * Function Collide()
* *
@ -357,6 +338,7 @@ protected:
PnsKind m_kind; PnsKind m_kind;
BOARD_CONNECTED_ITEM* m_parent; BOARD_CONNECTED_ITEM* m_parent;
PNS_NODE* m_owner;
PNS_LAYERSET m_layers; PNS_LAYERSET m_layers;
bool m_movable; bool m_movable;

View File

@ -24,43 +24,28 @@
#include "pns_line.h" #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() PNS_ITEMSET::~PNS_ITEMSET()
{ {
release();
} }
void PNS_ITEMSET::Add( const PNS_LINE& aLine ) void PNS_ITEMSET::Add( const PNS_LINE& aLine )
{ {
PNS_LINE* copy = aLine.Clone(); PNS_LINE* copy = aLine.Clone();
copy->SetOwner( this ); m_items.push_back( ENTRY( copy, true ) );
m_items.push_back( copy );
} }
void PNS_ITEMSET::Prepend( const PNS_LINE& aLine ) void PNS_ITEMSET::Prepend( const PNS_LINE& aLine )
{ {
PNS_LINE* copy = aLine.Clone(); PNS_LINE* copy = aLine.Clone();
copy->SetOwner( this ); m_items.insert( m_items.begin(), ENTRY( copy, true ) );
m_items.push_front( copy );
} }
PNS_ITEMSET& PNS_ITEMSET::FilterLayers( int aStart, int aEnd, bool aInvert ) PNS_ITEMSET& PNS_ITEMSET::FilterLayers( int aStart, int aEnd, bool aInvert )
{ {
ITEMS newItems; ENTRIES newItems;
PNS_LAYERSET l; PNS_LAYERSET l;
if( aEnd < 0 ) if( aEnd < 0 )
@ -68,16 +53,12 @@ PNS_ITEMSET& PNS_ITEMSET::FilterLayers( int aStart, int aEnd, bool aInvert )
else else
l = PNS_LAYERSET( aStart, aEnd ); l = PNS_LAYERSET( aStart, aEnd );
BOOST_FOREACH( PNS_ITEM* item, m_items ) BOOST_FOREACH( const ENTRY& ent, m_items )
if( item->Layers().Overlaps( l ) ^ aInvert )
{ {
newItems.push_back( item ); if( ent.item->Layers().Overlaps( l ) ^ aInvert )
} {
else newItems.push_back( ent );
{ }
if( item->BelongsTo( this ) )
item->SetOwner( NULL );
} }
m_items = newItems; 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 ) 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 ); newItems.push_back( ent );
}
else
{
if( item->BelongsTo( this ) )
item->SetOwner( NULL );
} }
} }
@ -111,18 +87,13 @@ PNS_ITEMSET& PNS_ITEMSET::FilterKinds( int aKindMask, bool aInvert )
PNS_ITEMSET& PNS_ITEMSET::FilterMarker( int aMarker, 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 ); newItems.push_back( ent );
}
else
{
if( item->BelongsTo( this ) )
item->SetOwner( NULL );
} }
} }
@ -134,18 +105,13 @@ PNS_ITEMSET& PNS_ITEMSET::FilterMarker( int aMarker, bool aInvert )
PNS_ITEMSET& PNS_ITEMSET::FilterNet( int aNet, 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 ); newItems.push_back( ent );
}
else
{
if( item->BelongsTo( this ) )
item->SetOwner( NULL );
} }
} }
@ -157,19 +123,13 @@ PNS_ITEMSET& PNS_ITEMSET::FilterNet( int aNet, bool aInvert )
PNS_ITEMSET& PNS_ITEMSET::ExcludeItem( const PNS_ITEM* aItem ) 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( ent.item != aItem )
{
if( item->BelongsTo( this ) )
item->SetOwner( NULL );
break; newItems.push_back( ent );
}
newItems.push_back( item );
} }
m_items = newItems; m_items = newItems;

View File

@ -21,7 +21,7 @@
#ifndef __PNS_ITEMSET_H #ifndef __PNS_ITEMSET_H
#define __PNS_ITEMSET_H #define __PNS_ITEMSET_H
#include <deque> #include <vector>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include "pns_item.h" #include "pns_item.h"
@ -34,32 +34,83 @@
**/ **/
class PNS_LINE; class PNS_LINE;
class PNS_ITEMSET : public PNS_OBJECT class PNS_ITEMSET
{ {
public: 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 ) PNS_ITEMSET( PNS_ITEM* aInitialItem = NULL, bool aBecomeOwner = false )
{ {
if( aInitialItem ) if( aInitialItem )
{ {
if( aBecomeOwner ) m_items.push_back( ENTRY( aInitialItem, aBecomeOwner ) );
aInitialItem->SetOwner( this );
m_items.push_back( aInitialItem );
} }
} }
PNS_ITEMSET( const PNS_ITEMSET& aOther ) PNS_ITEMSET( const PNS_ITEMSET& aOther )
{ {
copyFrom( aOther ); m_items = aOther.m_items;
} }
~PNS_ITEMSET(); ~PNS_ITEMSET();
const PNS_ITEMSET& operator=( const PNS_ITEMSET& aOther ) const PNS_ITEMSET& operator=( const PNS_ITEMSET& aOther )
{ {
copyFrom( aOther ); m_items = aOther.m_items;
return *this; return *this;
} }
@ -81,8 +132,8 @@ public:
return m_items.empty(); return m_items.empty();
} }
ITEMS& Items() { return m_items; } ENTRIES& Items() { return m_items; }
const ITEMS& CItems() const { return m_items; } const ENTRIES& CItems() const { return m_items; }
PNS_ITEMSET& FilterLayers( int aStart, int aEnd = -1, bool aInvert = false ); PNS_ITEMSET& FilterLayers( int aStart, int aEnd = -1, bool aInvert = false );
PNS_ITEMSET& FilterKinds( int aKindMask, bool aInvert = false ); PNS_ITEMSET& FilterKinds( int aKindMask, bool aInvert = false );
@ -114,57 +165,39 @@ public:
void Add( const PNS_LINE& aLine ); void Add( const PNS_LINE& aLine );
void Prepend( 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 ) void Add( PNS_ITEM* aItem, bool aBecomeOwner = false )
{ {
if( aBecomeOwner ) m_items.push_back( ENTRY( aItem, aBecomeOwner ) );
aItem->SetOwner( this );
m_items.push_back( aItem );
} }
void Prepend( PNS_ITEM* aItem, bool aBecomeOwner = false ) void Prepend( PNS_ITEM* aItem, bool aBecomeOwner = false )
{ {
if( aBecomeOwner ) m_items.insert( m_items.begin(), ENTRY( aItem, 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];
} }
void Clear() void Clear()
{ {
BOOST_FOREACH( PNS_ITEM* item, m_items )
{
if( item->BelongsTo( this ) )
delete item;
}
m_items.clear(); 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 ) 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() ) if( f != m_items.end() )
m_items.erase( f ); m_items.erase( f );
if( aItem->BelongsTo( this ) )
delete aItem;
} }
template<class T> template<class T>
@ -172,7 +205,7 @@ public:
{ {
int n = 0; int n = 0;
BOOST_FOREACH( PNS_ITEM* item, m_items ) BOOST_FOREACH( const PNS_ITEM* item, m_items )
{ {
if( item->OfKind( kind ) ) if( item->OfKind( kind ) )
{ {
@ -187,22 +220,8 @@ public:
} }
private: private:
void release();
void copyFrom( const PNS_ITEMSET& aOther ) ENTRIES m_items;
{
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;
}; };
#endif #endif

View File

@ -41,7 +41,7 @@
class PNS_JOINT : public PNS_ITEM class PNS_JOINT : public PNS_ITEM
{ {
public: public:
typedef std::deque<PNS_ITEM*> LINKED_ITEMS; typedef PNS_ITEMSET::ENTRIES LINKED_ITEMS;
///> Joints are hashed by their position, layers and net. ///> Joints are hashed by their position, layers and net.
/// Linked items are, obviously, not hashed /// Linked items are, obviously, not hashed
@ -87,10 +87,7 @@ public:
if( m_locked ) if( m_locked )
return false; return false;
if( m_linkedItems.Size() != 2 ) if( m_linkedItems.Size() != 2 || m_linkedItems.Count( SEGMENT ) != 2 )
return false;
if( m_linkedItems[0]->Kind() != SEGMENT || m_linkedItems[1]->Kind() != SEGMENT )
return false; return false;
PNS_SEGMENT* seg1 = static_cast<PNS_SEGMENT*>( m_linkedItems[0] ); PNS_SEGMENT* seg1 = static_cast<PNS_SEGMENT*>( m_linkedItems[0] );
@ -102,18 +99,10 @@ public:
bool IsNonFanoutVia() const bool IsNonFanoutVia() const
{ {
if( m_linkedItems.Size() != 3 ) int vias = m_linkedItems.Count( VIA );
return false; int segs = m_linkedItems.Count( SEGMENT );
int vias = 0, segs = 0; return ( m_linkedItems.Size() == 3 && vias == 1 && segs == 2 );
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 );
} }
///> Links the joint to a given board item (when it's added to the PNS_NODE) ///> Links the joint to a given board item (when it's added to the PNS_NODE)

View File

@ -41,7 +41,6 @@ PNS_LINE::PNS_LINE( const PNS_LINE& aOther ) :
m_net = aOther.m_net; m_net = aOther.m_net;
m_movable = aOther.m_movable; m_movable = aOther.m_movable;
m_layers = aOther.m_layers; m_layers = aOther.m_layers;
m_owner = aOther.m_owner;
m_via = aOther.m_via; m_via = aOther.m_via;
m_hasVia = aOther.m_hasVia; m_hasVia = aOther.m_hasVia;
m_marker = aOther.m_marker; 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_width = aOther.m_width;
m_net = aOther.m_net; m_net = aOther.m_net;
m_movable = aOther.m_movable; m_movable = aOther.m_movable;
m_owner = aOther.m_owner;
m_layers = aOther.m_layers; m_layers = aOther.m_layers;
m_via = aOther.m_via; m_via = aOther.m_via;
m_hasVia = aOther.m_hasVia; m_hasVia = aOther.m_hasVia;
@ -146,7 +144,6 @@ PNS_SEGMENT* PNS_SEGMENT::Clone() const
s->m_layers = m_layers; s->m_layers = m_layers;
s->m_marker = m_marker; s->m_marker = m_marker;
s->m_rank = m_rank; s->m_rank = m_rank;
s->m_owner = NULL;
return s; return s;
} }
@ -361,6 +358,13 @@ SHAPE_LINE_CHAIN dragCornerInternal( const SHAPE_LINE_CHAIN& aOrigin, const VECT
int i; int i;
int d = 2; 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? if( aOrigin.CSegment( -1 ).Length() > 100000 * 30 ) // fixme: constant/parameter?
d = 1; d = 1;
@ -411,7 +415,9 @@ SHAPE_LINE_CHAIN dragCornerInternal( const SHAPE_LINE_CHAIN& aOrigin, const VECT
return path; 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() );
} }

View File

@ -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 ) ) if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
{ {
Router()->DisplayDebugLine( l->CLine(), 5, 10000 ); Router()->DisplayDebugLine( l->CLine(), 5, 30000 );
} }
} }

View File

@ -130,6 +130,18 @@ int PNS_MEANDER_SKEW_PLACER::currentSkew() const
bool PNS_MEANDER_SKEW_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem ) 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 ); return doMove( aP, aEndItem, m_coupledLength + m_settings.m_targetSkew );
} }

View File

@ -634,7 +634,6 @@ void PNS_NODE::removeLine( PNS_LINE* aLine )
std::vector<PNS_SEGMENT*>* segRefs = aLine->LinkedSegments(); std::vector<PNS_SEGMENT*>* segRefs = aLine->LinkedSegments();
assert( segRefs != NULL ); assert( segRefs != NULL );
assert( aLine->Owner() );
BOOST_FOREACH( PNS_SEGMENT* seg, *segRefs ) BOOST_FOREACH( PNS_SEGMENT* seg, *segRefs )
{ {
@ -642,7 +641,6 @@ void PNS_NODE::removeLine( PNS_LINE* aLine )
} }
} }
void PNS_NODE::removeVia( PNS_VIA* aVia ) void PNS_NODE::removeVia( PNS_VIA* aVia )
{ {
// We have to split a single joint (associated with a via, binding together multiple layers) // We have to split a single joint (associated with a via, binding together multiple layers)

View File

@ -128,7 +128,7 @@ struct PNS_COLLISION_FILTER {
* - lightweight cloning/branching (for recursive optimization and shove * - lightweight cloning/branching (for recursive optimization and shove
* springback) * springback)
**/ **/
class PNS_NODE : public PNS_OBJECT class PNS_NODE
{ {
public: public:
typedef boost::optional<PNS_OBSTACLE> OPT_OBSTACLE; typedef boost::optional<PNS_OBSTACLE> OPT_OBSTACLE;

View File

@ -87,7 +87,6 @@ PNS_VIA* PNS_VIA::Clone() const
v->m_pos = m_pos; v->m_pos = m_pos;
v->m_diameter = m_diameter; v->m_diameter = m_diameter;
v->m_drill = m_drill; v->m_drill = m_drill;
v->m_owner = NULL;
v->m_shape = SHAPE_CIRCLE( m_pos, m_diameter / 2 ); v->m_shape = SHAPE_CIRCLE( m_pos, m_diameter / 2 );
v->m_rank = m_rank; v->m_rank = m_rank;
v->m_marker = m_marker; v->m_marker = m_marker;

View File

@ -72,7 +72,6 @@ public:
m_shape = SHAPE_CIRCLE( m_pos, m_diameter / 2 ); m_shape = SHAPE_CIRCLE( m_pos, m_diameter / 2 );
m_marker = aB.m_marker; m_marker = aB.m_marker;
m_rank = aB.m_rank; m_rank = aB.m_rank;
m_owner = aB.m_owner;
m_drill = aB.m_drill; m_drill = aB.m_drill;
m_viaType = aB.m_viaType; m_viaType = aB.m_viaType;
} }

View File

@ -438,7 +438,11 @@ bool ROUTER_TOOL::prepareInteractive()
// fixme: switch on invisible layer // 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() ); highlightNet( true, m_startItem->Net() );
// Update track width and via size shown in main toolbar comboboxes // Update track width and via size shown in main toolbar comboboxes