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:
parent
9d29e94cb5
commit
1e9da7f57b
common
eeschema
gerbview
include
pagelayout_editor
pcbnew
CMakeLists.txt
autorouter
autorout.cppautorout.hdist.cppgraphpcb.cppmove_and_route_event_functions.cppqueue.cppsolve.cppwork.cpp
class_board.cppclass_board.hclass_module.hclass_pcb_target.cppcross-probing.cppdeltrack.cppdialogs
dialog_cleanup_tracks_and_vias.cppdialog_drc.cppdialog_exchange_footprints.cppdialog_find.cppdialog_global_deletion.cppdialog_global_edit_tracks_and_vias.cppdialog_netlist.cppdialog_target_properties.cppdialog_text_properties.cppdialog_text_properties.h
dimension.cppdrag.hdragsegm.cppedit.cppedit_track_width.cppeditrack-part2.cppeditrack.cppevent_handlers_tracks_vias_sizes.cppfootprint_edit_frame.cppfootprint_edit_frame.hfootprint_editor_utils.cppfootprint_libraries_utils.cppfootprint_viewer_frame.cppfootprint_viewer_frame.hfootprint_wizard_frame_functions.cppinitpcb.cppload_select_footprint.cppmagnetic_tracks_functions.cppminimun_spanning_tree.cppminimun_spanning_tree.hnetlist.cpppcb_base_edit_frame.hpcb_base_frame.cpppcb_edit_frame.cpppcb_edit_frame.hpcb_footprint_edit_utils.cpppcb_legacy_draw_utils.cppprotos.hratsnest.cppspecctra_import_export
target_edit.cpptools
tracks_cleaner.cppundo_redo.cppzones_by_polygon.cpp@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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 )
|
||||
{
|
||||
|
@ -209,9 +209,6 @@ void SCH_SCREEN::DeleteItem( SCH_ITEM* aItem )
|
||||
}
|
||||
else
|
||||
{
|
||||
if( GetCurItem() == aItem )
|
||||
SetCurItem( nullptr );
|
||||
|
||||
m_drawList.Remove( aItem );
|
||||
delete aItem;
|
||||
}
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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 )
|
||||
{
|
||||
|
@ -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 );
|
||||
|
@ -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
|
||||
|
@ -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 );
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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 ); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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 );
|
||||
}
|
@ -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
Loading…
Reference in New Issue
Block a user