7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-20 18:11:42 +00:00

Remove CurItem() architecture and legacy routers and drawing code.

This commit is contained in:
Jeff Young 2019-05-29 00:23:58 +01:00
parent 9d29e94cb5
commit 1e9da7f57b
82 changed files with 548 additions and 8135 deletions
common
eeschema
gerbview
include
pagelayout_editor
pcbnew

View File

@ -59,8 +59,6 @@ BASE_SCREEN::BASE_SCREEN( KICAD_T aType ) :
m_FlagModified = false; // Set when any change is made on board.
m_FlagSave = false; // Used in auto save set when an auto save is required.
SetCurItem( NULL );
}

View File

@ -578,10 +578,7 @@ void EDA_DRAW_FRAME::SetMsgPanel( EDA_ITEM* aItem )
void EDA_DRAW_FRAME::UpdateMsgPanel()
{
EDA_ITEM* item = GetScreen()->GetCurItem();
if( item )
SetMsgPanel( item );
GetToolManager()->PostEvent( EVENTS::SelectedItemsModified );
}

View File

@ -674,10 +674,7 @@ void EDA_DRAW_FRAME::SetMsgPanel( EDA_ITEM* aItem )
void EDA_DRAW_FRAME::UpdateMsgPanel()
{
EDA_ITEM* item = GetScreen()->GetCurItem();
if( item )
SetMsgPanel( item );
GetToolManager()->PostEvent( EVENTS::SelectedItemsModified );
}

View File

