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
../../pcbnew
../../polygon
${INC_AFTER}
)
./
../
../../ include
../../ pcbnew
../../ polygon
$ { INC_AFTER }
)
set(PCBNEW_PNS_SRCS
direction.h
pns_via.h
pns_routing_settings.h
pns_shove.cpp
pns_line.cpp
pns_utils.h
pns_layerset.h
trace.h
pns_line.h
pns_walkaround.cpp
pns_node.h
pns_line_placer.cpp
pns_utils.cpp
pns_solid.h
pns_item.cpp
pns_via.cpp
pns_node.cpp
pns_solid.cpp
pns_line_placer.h
pns_optimizer.h
pns_walkaround.h
pns_shove.h
pns_router.h
pns_router.cpp
pns_index.h
pns_item.h
pns_optimizer.cpp
pns_joint.h
pns_segment.h
pns_itemset.h
pns_itemset.cpp
router_tool.cpp
router_tool.h
router_preview_item.cpp
router_preview_item.h
)
set( PCBNEW_PNS_SRCS
direction.h
pns_via.h
pns_routing_settings.h
pns_shove.cpp
pns_line.cpp
pns_utils.h
pns_layerset.h
trace.h
pns_line.h
pns_walkaround.cpp
pns_node.h
pns_line_placer.cpp
pns_utils.cpp
pns_solid.h
pns_item.cpp
pns_via.cpp
pns_node.cpp
pns_solid.cpp
pns_line_placer.h
pns_optimizer.h
pns_walkaround.h
pns_shove.h
pns_router.h
pns_router.cpp
pns_index.h
pns_item.h
pns_optimizer.cpp
pns_joint.h
pns_segment.h
pns_itemset.h
pns_itemset.cpp
router_tool.cpp
router_tool.h
router_preview_item.cpp
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 @@
*
* Copyright (C) 2013 CERN
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
*
* 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
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.or/licenses/>.
*/
......@@ -21,52 +21,69 @@
#include "pns_item.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!
if( m_net == aOther->m_net )
return false;
// same nets? no collision!
if( m_net == aOther->m_net )
return false;
// check if we are not on completely different layers first
if (!m_layers.Overlaps (aOther->m_layers))
return false;
// check if we are not on completely different layers first
if( !m_layers.Overlaps( aOther->m_layers ) )
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 ) )
return true;
// special case for "head" line with a via attached at the end.
if( aOther->m_kind == LINE )
{
const PNS_LINE *line = static_cast<const PNS_LINE *> (aOther);
if(line -> EndsWithVia())
return collideSimple( &line->GetVia(), aClearance - line->GetWidth() / 2, aNeedMTV, aMTV );
}
return false;
if( collideSimple( aOther, aClearance, aNeedMTV, aMTV ) )
return true;
// special case for "head" line with a via attached at the end.
if( aOther->m_kind == LINE )
{
const PNS_LINE* line = static_cast<const PNS_LINE*>( aOther );
if( line->EndsWithVia() )
return collideSimple( &line->GetVia(), aClearance - line->GetWidth() / 2, aNeedMTV,
aMTV );
}
return false;
}
const std::string PNS_ITEM::GetKindStr() const
{
switch(m_kind)
{
case LINE: return "line";
case SEGMENT: return "segment";
case VIA: return "via";
case JOINT: return "joint";
case SOLID: return "solid";
default: return "unknown";
}
switch( m_kind )
{
case LINE:
return "line";
case SEGMENT:
return "segment";
case VIA:
return "via";
case JOINT:
return "joint";
case SOLID:
return "solid";
default:
return "unknown";
}
}
PNS_ITEM::~PNS_ITEM()
{
}
\ No newline at end of file
......@@ -3,17 +3,17 @@
*
* Copyright (C) 2013 CERN
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
*
* 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
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.or/licenses/>.
*/
......@@ -37,119 +37,122 @@ class PNS_NODE;
* Base class for PNS router board items. Implements the shared properties of all PCB items -
* net, spanned layers, geometric shape & refererence to owning model.
*/
class PNS_ITEM
class PNS_ITEM
{
public:
static const int UnusedNet = INT_MAX;
///> Supported item types
enum PnsKind {
SOLID = 1,
LINE = 2,
JOINT = 4,
SEGMENT = 8,
VIA = 16,
ANY = 0xff
};
PNS_ITEM(PnsKind aKind)
{
m_net = UnusedNet;
m_movable = true;
m_kind = aKind;
m_parent = NULL;
m_world = NULL;
m_owner = NULL;
}
PNS_ITEM( const PNS_ITEM& aOther )
{
m_layers = aOther.m_layers;
m_net = aOther.m_net;
m_movable = aOther.m_movable;
m_kind = aOther.m_kind;
m_world = aOther.m_world;
m_parent = aOther.m_parent;
m_owner = NULL;
}
virtual ~PNS_ITEM();
virtual PNS_ITEM *Clone() const = 0;
///> Returns a convex polygon "hull" of a the item, that is used as the walkaround
/// path.
/// 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.
virtual const SHAPE_LINE_CHAIN Hull(int aClearance = 0, int aWalkaroundThickness = 0) const
{
return SHAPE_LINE_CHAIN();
};
PnsKind GetKind() const { return m_kind; }
bool OfKind( int aKind ) const { return (aKind & m_kind) != 0; }
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; }
BOARD_ITEM *GetParent() const { return m_parent; }
///> Net accessors
int GetNet() const { return m_net; }
void SetNet(int aNet) { m_net = aNet; }
///> Layers accessors
const PNS_LAYERSET& GetLayers() const { return m_layers; }
void SetLayers ( const PNS_LAYERSET& aLayers ) { m_layers = aLayers; }
void SetLayer ( int 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; }
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; }
PNS_NODE *GetWorld() const { return m_world; }
///> 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
/// collision if needed.
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
{
VECTOR2I dummy;
return Collide(aOther, aClearance, false, dummy);
}
///> Returns the geometric shape of the item
virtual const SHAPE* GetShape() const {
return NULL;
}
static const int UnusedNet = INT_MAX;
///> Supported item types
enum PnsKind
{
SOLID = 1,
LINE = 2,
JOINT = 4,
SEGMENT = 8,
VIA = 16,
ANY = 0xff
};
PNS_ITEM( PnsKind aKind )
{
m_net = UnusedNet;
m_movable = true;
m_kind = aKind;
m_parent = NULL;
m_world = NULL;
m_owner = NULL;
}
PNS_ITEM( const PNS_ITEM& aOther )
{
m_layers = aOther.m_layers;
m_net = aOther.m_net;
m_movable = aOther.m_movable;
m_kind = aOther.m_kind;
m_world = aOther.m_world;
m_parent = aOther.m_parent;
m_owner = NULL;
}
virtual ~PNS_ITEM();
virtual PNS_ITEM* Clone() const = 0;
///> Returns a convex polygon "hull" of a the item, that is used as the walkaround
/// path.
/// 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.
virtual const SHAPE_LINE_CHAIN Hull( int aClearance = 0, int aWalkaroundThickness = 0 ) const
{
return SHAPE_LINE_CHAIN();
};
PnsKind GetKind() const { return m_kind; }
bool OfKind( int aKind ) const { return (aKind & m_kind) != 0; }
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; }
BOARD_ITEM* GetParent() const { return m_parent; }
///> Net accessors
int GetNet() const { return m_net; }
void SetNet( int aNet ) { m_net = aNet; }
///> Layers accessors
const PNS_LAYERSET& GetLayers() const { return m_layers; }
void SetLayers( const PNS_LAYERSET& aLayers ) { m_layers = aLayers; }
void SetLayer( int 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; }
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; }
PNS_NODE* GetWorld() const { return m_world; }
///> 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 collision if needed.
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
{
VECTOR2I dummy;
return Collide( aOther, aClearance, false, dummy );
}
///> Returns the geometric shape of the item
virtual const SHAPE* GetShape() const
{
return NULL;
}
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:
PnsKind m_kind;
PnsKind m_kind;
BOARD_ITEM *m_parent;
PNS_NODE *m_world;
PNS_NODE *m_owner;
PNS_LAYERSET m_layers;
BOARD_ITEM* m_parent;
PNS_NODE* m_world;
PNS_NODE* m_owner;
PNS_LAYERSET m_layers;
bool m_movable;
int m_net;
bool m_movable;
int m_net;
};
#endif // __PNS_ITEM_H
#endif // __PNS_ITEM_Ha
......@@ -3,17 +3,17 @@
*
* Copyright (C) 2013 CERN
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
*
* 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
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.or/licenses/>.
*/
......@@ -25,49 +25,58 @@
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;
PNS_LAYERSET l;
if(aEnd < 0)
l = PNS_LAYERSET(aStart);
else
l = PNS_LAYERSET(aStart, aEnd);
BOOST_FOREACH( PNS_ITEM *item, m_items )
if(item->GetLayers(). Overlaps ( l ))
newItems.push_back(item);
m_items = newItems;
return *this;
ItemVector newItems;
PNS_LAYERSET l;
if( aEnd < 0 )
l = PNS_LAYERSET( aStart );
else
l = PNS_LAYERSET( aStart, aEnd );
BOOST_FOREACH( PNS_ITEM * item, m_items )
if( item->GetLayers().Overlaps( l ) )
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;
BOOST_FOREACH( PNS_ITEM *item, m_items )
if(item->GetKind() & aKindMask )
newItems.push_back(item);
m_items = newItems;
return *this;
ItemVector newItems;
BOOST_FOREACH( PNS_ITEM * item, m_items )
if( item->GetKind() & aKindMask )
newItems.push_back( item );
m_items = newItems;
return *this;
}
PNS_ITEMSET& PNS_ITEMSET::FilterNet ( int aNet )
PNS_ITEMSET& PNS_ITEMSET::FilterNet( int aNet )
{
ItemVector newItems;
BOOST_FOREACH( PNS_ITEM *item, m_items )
if(item->GetNet() == aNet)
newItems.push_back(item);
m_items = newItems;
return *this;
ItemVector newItems;
BOOST_FOREACH( PNS_ITEM * item, m_items )
if( item->GetNet() == aNet )
newItems.push_back( item );
m_items = newItems;
return *this;
}
......@@ -3,17 +3,17 @@
*
* Copyright (C) 2013 CERN
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
*
* 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
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.or/licenses/>.
*/
......@@ -28,35 +28,36 @@
/**
* 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
{
public:
typedef std::vector<PNS_ITEM*> ItemVector;
typedef std::vector<PNS_ITEM *> ItemVector;
PNS_ITEMSET();
~PNS_ITEMSET();
PNS_ITEMSET();
~PNS_ITEMSET();
ItemVector& Items() { return m_items; }
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 );
PNS_ITEMSET& FilterKinds ( int aKindMask );
PNS_ITEMSET& FilterNet ( int aNet );
int Size() { return m_items.size(); }
int Size() { return m_items.size(); }
void Add(PNS_ITEM *item)
{
m_items.push_back(item);
}
void Add( PNS_ITEM* 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:
ItemVector m_items;
ItemVector m_items;
};
#endif
......@@ -3,17 +3,17 @@
*
* Copyright (C) 2013 CERN
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
*
* 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
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.or/licenses/>.
*/
......@@ -31,158 +31,177 @@
/**
* Class PNS_JOINT
*
* Represents a 2D point on a given set of layers and belonging to a certain 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.
*
* Represents a 2D point on a given set of layers and belonging to a certain
* 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.
**/
class PNS_JOINT : public PNS_ITEM
{
public:
typedef std::vector<PNS_ITEM *> LinkedItems;
///> joints are hashed by their position, layers and net. Linked items are, obviously, not hashed
struct HashTag {
VECTOR2I pos;
int net;
};
PNS_JOINT():
PNS_ITEM(JOINT) {}
PNS_JOINT(const VECTOR2I& aPos, const PNS_LAYERSET& aLayers, int aNet = -1):
PNS_ITEM(JOINT)
{
m_tag.pos = aPos;
m_tag.net = aNet;
m_layers = aLayers;
}
PNS_JOINT(const PNS_JOINT& b):
PNS_ITEM(JOINT)
{
m_layers = b.m_layers;
m_tag.pos = b.m_tag.pos;
m_tag.net = b.m_tag.net;
m_linkedItems = b.m_linkedItems;
m_layers = b.m_layers;
}
PNS_ITEM *Clone() const
{
assert(false);
return NULL;
}
///> returns true if the joint is a trivial line corner, connecting two segments of the same net, on the same layer.
bool IsLineCorner() const
{
if(m_linkedItems.size() != 2)
return false;
if( m_linkedItems[0]->GetKind() != SEGMENT || m_linkedItems[1]->GetKind() != SEGMENT )
return false;
PNS_SEGMENT *seg1 = static_cast<PNS_SEGMENT *> (m_linkedItems[0]);
PNS_SEGMENT *seg2 = static_cast<PNS_SEGMENT *> (m_linkedItems[1]);
// joints between segments of different widths are not trivial.
return (seg1->GetWidth() == seg2->GetWidth());
}
///> Links the joint to a given board item (when it's added to the PNS_NODE)
void Link ( PNS_ITEM *aItem )
{
LinkedItems::iterator f = std::find(m_linkedItems.begin(), m_linkedItems.end(), aItem);
if(f != m_linkedItems.end())
return;
m_linkedItems.push_back(aItem);
}
///> Unlinks a given board item from the joint (upon its removal from a PNS_NODE)
///> Returns true if the joint became dangling after unlinking.
bool Unlink ( PNS_ITEM *aItem )
{
LinkedItems::iterator f = std::find(m_linkedItems.begin(), m_linkedItems.end(), aItem);
if(f != m_linkedItems.end())
m_linkedItems.erase(f);
return (m_linkedItems.size() == 0);
}
///> For trivial joints, returns the segment adjacent to (aCurrent). For non-trival ones, returns
///> NULL, indicating the end of line.
PNS_SEGMENT* NextSegment( PNS_SEGMENT* aCurrent) const
{
if(!IsLineCorner())
return NULL;
return static_cast<PNS_SEGMENT *> (m_linkedItems [ m_linkedItems[0] == aCurrent ? 1 : 0 ] );
}
/// trivial accessors
const HashTag& GetTag() const { return m_tag; }
const VECTOR2I& GetPos() const { return m_tag.pos; }
int GetNet() const { return m_tag.net; }
LinkedItems & GetLinkList() { return m_linkedItems; };
///> Returns the number of linked items of types listed in aMask.
int LinkCount( int aMask = -1 ) const
{
int n = 0;
for(LinkedItems::const_iterator i = m_linkedItems.begin(); i!= m_linkedItems.end(); ++i)
if( (*i)->GetKind() & aMask )
n++;
return n;
}
void Dump() const;
bool operator==(const PNS_JOINT& rhs) const
{
return m_tag.pos == rhs.m_tag.pos && m_tag.net == rhs.m_tag.net;
}
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);
}
typedef std::vector<PNS_ITEM*> LinkedItems;
///> Joints are hashed by their position, layers and net.
/// Linked items are, obviously, not hashed
struct HashTag
{
VECTOR2I pos;
int net;
};
PNS_JOINT() :
PNS_ITEM( JOINT ) {}
PNS_JOINT( const VECTOR2I& aPos, const PNS_LAYERSET& aLayers,
int aNet = -1 ) :
PNS_ITEM( JOINT )
{
m_tag.pos = aPos;
m_tag.net = aNet;
m_layers = aLayers;
}
PNS_JOINT( const PNS_JOINT& b ) :
PNS_ITEM( JOINT )
{
m_layers = b.m_layers;
m_tag.pos = b.m_tag.pos;
m_tag.net = b.m_tag.net;
m_linkedItems = b.m_linkedItems;
m_layers = b.m_layers;
}
PNS_ITEM* Clone() const
{
assert( false );
return NULL;
}
///> Returns true if the joint is a trivial line corner, connecting two
/// segments of the same net, on the same layer.
bool IsLineCorner() const
{
if( m_linkedItems.size() != 2 )
return false;
if( m_linkedItems[0]->GetKind() != SEGMENT ||
m_linkedItems[1]->GetKind() != SEGMENT )
return false;
PNS_SEGMENT* seg1 = static_cast<PNS_SEGMENT*> (m_linkedItems[0]);
PNS_SEGMENT* seg2 = static_cast<PNS_SEGMENT*> (m_linkedItems[1]);
// joints between segments of different widths are not trivial.
return seg1->GetWidth() == seg2->GetWidth();
}
///> Links the joint to a given board item (when it's added to the PNS_NODE)
void Link( PNS_ITEM* aItem )
{
LinkedItems::iterator f = std::find( m_linkedItems.begin(),
m_linkedItems.end(), aItem );
if( f != m_linkedItems.end() )
return;
m_linkedItems.push_back( aItem );
}
///> Unlinks a given board item from the joint (upon its removal from a PNS_NODE)
///> Returns true if the joint became dangling after unlinking.
bool Unlink( PNS_ITEM* aItem )
{
LinkedItems::iterator f = std::find( m_linkedItems.begin(),
m_linkedItems.end(), aItem );
if( f != m_linkedItems.end() )
m_linkedItems.erase( f );
return m_linkedItems.size() == 0;
}
///> For trivial joints, returns the segment adjacent to (aCurrent). For non-trival ones, returns
///> NULL, indicating the end of line.
PNS_SEGMENT* NextSegment( PNS_SEGMENT* aCurrent ) const
{
if( !IsLineCorner() )
return NULL;
return static_cast<PNS_SEGMENT*>( m_linkedItems[m_linkedItems[0] == aCurrent ? 1 : 0] );
}
/// trivial accessors
const HashTag& GetTag() const { return m_tag; }
const VECTOR2I& GetPos() const { return m_tag.pos; }
int GetNet() const { return m_tag.net; }
LinkedItems& GetLinkList() { return m_linkedItems; };
///> Returns the number of linked items of types listed in aMask.
int LinkCount( int aMask = -1 ) const
{
int n = 0;
for( LinkedItems::const_iterator i = m_linkedItems.begin();
i != m_linkedItems.end(); ++i )
if( (*i)->GetKind() & aMask )
n++;
return n;
}
void Dump() const;
bool operator==( const PNS_JOINT& rhs ) const
{
return m_tag.pos == rhs.m_tag.pos && m_tag.net == rhs.m_tag.net;
}
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:
///> hash tag for unordered_multimap
HashTag m_tag;
///> hash tag for unordered_multimap
HashTag m_tag;
///> list of items linked to this joint
LinkedItems m_linkedItems;
///> list of items linked to this joint
LinkedItems m_linkedItems;
};
// 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;
}
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;
boost::hash_combine(seed, p.pos.x);
boost::hash_combine(seed, p.pos.y);
boost::hash_combine(seed, p.net);
boost::hash_combine( seed, p.pos.x );
boost::hash_combine( seed, p.pos.y );
boost::hash_combine( seed, p.net );
return seed;
}
#endif // __PNS_JOINT_H
#endif // __PNS_JOINT_H
......@@ -3,17 +3,17 @@
*
* Copyright (C) 2013 CERN
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
*
* 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
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.or/licenses/>.
*/
......@@ -26,93 +26,95 @@
/**
* Class PNS_LAYERSET
*
* Represents a contiguous set of PCB layers.
* Represents a contiguous set of PCB layers.
*/
class PNS_LAYERSET
{
public:
PNS_LAYERSET():
m_start(-1),
m_end(-1)
{};
PNS_LAYERSET (int aStart, int aEnd)
{
if(aStart > aEnd)
std::swap(aStart, aEnd);
m_start = aStart;
m_end = aEnd;
}
PNS_LAYERSET (int aLayer)
{
m_start = m_end = aLayer;
}
PNS_LAYERSET(const PNS_LAYERSET &b) :
m_start(b.m_start),
m_end (b.m_end)
{}
~PNS_LAYERSET () {};
const PNS_LAYERSET& operator= ( const PNS_LAYERSET& b)
{
m_start = b.m_start;
m_end = b.m_end;
return *this;
}
bool Overlaps ( const PNS_LAYERSET& aOther ) const
{
return m_end >= aOther.m_start && m_start <= aOther.m_end;
}
bool Overlaps ( const int aLayer ) const
{
return aLayer >= m_start && aLayer <= m_end;
}
bool IsMultilayer ( ) const
{
return m_start != m_end;
}
int Start() const {
return m_start;
}
int End() const {
return m_end;
}
void Merge ( const PNS_LAYERSET& aOther )
{
if(m_start < 0 || m_end < 0)
{
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)
m_end = aOther.m_end;
}
///> Shortcut for comparisons/overlap tests
static PNS_LAYERSET All()
{
return PNS_LAYERSET(0, 256);
}
private:
int m_start;
int m_end;
public:
PNS_LAYERSET() :
m_start( -1 ),
m_end( -1 )
{};
PNS_LAYERSET( int aStart, int aEnd )
{
if( aStart > aEnd )
std::swap( aStart, aEnd );
m_start = aStart;
m_end = aEnd;
}
PNS_LAYERSET( int aLayer )
{
m_start = m_end = aLayer;
}
PNS_LAYERSET( const PNS_LAYERSET& b ) :
m_start( b.m_start ),
m_end( b.m_end )
{}
~PNS_LAYERSET() {};
const PNS_LAYERSET& operator=( const PNS_LAYERSET& b )
{
m_start = b.m_start;
m_end = b.m_end;
return *this;
}
bool Overlaps( const PNS_LAYERSET& aOther ) const
{
return m_end >= aOther.m_start && m_start <= aOther.m_end;
}
bool Overlaps( const int aLayer ) const
{
return aLayer >= m_start && aLayer <= m_end;
}
bool IsMultilayer() const
{
return m_start != m_end;
}
int Start() const
{
return m_start;
}
int End() const
{
return m_end;
}
void Merge( const PNS_LAYERSET& aOther )
{
if( m_start < 0 || m_end < 0 )
{
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 )
m_end = aOther.m_end;
}
///> Shortcut for comparisons/overlap tests
static PNS_LAYERSET All()
{
return PNS_LAYERSET( 0, 256 );
}
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 @@
*
* Copyright (C) 2013 CERN
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
*
* 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
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.or/licenses/>.
*/
#ifndef __PNS_OPTIMIZER_H
#define __PNS_OPTIMIZER_H
......@@ -30,135 +31,137 @@ class PNS_NODE;
class PNS_LINE;
class PNS_ROUTER;
/**
* Class PNS_COST_ESTIMATOR
*
* Calculates the cost of a given line, taking corner angles and total length into account.
**/
**/
class PNS_COST_ESTIMATOR
class PNS_COST_ESTIMATOR
{
public:
PNS_COST_ESTIMATOR():
m_lengthCost (0),
m_cornerCost (0)
{};
PNS_COST_ESTIMATOR(const PNS_COST_ESTIMATOR &b):
m_lengthCost (b.m_lengthCost),
m_cornerCost (b.m_cornerCost)
{};
~PNS_COST_ESTIMATOR() {};
static int CornerCost ( const SEG& a, const SEG& b);
static int CornerCost ( const SHAPE_LINE_CHAIN& aLine );
static int CornerCost ( const PNS_LINE& aLine);
void Add(PNS_LINE &aLine);
void Remove (PNS_LINE &aLine);
void Replace(PNS_LINE &aOldLine, PNS_LINE& aNewLine);
bool IsBetter( PNS_COST_ESTIMATOR& aOther, double aLengthTollerance, double aCornerTollerace ) const;
double GetLengthCost() const { return m_lengthCost; }
double GetCornerCost() const { return m_cornerCost; }
private:
double m_lengthCost;
int m_cornerCost;
public:
PNS_COST_ESTIMATOR() :
m_lengthCost( 0 ),
m_cornerCost( 0 )
{};
PNS_COST_ESTIMATOR( const PNS_COST_ESTIMATOR& b ) :
m_lengthCost( b.m_lengthCost ),
m_cornerCost( b.m_cornerCost )
{};
~PNS_COST_ESTIMATOR() {};
static int CornerCost( const SEG& a, const SEG& b );
static int CornerCost( const SHAPE_LINE_CHAIN& aLine );
static int CornerCost( const PNS_LINE& aLine );
void Add( PNS_LINE& aLine );
void Remove( PNS_LINE& aLine );
void Replace( PNS_LINE& aOldLine, PNS_LINE& aNewLine );
bool IsBetter( PNS_COST_ESTIMATOR& aOther, double aLengthTollerance,
double aCornerTollerace ) const;
double GetLengthCost() const { return m_lengthCost; }
double GetCornerCost() const { return m_cornerCost; }
private:
double m_lengthCost;
int m_cornerCost;
};
/**
* Class PNS_OPTIMIZER
*
*
* 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:
* - 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
* - 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
* - "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 {
MERGE_SEGMENTS = 0x1,
SMART_PADS = 0x2,
MERGE_OBTUSE = 0x4
};
PNS_OPTIMIZER( PNS_NODE* aWorld );
~PNS_OPTIMIZER();
PNS_OPTIMIZER( PNS_NODE *aWorld );
~PNS_OPTIMIZER();
///> a quick shortcut to optmize a line without creating and setting up an 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
static bool Optimize ( PNS_LINE *aLine, int aEffortLevel, PNS_NODE *aWorld = NULL );
bool Optimize( PNS_LINE* aLine, PNS_LINE* aResult = 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 CacheStaticItem (PNS_ITEM *aItem);
void CacheRemove( PNS_ITEM *aItem );
void ClearCache( bool aStaticOnly = false );
void SetCollisionMask( int aMask )
{
m_collisionKindMask = aMask;
}
void SetCollisionMask ( int aMask )
{
m_collisionKindMask = aMask;
}
void SetEffortLevel( int aEffort )
{
m_effortLevel = aEffort;
}
void SetEffortLevel ( int aEffort )
{
m_effortLevel = aEffort;
}
private:
private:
static const int MaxCachedItems = 256;
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
{
int hits;
bool isStatic;
};
struct CachedItem
{
int hits;
bool isStatic;
};
bool mergeObtuse (PNS_LINE *aLine);
bool mergeFull (PNS_LINE *aLine);
bool removeUglyCorners (PNS_LINE *aLine);
bool runSmartPads(PNS_LINE *aLine);
bool mergeStep ( PNS_LINE *aLine, SHAPE_LINE_CHAIN& aCurrentLine, int step );
bool mergeObtuse( PNS_LINE* aLine );
bool mergeFull( PNS_LINE* aLine );
bool removeUglyCorners( PNS_LINE* aLine );
bool runSmartPads( PNS_LINE* aLine );
bool mergeStep( PNS_LINE* aLine, SHAPE_LINE_CHAIN& aCurrentLine, int step );
bool checkColliding( PNS_ITEM *aItem, bool aUpdateCache = true );
bool checkColliding( PNS_LINE *aLine, const SHAPE_LINE_CHAIN& aOptPath );
bool checkColliding( PNS_ITEM* aItem, bool aUpdateCache = true );
bool checkColliding( PNS_LINE* aLine, const SHAPE_LINE_CHAIN& aOptPath );
void cacheAdd( PNS_ITEM *aItem, bool aIsStatic );
void removeCachedSegments (PNS_LINE *aLine, int aStartVertex = 0, int aEndVertex = -1);
void cacheAdd( PNS_ITEM* aItem, bool aIsStatic );
void removeCachedSegments( PNS_LINE* aLine, int aStartVertex = 0, int aEndVertex = -1 );
BreakoutList circleBreakouts( 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 computeBreakouts( int aWidth, const PNS_ITEM *aItem, bool aPermitDiagonal ) const;
BreakoutList circleBreakouts( 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 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;
CachedItemTags m_cacheTags;
PNS_NODE *m_world;
int m_collisionKindMask;
int m_effortLevel;
bool m_keepPostures;
typedef boost::unordered_map<PNS_ITEM*, CachedItem> CachedItemTags;
CachedItemTags m_cacheTags;
PNS_NODE* m_world;
int m_collisionKindMask;
int m_effortLevel;
bool m_keepPostures;
};
#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