2011-11-10 15:55:05 +00:00
|
|
|
/*
|
|
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
|
|
*
|
2012-06-08 09:56:42 +00:00
|
|
|
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
|
|
|
|
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
2011-11-10 15:55:05 +00:00
|
|
|
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
|
2012-06-08 09:56:42 +00:00
|
|
|
*
|
|
|
|
* Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
|
|
|
|
*
|
|
|
|
* First copyright (C) Randy Nevin, 1989 (see PCBCA package)
|
2011-11-10 15:55:05 +00:00
|
|
|
*
|
|
|
|
* 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 2
|
|
|
|
* 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, you may find one here:
|
|
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
|
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
|
|
|
* or you may write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
|
2012-06-08 09:56:42 +00:00
|
|
|
|
2011-09-20 13:57:40 +00:00
|
|
|
/**
|
|
|
|
* @file work.cpp
|
|
|
|
* @brief Automatic routing routines
|
|
|
|
*/
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2012-01-23 04:33:36 +00:00
|
|
|
#include <fctsys.h>
|
|
|
|
#include <common.h>
|
2011-09-20 13:57:40 +00:00
|
|
|
|
2012-01-23 04:33:36 +00:00
|
|
|
#include <pcbnew.h>
|
2012-06-05 19:07:33 +00:00
|
|
|
#include <autorout.h>
|
2012-01-23 04:33:36 +00:00
|
|
|
#include <cell.h>
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
|
|
|
2012-06-26 17:57:37 +00:00
|
|
|
struct CWORK // a unit of work is a source-target to connect
|
|
|
|
// this is a ratsnest item in the routing matrix world
|
2009-11-20 14:55:20 +00:00
|
|
|
{
|
2012-06-17 16:06:12 +00:00
|
|
|
int m_FromRow; // source row
|
|
|
|
int m_FromCol; // source column
|
|
|
|
int m_ToRow; // target row
|
|
|
|
int m_ToCol; // target column
|
|
|
|
RATSNEST_ITEM* m_Ratsnest; // Corresponding ratsnest
|
|
|
|
int m_NetCode; // m_NetCode
|
|
|
|
int m_ApxDist; // approximate distance
|
|
|
|
int m_Cost; // cost for sort by length
|
|
|
|
int m_Priority; // route priority
|
2012-06-26 17:57:37 +00:00
|
|
|
|
|
|
|
// the function that calculates the cost of this ratsnest:
|
|
|
|
void CalculateCost();
|
2009-11-20 14:55:20 +00:00
|
|
|
};
|
|
|
|
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2012-06-26 17:57:37 +00:00
|
|
|
// the list of ratsnests
|
|
|
|
static std::vector <CWORK> WorkList;
|
|
|
|
static unsigned Current = 0;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
|
|
|
2012-06-17 16:06:12 +00:00
|
|
|
// initialize the work list
|
2007-09-13 11:55:46 +00:00
|
|
|
void InitWork()
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2012-06-26 17:57:37 +00:00
|
|
|
WorkList.clear();
|
|
|
|
Current = 0;
|
2009-11-20 14:55:20 +00:00
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* add a unit of work to the work list
|
2009-11-20 14:55:20 +00:00
|
|
|
* Return:
|
|
|
|
* 1 if OK
|
|
|
|
* 0 if memory allocation failed
|
|
|
|
*/
|
|
|
|
|
2012-06-17 16:06:12 +00:00
|
|
|
int SetWork( int r1, int c1,
|
|
|
|
int n_c,
|
|
|
|
int r2, int c2,
|
|
|
|
RATSNEST_ITEM* pt_ch, int pri )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2012-06-26 17:57:37 +00:00
|
|
|
CWORK item;
|
|
|
|
item.m_FromRow = r1;
|
|
|
|
item.m_FromCol = c1;
|
|
|
|
item.m_NetCode = n_c;
|
|
|
|
item.m_ToRow = r2;
|
|
|
|
item.m_ToCol = c2;
|
|
|
|
item.m_Ratsnest = pt_ch;
|
|
|
|
item.m_ApxDist = RoutingMatrix.GetApxDist( r1, c1, r2, c2 );
|
|
|
|
item.CalculateCost();
|
|
|
|
item.m_Priority = pri;
|
|
|
|
WorkList.push_back( item );
|
|
|
|
return 1;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-20 14:55:20 +00:00
|
|
|
/* fetch a unit of work from the work list */
|
2012-06-17 16:06:12 +00:00
|
|
|
void GetWork( int* r1, int* c1,
|
|
|
|
int* n_c,
|
|
|
|
int* r2, int* c2,
|
2009-11-20 14:55:20 +00:00
|
|
|
RATSNEST_ITEM** pt_ch )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2012-06-26 17:57:37 +00:00
|
|
|
if( Current < WorkList.size() )
|
2009-11-20 14:55:20 +00:00
|
|
|
{
|
2012-06-26 17:57:37 +00:00
|
|
|
*r1 = WorkList[Current].m_FromRow;
|
|
|
|
*c1 = WorkList[Current].m_FromCol;
|
|
|
|
*n_c = WorkList[Current].m_NetCode;
|
|
|
|
*r2 = WorkList[Current].m_ToRow;
|
|
|
|
*c2 = WorkList[Current].m_ToCol;
|
|
|
|
*pt_ch = WorkList[Current].m_Ratsnest;
|
|
|
|
Current++;
|
2009-11-20 14:55:20 +00:00
|
|
|
}
|
2012-06-17 16:06:12 +00:00
|
|
|
else /* none left */
|
2009-11-20 14:55:20 +00:00
|
|
|
{
|
2012-06-17 16:06:12 +00:00
|
|
|
*r1 = *c1 = *r2 = *c2 = ILLEGAL;
|
|
|
|
*n_c = 0;
|
|
|
|
*pt_ch = NULL;
|
2009-11-20 14:55:20 +00:00
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-06-26 17:57:37 +00:00
|
|
|
// order the work items; shortest (low cost) first:
|
|
|
|
bool sort_by_cost( const CWORK& ref, const CWORK& item )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2012-06-26 17:57:37 +00:00
|
|
|
if( ref.m_Priority == item.m_Priority )
|
|
|
|
return ref.m_Cost < item.m_Cost;
|
2009-11-20 14:55:20 +00:00
|
|
|
|
2012-06-26 17:57:37 +00:00
|
|
|
return ref.m_Priority >= item.m_Priority;
|
|
|
|
}
|
2009-11-20 14:55:20 +00:00
|
|
|
|
2012-06-26 17:57:37 +00:00
|
|
|
void SortWork()
|
|
|
|
{
|
|
|
|
sort( WorkList.begin(), WorkList.end(), sort_by_cost );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-06-05 19:07:33 +00:00
|
|
|
/* Calculate the cost of a ratsnest:
|
2009-11-20 14:55:20 +00:00
|
|
|
* cost = (| dx | + | dy |) * disability
|
|
|
|
* disability = 1 if dx or dy = 0, max if | dx | # | dy |
|
|
|
|
*/
|
2012-06-26 17:57:37 +00:00
|
|
|
void CWORK::CalculateCost()
|
2007-05-06 16:03:28 +00:00
|
|
|
{
|
2012-06-17 16:06:12 +00:00
|
|
|
int dx, dy, mx, my;
|
|
|
|
double incl = 1.0;
|
2009-11-20 14:55:20 +00:00
|
|
|
|
2012-06-26 17:57:37 +00:00
|
|
|
dx = abs( m_ToCol - m_FromCol );
|
|
|
|
dy = abs( m_ToRow - m_FromRow );
|
2012-06-17 16:06:12 +00:00
|
|
|
mx = dx;
|
|
|
|
my = dy;
|
2009-11-20 14:55:20 +00:00
|
|
|
|
|
|
|
if( mx < my )
|
|
|
|
{
|
|
|
|
mx = dy; my = dx;
|
|
|
|
}
|
2011-09-20 13:57:40 +00:00
|
|
|
|
2009-11-20 14:55:20 +00:00
|
|
|
if( mx )
|
2012-06-05 19:07:33 +00:00
|
|
|
incl += (2 * (double) my / mx);
|
2009-11-20 14:55:20 +00:00
|
|
|
|
2012-06-26 17:57:37 +00:00
|
|
|
m_Cost = (int) ( ( dx + dy ) * incl );
|
2007-05-06 16:03:28 +00:00
|
|
|
}
|