Commit 5598acb6 authored by Maciej Sumiński's avatar Maciej Sumiński

Uncrustifying push&shove router

parent 87b3f2e4
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.
...@@ -3,20 +3,21 @@ ...@@ -3,20 +3,21 @@
* *
* 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_OPTIMIZER_H #ifndef __PNS_OPTIMIZER_H
#define __PNS_OPTIMIZER_H #define __PNS_OPTIMIZER_H
...@@ -30,135 +31,137 @@ class PNS_NODE; ...@@ -30,135 +31,137 @@ class PNS_NODE;
class PNS_LINE; class PNS_LINE;
class PNS_ROUTER; class PNS_ROUTER;
/** /**
* Class PNS_COST_ESTIMATOR * Class PNS_COST_ESTIMATOR
* *
* Calculates the cost of a given line, taking corner angles and total length into account. * Calculates the cost of a given line, taking corner angles and total length into account.
**/ **/
class PNS_COST_ESTIMATOR class PNS_COST_ESTIMATOR
{ {
public: public:
PNS_COST_ESTIMATOR(): PNS_COST_ESTIMATOR() :
m_lengthCost (0), m_lengthCost( 0 ),
m_cornerCost (0) m_cornerCost( 0 )
{}; {};
PNS_COST_ESTIMATOR(const PNS_COST_ESTIMATOR &b): PNS_COST_ESTIMATOR( const PNS_COST_ESTIMATOR& b ) :
m_lengthCost (b.m_lengthCost), m_lengthCost( b.m_lengthCost ),
m_cornerCost (b.m_cornerCost) m_cornerCost( b.m_cornerCost )
{}; {};
~PNS_COST_ESTIMATOR() {}; ~PNS_COST_ESTIMATOR() {};
static int CornerCost ( const SEG& a, const SEG& b); static int CornerCost( const SEG& a, const SEG& b );
static int CornerCost ( const SHAPE_LINE_CHAIN& aLine ); static int CornerCost( const SHAPE_LINE_CHAIN& aLine );
static int CornerCost ( const PNS_LINE& aLine); static int CornerCost( const PNS_LINE& aLine );
void Add(PNS_LINE &aLine); void Add( PNS_LINE& aLine );
void Remove (PNS_LINE &aLine); void Remove( PNS_LINE& aLine );
void Replace(PNS_LINE &aOldLine, PNS_LINE& aNewLine); void Replace( PNS_LINE& aOldLine, PNS_LINE& aNewLine );
bool IsBetter( PNS_COST_ESTIMATOR& aOther, double aLengthTollerance, double aCornerTollerace ) const; bool IsBetter( PNS_COST_ESTIMATOR& aOther, double aLengthTollerance,
double aCornerTollerace ) const;
double GetLengthCost() const { return m_lengthCost; }
double GetCornerCost() const { return m_cornerCost; } double GetLengthCost() const { return m_lengthCost; }
double GetCornerCost() const { return m_cornerCost; }
private:
double m_lengthCost; private:
int m_cornerCost; double m_lengthCost;
int m_cornerCost;
}; };
/** /**
* Class PNS_OPTIMIZER * Class PNS_OPTIMIZER
* *
* Performs various optimizations of the lines being routed, attempting to make the lines shorter * Performs various optimizations of the lines being routed, attempting to make the lines shorter
* and less cornery. There are 3 kinds of optimizations so far: * and less cornery. There are 3 kinds of optimizations so far:
* - Merging obtuse segments (MERGE_OBTUSE): tries to join together as many * - Merging obtuse segments (MERGE_OBTUSE): tries to join together as many
* obtuse segments as possible without causing collisions * obtuse segments as possible without causing collisions
* - Rerouting path between pair of line corners with a 2-segment "\__" line and iteratively repeating * - Rerouting path between pair of line corners with a 2-segment "\__" line and iteratively repeating
* the procedure as long as the total cost of the line keeps decreasing * the procedure as long as the total cost of the line keeps decreasing
* - "Smart Pads" - that is, rerouting pad/via exits to make them look nice (SMART_PADS). * - "Smart Pads" - that is, rerouting pad/via exits to make them look nice (SMART_PADS).
**/ **/
class PNS_OPTIMIZER class PNS_OPTIMIZER
{ {
public: public:
enum OptimizationEffort
{
MERGE_SEGMENTS = 0x01,
SMART_PADS = 0x02,
MERGE_OBTUSE = 0x04
};
enum OptimizationEffort { PNS_OPTIMIZER( PNS_NODE* aWorld );
MERGE_SEGMENTS = 0x1, ~PNS_OPTIMIZER();
SMART_PADS = 0x2,
MERGE_OBTUSE = 0x4
};
PNS_OPTIMIZER( PNS_NODE *aWorld ); ///> a quick shortcut to optmize a line without creating and setting up an optimizer
~PNS_OPTIMIZER(); static bool Optimize( PNS_LINE* aLine, int aEffortLevel, PNS_NODE* aWorld = NULL );
///> a quick shortcut to optmize a line without creating and setting up an optimizer bool Optimize( PNS_LINE* aLine, PNS_LINE* aResult = NULL,
static bool Optimize ( PNS_LINE *aLine, int aEffortLevel, PNS_NODE *aWorld = NULL ); int aStartVertex = 0, int aEndVertex = -1 );
bool Optimize ( PNS_LINE *aLine, PNS_LINE *aResult = NULL, int aStartVertex = 0, int aEndVertex = -1); void SetWorld( PNS_NODE* aNode ) { m_world = aNode; }
void CacheStaticItem( PNS_ITEM* aItem );
void CacheRemove( PNS_ITEM* aItem );
void ClearCache( bool aStaticOnly = false );
void SetWorld(PNS_NODE *aNode) { m_world = aNode; } void SetCollisionMask( int aMask )
void CacheStaticItem (PNS_ITEM *aItem); {
void CacheRemove( PNS_ITEM *aItem ); m_collisionKindMask = aMask;
void ClearCache( bool aStaticOnly = false ); }
void SetCollisionMask ( int aMask ) void SetEffortLevel( int aEffort )
{ {
m_collisionKindMask = aMask; m_effortLevel = aEffort;
} }
void SetEffortLevel ( int aEffort ) private:
{ static const int MaxCachedItems = 256;
m_effortLevel = aEffort;
}
private:
static const int MaxCachedItems = 256; typedef std::vector<SHAPE_LINE_CHAIN> BreakoutList;
typedef std::vector<SHAPE_LINE_CHAIN> BreakoutList; struct CacheVisitor;
struct CacheVisitor; struct CachedItem
{
struct CachedItem int hits;
{ bool isStatic;
int hits; };
bool isStatic;
};
bool mergeObtuse (PNS_LINE *aLine); bool mergeObtuse( PNS_LINE* aLine );
bool mergeFull (PNS_LINE *aLine); bool mergeFull( PNS_LINE* aLine );
bool removeUglyCorners (PNS_LINE *aLine); bool removeUglyCorners( PNS_LINE* aLine );
bool runSmartPads(PNS_LINE *aLine); bool runSmartPads( PNS_LINE* aLine );
bool mergeStep ( PNS_LINE *aLine, SHAPE_LINE_CHAIN& aCurrentLine, int step ); bool mergeStep( PNS_LINE* aLine, SHAPE_LINE_CHAIN& aCurrentLine, int step );
bool checkColliding( PNS_ITEM *aItem, bool aUpdateCache = true ); bool checkColliding( PNS_ITEM* aItem, bool aUpdateCache = true );
bool checkColliding( PNS_LINE *aLine, const SHAPE_LINE_CHAIN& aOptPath ); bool checkColliding( PNS_LINE* aLine, const SHAPE_LINE_CHAIN& aOptPath );
void cacheAdd( PNS_ITEM *aItem, bool aIsStatic ); void cacheAdd( PNS_ITEM* aItem, bool aIsStatic );
void removeCachedSegments (PNS_LINE *aLine, int aStartVertex = 0, int aEndVertex = -1); void removeCachedSegments( PNS_LINE* aLine, int aStartVertex = 0, int aEndVertex = -1 );
BreakoutList circleBreakouts( int aWidth, const SHAPE *aShape, bool aPermitDiagonal ) const; BreakoutList circleBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const;
BreakoutList rectBreakouts( int aWidth, const SHAPE *aShape, bool aPermitDiagonal ) const; BreakoutList rectBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const;
BreakoutList ovalBreakouts( int aWidth, const SHAPE *aShape, bool aPermitDiagonal ) const; BreakoutList ovalBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const;
BreakoutList computeBreakouts( int aWidth, const PNS_ITEM *aItem, bool aPermitDiagonal ) const; BreakoutList computeBreakouts( int aWidth, const PNS_ITEM* aItem,
bool aPermitDiagonal ) const;
int smartPadsSingle( PNS_LINE *aLine, PNS_ITEM *aPad, bool aEnd, int aEndVertex ); int smartPadsSingle( PNS_LINE* aLine, PNS_ITEM* aPad, bool aEnd, int aEndVertex );
PNS_ITEM *findPadOrVia ( int aLayer, int aNet, const VECTOR2I& aP) const; PNS_ITEM* findPadOrVia( int aLayer, int aNet, const VECTOR2I& aP ) const;
SHAPE_INDEX_LIST<PNS_ITEM *> m_cache; SHAPE_INDEX_LIST<PNS_ITEM*> m_cache;
typedef boost::unordered_map<PNS_ITEM*, CachedItem> CachedItemTags; typedef boost::unordered_map<PNS_ITEM*, CachedItem> CachedItemTags;
CachedItemTags m_cacheTags; CachedItemTags m_cacheTags;
PNS_NODE *m_world; PNS_NODE* m_world;
int m_collisionKindMask; int m_collisionKindMask;
int m_effortLevel; int m_effortLevel;
bool m_keepPostures; bool m_keepPostures;
}; };
#endif #endif
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.
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