@ -533,6 +533,7 @@ void EDA_DRAW_PANEL::DoPrepareDC( wxDC& dc )
void EDA_DRAW_PANEL::OnPaint( wxPaintEvent& event )
{
// JEY TODO: this is all OBSOLETE...
if( GetScreen() == NULL )
{
event.Skip();

View File

@ -574,7 +574,6 @@ void LIB_EDIT_FRAME::SetCurPart( LIB_PART* aPart )
return;
m_toolManager->RunAction( EE_ACTIONS::clearSelection, true );
GetScreen()->SetCurItem( nullptr );
if( m_my_part != aPart )
{

View File

@ -209,9 +209,6 @@ void SCH_SCREEN::DeleteItem( SCH_ITEM* aItem )
}
else
{
if( GetCurItem() == aItem )
SetCurItem( nullptr );
m_drawList.Remove( aItem );
delete aItem;
}

View File

@ -81,8 +81,6 @@ void GERBVIEW_FRAME::Erase_Current_DrawLayer( bool query )
if( query && !IsOK( this, msg ) )
return;
SetCurItem( NULL );
if( m_toolManager )
m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD );

View File

@ -45,6 +45,8 @@
#include <gerbview_draw_panel_gal.h>
#include <gal/graphics_abstraction_layer.h>
#include <tool/tool_manager.h>
#include <tool/selection.h>
#include <tools/gerbview_selection_tool.h>
#include <gerbview_painter.h>
#include <view/view.h>
@ -138,10 +140,10 @@ END_EVENT_TABLE()
*/
void GERBVIEW_FRAME::Process_Special_Functions( wxCommandEvent& event )
{
// JEY TODO: OBSOLETE?
int id = event.GetId();
GERBER_DRAW_ITEM* currItem = (GERBER_DRAW_ITEM*) GetScreen()->GetCurItem();
int id = event.GetId();
GERBVIEW_SELECTION_TOOL* selTool = GetToolManager()->GetTool<GERBVIEW_SELECTION_TOOL>();
SELECTION& selection = selTool->GetSelection();
GERBER_DRAW_ITEM* currItem = (GERBER_DRAW_ITEM*) selection.Front();
switch( id )
{

View File

@ -994,26 +994,6 @@ void GERBVIEW_FRAME::SetAuxOrigin( const wxPoint& aPosition )
}
void GERBVIEW_FRAME::SetCurItem( GERBER_DRAW_ITEM* aItem, bool aDisplayInfo )
{
GetScreen()->SetCurItem( aItem );
if( aItem )
{
if( aDisplayInfo )
{
MSG_PANEL_ITEMS items;
aItem->GetMsgPanelInfo( m_UserUnits, items );
SetMsgPanel( items );
}
}
else
{
EraseMsgBox();
}
}
void GERBVIEW_FRAME::SetGridColor( COLOR4D aColor )
{
GetGalCanvas()->GetGAL()->SetGridColor( aColor );

View File

@ -108,18 +108,6 @@ public:
const TITLE_BLOCK& GetTitleBlock() const override;
void SetTitleBlock( const TITLE_BLOCK& aTitleBlock ) override;
/**
* Function SetCurItem
* sets the currently selected item and displays it in the MsgPanel.
* If the given item is NULL then the MsgPanel is erased and there is no
* currently selected item. This function is intended to make the process
* of "selecting" an item more formal, and to indivisibly tie the operation
* of selecting an item to displaying it using GERBER_DRAW_ITEM::Display_Infos().
* @param aItem The GERBER_DRAW_ITEM to make the selected item or NULL if none.
* @param aDisplayInfo = true to display item info, false if not (default = true)
*/
void SetCurItem( GERBER_DRAW_ITEM* aItem, bool aDisplayInfo = true );
/** Install the dialog box for layer selection
* @param aDefaultLayer = Preselection (NB_PCB_LAYERS for "(Deselect)" layer)
* @param aCopperLayerCount = number of copper layers

View File

@ -240,6 +240,28 @@ int GERBVIEW_CONTROL::ShowHelp( const TOOL_EVENT& aEvent )
}
int GERBVIEW_CONTROL::UpdateMessagePanel( const TOOL_EVENT& aEvent )
{
GERBVIEW_SELECTION_TOOL* selTool = m_toolMgr->GetTool<GERBVIEW_SELECTION_TOOL>();
SELECTION& selection = selTool->GetSelection();
if( selection.GetSize() == 1 )
{
EDA_ITEM* item = (EDA_ITEM*) selection.Front();
MSG_PANEL_ITEMS msgItems;
item->GetMsgPanelInfo( m_frame->GetUserUnits(), msgItems );
m_frame->SetMsgPanel( msgItems );
}
else
{
m_frame->EraseMsgBox();
}
return 0;
}
void GERBVIEW_CONTROL::setTransitions()
{
Go( &GERBVIEW_CONTROL::HighlightControl, GERBVIEW_ACTIONS::highlightClear.MakeEvent() );
@ -257,4 +279,8 @@ void GERBVIEW_CONTROL::setTransitions()
Go( &GERBVIEW_CONTROL::DisplayControl, GERBVIEW_ACTIONS::dcodeDisplay.MakeEvent() );
Go( &GERBVIEW_CONTROL::ShowHelp, GERBVIEW_ACTIONS::showHelp.MakeEvent() );
Go( &GERBVIEW_CONTROL::UpdateMessagePanel, EVENTS::SelectedEvent );
Go( &GERBVIEW_CONTROL::UpdateMessagePanel, EVENTS::UnselectedEvent );
Go( &GERBVIEW_CONTROL::UpdateMessagePanel, EVENTS::ClearedEvent );
}

View File

@ -59,6 +59,7 @@ public:
// Miscellaneous
int SwitchUnits( const TOOL_EVENT& aEvent );
int ShowHelp( const TOOL_EVENT& aEvent );
int UpdateMessagePanel( const TOOL_EVENT& aEvent );
///> Sets up handlers for various events.
void setTransitions() override;

View File

@ -452,11 +452,6 @@ bool GERBVIEW_SELECTION_TOOL::selectMultiple()
}
}
if( m_selection.Size() == 1 )
m_frame->SetCurItem( static_cast<GERBER_DRAW_ITEM*>( m_selection.Front() ) );
else
m_frame->SetCurItem( NULL );
// Inform other potentially interested tools
if( !m_selection.Empty() )
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
@ -592,8 +587,6 @@ void GERBVIEW_SELECTION_TOOL::clearSelection()
m_selection.Clear();
m_frame->SetCurItem( NULL );
// Inform other potentially interested tools
m_toolMgr->ProcessEvent( EVENTS::ClearedEvent );
}
@ -727,17 +720,6 @@ void GERBVIEW_SELECTION_TOOL::select( EDA_ITEM* aItem )
m_selection.Add( aItem );
getView()->Add( &m_selection );
selectVisually( aItem );
if( m_selection.Size() == 1 )
{
// Set as the current item, so the information about selection is displayed
m_frame->SetCurItem( static_cast<GERBER_DRAW_ITEM*>( aItem ), true );
}
else if( m_selection.Size() == 2 ) // Check only for 2, so it will not be
{ // called for every next selected item
// If multiple items are selected, do not show the information about the selected item
m_frame->SetCurItem( NULL, true );
}
}
@ -750,10 +732,7 @@ void GERBVIEW_SELECTION_TOOL::unselect( EDA_ITEM* aItem )
m_selection.Remove( aItem );
if( m_selection.Empty() )
{
m_frame->SetCurItem( NULL );
getView()->Remove( &m_selection );
}
}

View File

@ -211,15 +211,6 @@ public:
BASE_SCREEN( KICAD_T aType = SCREEN_T );
~BASE_SCREEN();
/**
* Function SetCurItem
* sets the currently selected object, m_CurrentItem.
* @param aItem Any object derived from EDA_ITEM
*/
void SetCurItem( EDA_ITEM* aItem ) { m_CurrentItem = aItem; }
EDA_ITEM* GetCurItem() const { return m_CurrentItem; }
void InitDataPoints( const wxSize& aPageSizeInternalUnits );
/* general Undo/Redo command control */

View File

@ -75,7 +75,6 @@ public:
protected:
BOARD* m_Pcb;
GENERAL_COLLECTOR* m_Collector;
PCB_GENERAL_SETTINGS m_configSettings;
@ -242,23 +241,6 @@ public:
void ProcessItemSelection( wxCommandEvent& event );
/**
* Function SetCurItem
* sets the currently selected item and displays it in the MsgPanel.
* If the given item is NULL then the MsgPanel is erased and there is no
* currently selected item. This function is intended to make the process
* of "selecting" an item more formal, and to indivisibly tie the operation
* of selecting an item to displaying it using BOARD_ITEM::Display_Infos().
* @param aItem The BOARD_ITEM to make the selected item or NULL if none.
* @param aDisplayInfo = true to display item info, false if not (default = true)
*/
void SetCurItem( BOARD_ITEM* aItem, bool aDisplayInfo = true );
BOARD_ITEM* GetCurItem();
///> @copydoc EDA_DRAW_FRAME::UpdateMsgPanel()
void UpdateMsgPanel() override;
/**
* Function GetCollectorsGuide
* @return GENERAL_COLLECTORS_GUIDE - that considers the global
@ -310,7 +292,6 @@ public:
MODULE* CreateNewModule( const wxString& aModuleName );
void Edit_Module( MODULE* module, wxDC* DC );
void Rotate_Module( wxDC* DC, MODULE* module, double angle, bool incremental );
/**
* Function PlaceModule
@ -318,11 +299,9 @@ public:
* with the new position.
*
* @param aModule A MODULE object point of the module to be placed.
* @param aDC A wxDC object point of the device context to draw \a aModule on
* or NULL if no display screen need updated.
* @param aRecreateRatsnest A bool true redraws the module rats nest.
*/
void PlaceModule( MODULE* aModule, wxDC* aDC, bool aRecreateRatsnest = true );
void PlaceModule( MODULE* aModule, bool aRecreateRatsnest = true );
void InstallPadOptionsFrame( D_PAD* pad );
@ -379,24 +358,6 @@ public:
*/
void Compile_Ratsnest( wxDC* aDC, bool aDisplayStatus );
/**
* Function build_ratsnest_module
* Build a ratsnest relative to one footprint. This is a simplified computation
* used only in move footprint. It is not optimal, but it is fast and sufficient
* to help a footprint placement
* It shows the connections from a pad to the nearest connected pad
* @param aMoveVector = move vector of the footprint being moved.
* @param aModule = module to consider.
*/
void build_ratsnest_module( MODULE *aModule, wxPoint aMoveVector );
/**
* Function TraceModuleRatsNest
* display the rats nest of a moving footprint, computed by
* build_ratsnest_module()
*/
void TraceModuleRatsNest( wxDC* aDC );
/**
* function Displays the general ratsnest
* Only ratsnest with the status bit CH_VISIBLE is set are displayed
@ -406,29 +367,6 @@ public:
*/
void DrawGeneralRatsnest( wxDC* aDC, int aNetcode = 0 );
/**
* Function TraceAirWiresToTargets
* This functions shows airwires to nearest connecting points (pads)
* from the current new track end during track creation
* Uses data prepared by BuildAirWiresTargetsList()
* @param aDC = the current device context
*/
void TraceAirWiresToTargets( wxDC* aDC );
/**
* Function BuildAirWiresTargetsList
* Build a list of candidates that can be a coonection point
* when a track is started.
* This functions prepares data to show airwires to nearest connecting points (pads)
* from the current new track to candidates during track creation
* @param aItemRef = the item connected to the starting point of the new track (track or pad)
* @param aPosition = the position of the new track end (usually the mouse cursor on grid)
* @param aNet = the netcode of the track
*/
void BuildAirWiresTargetsList( BOARD_CONNECTED_ITEM* aItemRef,
const wxPoint& aPosition,
int aNet );
/**
* Function TestNetConnection
* tests the connections relative to \a aNetCode. Track segments are assumed to be

View File

@ -57,24 +57,6 @@ public:
PCB_SCREEN* Next() const { return static_cast<PCB_SCREEN*>( Pnext ); }
/**
* Function GetCurItem
* returns the currently selected BOARD_ITEM, overriding
* BASE_SCREEN::GetCurItem().
* @return BOARD_ITEM* - the one selected, or NULL.
*/
BOARD_ITEM* GetCurItem() const
{
return (BOARD_ITEM*) BASE_SCREEN::GetCurItem();
}
/**
* Function SetCurItem
* sets the currently selected object, m_CurrentItem.
* @param aItem Any object derived from BOARD_ITEM
*/
void SetCurItem( BOARD_ITEM* aItem ) { BASE_SCREEN::SetCurItem( (EDA_ITEM*)aItem ); }
/* full undo redo management : */
// use BASE_SCREEN::ClearUndoRedoList()

View File

@ -53,24 +53,6 @@ public:
* virtual pure in BASE_SCREEN, so it must be defined here
*/
void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 ) override;
/**
* Function GetCurItem
* returns the currently selected WORKSHEET_DATAITEM, overriding
* BASE_SCREEN::GetCurItem().
* @return WORKSHEET_DATAITEM* - the one selected, or NULL.
*/
WS_DATA_ITEM* GetCurItem() const
{
return (WS_DATA_ITEM*) BASE_SCREEN::GetCurItem();
}
/**
* Function SetCurItem
* sets the currently selected object, m_CurrentItem.
* @param aItem Any object derived from WORKSHEET_DATAITEM
*/
void SetCurItem( WS_DATA_ITEM* aItem ) { BASE_SCREEN::SetCurItem( (EDA_ITEM*)aItem ); }
};

View File

@ -135,6 +135,7 @@ set( PCBNEW_DIALOGS
dialogs/dialog_set_grid_base.cpp
dialogs/dialog_swap_layers.cpp
dialogs/dialog_swap_layers_base.cpp
dialogs/dialog_target_properties.cpp
dialogs/dialog_target_properties_base.cpp
dialogs/dialog_text_properties.cpp
dialogs/dialog_text_properties_base.cpp
@ -236,16 +237,10 @@ set( PCBNEW_CLASS_SRCS
build_BOM_from_board.cpp
connect.cpp
cross-probing.cpp
deltrack.cpp
dimension.cpp
dragsegm.cpp
drc.cpp
drc_clearance_test_functions.cpp
edit.cpp
edit_track_width.cpp
editrack-part2.cpp
editrack.cpp
event_handlers_tracks_vias_sizes.cpp
files.cpp
footprint_info_impl.cpp
footprint_wizard.cpp
@ -263,16 +258,13 @@ set( PCBNEW_CLASS_SRCS
initpcb.cpp
layer_widget.cpp
load_select_footprint.cpp
magnetic_tracks_functions.cpp
menubar_footprint_editor.cpp
menubar_pcb_editor.cpp
microwave.cpp
minimun_spanning_tree.cpp
netlist.cpp
pad_edit_functions.cpp
pad_naming.cpp
pcb_base_edit_frame.cpp
pcb_footprint_edit_utils.cpp
pcb_layer_box_selector.cpp
pcb_layer_widget.cpp
# pcb_draw_panel_gal.cpp
@ -289,7 +281,6 @@ set( PCBNEW_CLASS_SRCS
specctra_import_export/specctra_export.cpp
specctra_import_export/specctra_import.cpp
specctra_import_export/specctra_keywords.cpp
target_edit.cpp
text_mod_grid_table.cpp
toolbars_footprint_editor.cpp
toolbars_footprint_viewer.cpp

View File

@ -1,278 +0,0 @@
/**
* @file autorout.cpp
* @brief Autorouting command and control.
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
*
* Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
*
* 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
*/
#include <fctsys.h>
#include <class_drawpanel.h>
#include <wxPcbStruct.h>
#include <gr_basic.h>
#include <msgpanel.h>
#include <pcbnew.h>
#include <cell.h>
#include <zones.h>
#include <class_board.h>
#include <class_module.h>
#include <class_track.h>
#include <convert_to_biu.h>
#include <autorout.h>
MATRIX_ROUTING_HEAD RoutingMatrix; // routing matrix (grid) to route 2-sided boards
/* init board, route traces*/
void PCB_EDIT_FRAME::Autoroute( wxDC* DC, int mode )
{
int start, stop;
MODULE* Module = NULL;
D_PAD* Pad = NULL;
int autoroute_net_code = -1;
wxString msg;
if( GetBoard()->GetCopperLayerCount() > 1 )
{
g_Route_Layer_TOP = GetScreen()->m_Route_Layer_TOP;
g_Route_Layer_BOTTOM = GetScreen()->m_Route_Layer_BOTTOM;
}
else
{
g_Route_Layer_TOP = g_Route_Layer_BOTTOM = B_Cu;
}
switch( mode )
{
case ROUTE_NET:
if( GetScreen()->GetCurItem() )
{
switch( GetScreen()->GetCurItem()->Type() )
{
case PCB_PAD_T:
Pad = (D_PAD*) GetScreen()->GetCurItem();
autoroute_net_code = Pad->GetNetCode();
break;
default:
break;
}
}
if( autoroute_net_code <= 0 )
{
wxMessageBox( _( "Net not selected" ) ); return;
}
break;
case ROUTE_MODULE:
Module = (MODULE*) GetScreen()->GetCurItem();
if( (Module == NULL) || (Module->Type() != PCB_MODULE_T) )
{
wxMessageBox( _( "Footprint not selected" ) );
return;
}
break;
case ROUTE_PAD:
Pad = (D_PAD*) GetScreen()->GetCurItem();
if( (Pad == NULL) || (Pad->Type() != PCB_PAD_T) )
{
wxMessageBox( _( "Pad not selected" ) );
return;
}
break;
}
if( (GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK ) == 0 )
Compile_Ratsnest( DC, true );
/* Set the flag on the ratsnest to CH_ROUTE_REQ. */
for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
{
RATSNEST_ITEM* ptmp = &GetBoard()->m_FullRatsnest[ii];
ptmp->m_Status &= ~CH_ROUTE_REQ;
switch( mode )
{
case ROUTE_ALL:
ptmp->m_Status |= CH_ROUTE_REQ;
break;
case ROUTE_NET:
if( autoroute_net_code == ptmp->GetNet() )
ptmp->m_Status |= CH_ROUTE_REQ;
break;
case ROUTE_MODULE:
{
D_PAD* pt_pad = (D_PAD*) Module->Pads();
for( ; pt_pad != NULL; pt_pad = pt_pad->Next() )
{
if( ptmp->m_PadStart == pt_pad )
ptmp->m_Status |= CH_ROUTE_REQ;
if( ptmp->m_PadEnd == pt_pad )
ptmp->m_Status |= CH_ROUTE_REQ;
}
break;
}
case ROUTE_PAD:
if( ( ptmp->m_PadStart == Pad ) || ( ptmp->m_PadEnd == Pad ) )
ptmp->m_Status |= CH_ROUTE_REQ;
break;
}
}
start = time( NULL );
/* Calculation of no fixed routing to 5 mils and more. */
RoutingMatrix.m_GridRouting = (int)GetScreen()->GetGridSize().x;
if( RoutingMatrix.m_GridRouting < (5*IU_PER_MILS) )
RoutingMatrix.m_GridRouting = 5*IU_PER_MILS;
/* Calculated ncol and nrow, matrix size for routing. */
RoutingMatrix.ComputeMatrixSize( GetBoard() );
AUTOROUTER_CONTEXT ctx = { this, GetBoard(), RoutingMatrix.m_BrdBox, DC };
m_messagePanel->EraseMsgBox();
/* Map the board */
RoutingMatrix.m_RoutingLayersCount = 1;
if( g_Route_Layer_TOP != g_Route_Layer_BOTTOM )
RoutingMatrix.m_RoutingLayersCount = 2;
if( RoutingMatrix.InitRoutingMatrix() < 0 )
{
wxMessageBox( _( "No memory for autorouting" ) );
RoutingMatrix.UnInitRoutingMatrix(); /* Free memory. */
return;
}
SetStatusText( _( "Place Cells" ) );
PlaceCells( GetBoard(), -1, FORCE_PADS );
/* Construction of the track list for router. */
RoutingMatrix.m_RouteCount = Build_Work( GetBoard() );
// DisplayRoutingMatrix( m_canvas, DC );
Solve( ctx, RoutingMatrix.m_RoutingLayersCount );
/* Free memory. */
FreeQueue();
InitWork(); /* Free memory for the list of router connections. */
RoutingMatrix.UnInitRoutingMatrix();
stop = time( NULL ) - start;
msg.Printf( wxT( "time = %d second%s" ), stop, ( stop == 1 ) ? wxT( "" ) : wxT( "s" ) );
SetStatusText( msg );
}
/* Clear the flag CH_NOROUTABLE which is set to 1 by Solve(),
* when a track was not routed.
* (If this flag is 1 the corresponding track it is not rerouted)
*/
void PCB_EDIT_FRAME::Reset_Noroutable( wxDC* DC )
{
if( ( GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK )== 0 )
Compile_Ratsnest( DC, true );
for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
{
GetBoard()->m_FullRatsnest[ii].m_Status &= ~CH_UNROUTABLE;
}
}
/* DEBUG Function: displays the routing matrix */
void DisplayRoutingMatrix( EDA_DRAW_PANEL* panel, wxDC* DC )
{
int dcell0;
COLOR4D color;
int maxi = 600 / RoutingMatrix.m_Ncols;
maxi = ( maxi * 3 ) / 4;
if( !maxi )
maxi = 1;
GRSetDrawMode( DC, GR_COPY );
for( int col = 0; col < RoutingMatrix.m_Ncols; col++ )
{
for( int row = 0; row < RoutingMatrix.m_Nrows; row++ )
{
color = COLOR4D::BLACK;
dcell0 = RoutingMatrix.GetCell( row, col, BOTTOM );
if( dcell0 & HOLE )
color = COLOR4D( GREEN );
#if 0
int dcell1 = 0;
if( RoutingMatrix.m_RoutingLayersCount )
dcell1 = GetCell( row, col, TOP );
if( dcell1 & HOLE )
color = COLOR4D( RED );
dcell0 |= dcell1;
#endif
if( ( color == COLOR4D::BLACK ) && ( dcell0 & VIA_IMPOSSIBLE ) )
color = COLOR4D( BLUE );
if( dcell0 & CELL_is_EDGE )
color = COLOR4D( YELLOW );
else if( dcell0 & CELL_is_ZONE )
color = COLOR4D( YELLOW );
#define DRAW_OFFSET_X -20
#define DRAW_OFFSET_Y 20
// if( color )
{
for( int i = 0; i < maxi; i++ )
for( int j = 0; j < maxi; j++ )
GRPutPixel( panel->GetClipBox(), DC,
( col * maxi ) + i + DRAW_OFFSET_X,
( row * maxi ) + j + DRAW_OFFSET_Y, color );
}
}
}
}

View File

@ -1,248 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
*
* Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
*
* 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
*/
/**
* @file autorout.h
*/
#ifndef AUTOROUT_H
#define AUTOROUT_H
#include <base_struct.h>
#include <class_eda_rect.h>
#include <layers_id_colors_and_visibility.h>
class BOARD;
class DRAWSEGMENT;
class TRACK;
class D_PAD;
class RATSNEST_ITEM;
class PCB_EDIT_FRAME;
#define TOP 0
#define BOTTOM 1
#define EMPTY 0
#define ILLEGAL -1
/* Autorouter commands. */
enum AUTOPLACEROUTE_OPTIONS
{
PLACE_ALL,
PLACE_OUT_OF_BOARD,
PLACE_INCREMENTAL,
PLACE_1_MODULE,
ROUTE_ALL,
ROUTE_NET,
ROUTE_MODULE,
ROUTE_PAD
};
#define MAX_ROUTING_LAYERS_COUNT 2
#define FORCE_PADS 1 /* Force placement of pads for any Netcode */
/* search statistics */
extern int OpenNodes; /* total number of nodes opened */
extern int ClosNodes; /* total number of nodes closed */
extern int MoveNodes; /* total number of nodes moved */
extern int MaxNodes; /* maximum number of nodes opened at one time */
/* Structures useful to the generation of board as bitmap. */
typedef unsigned char MATRIX_CELL;
typedef int DIST_CELL;
typedef char DIR_CELL;
struct AUTOROUTER_CONTEXT
{
///> Parent frame
PCB_EDIT_FRAME* pcbframe;
///> Board to be routed
BOARD* board;
///> Cached board bounding box
const EDA_RECT bbox;
///> Drawing context
wxDC* dc;
};
/**
* class MATRIX_ROUTING_HEAD
* handle the matrix routing that describes the actual board
*/
class MATRIX_ROUTING_HEAD
{
public:
MATRIX_CELL* m_BoardSide[MAX_ROUTING_LAYERS_COUNT]; // the image map of 2 board sides
DIST_CELL* m_DistSide[MAX_ROUTING_LAYERS_COUNT]; // the image map of 2 board sides:
// distance to cells
DIR_CELL* m_DirSide[MAX_ROUTING_LAYERS_COUNT]; // the image map of 2 board sides:
// pointers back to source
bool m_InitMatrixDone;
int m_RoutingLayersCount; // Number of layers for autorouting (0 or 1)
int m_GridRouting; // Size of grid for autoplace/autoroute
EDA_RECT m_BrdBox; // Actual board bounding box
int m_Nrows, m_Ncols; // Matrix size
int m_MemSize; // Memory requirement, just for statistics
int m_RouteCount; // Number of routes
private:
// a pointer to the current selected cell operation
void (MATRIX_ROUTING_HEAD::* m_opWriteCell)( int aRow, int aCol,
int aSide, MATRIX_CELL aCell);
public:
MATRIX_ROUTING_HEAD();
~MATRIX_ROUTING_HEAD();
void WriteCell( int aRow, int aCol, int aSide, MATRIX_CELL aCell)
{
(*this.*m_opWriteCell)( aRow, aCol, aSide, aCell );
}
/**
* function GetBrdCoordOrigin
* @return the board coordinate corresponding to the
* routing matrix origin ( board coordinate offset )
*/
wxPoint GetBrdCoordOrigin()
{
return m_BrdBox.GetOrigin();
}
/**
* Function ComputeMatrixSize
* calculates the number of rows and columns of dimensions of \a aPcb for routing and
* automatic calculation of area.
* @param aPcb = the physical board
* @param aUseBoardEdgesOnly = true to use board edges only,
* = false to use the full board bounding box (default)
*/
bool ComputeMatrixSize( BOARD* aPcb, bool aUseBoardEdgesOnly = false );
/**
* Function InitBoard
* initializes the data structures.
*
* @return the amount of memory used or -1 if default.
*/
int InitRoutingMatrix();
void UnInitRoutingMatrix();
// Initialize WriteCell to make the aLogicOp
void SetCellOperation( int aLogicOp );
// functions to read/write one cell ( point on grid routing matrix:
MATRIX_CELL GetCell( int aRow, int aCol, int aSide);
void SetCell( int aRow, int aCol, int aSide, MATRIX_CELL aCell);
void OrCell( int aRow, int aCol, int aSide, MATRIX_CELL aCell);
void XorCell( int aRow, int aCol, int aSide, MATRIX_CELL aCell);
void AndCell( int aRow, int aCol, int aSide, MATRIX_CELL aCell);
void AddCell( int aRow, int aCol, int aSide, MATRIX_CELL aCell);
DIST_CELL GetDist( int aRow, int aCol, int aSide );
void SetDist( int aRow, int aCol, int aSide, DIST_CELL );
int GetDir( int aRow, int aCol, int aSide );
void SetDir( int aRow, int aCol, int aSide, int aDir);
// calculate distance (with penalty) of a trace through a cell
int CalcDist(int x,int y,int z ,int side );
// calculate approximate distance (manhattan distance)
int GetApxDist( int r1, int c1, int r2, int c2 );
};
extern MATRIX_ROUTING_HEAD RoutingMatrix; /* 2-sided board */
/* Constants used to trace the cells on the BOARD */
#define WRITE_CELL 0
#define WRITE_OR_CELL 1
#define WRITE_XOR_CELL 2
#define WRITE_AND_CELL 3
#define WRITE_ADD_CELL 4
// Functions:
/* Initialize a color value, the cells included in the board edge of the
* pad surface by pt_pad, with the margin reserved for isolation and the
* half width of the runway
* Parameters:
* Pt_pad: pointer to the description of the pad
* color: mask write in cells
* margin: add a value to the radius or half the score pad
* op_logic: type of writing in the cell (WRITE, OR)
*/
void PlacePad( D_PAD* pt_pad, int type, int marge, int op_logic );
/* Draws a segment of track on the board. */
void TraceSegmentPcb( TRACK* pt_segm, int type, int marge, int op_logic );
void TraceSegmentPcb( DRAWSEGMENT* pt_segm, int type, int marge, int op_logic );
/* Uses the color value of all cells included in the board
* coord of the rectangle ux0, uy0 (top right corner)
* a ux1, uy1 (lower left corner) (coord PCB)
* the rectangle is horizontal (or vertical)
* masque_layer = mask layers;
* op_logic = WRITE_CELL, WRITE_OR_CELL, WRITE_XOR_CELL, WRITE_AND_CELL
*/
void TraceFilledRectangle( int ux0, int uy0, int ux1, int uy1,
LSET side, int color, int op_logic);
/* Same as above, but the rectangle is inclined angle angle. */
void TraceFilledRectangle( int ux0, int uy0, int ux1, int uy1,
double angle, LSET masque_layer,
int color, int op_logic );
/* QUEUE.CPP */
void FreeQueue();
void InitQueue();
void GetQueue( int *, int *, int *, int *, int * );
bool SetQueue( int, int, int, int, int, int, int );
void ReSetQueue( int, int, int, int, int, int, int );
/* WORK.CPP */
void InitWork();
void ReInitWork();
int SetWork( int, int, int , int, int, RATSNEST_ITEM *, int );
void GetWork( int *, int *, int *, int *, int *, RATSNEST_ITEM ** );
void SortWork(); /* order the work items; shortest first */
/* routing_matrix.cpp */
int Build_Work( BOARD * Pcb );
void PlaceCells( BOARD * Pcb, int net_code, int flag = 0 );
#endif // AUTOROUT_H

View File

@ -1,171 +0,0 @@
/**
* @file dist.cpp
* @brief Routines to calculate PCB editor auto routing distances.
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
*
* First copyright (C) Randy Nevin, 1989 (see PCBCA package)
*
* 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
*/
#include <autorout.h>
#include <cell.h>
/* The tables of distances and keep out areas are established on the basis of a
* 50 units grid size (the pitch between the cells is 50 units).
* The actual distance could be computed by a scaling factor, but this is
* not needed, we can use only reduced values
*/
/* calculate approximate distance (manhattan distance)
*/
int MATRIX_ROUTING_HEAD::GetApxDist( int r1, int c1, int r2, int c2 )
{
int d1, d2; /* row and column deltas */
if( ( d1 = r1 - r2 ) < 0 ) /* get absolute row delta */
d1 = -d1;
if( ( d2 = c1 - c2 ) < 0 ) /* get absolute column delta */
d2 = -d2;
return ( d1+d2 ) * 50;
}
/* distance to go thru a cell (en mils) */
static const int dist[10][10] =
{ /* OT=Otherside, OR=Origin (source) cell */
/*..........N, NE, E, SE, S, SW, W, NW, OT, OR */
/* N */ { 50, 60, 35, 60, 99, 60, 35, 60, 12, 12 },
/* NE */ { 60, 71, 60, 71, 60, 99, 60, 71, 23, 23 },
/* E */ { 35, 60, 50, 60, 35, 60, 99, 60, 12, 12 },
/* SE */ { 60, 71, 60, 71, 60, 71, 60, 99, 23, 23 },
/* S */ { 99, 60, 35, 60, 50, 60, 35, 60, 12, 12 },
/* SW */ { 60, 99, 60, 71, 60, 71, 60, 71, 23, 23 },
/* W */ { 35, 60, 99, 60, 35, 60, 50, 60, 12, 12 },
/* NW */ { 60, 71, 60, 99, 60, 71, 60, 71, 23, 23 },
/* OT */ { 12, 23, 12, 23, 12, 23, 12, 23, 99, 99 },
/* OR */ { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 }
};
/* penalty for extraneous holes and corners, scaled by sharpness of turn */
static const int penalty[10][10] =
{ /* OT=Otherside, OR=Origin (source) cell */
/*......... N, NE, E, SE, S, SW, W, NW, OT, OR */
/* N */ { 0, 5, 10, 15, 20, 15, 10, 5, 50, 0 },
/* NE */ { 5, 0, 5, 10, 15, 20, 15, 10, 50, 0 },
/* E */ { 10, 5, 0, 5, 10, 15, 20, 15, 50, 0 },
/* SE */ { 15, 10, 5, 0, 5, 10, 15, 20, 50, 0 },
/* S */ { 20, 15, 10, 5, 0, 5, 10, 15, 50, 0 },
/* SW */ { 15, 20, 15, 10, 5, 0, 5, 10, 50, 0 },
/* W */ { 10, 15, 20, 15, 10, 5, 0, 5, 50, 0 },
/* NW */ { 5, 10, 15, 20, 15, 10, 5, 0, 50, 0 },
/* OT */ { 50, 50, 50, 50, 50, 50, 50, 50, 100, 0 },
/* OR */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
/* penalty pour directions preferencielles */
#define PN 20
static const int dir_penalty_TOP[10][10] =
{
/* OT=Otherside, OR=Origin (source) cell */
/*......... N, NE, E, SE, S, SW, W, NW, OT, OR */
/* N */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
/* NE */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
/* E */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
/* SE */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
/* S */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
/* SW */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
/* W */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
/* NW */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
/* OT */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
/* OR */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 }
};
static int dir_penalty_BOTTOM[10][10] =
{
/* OT=Otherside, OR=Origin (source) cell */
/*......... N, NE, E, SE, S, SW, W, NW, OT, OR */
/* N */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
/* NE */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
/* E */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
/* SE */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
/* S */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
/* SW */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
/* W */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
/* NW */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
/* OT */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
/* OR */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 }
};
/*
** x is the direction to enter the cell of interest.
** y is the direction to exit the cell of interest.
** z is the direction to really exit the cell, if y=FROM_OTHERSIDE.
**
** return the distance of the trace through the cell of interest.
** the calculation is driven by the tables above.
*/
/* calculate distance (with penalty) of a trace through a cell
*/
int MATRIX_ROUTING_HEAD::CalcDist(int x,int y,int z ,int side )
{
int adjust, ldist;
adjust = 0; /* set if hole is encountered */
if( x == EMPTY )
x = 10;
if( y == EMPTY )
{
y = 10;
}
else if( y == FROM_OTHERSIDE )
{
if( z == EMPTY )
z = 10;
adjust = penalty[x-1][z-1];
}
ldist = dist[x-1][y-1] + penalty[x-1][y-1] + adjust;
if( m_RouteCount > 1 )
{
if( side == BOTTOM )
ldist += dir_penalty_TOP[x-1][y-1];
if( side == TOP )
ldist += dir_penalty_BOTTOM[x-1][y-1];
}
return ldist * 10;
}

View File

@ -1,843 +0,0 @@
/**
* @file graphpcb.cpp
* @brief PCB editor autorouting and "graphics" routines.
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
*
* Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
*
* 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
*/
#include <fctsys.h>
#include <common.h>
#include <macros.h>
#include <trigo.h>
#include <math_for_graphics.h>
#include <class_board.h>
#include <class_track.h>
#include <class_drawsegment.h>
#include <pcbnew.h>
#include <autorout.h>
#include <cell.h>
void TracePcbLine( int x0, int y0, int x1, int y1, LAYER_NUM layer, int color );
void TraceArc( int ux0, int uy0,
int ux1, int uy1,
double ArcAngle,
int lg, LAYER_NUM layer, int color,
int op_logic );
static void DrawSegmentQcq( int ux0, int uy0,
int ux1, int uy1,
int lg, LAYER_NUM layer, int color,
int op_logic );
static void TraceFilledCircle( int cx, int cy, int radius,
LSET aLayerMask,
int color,
int op_logic );
static void TraceCircle( int ux0, int uy0, int ux1, int uy1, int lg, LAYER_NUM layer,
int color, int op_logic );
// Macro call to update cell.
#define OP_CELL( layer, dy, dx ) \
{ \
if( layer == UNDEFINED_LAYER ) \
{ \
RoutingMatrix.WriteCell( dy, dx, BOTTOM, color ); \
if( RoutingMatrix.m_RoutingLayersCount > 1 ) \
RoutingMatrix.WriteCell( dy, dx, TOP, color ); \
} \
else \
{ \
if( layer == g_Route_Layer_BOTTOM ) \
RoutingMatrix.WriteCell( dy, dx, BOTTOM, color ); \
if( RoutingMatrix.m_RoutingLayersCount > 1 ) \
if( layer == g_Route_Layer_TOP ) \
RoutingMatrix.WriteCell( dy, dx, TOP, color ); \
} \
}
void PlacePad( D_PAD* aPad, int color, int marge, int op_logic )
{
int dx, dy;
wxPoint shape_pos = aPad->ShapePos();
dx = aPad->GetSize().x / 2;
dx += marge;
if( aPad->GetShape() == PAD_SHAPE_CIRCLE )
{
TraceFilledCircle( shape_pos.x, shape_pos.y, dx,
aPad->GetLayerSet(), color, op_logic );
return;
}
dy = aPad->GetSize().y / 2;
dy += marge;
if( aPad->GetShape() == PAD_SHAPE_TRAPEZOID )
{
dx += abs( aPad->GetDelta().y ) / 2;
dy += abs( aPad->GetDelta().x ) / 2;
}
// The pad is a rectangle ( horizontal or vertical )
if( int( aPad->GetOrientation() ) % 900 == 0 )
{
// Orientation turned 90 deg.
if( aPad->GetOrientation() == 900 || aPad->GetOrientation() == 2700 )
{
std::swap( dx, dy );
}
TraceFilledRectangle( shape_pos.x - dx, shape_pos.y - dy,
shape_pos.x + dx, shape_pos.y + dy,
aPad->GetLayerSet(), color, op_logic );
}
else
{
TraceFilledRectangle( shape_pos.x - dx, shape_pos.y - dy,
shape_pos.x + dx, shape_pos.y + dy,
aPad->GetOrientation(),
aPad->GetLayerSet(), color, op_logic );
}
}
/* Set to color the cells included in the circle
* Parameters:
* center: cx, cy.
* radius: a value add to the radius or half the score pad
* aLayerMask: layer occupied
* color: mask write in cells
* op_logic: type of writing in the cell (WRITE, OR)
*/
void TraceFilledCircle( int cx, int cy, int radius,
LSET aLayerMask, int color, int op_logic )
{
int row, col;
int ux0, uy0, ux1, uy1;
int row_max, col_max, row_min, col_min;
int trace = 0;
double fdistmin, fdistx, fdisty;
int tstwrite = 0;
int distmin;
if( aLayerMask[g_Route_Layer_BOTTOM] )
trace = 1; // Trace on BOTTOM
if( aLayerMask[g_Route_Layer_TOP] )
if( RoutingMatrix.m_RoutingLayersCount > 1 )
trace |= 2; // Trace on TOP
if( trace == 0 )
return;
RoutingMatrix.SetCellOperation( op_logic );
cx -= RoutingMatrix.GetBrdCoordOrigin().x;
cy -= RoutingMatrix.GetBrdCoordOrigin().y;
distmin = radius;
// Calculate the bounding rectangle of the circle.
ux0 = cx - radius;
uy0 = cy - radius;
ux1 = cx + radius;
uy1 = cy + radius;
// Calculate limit coordinates of cells belonging to the rectangle.
row_max = uy1 / RoutingMatrix.m_GridRouting;
col_max = ux1 / RoutingMatrix.m_GridRouting;
row_min = uy0 / RoutingMatrix.m_GridRouting; // if (uy0 > row_min*Board.m_GridRouting) row_min++;
col_min = ux0 / RoutingMatrix.m_GridRouting; // if (ux0 > col_min*Board.m_GridRouting) col_min++;
if( row_min < 0 )
row_min = 0;
if( row_max >= (RoutingMatrix.m_Nrows - 1) )
row_max = RoutingMatrix.m_Nrows - 1;
if( col_min < 0 )
col_min = 0;
if( col_max >= (RoutingMatrix.m_Ncols - 1) )
col_max = RoutingMatrix.m_Ncols - 1;
// Calculate coordinate limits of cell belonging to the rectangle.
if( row_min > row_max )
row_max = row_min;
if( col_min > col_max )
col_max = col_min;
fdistmin = (double) distmin * distmin;
for( row = row_min; row <= row_max; row++ )
{
fdisty = (double) ( cy - ( row * RoutingMatrix.m_GridRouting ) );
fdisty *= fdisty;
for( col = col_min; col <= col_max; col++ )
{
fdistx = (double) ( cx - ( col * RoutingMatrix.m_GridRouting ) );
fdistx *= fdistx;
if( fdistmin <= ( fdistx + fdisty ) )
continue;
if( trace & 1 )
RoutingMatrix.WriteCell( row, col, BOTTOM, color );
if( trace & 2 )
RoutingMatrix.WriteCell( row, col, TOP, color );
tstwrite = 1;
}
}
if( tstwrite )
return;
/* If no cell has been written, it affects the 4 neighboring diagonal
* (Adverse event: pad off grid in the center of the 4 neighboring
* diagonal) */
distmin = RoutingMatrix.m_GridRouting / 2 + 1;
fdistmin = ( (double) distmin * distmin ) * 2; // Distance to center point diagonally
for( row = row_min; row <= row_max; row++ )
{
fdisty = (double) ( cy - ( row * RoutingMatrix.m_GridRouting ) );
fdisty *= fdisty;
for( col = col_min; col <= col_max; col++ )
{
fdistx = (double) ( cx - ( col * RoutingMatrix.m_GridRouting ) );
fdistx *= fdistx;
if( fdistmin <= ( fdistx + fdisty ) )
continue;
if( trace & 1 )
RoutingMatrix.WriteCell( row, col, BOTTOM, color );
if( trace & 2 )
RoutingMatrix.WriteCell( row, col, TOP, color );
}
}
}
void TraceSegmentPcb( DRAWSEGMENT* pt_segm, int color, int marge, int op_logic )
{
int half_width = ( pt_segm->GetWidth() / 2 ) + marge;
// Calculate the bounding rectangle of the segment (if H, V or Via)
int ux0 = pt_segm->GetStart().x - RoutingMatrix.GetBrdCoordOrigin().x;
int uy0 = pt_segm->GetStart().y - RoutingMatrix.GetBrdCoordOrigin().y;
int ux1 = pt_segm->GetEnd().x - RoutingMatrix.GetBrdCoordOrigin().x;
int uy1 = pt_segm->GetEnd().y - RoutingMatrix.GetBrdCoordOrigin().y;
LAYER_NUM layer = pt_segm->GetLayer();
if( color == VIA_IMPOSSIBLE )
layer = UNDEFINED_LAYER;
switch( pt_segm->GetShape() )
{
// The segment is here a straight line or a circle or an arc.:
case S_CIRCLE:
TraceCircle( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic );
break;
case S_ARC:
TraceArc( ux0, uy0, ux1, uy1, pt_segm->GetAngle(), half_width, layer, color, op_logic );
break;
// The segment is here a line segment.
default:
DrawSegmentQcq( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic );
break;
}
}
void TraceSegmentPcb( TRACK* aTrack, int color, int marge, int op_logic )
{
int half_width = ( aTrack->GetWidth() / 2 ) + marge;
// Test if VIA (filled circle need to be drawn)
if( aTrack->Type() == PCB_VIA_T )
{
LSET layer_mask;
if( aTrack->IsOnLayer( g_Route_Layer_BOTTOM ) )
layer_mask.set( g_Route_Layer_BOTTOM );
if( aTrack->IsOnLayer( g_Route_Layer_TOP ) )
{
if( !layer_mask.any() )
layer_mask = LSET( g_Route_Layer_TOP );
else
layer_mask.set();
}
if( color == VIA_IMPOSSIBLE )
layer_mask.set();
if( layer_mask.any() )
TraceFilledCircle( aTrack->GetStart().x, aTrack->GetStart().y,
half_width, layer_mask, color, op_logic );
}
else
{
// Calculate the bounding rectangle of the segment
int ux0 = aTrack->GetStart().x - RoutingMatrix.GetBrdCoordOrigin().x;
int uy0 = aTrack->GetStart().y - RoutingMatrix.GetBrdCoordOrigin().y;
int ux1 = aTrack->GetEnd().x - RoutingMatrix.GetBrdCoordOrigin().x;
int uy1 = aTrack->GetEnd().y - RoutingMatrix.GetBrdCoordOrigin().y;
// Ordinary track
PCB_LAYER_ID layer = aTrack->GetLayer();
if( color == VIA_IMPOSSIBLE )
layer = UNDEFINED_LAYER;
DrawSegmentQcq( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic );
}
}
/* Draws a line, if layer = -1 on all layers
*/
void TracePcbLine( int x0, int y0, int x1, int y1, LAYER_NUM layer, int color, int op_logic )
{
int dx, dy, lim;
int cumul, inc, il, delta;
RoutingMatrix.SetCellOperation( op_logic );
if( x0 == x1 ) // Vertical.
{
if( y1 < y0 )
std::swap( y0, y1 );
dy = y0 / RoutingMatrix.m_GridRouting;
lim = y1 / RoutingMatrix.m_GridRouting;
dx = x0 / RoutingMatrix.m_GridRouting;
// Clipping limits of board.
if( ( dx < 0 ) || ( dx >= RoutingMatrix.m_Ncols ) )
return;
if( dy < 0 )
dy = 0;
if( lim >= RoutingMatrix.m_Nrows )
lim = RoutingMatrix.m_Nrows - 1;
for( ; dy <= lim; dy++ )
{
OP_CELL( layer, dy, dx );
}
return;
}
if( y0 == y1 ) // Horizontal
{
if( x1 < x0 )
std::swap( x0, x1 );
dx = x0 / RoutingMatrix.m_GridRouting;
lim = x1 / RoutingMatrix.m_GridRouting;
dy = y0 / RoutingMatrix.m_GridRouting;
// Clipping limits of board.
if( ( dy < 0 ) || ( dy >= RoutingMatrix.m_Nrows ) )
return;
if( dx < 0 )
dx = 0;
if( lim >= RoutingMatrix.m_Ncols )
lim = RoutingMatrix.m_Ncols - 1;
for( ; dx <= lim; dx++ )
{
OP_CELL( layer, dy, dx );
}
return;
}
// Here is some perspective: using the algorithm LUCAS.
if( abs( x1 - x0 ) >= abs( y1 - y0 ) ) // segment slightly inclined/
{
if( x1 < x0 )
{
std::swap( x1, x0 );
std::swap( y1, y0 );
}
dx = x0 / RoutingMatrix.m_GridRouting;
lim = x1 / RoutingMatrix.m_GridRouting;
dy = y0 / RoutingMatrix.m_GridRouting;
inc = 1;
if( y1 < y0 )
inc = -1;
il = lim - dx; cumul = il / 2;
delta = abs( y1 - y0 ) / RoutingMatrix.m_GridRouting;
for( ; dx <= lim; )
{
if( ( dx >= 0 ) && ( dy >= 0 ) &&
( dx < RoutingMatrix.m_Ncols ) &&
( dy < RoutingMatrix.m_Nrows ) )
{
OP_CELL( layer, dy, dx );
}
dx++;
cumul += delta;
if( cumul > il )
{
cumul -= il;
dy += inc;
}
}
}
else
{
if( y1 < y0 )
{
std::swap( x1, x0 );
std::swap( y1, y0 );
}
dy = y0 / RoutingMatrix.m_GridRouting;
lim = y1 / RoutingMatrix.m_GridRouting;
dx = x0 / RoutingMatrix.m_GridRouting;
inc = 1;
if( x1 < x0 )
inc = -1;
il = lim - dy;
cumul = il / 2;
delta = abs( x1 - x0 ) / RoutingMatrix.m_GridRouting;
for( ; dy <= lim; )
{
if( ( dx >= 0 ) && ( dy >= 0 ) && ( dx < RoutingMatrix.m_Ncols ) && ( dy < RoutingMatrix.m_Nrows ) )
{
OP_CELL( layer, dy, dx );
}
dy++;
cumul += delta;
if( cumul > il )
{
cumul -= il;
dx += inc;
}
}
}
}
void TraceFilledRectangle( int ux0, int uy0, int ux1, int uy1,
LSET aLayerMask, int color, int op_logic )
{
int row, col;
int row_min, row_max, col_min, col_max;
int trace = 0;
if( aLayerMask[g_Route_Layer_BOTTOM] )
trace = 1; // Trace on BOTTOM
if( aLayerMask[g_Route_Layer_TOP] && RoutingMatrix.m_RoutingLayersCount > 1 )
trace |= 2; // Trace on TOP
if( trace == 0 )
return;
RoutingMatrix.SetCellOperation( op_logic );
ux0 -= RoutingMatrix.GetBrdCoordOrigin().x;
uy0 -= RoutingMatrix.GetBrdCoordOrigin().y;
ux1 -= RoutingMatrix.GetBrdCoordOrigin().x;
uy1 -= RoutingMatrix.GetBrdCoordOrigin().y;
// Calculating limits coord cells belonging to the rectangle.
row_max = uy1 / RoutingMatrix.m_GridRouting;
col_max = ux1 / RoutingMatrix.m_GridRouting;
row_min = uy0 / RoutingMatrix.m_GridRouting;
if( uy0 > row_min * RoutingMatrix.m_GridRouting )
row_min++;
col_min = ux0 / RoutingMatrix.m_GridRouting;
if( ux0 > col_min * RoutingMatrix.m_GridRouting )
col_min++;
if( row_min < 0 )
row_min = 0;
if( row_max >= ( RoutingMatrix.m_Nrows - 1 ) )
row_max = RoutingMatrix.m_Nrows - 1;
if( col_min < 0 )
col_min = 0;
if( col_max >= ( RoutingMatrix.m_Ncols - 1 ) )
col_max = RoutingMatrix.m_Ncols - 1;
for( row = row_min; row <= row_max; row++ )
{
for( col = col_min; col <= col_max; col++ )
{
if( trace & 1 )
RoutingMatrix.WriteCell( row, col, BOTTOM, color );
if( trace & 2 )
RoutingMatrix.WriteCell( row, col, TOP, color );
}
}
}
void TraceFilledRectangle( int ux0, int uy0, int ux1, int uy1,
double angle, LSET aLayerMask, int color, int op_logic )
{
int row, col;
int cx, cy; // Center of rectangle
int radius; // Radius of the circle
int row_min, row_max, col_min, col_max;
int rotrow, rotcol;
int trace = 0;
if( aLayerMask[g_Route_Layer_BOTTOM] )
trace = 1; // Trace on BOTTOM
if( aLayerMask[g_Route_Layer_TOP] )
{
if( RoutingMatrix.m_RoutingLayersCount > 1 )
trace |= 2; // Trace on TOP
}
if( trace == 0 )
return;
RoutingMatrix.SetCellOperation( op_logic );
ux0 -= RoutingMatrix.GetBrdCoordOrigin().x;
uy0 -= RoutingMatrix.GetBrdCoordOrigin().y;
ux1 -= RoutingMatrix.GetBrdCoordOrigin().x;
uy1 -= RoutingMatrix.GetBrdCoordOrigin().y;
cx = (ux0 + ux1) / 2;
cy = (uy0 + uy1) / 2;
radius = KiROUND( Distance( ux0, uy0, cx, cy ) );
// Calculating coordinate limits belonging to the rectangle.
row_max = ( cy + radius ) / RoutingMatrix.m_GridRouting;
col_max = ( cx + radius ) / RoutingMatrix.m_GridRouting;
row_min = ( cy - radius ) / RoutingMatrix.m_GridRouting;
if( uy0 > row_min * RoutingMatrix.m_GridRouting )
row_min++;
col_min = ( cx - radius ) / RoutingMatrix.m_GridRouting;
if( ux0 > col_min * RoutingMatrix.m_GridRouting )
col_min++;
if( row_min < 0 )
row_min = 0;
if( row_max >= ( RoutingMatrix.m_Nrows - 1 ) )
row_max = RoutingMatrix.m_Nrows - 1;
if( col_min < 0 )
col_min = 0;
if( col_max >= ( RoutingMatrix.m_Ncols - 1 ) )
col_max = RoutingMatrix.m_Ncols - 1;
for( row = row_min; row <= row_max; row++ )
{
for( col = col_min; col <= col_max; col++ )
{
rotrow = row * RoutingMatrix.m_GridRouting;
rotcol = col * RoutingMatrix.m_GridRouting;
RotatePoint( &rotcol, &rotrow, cx, cy, -angle );
if( rotrow <= uy0 )
continue;
if( rotrow >= uy1 )
continue;
if( rotcol <= ux0 )
continue;
if( rotcol >= ux1 )
continue;
if( trace & 1 )
RoutingMatrix.WriteCell( row, col, BOTTOM, color );
if( trace & 2 )
RoutingMatrix.WriteCell( row, col, TOP, color );
}
}
}
/* Fills all cells inside a segment
* half-width = lg, org = ux0,uy0 end = ux1,uy1
* coordinates are in PCB units
*/
void DrawSegmentQcq( int ux0, int uy0, int ux1, int uy1, int lg, LAYER_NUM layer,
int color, int op_logic )
{
int row, col;
int inc;
int row_max, col_max, row_min, col_min;
int demi_pas;
int cx, cy, dx, dy;
RoutingMatrix.SetCellOperation( op_logic );
// Make coordinate ux1 tj > ux0 to simplify calculations
if( ux1 < ux0 )
{
std::swap( ux1, ux0 );
std::swap( uy1, uy0 );
}
// Calculating the incrementing the Y axis
inc = 1;
if( uy1 < uy0 )
inc = -1;
demi_pas = RoutingMatrix.m_GridRouting / 2;
col_min = ( ux0 - lg ) / RoutingMatrix.m_GridRouting;
if( col_min < 0 )
col_min = 0;
col_max = ( ux1 + lg + demi_pas ) / RoutingMatrix.m_GridRouting;
if( col_max > ( RoutingMatrix.m_Ncols - 1 ) )
col_max = RoutingMatrix.m_Ncols - 1;
if( inc > 0 )
{
row_min = ( uy0 - lg ) / RoutingMatrix.m_GridRouting;
row_max = ( uy1 + lg + demi_pas ) / RoutingMatrix.m_GridRouting;
}
else
{
row_min = ( uy1 - lg ) / RoutingMatrix.m_GridRouting;
row_max = ( uy0 + lg + demi_pas ) / RoutingMatrix.m_GridRouting;
}
if( row_min < 0 )
row_min = 0;
if( row_min > ( RoutingMatrix.m_Nrows - 1 ) )
row_min = RoutingMatrix.m_Nrows - 1;
if( row_max < 0 )
row_max = 0;
if( row_max > ( RoutingMatrix.m_Nrows - 1 ) )
row_max = RoutingMatrix.m_Nrows - 1;
dx = ux1 - ux0;
dy = uy1 - uy0;
double angle;
if( dx )
{
angle = ArcTangente( dy, dx );
}
else
{
angle = 900;
if( dy < 0 )
angle = -900;
}
RotatePoint( &dx, &dy, angle ); // dx = length, dy = 0
for( col = col_min; col <= col_max; col++ )
{
int cxr;
cxr = ( col * RoutingMatrix.m_GridRouting ) - ux0;
for( row = row_min; row <= row_max; row++ )
{
cy = (row * RoutingMatrix.m_GridRouting) - uy0;
cx = cxr;
RotatePoint( &cx, &cy, angle );
if( abs( cy ) > lg )
continue; // The point is too far on the Y axis.
/* This point a test is close to the segment: the position
* along the X axis must be tested.
*/
if( ( cx >= 0 ) && ( cx <= dx ) )
{
OP_CELL( layer, row, col );
continue;
}
// Examination of extremities are rounded.
if( ( cx < 0 ) && ( cx >= -lg ) )
{
if( ( ( cx * cx ) + ( cy * cy ) ) <= ( lg * lg ) )
OP_CELL( layer, row, col );
continue;
}
if( ( cx > dx ) && ( cx <= ( dx + lg ) ) )
{
if( ( ( ( cx - dx ) * ( cx - dx ) ) + ( cy * cy ) ) <= ( lg * lg ) )
OP_CELL( layer, row, col );
continue;
}
}
}
}
/* Fills all cells of the routing matrix contained in the circle
* half-width = lg, center = ux0, uy0, ux1,uy1 is a point on the circle.
* coord are in PCB units.
*/
void TraceCircle( int ux0, int uy0, int ux1, int uy1, int lg, LAYER_NUM layer,
int color, int op_logic )
{
int radius, nb_segm;
int x0, y0, // Starting point of the current segment trace.
x1, y1; // End point.
int ii;
int angle;
radius = KiROUND( Distance( ux0, uy0, ux1, uy1 ) );
x0 = x1 = radius;
y0 = y1 = 0;
if( lg < 1 )
lg = 1;
nb_segm = ( 2 * radius ) / lg;
if( nb_segm < 5 )
nb_segm = 5;
if( nb_segm > 100 )
nb_segm = 100;
for( ii = 1; ii < nb_segm; ii++ )
{
angle = (3600 * ii) / nb_segm;
x1 = KiROUND( cosdecideg( radius, angle ) );
y1 = KiROUND( sindecideg( radius, angle ) );
DrawSegmentQcq( x0 + ux0, y0 + uy0, x1 + ux0, y1 + uy0, lg, layer, color, op_logic );
x0 = x1;
y0 = y1;
}
DrawSegmentQcq( x1 + ux0, y1 + uy0, ux0 + radius, uy0, lg, layer, color, op_logic );
}
/* Fills all routing matrix cells contained in the arc
* angle = ArcAngle, half-width lg
* center = ux0,uy0, starting at ux1, uy1. Coordinates are in
* PCB units.
*/
void TraceArc( int ux0, int uy0, int ux1, int uy1, double ArcAngle, int lg,
LAYER_NUM layer, int color, int op_logic )
{
int radius, nb_segm;
int x0, y0, // Starting point of the current segment trace
x1, y1; // End point
int ii;
double angle, StAngle;
radius = KiROUND( Distance( ux0, uy0, ux1, uy1 ) );
x0 = ux1 - ux0;
y0 = uy1 - uy0;
StAngle = ArcTangente( uy1 - uy0, ux1 - ux0 );
if( lg < 1 )
lg = 1;
nb_segm = ( 2 * radius ) / lg;
nb_segm = ( nb_segm * std::abs( ArcAngle ) ) / 3600;
if( nb_segm < 5 )
nb_segm = 5;
if( nb_segm > 100 )
nb_segm = 100;
for( ii = 1; ii <= nb_segm; ii++ )
{
angle = ( ArcAngle * ii ) / nb_segm;
angle += StAngle;
NORMALIZE_ANGLE_POS( angle );
x1 = KiROUND( cosdecideg( radius, angle ) );
y1 = KiROUND( cosdecideg( radius, angle ) );
DrawSegmentQcq( x0 + ux0, y0 + uy0, x1 + ux0, y1 + uy0, lg, layer, color, op_logic );
x0 = x1;
y0 = y1;
}
}

View File

@ -1,173 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
*
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
*
* 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
*/
/**
* @file move_and_route_event_functions.cpp
* @brief Routines for automatic displacement and rotation of modules.
*/
#include <algorithm>
#include <fctsys.h>
#include <class_drawpanel.h>
#include <confirm.h>
#include <kicad_string.h>
#include <pcbnew.h>
#include <wxPcbStruct.h>
#include <kicad_device_context.h>
#include <autorout.h>
#include <cell.h>
#include <pcbnew_id.h>
#include <class_board.h>
#include <class_module.h>
typedef enum {
FIXE_MODULE,
FREE_MODULE,
FIXE_ALL_MODULES,
FREE_ALL_MODULES
} SelectFixeFct;
wxString ModulesMaskSelection = wxT( "*" );
/* Called on events (popup menus) relative to automove and autoplace footprints
*/
void PCB_EDIT_FRAME::OnPlaceOrRouteFootprints( wxCommandEvent& event )
{
int id = event.GetId();
if( m_mainToolBar == NULL )
return;
INSTALL_UNBUFFERED_DC( dc, m_canvas );
switch( id )
{
case ID_POPUP_PCB_AUTOROUTE_SELECT_LAYERS:
return;
case ID_POPUP_PCB_AUTOPLACE_FIXE_MODULE:
LockModule( (MODULE*) GetScreen()->GetCurItem(), true );
return;
case ID_POPUP_PCB_AUTOPLACE_FREE_MODULE:
LockModule( (MODULE*) GetScreen()->GetCurItem(), false );
return;
case ID_POPUP_PCB_AUTOPLACE_FREE_ALL_MODULES:
LockModule( NULL, false );
return;
case ID_POPUP_PCB_AUTOPLACE_FIXE_ALL_MODULES:
LockModule( NULL, true );
return;
default: // Abort a current command (if any)
m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
break;
}
// Erase ratsnest if needed
if( GetBoard()->IsElementVisible( LAYER_RATSNEST ) )
DrawGeneralRatsnest( &dc );
GetBoard()->m_Status_Pcb |= DO_NOT_SHOW_GENERAL_RASTNEST;
switch( id )
{
case ID_POPUP_PCB_AUTOPLACE_CURRENT_MODULE:
AutoPlaceModule( (MODULE*) GetScreen()->GetCurItem(), PLACE_1_MODULE, &dc );
break;
case ID_POPUP_PCB_AUTOPLACE_ALL_MODULES:
AutoPlaceModule( NULL, PLACE_ALL, &dc );
break;
case ID_POPUP_PCB_AUTOPLACE_NEW_MODULES:
AutoPlaceModule( NULL, PLACE_OUT_OF_BOARD, &dc );
break;
case ID_POPUP_PCB_AUTOPLACE_NEXT_MODULE:
AutoPlaceModule( NULL, PLACE_INCREMENTAL, &dc );
break;
case ID_POPUP_PCB_SPREAD_ALL_MODULES:
if( !IsOK( this,
_("Not locked footprints inside the board will be moved. OK?") ) )
break;
// Fall through
case ID_POPUP_PCB_SPREAD_NEW_MODULES:
if( GetBoard()->m_Modules == NULL )
{
DisplayError( this, _( "No footprint found!" ) );
return;
}
else
{
MODULE* footprint = GetBoard()->m_Modules;
std::vector<MODULE*> footprintList;
for( ; footprint != NULL; footprint = footprint->Next() )
footprintList.push_back( footprint );
SpreadFootprints( &footprintList, id == ID_POPUP_PCB_SPREAD_NEW_MODULES,
true, GetCrossHairPosition() );
}
break;
case ID_POPUP_PCB_AUTOROUTE_ALL_MODULES:
Autoroute( &dc, ROUTE_ALL );
break;
case ID_POPUP_PCB_AUTOROUTE_MODULE:
Autoroute( &dc, ROUTE_MODULE );
break;
case ID_POPUP_PCB_AUTOROUTE_PAD:
Autoroute( &dc, ROUTE_PAD );
break;
case ID_POPUP_PCB_AUTOROUTE_NET:
Autoroute( &dc, ROUTE_NET );
break;
case ID_POPUP_PCB_AUTOROUTE_RESET_UNROUTED:
Reset_Noroutable( &dc );
break;
default:
wxMessageBox( wxT( "OnPlaceOrRouteFootprints command error" ) );
break;
}
GetBoard()->m_Status_Pcb &= ~DO_NOT_SHOW_GENERAL_RASTNEST;
Compile_Ratsnest( &dc, true );
}

View File

@ -1,220 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
*
* Copyright (C) 1992-2015 KiCad Developers, see change_log.txt for contributors.
*
* First copyright (C) Randy Nevin, 1989 (see PCBCA package)
*
* 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
*/
/**
* @file queue.cpp
*/
#include <fctsys.h>
#include <common.h>
#include <pcbnew.h>
#include <autorout.h>
#include <cell.h>
struct PcbQueue /* search queue structure */
{
struct PcbQueue* Next;
int Row; /* current row */
int Col; /* current column */
int Side; /* 0=top, 1=bottom */
int Dist; /* path distance to this cell so far */
int ApxDist; /* approximate distance to target from here */
};
static long qlen = 0; /* current queue length */
static struct PcbQueue* Head = NULL;
static struct PcbQueue* Tail = NULL;
static struct PcbQueue* Save = NULL; /* hold empty queue structs */
/* Free the memory used for storing all the queue */
void FreeQueue()
{
struct PcbQueue* p;
InitQueue();
while( (p = Save) != NULL )
{
Save = p->Next;
delete p;
}
}
/* initialize the search queue */
void InitQueue()
{
struct PcbQueue* p;
while( (p = Head) != NULL )
{
Head = p->Next;
p->Next = Save; Save = p;
}
Tail = NULL;
OpenNodes = ClosNodes = MoveNodes = MaxNodes = qlen = 0;
}
/* get search queue item from list */
void GetQueue( int* r, int* c, int* s, int* d, int* a )
{
struct PcbQueue* p;
if( (p = Head) != NULL ) /* return first item in list */
{
*r = p->Row; *c = p->Col;
*s = p->Side;
*d = p->Dist; *a = p->ApxDist;
if( (Head = p->Next) == NULL )
Tail = NULL;
/* put node on free list */
p->Next = Save; Save = p;
ClosNodes++; qlen--;
}
else /* empty list */
{
*r = *c = *s = *d = *a = ILLEGAL;
}
}
/* add a search node to the list
* :
* 1 - OK
* 0 - Failed to allocate memory.
*/
bool SetQueue( int r, int c, int side, int d, int a, int r2, int c2 )
{
struct PcbQueue* p, * q, * t;
int i, j;
j = 0; // gcc warning fix
if( (p = Save) != NULL ) /* try free list first */
{
Save = p->Next;
}
else if( ( p = (PcbQueue*) operator new( sizeof( PcbQueue ), std::nothrow ) ) == NULL )
{
return 0;
}
p->Row = r;
p->Col = c;
p->Side = side;
i = (p->Dist = d) + (p->ApxDist = a);
p->Next = NULL;
if( (q = Head) != NULL ) /* insert in proper position in list */
{
if( q->Dist + q->ApxDist > i ) /* insert at head */
{
p->Next = q; Head = p;
}
else /* search for proper position */
{
for( t = q, q = q->Next; q && i > ( j = q->Dist + q->ApxDist ); t = q, q = q->Next )
;
if( q && i == j && q->Row == r2 && q->Col == c2 )
{
/* insert after q, which is a goal node */
if( ( p->Next = q->Next ) == NULL )
Tail = p;
q->Next = p;
}
else /* insert in front of q */
{
if( ( p->Next = q ) == NULL )
Tail = p;
t->Next = p;
}
}
}
else /* empty search list */
{
Head = Tail = p;
}
OpenNodes++;
if( ++qlen > MaxNodes )
MaxNodes = qlen;
return 1;
}
/* reposition node in list */
void ReSetQueue( int r, int c, int s, int d, int a, int r2, int c2 )
{
struct PcbQueue* p, * q;
/* first, see if it is already in the list */
for( q = NULL, p = Head; p; q = p, p = p->Next )
{
if( p->Row == r && p->Col == c && p->Side == s )
{
/* old one to remove */
if( q )
{
if( ( q->Next = p->Next ) == NULL )
Tail = q;
}
else if( ( Head = p->Next ) == NULL )
{
Tail = NULL;
}
p->Next = Save;
Save = p;
OpenNodes--;
MoveNodes++;
qlen--;
break;
}
}
if( !p ) /* not found, it has already been closed once */
ClosNodes--; /* we will close it again, but just count once */
/* if it was there, it's gone now; insert it at the proper position */
bool res = SetQueue( r, c, s, d, a, r2, c2 );
(void) res;
}

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More