Commit 936e0be0 authored by Maciej Suminski's avatar Maciej Suminski

Uncrustified the push&shove source, fixed some warnings.

parents 87b3f2e4 5598acb6
...@@ -362,7 +362,7 @@ void CACHED_CONTAINER::mergeFreeChunks() ...@@ -362,7 +362,7 @@ void CACHED_CONTAINER::mergeFreeChunks()
if( m_freeChunks.size() <= 1 ) // There are no chunks that can be merged if( m_freeChunks.size() <= 1 ) // There are no chunks that can be merged
return; return;
#ifdef CACHED_CONTAINER_TEST > 0 #if CACHED_CONTAINER_TEST > 0
prof_counter totalTime; prof_counter totalTime;
prof_start( &totalTime, false ); prof_start( &totalTime, false );
#endif #endif
...@@ -406,7 +406,7 @@ void CACHED_CONTAINER::mergeFreeChunks() ...@@ -406,7 +406,7 @@ void CACHED_CONTAINER::mergeFreeChunks()
// Add the last one // Add the last one
m_freeChunks.insert( std::make_pair( size, offset ) ); m_freeChunks.insert( std::make_pair( size, offset ) );
#ifdef CACHED_CONTAINER_TEST > 0 #if CACHED_CONTAINER_TEST > 0
prof_end( &totalTime ); prof_end( &totalTime );
wxLogDebug( wxT( "Merged free chunks / %.1f ms" ), (double) totalTime.value / 1000.0 ); wxLogDebug( wxT( "Merged free chunks / %.1f ms" ), (double) totalTime.value / 1000.0 );
......
...@@ -69,7 +69,7 @@ void VIEW_ITEM::ViewRelease() ...@@ -69,7 +69,7 @@ void VIEW_ITEM::ViewRelease()
void VIEW_ITEM::getLayers( int* aLayers, int& aCount ) const void VIEW_ITEM::getLayers( int* aLayers, int& aCount ) const
{ {
int* layersPtr = aLayers; int* layersPtr = aLayers;
for( int i = 0; i < m_layers.size(); ++i ) for( unsigned int i = 0; i < m_layers.size(); ++i )
{ {
if( m_layers[i] ) if( m_layers[i] )
*layersPtr++ = i; *layersPtr++ = i;
......
include_directories(BEFORE ${INC_BEFORE}) include_directories( BEFORE ${INC_BEFORE} )
include_directories( include_directories(
./ ./
../ ../
../../include ../../include
../../pcbnew ../../pcbnew
../../polygon ../../polygon
${INC_AFTER} ${INC_AFTER}
) )
set(PCBNEW_PNS_SRCS set( PCBNEW_PNS_SRCS
direction.h direction.h
pns_via.h pns_via.h
pns_routing_settings.h pns_routing_settings.h
pns_shove.cpp pns_shove.cpp
pns_line.cpp pns_line.cpp
pns_utils.h pns_utils.h
pns_layerset.h pns_layerset.h
trace.h trace.h
pns_line.h pns_line.h
pns_walkaround.cpp pns_walkaround.cpp
pns_node.h pns_node.h
pns_line_placer.cpp pns_line_placer.cpp
pns_utils.cpp pns_utils.cpp
pns_solid.h pns_solid.h
pns_item.cpp pns_item.cpp
pns_via.cpp pns_via.cpp
pns_node.cpp pns_node.cpp
pns_solid.cpp pns_solid.cpp
pns_line_placer.h pns_line_placer.h
pns_optimizer.h pns_optimizer.h
pns_walkaround.h pns_walkaround.h
pns_shove.h pns_shove.h
pns_router.h pns_router.h
pns_router.cpp pns_router.cpp
pns_index.h pns_index.h
pns_item.h pns_item.h
pns_optimizer.cpp pns_optimizer.cpp
pns_joint.h pns_joint.h
pns_segment.h pns_segment.h
pns_itemset.h pns_itemset.h
pns_itemset.cpp pns_itemset.cpp
router_tool.cpp router_tool.cpp
router_tool.h router_tool.h
router_preview_item.cpp router_preview_item.cpp
router_preview_item.h router_preview_item.h
) )
add_library( pnsrouter STATIC ${PCBNEW_PNS_SRCS} )
add_library(pnsrouter STATIC ${PCBNEW_PNS_SRCS})
This diff is collapsed.
This diff is collapsed.
...@@ -3,17 +3,17 @@ ...@@ -3,17 +3,17 @@
* *
* Copyright (C) 2013 CERN * Copyright (C) 2013 CERN
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* *
* This program is free software: you can redistribute it and/or modify it * This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the * under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your * Free Software Foundation, either version 3 of the License, or (at your
* option) any later version. * option) any later version.
* *
* This program is distributed in the hope that it will be useful, but * This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of * WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. * General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.or/licenses/>. * with this program. If not, see <http://www.gnu.or/licenses/>.
*/ */
...@@ -21,52 +21,69 @@ ...@@ -21,52 +21,69 @@
#include "pns_item.h" #include "pns_item.h"
#include "pns_line.h" #include "pns_line.h"
bool PNS_ITEM::collideSimple ( const PNS_ITEM *aOther, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) const bool PNS_ITEM::collideSimple( const PNS_ITEM* aOther, int aClearance, bool aNeedMTV,
VECTOR2I& aMTV ) const
{ {
// same nets? no collision! // same nets? no collision!
if( m_net == aOther->m_net ) if( m_net == aOther->m_net )
return false; return false;
// check if we are not on completely different layers first // check if we are not on completely different layers first
if (!m_layers.Overlaps (aOther->m_layers)) if( !m_layers.Overlaps( aOther->m_layers ) )
return false; return false;
return GetShape()->Collide ( aOther->GetShape(), aClearance ); return GetShape()->Collide( aOther->GetShape(), aClearance );
// fixme: MTV // fixme: MTV
} }
bool PNS_ITEM::Collide( const PNS_ITEM *aOther, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) const
bool PNS_ITEM::Collide( const PNS_ITEM* aOther, int aClearance, bool aNeedMTV,
VECTOR2I& aMTV ) const
{ {
if( collideSimple( aOther, aClearance, aNeedMTV, aMTV ) ) if( collideSimple( aOther, aClearance, aNeedMTV, aMTV ) )
return true; return true;
// special case for "head" line with a via attached at the end. // special case for "head" line with a via attached at the end.
if( aOther->m_kind == LINE ) if( aOther->m_kind == LINE )
{ {
const PNS_LINE *line = static_cast<const PNS_LINE *> (aOther); const PNS_LINE* line = static_cast<const PNS_LINE*>( aOther );
if(line -> EndsWithVia())
return collideSimple( &line->GetVia(), aClearance - line->GetWidth() / 2, aNeedMTV, aMTV ); if( line->EndsWithVia() )
} return collideSimple( &line->GetVia(), aClearance - line->GetWidth() / 2, aNeedMTV,
aMTV );
return false; }
return false;
} }
const std::string PNS_ITEM::GetKindStr() const const std::string PNS_ITEM::GetKindStr() const
{ {
switch(m_kind) switch( m_kind )
{ {
case LINE: return "line"; case LINE:
case SEGMENT: return "segment"; return "line";
case VIA: return "via";
case JOINT: return "joint"; case SEGMENT:
case SOLID: return "solid"; return "segment";
default: return "unknown";
} case VIA:
return "via";
case JOINT:
return "joint";
case SOLID:
return "solid";
default:
return "unknown";
}
} }
PNS_ITEM::~PNS_ITEM() PNS_ITEM::~PNS_ITEM()
{ {
} }
\ No newline at end of file
...@@ -3,17 +3,17 @@ ...@@ -3,17 +3,17 @@
* *
* Copyright (C) 2013 CERN * Copyright (C) 2013 CERN
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* *
* This program is free software: you can redistribute it and/or modify it * This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the * under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your * Free Software Foundation, either version 3 of the License, or (at your
* option) any later version. * option) any later version.
* *
* This program is distributed in the hope that it will be useful, but * This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of * WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. * General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.or/licenses/>. * with this program. If not, see <http://www.gnu.or/licenses/>.
*/ */
...@@ -37,119 +37,122 @@ class PNS_NODE; ...@@ -37,119 +37,122 @@ class PNS_NODE;
* 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 class PNS_ITEM
{ {
public: public:
static const int UnusedNet = INT_MAX;
static const int UnusedNet = INT_MAX;
///> Supported item types
///> Supported item types enum PnsKind
enum PnsKind { {
SOLID = 1, SOLID = 1,
LINE = 2, LINE = 2,
JOINT = 4, JOINT = 4,
SEGMENT = 8, SEGMENT = 8,
VIA = 16, VIA = 16,
ANY = 0xff ANY = 0xff
}; };
PNS_ITEM(PnsKind aKind) PNS_ITEM( PnsKind aKind )
{ {
m_net = UnusedNet; m_net = UnusedNet;
m_movable = true; m_movable = true;
m_kind = aKind; m_kind = aKind;
m_parent = NULL; m_parent = NULL;
m_world = NULL; m_world = NULL;
m_owner = NULL; m_owner = NULL;
} }
PNS_ITEM( const PNS_ITEM& aOther ) PNS_ITEM( const PNS_ITEM& aOther )
{ {
m_layers = aOther.m_layers; m_layers = aOther.m_layers;
m_net = aOther.m_net; m_net = aOther.m_net;
m_movable = aOther.m_movable; m_movable = aOther.m_movable;
m_kind = aOther.m_kind; m_kind = aOther.m_kind;
m_world = aOther.m_world; m_world = aOther.m_world;
m_parent = aOther.m_parent; m_parent = aOther.m_parent;
m_owner = NULL; m_owner = NULL;
} }
virtual ~PNS_ITEM(); virtual ~PNS_ITEM();
virtual PNS_ITEM *Clone() const = 0; virtual PNS_ITEM* Clone() const = 0;
///> Returns a convex polygon "hull" of a the item, that is used as the walkaround ///> Returns a convex polygon "hull" of a the item, that is used as the walkaround
/// path. /// path.
/// aClearance defines how far from the body of the item the hull should be, /// aClearance defines how far from the body of the item the hull should be,
/// aWalkaroundThickness is the width of the line that walks around this hull. /// aWalkaroundThickness is the width of the line that walks around this hull.
virtual const SHAPE_LINE_CHAIN Hull(int aClearance = 0, int aWalkaroundThickness = 0) const virtual const SHAPE_LINE_CHAIN Hull( int aClearance = 0, int aWalkaroundThickness = 0 ) const
{ {
return SHAPE_LINE_CHAIN(); return SHAPE_LINE_CHAIN();
}; };
PnsKind GetKind() const { return m_kind; }
bool OfKind( int aKind ) const { return (aKind & m_kind) != 0; }
PnsKind GetKind() const { return m_kind; }
bool OfKind( int aKind ) const { return (aKind & m_kind) != 0; } const std::string GetKindStr() const;
const std::string GetKindStr() const; ///> Gets/Sets the corresponding parent object in the host application's model (pcbnew)
void SetParent( BOARD_ITEM* aParent ) { m_parent = aParent; }
///> Gets/Sets the corresponding parent object in the host application's model (pcbnew) BOARD_ITEM* GetParent() const { return m_parent; }
void SetParent(BOARD_ITEM *aParent) { m_parent = aParent; }
BOARD_ITEM *GetParent() const { return m_parent; } ///> Net accessors
int GetNet() const { return m_net; }
///> Net accessors void SetNet( int aNet ) { m_net = aNet; }
int GetNet() const { return m_net; }
void SetNet(int aNet) { m_net = aNet; } ///> Layers accessors
const PNS_LAYERSET& GetLayers() const { return m_layers; }
///> Layers accessors void SetLayers( const PNS_LAYERSET& aLayers ) { m_layers = aLayers; }
const PNS_LAYERSET& GetLayers() const { return m_layers; } void SetLayer( int aLayer )
void SetLayers ( const PNS_LAYERSET& aLayers ) { m_layers = aLayers; } {
void SetLayer ( int aLayer ) { m_layers = PNS_LAYERSET (aLayer, aLayer); } m_layers = PNS_LAYERSET( aLayer, aLayer );
}
///> Ownership management. An item can belong to a single PNS_NODE or stay unowned.
void SetOwner (PNS_NODE *aOwner) { m_owner = aOwner; } ///> Ownership management. An item can belong to a single PNS_NODE or stay unowned.
bool BelongsTo (PNS_NODE *aNode) const { return m_owner == aNode; } void SetOwner( PNS_NODE* aOwner ) { m_owner = aOwner; }
PNS_NODE *GetOwner() const { return m_owner; } bool BelongsTo( PNS_NODE* aNode ) const { return m_owner == aNode; }
PNS_NODE* GetOwner() const { return m_owner; }
///> Sets the world that is used for collision resolution.
void SetWorld (PNS_NODE *aWorld) { m_world = aWorld; } ///> Sets the world that is used for collision resolution.
PNS_NODE *GetWorld() const { return m_world; } void SetWorld( PNS_NODE* aWorld ) { m_world = aWorld; }
PNS_NODE* GetWorld() const { return m_world; }
///> Collision function. Checks if the item aOther is closer to us than ///> Collision function. Checks if the item aOther is closer to us than
/// aClearance and returns true if so. It can also calculate a minimum translation vector that resolves the /// aClearance and returns true if so. It can also calculate a minimum translation vector that
/// collision if needed. /// resolves the collision if needed.
virtual bool Collide( const PNS_ITEM *aOther, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) const; virtual bool Collide( const PNS_ITEM* aOther, int aClearance, bool aNeedMTV,
VECTOR2I& aMTV ) const;
///> A shortcut without MTV calculation
bool Collide( const PNS_ITEM *aOther, int aClearance ) const ///> A shortcut without MTV calculation
{ bool Collide( const PNS_ITEM* aOther, int aClearance ) const
VECTOR2I dummy; {
return Collide(aOther, aClearance, false, dummy); VECTOR2I dummy;
}
return Collide( aOther, aClearance, false, dummy );
///> Returns the geometric shape of the item }
virtual const SHAPE* GetShape() const {
return NULL; ///> Returns the geometric shape of the item
} virtual const SHAPE* GetShape() const
{
return NULL;
}
private: private:
bool collideSimple ( const PNS_ITEM *aOther, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) const; bool collideSimple( const PNS_ITEM* aOther, int aClearance, bool aNeedMTV,
VECTOR2I& aMTV ) const;
protected: protected:
PnsKind m_kind;
PnsKind m_kind; BOARD_ITEM* m_parent;
PNS_NODE* m_world;
BOARD_ITEM *m_parent; PNS_NODE* m_owner;
PNS_NODE *m_world; PNS_LAYERSET m_layers;
PNS_NODE *m_owner;
PNS_LAYERSET m_layers;
bool m_movable; bool m_movable;
int m_net; int m_net;
}; };
#endif // __PNS_ITEM_H #endif // __PNS_ITEM_Ha
...@@ -3,17 +3,17 @@ ...@@ -3,17 +3,17 @@
* *
* Copyright (C) 2013 CERN * Copyright (C) 2013 CERN
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* *
* This program is free software: you can redistribute it and/or modify it * This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the * under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your * Free Software Foundation, either version 3 of the License, or (at your
* option) any later version. * option) any later version.
* *
* This program is distributed in the hope that it will be useful, but * This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of * WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. * General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.or/licenses/>. * with this program. If not, see <http://www.gnu.or/licenses/>.
*/ */
...@@ -25,49 +25,58 @@ ...@@ -25,49 +25,58 @@
PNS_ITEMSET::PNS_ITEMSET() PNS_ITEMSET::PNS_ITEMSET()
{ {
} }
PNS_ITEMSET::~PNS_ITEMSET() PNS_ITEMSET::~PNS_ITEMSET()
{ {
} }
PNS_ITEMSET& PNS_ITEMSET::FilterLayers ( int aStart, int aEnd )
PNS_ITEMSET& PNS_ITEMSET::FilterLayers( int aStart, int aEnd )
{ {
ItemVector newItems; ItemVector newItems;
PNS_LAYERSET l; PNS_LAYERSET l;
if(aEnd < 0)
l = PNS_LAYERSET(aStart); if( aEnd < 0 )
else l = PNS_LAYERSET( aStart );
l = PNS_LAYERSET(aStart, aEnd); else
l = PNS_LAYERSET( aStart, aEnd );
BOOST_FOREACH( PNS_ITEM *item, m_items )
if(item->GetLayers(). Overlaps ( l )) BOOST_FOREACH( PNS_ITEM * item, m_items )
newItems.push_back(item);
m_items = newItems; if( item->GetLayers().Overlaps( l ) )
return *this; newItems.push_back( item );
m_items = newItems;
return *this;
} }
PNS_ITEMSET& PNS_ITEMSET::FilterKinds ( int aKindMask )
PNS_ITEMSET& PNS_ITEMSET::FilterKinds( int aKindMask )
{ {
ItemVector newItems; ItemVector newItems;
BOOST_FOREACH( PNS_ITEM *item, m_items ) BOOST_FOREACH( PNS_ITEM * item, m_items )
if(item->GetKind() & aKindMask )
newItems.push_back(item); if( item->GetKind() & aKindMask )
m_items = newItems; newItems.push_back( item );
return *this;
m_items = newItems;
return *this;
} }
PNS_ITEMSET& PNS_ITEMSET::FilterNet ( int aNet )
PNS_ITEMSET& PNS_ITEMSET::FilterNet( int aNet )
{ {
ItemVector newItems; ItemVector newItems;
BOOST_FOREACH( PNS_ITEM *item, m_items ) BOOST_FOREACH( PNS_ITEM * item, m_items )
if(item->GetNet() == aNet)
newItems.push_back(item); if( item->GetNet() == aNet )
m_items = newItems; newItems.push_back( item );
return *this;
m_items = newItems;
return *this;
} }
...@@ -3,17 +3,17 @@ ...@@ -3,17 +3,17 @@
* *
* Copyright (C) 2013 CERN * Copyright (C) 2013 CERN
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* *
* This program is free software: you can redistribute it and/or modify it * This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the * under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your * Free Software Foundation, either version 3 of the License, or (at your
* option) any later version. * option) any later version.
* *
* This program is distributed in the hope that it will be useful, but * This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of * WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. * General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.or/licenses/>. * with this program. If not, see <http://www.gnu.or/licenses/>.
*/ */
...@@ -28,35 +28,36 @@ ...@@ -28,35 +28,36 @@
/** /**
* Class PNS_ITEMSET * Class PNS_ITEMSET
* *
* Holds a list of board items, that can be filtered against net, kinds, layers, etc. * Holds a list of board items, that can be filtered against net, kinds,
* layers, etc.
**/ **/
class PNS_ITEMSET class PNS_ITEMSET
{ {
public: public:
typedef std::vector<PNS_ITEM*> ItemVector;
typedef std::vector<PNS_ITEM *> ItemVector; PNS_ITEMSET();
~PNS_ITEMSET();
PNS_ITEMSET(); ItemVector& Items() { return m_items; }
~PNS_ITEMSET();
ItemVector& Items() { return m_items; } PNS_ITEMSET& FilterLayers( int aStart, int aEnd = -1 );
PNS_ITEMSET& FilterKinds( int aKindMask );
PNS_ITEMSET& FilterNet( int aNet );
PNS_ITEMSET& FilterLayers ( int aStart, int aEnd = -1 ); int Size() { return m_items.size(); }
PNS_ITEMSET& FilterKinds ( int aKindMask );
PNS_ITEMSET& FilterNet ( int aNet );
int Size() { return m_items.size(); }
void Add(PNS_ITEM *item) void Add( PNS_ITEM* item )
{ {
m_items.push_back(item); m_items.push_back( item );
} }
PNS_ITEM *Get( int index ) const { return m_items[index]; } PNS_ITEM* Get( int index ) const { return m_items[index]; }
private: private:
ItemVector m_items; ItemVector m_items;
}; };
#endif #endif
...@@ -3,17 +3,17 @@ ...@@ -3,17 +3,17 @@
* *
* Copyright (C) 2013 CERN * Copyright (C) 2013 CERN
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* *
* This program is free software: you can redistribute it and/or modify it * This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the * under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your * Free Software Foundation, either version 3 of the License, or (at your
* option) any later version. * option) any later version.
* *
* This program is distributed in the hope that it will be useful, but * This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of * WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. * General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.or/licenses/>. * with this program. If not, see <http://www.gnu.or/licenses/>.
*/ */
...@@ -31,158 +31,177 @@ ...@@ -31,158 +31,177 @@
/** /**
* Class PNS_JOINT * Class PNS_JOINT
* *
* Represents a 2D point on a given set of layers and belonging to a certain net, * Represents a 2D point on a given set of layers and belonging to a certain
* that links together a number of board items. * net, that links together a number of board items.
* A hash table of joints is used by the router to follow connectivity between the items. * A hash table of joints is used by the router to follow connectivity between
* the items.
**/ **/
class PNS_JOINT : public PNS_ITEM class PNS_JOINT : public PNS_ITEM
{ {
public: public:
typedef std::vector<PNS_ITEM *> LinkedItems; typedef std::vector<PNS_ITEM*> LinkedItems;
///> joints are hashed by their position, layers and net. Linked items are, obviously, not hashed ///> Joints are hashed by their position, layers and net.
struct HashTag { /// Linked items are, obviously, not hashed
VECTOR2I pos; struct HashTag
int net; {
}; VECTOR2I pos;
int net;
PNS_JOINT(): };
PNS_ITEM(JOINT) {}
PNS_JOINT() :
PNS_JOINT(const VECTOR2I& aPos, const PNS_LAYERSET& aLayers, int aNet = -1): PNS_ITEM( JOINT ) {}
PNS_ITEM(JOINT)
{ PNS_JOINT( const VECTOR2I& aPos, const PNS_LAYERSET& aLayers,
m_tag.pos = aPos; int aNet = -1 ) :
m_tag.net = aNet; PNS_ITEM( JOINT )
m_layers = aLayers; {
} m_tag.pos = aPos;
m_tag.net = aNet;
PNS_JOINT(const PNS_JOINT& b): m_layers = aLayers;
PNS_ITEM(JOINT) }
{
m_layers = b.m_layers; PNS_JOINT( const PNS_JOINT& b ) :
m_tag.pos = b.m_tag.pos; PNS_ITEM( JOINT )
m_tag.net = b.m_tag.net; {
m_linkedItems = b.m_linkedItems; m_layers = b.m_layers;
m_layers = b.m_layers; m_tag.pos = b.m_tag.pos;
} m_tag.net = b.m_tag.net;
m_linkedItems = b.m_linkedItems;
PNS_ITEM *Clone() const m_layers = b.m_layers;
{ }
assert(false);
return NULL; PNS_ITEM* Clone() const
} {
assert( false );
///> returns true if the joint is a trivial line corner, connecting two segments of the same net, on the same layer. return NULL;
bool IsLineCorner() const }
{
if(m_linkedItems.size() != 2) ///> Returns true if the joint is a trivial line corner, connecting two
return false; /// segments of the same net, on the same layer.
bool IsLineCorner() const
if( m_linkedItems[0]->GetKind() != SEGMENT || m_linkedItems[1]->GetKind() != SEGMENT ) {
return false; if( m_linkedItems.size() != 2 )
return false;
PNS_SEGMENT *seg1 = static_cast<PNS_SEGMENT *> (m_linkedItems[0]);
PNS_SEGMENT *seg2 = static_cast<PNS_SEGMENT *> (m_linkedItems[1]); if( m_linkedItems[0]->GetKind() != SEGMENT ||
m_linkedItems[1]->GetKind() != SEGMENT )
// joints between segments of different widths are not trivial. return false;
return (seg1->GetWidth() == seg2->GetWidth());
} PNS_SEGMENT* seg1 = static_cast<PNS_SEGMENT*> (m_linkedItems[0]);
PNS_SEGMENT* seg2 = static_cast<PNS_SEGMENT*> (m_linkedItems[1]);
///> Links the joint to a given board item (when it's added to the PNS_NODE)
void Link ( PNS_ITEM *aItem ) // joints between segments of different widths are not trivial.
{ return seg1->GetWidth() == seg2->GetWidth();
LinkedItems::iterator f = std::find(m_linkedItems.begin(), m_linkedItems.end(), aItem); }
if(f != m_linkedItems.end())
return; ///> Links the joint to a given board item (when it's added to the PNS_NODE)
m_linkedItems.push_back(aItem); void Link( PNS_ITEM* aItem )
} {
LinkedItems::iterator f = std::find( m_linkedItems.begin(),
///> Unlinks a given board item from the joint (upon its removal from a PNS_NODE) m_linkedItems.end(), aItem );
///> Returns true if the joint became dangling after unlinking.
bool Unlink ( PNS_ITEM *aItem ) if( f != m_linkedItems.end() )
{ return;
LinkedItems::iterator f = std::find(m_linkedItems.begin(), m_linkedItems.end(), aItem);
if(f != m_linkedItems.end()) m_linkedItems.push_back( aItem );
m_linkedItems.erase(f); }
return (m_linkedItems.size() == 0);
} ///> Unlinks a given board item from the joint (upon its removal from a PNS_NODE)
///> Returns true if the joint became dangling after unlinking.
///> For trivial joints, returns the segment adjacent to (aCurrent). For non-trival ones, returns bool Unlink( PNS_ITEM* aItem )
///> NULL, indicating the end of line. {
PNS_SEGMENT* NextSegment( PNS_SEGMENT* aCurrent) const LinkedItems::iterator f = std::find( m_linkedItems.begin(),
{ m_linkedItems.end(), aItem );
if(!IsLineCorner())
return NULL; if( f != m_linkedItems.end() )
m_linkedItems.erase( f );
return static_cast<PNS_SEGMENT *> (m_linkedItems [ m_linkedItems[0] == aCurrent ? 1 : 0 ] );
} return m_linkedItems.size() == 0;
}
/// trivial accessors
const HashTag& GetTag() const { return m_tag; } ///> For trivial joints, returns the segment adjacent to (aCurrent). For non-trival ones, returns
const VECTOR2I& GetPos() const { return m_tag.pos; } ///> NULL, indicating the end of line.
int GetNet() const { return m_tag.net; } PNS_SEGMENT* NextSegment( PNS_SEGMENT* aCurrent ) const
LinkedItems & GetLinkList() { return m_linkedItems; }; {
if( !IsLineCorner() )
///> Returns the number of linked items of types listed in aMask. return NULL;
int LinkCount( int aMask = -1 ) const
{ return static_cast<PNS_SEGMENT*>( m_linkedItems[m_linkedItems[0] == aCurrent ? 1 : 0] );
int n = 0; }
for(LinkedItems::const_iterator i = m_linkedItems.begin(); i!= m_linkedItems.end(); ++i)
if( (*i)->GetKind() & aMask ) /// trivial accessors
n++; const HashTag& GetTag() const { return m_tag; }
return n; const VECTOR2I& GetPos() const { return m_tag.pos; }
} int GetNet() const { return m_tag.net; }
LinkedItems& GetLinkList() { return m_linkedItems; };
void Dump() const;
///> Returns the number of linked items of types listed in aMask.
bool operator==(const PNS_JOINT& rhs) const int LinkCount( int aMask = -1 ) const
{ {
return m_tag.pos == rhs.m_tag.pos && m_tag.net == rhs.m_tag.net; int n = 0;
}
for( LinkedItems::const_iterator i = m_linkedItems.begin();
void Merge( const PNS_JOINT& aJoint ) i != m_linkedItems.end(); ++i )
{ if( (*i)->GetKind() & aMask )
if(!Overlaps(aJoint)) n++;
return;
return n;
m_layers.Merge (aJoint.m_layers); }
// fixme: duplicate links (?) void Dump() const;
for(LinkedItems::const_iterator i =aJoint.m_linkedItems.begin(); i!=aJoint.m_linkedItems.end();++i)
m_linkedItems.push_back(*i); bool operator==( const PNS_JOINT& rhs ) const
} {
return m_tag.pos == rhs.m_tag.pos && m_tag.net == rhs.m_tag.net;
bool Overlaps(const PNS_JOINT& rhs) const }
{
return m_tag.pos == rhs.m_tag.pos && m_tag.net == rhs.m_tag.net && m_layers.Overlaps(rhs.m_layers); void Merge( const PNS_JOINT& aJoint )
} {
if( !Overlaps( aJoint ) )
return;
m_layers.Merge( aJoint.m_layers );
// fixme: duplicate links (?)
for( LinkedItems::const_iterator i = aJoint.m_linkedItems.begin();
i != aJoint.m_linkedItems.end(); ++i )
m_linkedItems.push_back( *i );
}
bool Overlaps( const PNS_JOINT& rhs ) const
{
return m_tag.pos == rhs.m_tag.pos &&
m_tag.net == rhs.m_tag.net && m_layers.Overlaps( rhs.m_layers );
}
private: private:
///> hash tag for unordered_multimap
HashTag m_tag;
///> hash tag for unordered_multimap ///> list of items linked to this joint
HashTag m_tag; LinkedItems m_linkedItems;
///> list of items linked to this joint
LinkedItems m_linkedItems;
}; };
// hash function & comparison operator for boost::unordered_map<> // hash function & comparison operator for boost::unordered_map<>
inline bool operator==(PNS_JOINT::HashTag const& p1, PNS_JOINT::HashTag const& p2) inline bool operator==( PNS_JOINT::HashTag const& p1,
PNS_JOINT::HashTag const& p2 )
{ {
return p1.pos == p2.pos && p1.net == p2.net; return p1.pos == p2.pos && p1.net == p2.net;
} }
inline std::size_t hash_value(PNS_JOINT::HashTag const& p)
inline std::size_t hash_value( PNS_JOINT::HashTag const& p )
{ {
std::size_t seed = 0; std::size_t seed = 0;
boost::hash_combine(seed, p.pos.x); boost::hash_combine( seed, p.pos.x );
boost::hash_combine(seed, p.pos.y); boost::hash_combine( seed, p.pos.y );
boost::hash_combine(seed, p.net); boost::hash_combine( seed, p.net );
return seed; return seed;
} }
#endif // __PNS_JOINT_H #endif // __PNS_JOINT_H
...@@ -3,17 +3,17 @@ ...@@ -3,17 +3,17 @@
* *
* Copyright (C) 2013 CERN * Copyright (C) 2013 CERN
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* *
* This program is free software: you can redistribute it and/or modify it * This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the * under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your * Free Software Foundation, either version 3 of the License, or (at your
* option) any later version. * option) any later version.
* *
* This program is distributed in the hope that it will be useful, but * This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of * WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. * General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.or/licenses/>. * with this program. If not, see <http://www.gnu.or/licenses/>.
*/ */
...@@ -26,93 +26,95 @@ ...@@ -26,93 +26,95 @@
/** /**
* Class PNS_LAYERSET * Class PNS_LAYERSET
* *
* Represents a contiguous set of PCB layers. * Represents a contiguous set of PCB layers.
*/ */
class PNS_LAYERSET class PNS_LAYERSET
{ {
public: public:
PNS_LAYERSET() :
PNS_LAYERSET(): m_start( -1 ),
m_start(-1), m_end( -1 )
m_end(-1) {};
{};
PNS_LAYERSET( int aStart, int aEnd )
PNS_LAYERSET (int aStart, int aEnd) {
{ if( aStart > aEnd )
if(aStart > aEnd) std::swap( aStart, aEnd );
std::swap(aStart, aEnd);
m_start = aStart; m_start = aStart;
m_end = aEnd; m_end = aEnd;
} }
PNS_LAYERSET (int aLayer) PNS_LAYERSET( int aLayer )
{ {
m_start = m_end = aLayer; m_start = m_end = aLayer;
} }
PNS_LAYERSET(const PNS_LAYERSET &b) : PNS_LAYERSET( const PNS_LAYERSET& b ) :
m_start(b.m_start), m_start( b.m_start ),
m_end (b.m_end) m_end( b.m_end )
{} {}
~PNS_LAYERSET () {}; ~PNS_LAYERSET() {};
const PNS_LAYERSET& operator= ( const PNS_LAYERSET& b) const PNS_LAYERSET& operator=( const PNS_LAYERSET& b )
{ {
m_start = b.m_start; m_start = b.m_start;
m_end = b.m_end; m_end = b.m_end;
return *this; return *this;
} }
bool Overlaps ( const PNS_LAYERSET& aOther ) const bool Overlaps( const PNS_LAYERSET& aOther ) const
{ {
return m_end >= aOther.m_start && m_start <= aOther.m_end; return m_end >= aOther.m_start && m_start <= aOther.m_end;
} }
bool Overlaps ( const int aLayer ) const bool Overlaps( const int aLayer ) const
{ {
return aLayer >= m_start && aLayer <= m_end; return aLayer >= m_start && aLayer <= m_end;
} }
bool IsMultilayer ( ) const bool IsMultilayer() const
{ {
return m_start != m_end; return m_start != m_end;
} }
int Start() const { int Start() const
return m_start; {
} return m_start;
}
int End() const {
return m_end; int End() const
} {
return m_end;
void Merge ( const PNS_LAYERSET& aOther ) }
{
if(m_start < 0 || m_end < 0) void Merge( const PNS_LAYERSET& aOther )
{ {
m_start = aOther.m_start; if( m_start < 0 || m_end < 0 )
m_end = aOther.m_end; {
return; m_start = aOther.m_start;
} m_end = aOther.m_end;
return;
if(aOther.m_start < m_start) }
m_start = aOther.m_start;
if(aOther.m_end > m_end) if( aOther.m_start < m_start )
m_end = aOther.m_end; m_start = aOther.m_start;
}
if( aOther.m_end > m_end )
///> Shortcut for comparisons/overlap tests m_end = aOther.m_end;
static PNS_LAYERSET All() }
{
return PNS_LAYERSET(0, 256); ///> Shortcut for comparisons/overlap tests
} static PNS_LAYERSET All()
{
private: return PNS_LAYERSET( 0, 256 );
}
int m_start;
int m_end; private:
int m_start;
int m_end;
}; };
#endif // __PNS_LAYERSET_H #endif // __PNS_LAYERSET_H
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -3,50 +3,51 @@ ...@@ -3,50 +3,51 @@
* *
* Copyright (C) 2013 CERN * Copyright (C) 2013 CERN
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* *
* This program is free software: you can redistribute it and/or modify it * This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the * under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your * Free Software Foundation, either version 3 of the License, or (at your
* option) any later version. * option) any later version.
* *
* This program is distributed in the hope that it will be useful, but * This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of * WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. * General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.or/licenses/>. * with this program. If not, see <http://www.gnu.or/licenses/>.
*/ */
#ifndef __PNS_ROUTER_SETTINGS #ifndef __PNS_ROUTER_SETTINGS
#define __PNS_ROUTER_SETTINGS #define __PNS_ROUTER_SETTINGS
///> Routing modes ///> Routing modes
enum PNS_MODE { enum PNS_MODE
RM_Ignore = 0, ///> Ignore collisions {
RM_Shove, ///> Only shove RM_Ignore = 0, ///> Ignore collisions
RM_Walkaround, ///> Only walkaround RM_Shove, ///> Only shove
RM_Smart ///> Guess what's better RM_Walkaround, ///> Only walkaround
RM_Smart ///> Guess what's better
}; };
class PNS_ROUTING_SETTINGS class PNS_ROUTING_SETTINGS
{ {
public: public:
PNS_MODE m_routingMode; PNS_MODE m_routingMode;
bool m_removeLoops; bool m_removeLoops;
bool m_smartPads; bool m_smartPads;
bool m_suggestEnding; bool m_suggestEnding;
bool m_shoveOnRequest; bool m_shoveOnRequest;
bool m_changePostures; bool m_changePostures;
bool m_followMouse; bool m_followMouse;
int m_lineWidth; int m_lineWidth;
int m_viaDiameter; int m_viaDiameter;
int m_viaDrill; int m_viaDrill;
int m_preferredLayer; int m_preferredLayer;
int m_walkaroundIterationLimit; int m_walkaroundIterationLimit;
int m_shoveIterationLimit; int m_shoveIterationLimit;
}; };
#endif #endif
......
This diff is collapsed.
This diff is collapsed.
...@@ -3,17 +3,17 @@ ...@@ -3,17 +3,17 @@
* *
* Copyright (C) 2013 CERN * Copyright (C) 2013 CERN
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* *
* This program is free software: you can redistribute it and/or modify it * This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the * under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your * Free Software Foundation, either version 3 of the License, or (at your
* option) any later version. * option) any later version.
* *
* This program is distributed in the hope that it will be useful, but * This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of * WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. * General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.or/licenses/>. * with this program. If not, see <http://www.gnu.or/licenses/>.
*/ */
...@@ -30,53 +30,57 @@ class PNS_LINE; ...@@ -30,53 +30,57 @@ class PNS_LINE;
class PNS_NODE; class PNS_NODE;
class PNS_ROUTER; class PNS_ROUTER;
class PNS_SHOVE { class PNS_SHOVE
{
public:
PNS_SHOVE( PNS_NODE* aWorld );
~PNS_SHOVE();
public: enum ShoveStatus
PNS_SHOVE(PNS_NODE *aWorld); {
~PNS_SHOVE(); SH_OK = 0,
SH_NULL,
SH_INCOMPLETE
};
enum ShoveStatus { ShoveStatus ShoveLines( PNS_LINE* aCurrentHead );
SH_OK = 0,
SH_NULL,
SH_INCOMPLETE
};
ShoveStatus ShoveLines(PNS_LINE* aCurrentHead); PNS_NODE* GetCurrentNode()
{
return m_nodeStack.empty() ? m_root : m_nodeStack.back().node;
}
PNS_NODE *GetCurrentNode() const PNS_COST_ESTIMATOR TotalCost() const;
{
return m_nodeStack.empty() ? m_root : m_nodeStack.back().node;
}
const PNS_COST_ESTIMATOR TotalCost() const; void Reset();
void KillChildNodes();
void Reset(); private:
void KillChildNodes(); static const int ShoveTimeLimit = 3000;
private: bool tryShove( PNS_NODE* aWorld, PNS_LINE* aTrack, PNS_LINE* aObstacle,
PNS_SEGMENT& aObstacleSeg, PNS_LINE* aResult, bool aInvertWinding );
static const int ShoveTimeLimit = 3000; ShoveStatus shoveSingleLine( PNS_NODE* aNode, PNS_LINE* aCurrent, PNS_LINE* aObstacle,
PNS_SEGMENT& aObstacleSeg, PNS_LINE* aResult );
bool tryShove(PNS_NODE *aWorld, PNS_LINE *aTrack, PNS_LINE * aObstacle, PNS_SEGMENT& aObstacleSeg, PNS_LINE *aResult, bool aInvertWinding ); bool reduceSpringback( PNS_LINE* aHead );
bool pushSpringback( PNS_NODE* aNode, PNS_LINE* aHead, const PNS_COST_ESTIMATOR& aCost );
ShoveStatus shoveSingleLine(PNS_NODE *aNode, PNS_LINE *aCurrent, PNS_LINE *aObstacle, PNS_SEGMENT& aObstacleSeg, PNS_LINE *aResult ); struct SpringbackTag
{
int64_t length;
int segments;
VECTOR2I p;
PNS_NODE* node;
PNS_COST_ESTIMATOR cost;
};
bool reduceSpringback( PNS_LINE *aHead ); std::vector<SpringbackTag> m_nodeStack;
bool pushSpringback( PNS_NODE *aNode, PNS_LINE *aHead, const PNS_COST_ESTIMATOR& aCost ); PNS_NODE* m_root;
PNS_NODE* m_currentNode;
struct SpringbackTag { int m_iterLimit;
int64_t length;
int segments;
VECTOR2I p;
PNS_NODE *node;
PNS_COST_ESTIMATOR cost;
};
std::vector<SpringbackTag> m_nodeStack;
PNS_NODE *m_root;
PNS_NODE *m_currentNode;
int m_iterLimit;
}; };
#endif #endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -3,17 +3,17 @@ ...@@ -3,17 +3,17 @@
* *
* Copyright (C) 2013 CERN * Copyright (C) 2013 CERN
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* *
* This program is free software: you can redistribute it and/or modify it * This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the * under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your * Free Software Foundation, either version 3 of the License, or (at your
* option) any later version. * option) any later version.
* *
* This program is distributed in the hope that it will be useful, but * This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of * WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. * General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.or/licenses/>. * with this program. If not, see <http://www.gnu.or/licenses/>.
*/ */
...@@ -24,10 +24,10 @@ ...@@ -24,10 +24,10 @@
#include <math/vector2d.h> #include <math/vector2d.h>
#include <geometry/shape_line_chain.h> #include <geometry/shape_line_chain.h>
/** Various utility functions */ /** Various utility functions */
const SHAPE_LINE_CHAIN OctagonalHull(const VECTOR2I& aP0, const VECTOR2I& aSize, int aClearance, int aChamfer); const SHAPE_LINE_CHAIN OctagonalHull( const VECTOR2I& aP0, const VECTOR2I& aSize,
int aClearance, int aChamfer );
#endif // __PNS_UTILS_H #endif // __PNS_UTILS_H
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
You'll see the P&S router sources here, but just not right now.
We are still dealing with some non-technical issues that should be solved by the next week.
Tom
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment