From fc7798b7d7d8156da51410ac9ac6e7ef4b0fb24a Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 28 Nov 2013 15:19:50 +0100 Subject: [PATCH 01/95] Double click support for the Tool Framework. --- common/drawpanel_gal.cpp | 27 +++++++++-------- common/gal/cairo/cairo_gal.cpp | 19 +++++++----- common/gal/opengl/opengl_gal.cpp | 19 +++++++----- common/tool/tool_dispatcher.cpp | 25 +++++++++++---- common/tool/tool_event.cpp | 3 +- include/tool/tool_event.h | 52 +++++++++++++++++++------------- 6 files changed, 89 insertions(+), 56 deletions(-) diff --git a/common/drawpanel_gal.cpp b/common/drawpanel_gal.cpp index 3ec9568fde..bbfefd3c10 100644 --- a/common/drawpanel_gal.cpp +++ b/common/drawpanel_gal.cpp @@ -78,18 +78,21 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin Connect( wxEVT_SIZE, wxSizeEventHandler( EDA_DRAW_PANEL_GAL::onSize ), NULL, this ); /* Generic events for the Tool Dispatcher */ - Connect( wxEVT_MOTION, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_LEFT_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_LEFT_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_RIGHT_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_RIGHT_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_MIDDLE_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_MIDDLE_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_MOUSEWHEEL, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_CHAR_HOOK, wxEventHandler( EDA_DRAW_PANEL_GAL::skipEvent ) ); - Connect( wxEVT_KEY_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_KEY_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_ENTER_WINDOW, wxEventHandler( EDA_DRAW_PANEL_GAL::onEnter ), NULL, this ); + Connect( wxEVT_MOTION, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); + Connect( wxEVT_LEFT_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); + Connect( wxEVT_LEFT_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); + Connect( wxEVT_LEFT_DCLICK, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); + Connect( wxEVT_RIGHT_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); + Connect( wxEVT_RIGHT_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); + Connect( wxEVT_RIGHT_DCLICK, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); + Connect( wxEVT_MIDDLE_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); + Connect( wxEVT_MIDDLE_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); + Connect( wxEVT_MIDDLE_DCLICK, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); + Connect( wxEVT_MOUSEWHEEL, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); + Connect( wxEVT_CHAR_HOOK, wxEventHandler( EDA_DRAW_PANEL_GAL::skipEvent ) ); + Connect( wxEVT_KEY_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); + Connect( wxEVT_KEY_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); + Connect( wxEVT_ENTER_WINDOW, wxEventHandler( EDA_DRAW_PANEL_GAL::onEnter ), NULL, this ); Connect( KIGFX::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); diff --git a/common/gal/cairo/cairo_gal.cpp b/common/gal/cairo/cairo_gal.cpp index 110f647146..5f180d7338 100644 --- a/common/gal/cairo/cairo_gal.cpp +++ b/common/gal/cairo/cairo_gal.cpp @@ -57,15 +57,18 @@ CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, Connect( wxEVT_PAINT, wxPaintEventHandler( CAIRO_GAL::onPaint ) ); // Mouse events are skipped to the parent - Connect( wxEVT_MOTION, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); - Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); - Connect( wxEVT_LEFT_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); - Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); - Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); - Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); - Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); + Connect( wxEVT_MOTION, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); + Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); + Connect( wxEVT_LEFT_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); + Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); + Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); + Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); + Connect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); + Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); + Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); + Connect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); #if defined _WIN32 || defined _WIN64 - Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); + Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); #endif SetSize( aParent->GetSize() ); diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index 970cc32d16..f9cccbd365 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -70,15 +70,18 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, Connect( wxEVT_PAINT, wxPaintEventHandler( OPENGL_GAL::onPaint ) ); // Mouse events are skipped to the parent - Connect( wxEVT_MOTION, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); - Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); - Connect( wxEVT_LEFT_UP, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); - Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); - Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); - Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); - Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); + Connect( wxEVT_MOTION, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); + Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); + Connect( wxEVT_LEFT_UP, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); + Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); + Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); + Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); + Connect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); + Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); + Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); + Connect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); #if defined _WIN32 || defined _WIN64 - Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); + Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); #endif SetSize( aParent->GetSize() ); diff --git a/common/tool/tool_dispatcher.cpp b/common/tool/tool_dispatcher.cpp index 49ab4382ac..b655113b38 100644 --- a/common/tool/tool_dispatcher.cpp +++ b/common/tool/tool_dispatcher.cpp @@ -43,10 +43,11 @@ using boost::optional; struct TOOL_DISPATCHER::BUTTON_STATE { BUTTON_STATE( TOOL_MOUSE_BUTTONS aButton, const wxEventType& aDownEvent, - const wxEventType& aUpEvent ) : + const wxEventType& aUpEvent, const wxEventType& aDblClickEvent ) : button( aButton ), downEvent( aDownEvent ), - upEvent( aUpEvent ) + upEvent( aUpEvent ), + dblClickEvent( aDblClickEvent ) {}; ///> Flag indicating that dragging is active for the given button. @@ -74,6 +75,9 @@ struct TOOL_DISPATCHER::BUTTON_STATE ///> The type of wxEvent that determines mouse button release. wxEventType upEvent; + ///> The type of wxEvent that determines mouse button double click. + wxEventType dblClickEvent; + ///> Time stamp for the last mouse button press event. wxLongLong downTimestamp; @@ -89,9 +93,12 @@ struct TOOL_DISPATCHER::BUTTON_STATE TOOL_DISPATCHER::TOOL_DISPATCHER( TOOL_MANAGER* aToolMgr, PCB_BASE_FRAME* aEditFrame ) : m_toolMgr( aToolMgr ), m_editFrame( aEditFrame ) { - m_buttons.push_back( new BUTTON_STATE( BUT_LEFT, wxEVT_LEFT_DOWN, wxEVT_LEFT_UP ) ); - m_buttons.push_back( new BUTTON_STATE( BUT_RIGHT, wxEVT_RIGHT_DOWN, wxEVT_RIGHT_UP ) ); - m_buttons.push_back( new BUTTON_STATE( BUT_MIDDLE, wxEVT_MIDDLE_DOWN, wxEVT_MIDDLE_UP ) ); + m_buttons.push_back( new BUTTON_STATE( BUT_LEFT, wxEVT_LEFT_DOWN, + wxEVT_LEFT_UP, wxEVT_LEFT_DCLICK ) ); + m_buttons.push_back( new BUTTON_STATE( BUT_RIGHT, wxEVT_RIGHT_DOWN, + wxEVT_RIGHT_UP, wxEVT_RIGHT_DCLICK ) ); + m_buttons.push_back( new BUTTON_STATE( BUT_MIDDLE, wxEVT_MIDDLE_DOWN, + wxEVT_MIDDLE_UP, wxEVT_MIDDLE_DCLICK ) ); ResetState(); } @@ -126,6 +133,7 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti bool up = type == st->upEvent; bool down = type == st->downEvent; + bool dblClick = type == st->dblClickEvent; int mods = decodeModifiers( static_cast( &aEvent ) ); int args = st->button | mods; @@ -162,6 +170,10 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti st->dragging = false; } + else if( dblClick ) + { + evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_DBLCLICK, args ); + } if( st->pressed && aMotion ) { @@ -204,8 +216,9 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) type == wxEVT_LEFT_DOWN || type == wxEVT_LEFT_UP || type == wxEVT_MIDDLE_DOWN || type == wxEVT_MIDDLE_UP || type == wxEVT_RIGHT_DOWN || type == wxEVT_RIGHT_UP || + type == wxEVT_LEFT_DCLICK || type == wxEVT_MIDDLE_DCLICK || type == wxEVT_RIGHT_DCLICK || // Event issued whem mouse retains position in screen coordinates, - // but changes in world coordinates (eg. autopanning) + // but changes in world coordinates (e.g. autopanning) type == KIGFX::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE ) { VECTOR2D screenPos = m_toolMgr->GetViewControls()->GetCursorPosition(); diff --git a/common/tool/tool_event.cpp b/common/tool/tool_event.cpp index 15ae3314e7..978550406b 100644 --- a/common/tool/tool_event.cpp +++ b/common/tool/tool_event.cpp @@ -77,6 +77,7 @@ const std::string TOOL_EVENT::Format() const const FlagString actions[] = { { TA_MOUSE_CLICK, "click" }, + { TA_MOUSE_DBLCLICK, "double click" }, { TA_MOUSE_UP, "button-up" }, { TA_MOUSE_DOWN, "button-down" }, { TA_MOUSE_DRAG, "drag" }, @@ -102,7 +103,7 @@ const std::string TOOL_EVENT::Format() const { BUT_LEFT, "left" }, { BUT_RIGHT, "right" }, { BUT_MIDDLE, "middle" }, - { 0, "" } + { 0, "" } }; const FlagString modifiers[] = diff --git a/include/tool/tool_event.h b/include/tool/tool_event.h index 44cb4379cd..1ec5b1414d 100644 --- a/include/tool/tool_event.h +++ b/include/tool/tool_event.h @@ -54,39 +54,43 @@ enum TOOL_EVENT_CATEGORY enum TOOL_ACTIONS { // UI input events - TA_NONE = 0x0000, - TA_MOUSE_CLICK = 0x0001, - TA_MOUSE_UP = 0x0002, - TA_MOUSE_DOWN = 0x0004, - TA_MOUSE_DRAG = 0x0008, - TA_MOUSE_MOTION = 0x0010, - TA_MOUSE_WHEEL = 0x0020, - TA_MOUSE = 0x003f, - TA_KEY_UP = 0x0040, - TA_KEY_DOWN = 0x0080, - TA_KEYBOARD = TA_KEY_UP | TA_KEY_DOWN, + TA_NONE = 0x0000, + TA_MOUSE_CLICK = 0x0001, + TA_MOUSE_DBLCLICK = 0x0002, + TA_MOUSE_UP = 0x0004, + TA_MOUSE_DOWN = 0x0008, + TA_MOUSE_DRAG = 0x0010, + TA_MOUSE_MOTION = 0x0020, + TA_MOUSE_WHEEL = 0x0040, + TA_MOUSE = 0x007f, + + TA_KEY_UP = 0x0080, + TA_KEY_DOWN = 0x0100, + TA_KEYBOARD = TA_KEY_UP | TA_KEY_DOWN, // View related events - TA_VIEW_REFRESH = 0x0100, - TA_VIEW_ZOOM = 0x0200, - TA_VIEW_PAN = 0x0400, - TA_VIEW_DIRTY = 0x0800, - TA_CHANGE_LAYER = 0x1000, + TA_VIEW_REFRESH = 0x0200, + TA_VIEW_ZOOM = 0x0400, + TA_VIEW_PAN = 0x0800, + TA_VIEW_DIRTY = 0x1000, + TA_VIEW = 0x1e00, + + TA_CHANGE_LAYER = 0x2000, // Tool cancel event. Issued automagically when the user hits escape or selects End Tool from // the context menu. - TA_CANCEL_TOOL = 0x2000, + TA_CANCEL_TOOL = 0x4000, // Context menu update. Issued whenever context menu is open and the user hovers the mouse // over one of choices. Used in dynamic highligting in disambiguation menu - TA_CONTEXT_MENU_UPDATE = 0x4000, + TA_CONTEXT_MENU_UPDATE = 0x8000, // Context menu choice. Sent if the user picked something from the context menu or // closed it without selecting anything. - TA_CONTEXT_MENU_CHOICE = 0x8000, + TA_CONTEXT_MENU_CHOICE = 0x10000, // Tool action (allows to control tools) - TA_ACTION = 0x10000, + TA_ACTION = 0x20000, TA_ANY = 0xffffffff }; @@ -233,6 +237,12 @@ public: && ( ( m_mouseButtons & aButtonMask ) == aButtonMask ); } + bool IsDblClick( int aButtonMask = BUT_ANY ) const + { + return ( m_actions == TA_MOUSE_DBLCLICK ) + && ( ( m_mouseButtons & aButtonMask ) == aButtonMask ); + } + bool IsDrag( int aButtonMask = BUT_ANY ) const { return ( m_actions == TA_MOUSE_DRAG ) && ( ( m_mouseButtons & aButtonMask ) == aButtonMask ); @@ -277,7 +287,7 @@ public: void SetMouseDragOrigin( const VECTOR2D& aP ) { m_mouseDragOrigin = aP; - } + } void SetMousePosition( const VECTOR2D& aP ) { From 4343c6a24f870fb299cb35744c6b17fc5de9165e Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 28 Nov 2013 15:24:19 +0100 Subject: [PATCH 02/95] Automatic unregistration of tool actions during ACTION_MANAGER destruction. --- common/tool/action_manager.cpp | 7 +++++++ include/tool/action_manager.h | 6 ++++++ pcbnew/tools/pcb_tools.cpp | 7 +------ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/common/tool/action_manager.cpp b/common/tool/action_manager.cpp index be90ef055f..63aa99f8d8 100644 --- a/common/tool/action_manager.cpp +++ b/common/tool/action_manager.cpp @@ -34,6 +34,13 @@ ACTION_MANAGER::ACTION_MANAGER( TOOL_MANAGER* aToolManager ) : } +ACTION_MANAGER::~ACTION_MANAGER() +{ + while( !m_actionIdIndex.empty() ) + UnregisterAction( m_actionIdIndex.begin()->second ); +} + + void ACTION_MANAGER::RegisterAction( TOOL_ACTION* aAction ) { assert( aAction->GetId() == -1 ); // Check if the TOOL_ACTION was not registered before diff --git a/include/tool/action_manager.h b/include/tool/action_manager.h index 239ad606b7..dbcb7b33b6 100644 --- a/include/tool/action_manager.h +++ b/include/tool/action_manager.h @@ -47,6 +47,12 @@ public: */ ACTION_MANAGER( TOOL_MANAGER* aToolManager ); + /** + * Destructor. + * Unregisters every registered action. + */ + ~ACTION_MANAGER(); + /** * Function RegisterAction() * Adds a tool action to the manager and sets it up. After that is is possible to invoke diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index f3749a0c94..2f9676cb94 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -61,13 +61,8 @@ void PCB_EDIT_FRAME::setupTools() void PCB_EDIT_FRAME::destroyTools() { - m_toolManager->UnregisterAction( &COMMON_ACTIONS::moveActivate ); - m_toolManager->UnregisterAction( &COMMON_ACTIONS::selectionActivate ); - m_toolManager->UnregisterAction( &COMMON_ACTIONS::rotate ); - m_toolManager->UnregisterAction( &COMMON_ACTIONS::flip ); - - delete m_toolDispatcher; delete m_toolManager; + delete m_toolDispatcher; } From 947a846d2eb51e3d3ac64c4dbfa6e3bcb6f992b3 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 29 Nov 2013 09:37:23 +0100 Subject: [PATCH 03/95] Moved the SELECTION_TOOL out of the KIGFX namespace. --- pcbnew/tools/selection_tool.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 262d93ac45..decd7fe9e5 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -47,7 +47,6 @@ #include "bright_box.h" #include "common_actions.h" -using namespace KIGFX; using boost::optional; SELECTION_TOOL::SELECTION_TOOL() : @@ -81,7 +80,7 @@ void SELECTION_TOOL::Reset() int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) { - VIEW* view = getView(); + KIGFX::VIEW* view = getView(); assert( getModel( PCB_T ) != NULL ); @@ -176,7 +175,7 @@ void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem ) void SELECTION_TOOL::clearSelection() { - VIEW_GROUP::const_iter it, it_end; + KIGFX::VIEW_GROUP::const_iter it, it_end; for( it = m_selection.group->Begin(), it_end = m_selection.group->End(); it != it_end; ++it ) { @@ -286,7 +285,7 @@ bool SELECTION_TOOL::selectMultiple() { bool cancelled = false; // Was the tool cancelled while it was running? m_multiple = true; // Multiple selection mode is active - VIEW* view = getView(); + KIGFX::VIEW* view = getView(); getViewControls()->SetAutoPan( true ); view->Add( m_selArea ); @@ -308,7 +307,7 @@ bool SELECTION_TOOL::selectMultiple() m_selArea->SetOrigin( evt->DragOrigin() ); m_selArea->SetEnd( evt->Position() ); m_selArea->ViewSetVisible( true ); - m_selArea->ViewUpdate( VIEW_ITEM::GEOMETRY ); + m_selArea->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } if( evt->IsMouseUp( BUT_LEFT ) ) @@ -317,11 +316,11 @@ bool SELECTION_TOOL::selectMultiple() m_selArea->ViewSetVisible( false ); // Mark items within the selection box as selected - std::vector selectedItems; + std::vector selectedItems; BOX2I selectionBox = m_selArea->ViewBBox(); view->Query( selectionBox, selectedItems ); // Get the list of selected items - std::vector::iterator it, it_end; + std::vector::iterator it, it_end; for( it = selectedItems.begin(), it_end = selectedItems.end(); it != it_end; ++it ) { @@ -405,7 +404,7 @@ BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector ) } // Removes possible brighten mark - getView()->MarkTargetDirty( TARGET_OVERLAY ); + getView()->MarkTargetDirty( KIGFX::TARGET_OVERLAY ); // Restore the original menu SetContextMenu( &m_menu, CMENU_BUTTON ); From a078fa67798fc6e25416762577adb49b977152a7 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 29 Nov 2013 16:45:39 +0100 Subject: [PATCH 04/95] Storing the selected item position from a context menu. --- common/tool/context_menu.cpp | 7 +++++-- common/tool/tool_dispatcher.cpp | 2 +- common/tool/tool_manager.cpp | 9 ++++++--- include/tool/context_menu.h | 14 ++++++++++++++ 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/common/tool/context_menu.cpp b/common/tool/context_menu.cpp index e20dfdf115..6dfab27e58 100644 --- a/common/tool/context_menu.cpp +++ b/common/tool/context_menu.cpp @@ -29,7 +29,7 @@ #include CONTEXT_MENU::CONTEXT_MENU() : - m_titleSet( false ), m_handler( this ), m_tool( NULL ) + m_titleSet( false ), m_selected( -1 ), m_handler( this ), m_tool( NULL ) { m_menu.Connect( wxEVT_MENU_HIGHLIGHT, wxEventHandler( CMEventHandler::onEvent ), NULL, &m_handler ); @@ -43,7 +43,7 @@ CONTEXT_MENU::CONTEXT_MENU() : CONTEXT_MENU::CONTEXT_MENU( const CONTEXT_MENU& aMenu ) : - m_titleSet( aMenu.m_titleSet ), m_handler( this ), m_tool( aMenu.m_tool ) + m_titleSet( aMenu.m_titleSet ), m_selected( -1 ), m_handler( this ), m_tool( aMenu.m_tool ) { m_menu.Connect( wxEVT_MENU_HIGHLIGHT, wxEventHandler( CMEventHandler::onEvent ), NULL, &m_handler ); @@ -164,6 +164,9 @@ void CONTEXT_MENU::CMEventHandler::onEvent( wxEvent& aEvent ) // One of menu entries was selected.. else if( type == wxEVT_COMMAND_MENU_SELECTED ) { + // Store the selected position + m_menu->m_selected = aEvent.GetId(); + // Check if there is a TOOL_ACTION for the given ID if( m_menu->m_toolActions.count( aEvent.GetId() ) == 1 ) { diff --git a/common/tool/tool_dispatcher.cpp b/common/tool/tool_dispatcher.cpp index b655113b38..35cefd81a2 100644 --- a/common/tool/tool_dispatcher.cpp +++ b/common/tool/tool_dispatcher.cpp @@ -147,7 +147,7 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti st->pressed = true; evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_DOWN, args ); } - else if( up ) // Handle mouse button release + else if( up ) // Handle mouse button release { st->pressed = false; diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index 75ac02574e..2644076508 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -446,9 +446,12 @@ bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent ) boost::scoped_ptr menu( new CONTEXT_MENU( *st->contextMenu ) ); GetEditFrame()->PopupMenu( menu->GetMenu() ); - // - TOOL_EVENT evt( TC_COMMAND, TA_CONTEXT_MENU_CHOICE ); - dispatchInternal( evt ); + // If nothing was chosen from the context menu, we must notify the tool as well + if( menu->GetSelected() < 0 ) + { + TOOL_EVENT evt( TC_COMMAND, TA_CONTEXT_MENU_CHOICE ); + dispatchInternal( evt ); + } break; } diff --git a/include/tool/context_menu.h b/include/tool/context_menu.h index 90a5e106e8..df6f7cb0b7 100644 --- a/include/tool/context_menu.h +++ b/include/tool/context_menu.h @@ -78,6 +78,17 @@ public: */ void Clear(); + /** + * Function GetSelected() + * Returns the position of selected item. If the returned value is negative, that means that + * menu was dismissed. + * @return The position of selected item in the context menu. + */ + int GetSelected() const + { + return m_selected; + } + /** * Function GetMenu() * Returns the instance of wxMenu object used to display the menu. @@ -131,6 +142,9 @@ private: ///> Instance of wxMenu used for display of the context menu. wxMenu m_menu; + ///> Stores the id number of selected item. + int m_selected; + ///> Instance of menu event handler. CMEventHandler m_handler; From a8bdd44cd18b6c15d3599038d00a5cd360d7229f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 2 Dec 2013 14:35:05 +0100 Subject: [PATCH 05/95] Overridden ViewUpdate() for MODULE class, so it handles its pads, drawings and texts. --- common/view/view.cpp | 2 +- common/view/view_item.cpp | 2 +- include/view/view.h | 13 ++++++++----- pcbnew/class_module.cpp | 22 ++++++++++++++++++++++ pcbnew/class_module.h | 3 +++ 5 files changed, 35 insertions(+), 7 deletions(-) diff --git a/common/view/view.cpp b/common/view/view.cpp index 078fa0b907..ebc0b1c1b9 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -819,7 +819,7 @@ void VIEW::clearGroupCache() } -void VIEW::invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags ) +void VIEW::InvalidateItem( VIEW_ITEM* aItem, int aUpdateFlags ) { // updateLayers updates geometry too, so we do not have to update both of them at the same time if( aUpdateFlags & VIEW_ITEM::LAYERS ) diff --git a/common/view/view_item.cpp b/common/view/view_item.cpp index 1521c88a9e..e2ddd6a01d 100644 --- a/common/view/view_item.cpp +++ b/common/view/view_item.cpp @@ -53,7 +53,7 @@ void VIEW_ITEM::ViewUpdate( int aUpdateFlags ) if( !m_view ) return; - m_view->invalidateItem( this, aUpdateFlags ); + m_view->InvalidateItem( this, aUpdateFlags ); } diff --git a/include/view/view.h b/include/view/view.h index a5e0756219..f7a7e90984 100644 --- a/include/view/view.h +++ b/include/view/view.h @@ -493,6 +493,14 @@ public: m_scaleLimits = VECTOR2D( aMaximum, aMinimum ); } + /** + * Function InvalidateItem() + * Manages dirty flags & redraw queueing when updating an item. + * @param aItem is the item to be updated. + * @param aUpdateFlags determines the way an item is refreshed. + */ + void InvalidateItem( VIEW_ITEM* aItem, int aUpdateFlags ); + static const int VIEW_MAX_LAYERS = 128; ///* maximum number of layers that may be shown private: @@ -563,11 +571,6 @@ private: */ void draw( VIEW_GROUP* aGroup, bool aImmediate = false ) const; - - ///* Manages dirty flags & redraw queueing when updating an item. Called internally - /// via VIEW_ITEM::ViewUpdate() - void invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags ); - ///* Sorts m_orderedLayers when layer rendering order has changed void sortLayers(); diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp index dd1aca96e5..9694607a39 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -728,6 +728,28 @@ EDA_ITEM* MODULE::Clone() const } +void MODULE::ViewUpdate( int aUpdateFlags ) +{ + if( !m_view ) + return; + + // Update pads + for( D_PAD* pad = m_Pads.GetFirst(); pad; pad = pad->Next() ) + m_view->InvalidateItem( pad, aUpdateFlags ); + + // Update module's drawing (mostly silkscreen) + for( BOARD_ITEM* drawing = m_Drawings.GetFirst(); drawing; drawing = drawing->Next() ) + m_view->InvalidateItem( drawing, aUpdateFlags ); + + // Update module's texts + m_view->InvalidateItem( m_Reference, aUpdateFlags ); + m_view->InvalidateItem( m_Value, aUpdateFlags ); + + // Update the module itself + m_view->InvalidateItem( this, aUpdateFlags ); +} + + /* Test for validity of the name in a library of the footprint * ( no spaces, dir separators ... ) * return true if the given name is valid diff --git a/pcbnew/class_module.h b/pcbnew/class_module.h index 184e9e7288..a1564db05e 100644 --- a/pcbnew/class_module.h +++ b/pcbnew/class_module.h @@ -447,6 +447,9 @@ public: EDA_ITEM* Clone() const; + /// @copydoc VIEW_ITEM::ViewUpdate() + void ViewUpdate( int aUpdateFlags ); + /** * Function CopyNetlistSettings * copies the netlist settings to \a aModule. From bc41f8298b510d79832ba9c2536034889bd975ce Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 3 Dec 2013 15:17:43 +0100 Subject: [PATCH 06/95] Added some comments & asserts. --- common/tool/action_manager.cpp | 2 ++ common/tool/tool_manager.cpp | 16 +++++++++++++--- include/tool/tool_event.h | 3 +++ pcbnew/basepcbframe.cpp | 2 +- pcbnew/tools/selection_tool.h | 11 ++++++++++- 5 files changed, 29 insertions(+), 5 deletions(-) diff --git a/common/tool/action_manager.cpp b/common/tool/action_manager.cpp index 63aa99f8d8..d38ad1eccf 100644 --- a/common/tool/action_manager.cpp +++ b/common/tool/action_manager.cpp @@ -44,6 +44,8 @@ ACTION_MANAGER::~ACTION_MANAGER() void ACTION_MANAGER::RegisterAction( TOOL_ACTION* aAction ) { assert( aAction->GetId() == -1 ); // Check if the TOOL_ACTION was not registered before + assert( m_actionNameIndex.find( aAction->m_name ) == m_actionNameIndex.end() ); + assert( m_actionIdIndex.find( aAction->m_id ) == m_actionIdIndex.end() ); aAction->setId( MakeActionId( aAction->m_name ) ); diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index 2644076508..9fe8715604 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -120,6 +120,11 @@ TOOL_MANAGER::~TOOL_MANAGER() void TOOL_MANAGER::RegisterTool( TOOL_BASE* aTool ) { + wxASSERT_MSG( m_toolNameIndex.find( aTool->GetName() ) == m_toolNameIndex.end(), + wxT( "Adding two tools with the same name may result in unexpected behaviour.") ); + wxASSERT_MSG( m_toolIdIndex.find( aTool->GetId() ) == m_toolIdIndex.end(), + wxT( "Adding two tools with the same ID may result in unexpected behaviour.") ); + TOOL_STATE* st = new TOOL_STATE; st->theTool = aTool; @@ -227,7 +232,10 @@ bool TOOL_MANAGER::runTool( TOOL_BASE* aTool ) wxASSERT( aTool != NULL ); if( !isRegistered( aTool ) ) + { + wxASSERT_MSG( false, wxT( "You cannot run unregistered tools" ) ); return false; + } TOOL_STATE* state = m_toolState[aTool]; @@ -334,10 +342,11 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent ) // Go() method that match the event. if( st->transitions.size() ) { - BOOST_FOREACH( TRANSITION tr, st->transitions ) + BOOST_FOREACH( TRANSITION& tr, st->transitions ) { if( tr.first.Matches( aEvent ) ) { + // as the state changes, the transition table has to be set up again st->transitions.clear(); // no tool context allocated yet? Create one. @@ -351,6 +360,9 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent ) if( !st->cofunc->Running() ) finishTool( st ); // The couroutine has finished immediately? + + // there is no point in further checking, as transitions got cleared + break; } } } @@ -406,8 +418,6 @@ void TOOL_MANAGER::finishTool( TOOL_STATE* aState ) if( it != m_activeTools.end() ) m_activeTools.erase( it ); - else - wxLogWarning( wxT( "Tried to finish inactive tool" ) ); aState->idle = true; delete aState->cofunc; diff --git a/include/tool/tool_event.h b/include/tool/tool_event.h index 1ec5b1414d..a2815035d2 100644 --- a/include/tool/tool_event.h +++ b/include/tool/tool_event.h @@ -321,6 +321,9 @@ public: if( m_commandId && aEvent.m_commandId ) return *m_commandId == *aEvent.m_commandId; + + // Command-type event has to contain either id or string + assert( false ); } return true; diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index 89c5a8866e..dd235976c3 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -609,7 +609,7 @@ void PCB_BASE_FRAME::UseGalCanvas( bool aEnable ) EDA_DRAW_FRAME::UseGalCanvas( aEnable ); m_toolManager->SetEnvironment( m_Pcb, m_galCanvas->GetView(), - m_galCanvas->GetViewControls(), this ); + m_galCanvas->GetViewControls(), this ); ViewReloadBoard( m_Pcb ); } diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h index ee8cf45003..faf48ef8db 100644 --- a/pcbnew/tools/selection_tool.h +++ b/pcbnew/tools/selection_tool.h @@ -68,7 +68,16 @@ public: KIGFX::VIEW_GROUP* group; /// Checks if there is anything selected - bool Empty() const { return items.empty(); } + bool Empty() const + { + return items.empty(); + } + + /// Returns the number of selected parts + int Size() const + { + return items.size(); + } }; /// @copydoc TOOL_INTERACTIVE::Reset() From 4a4c0914bcb835981f2eec84766dfc806aa9c868 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 3 Dec 2013 15:41:41 +0100 Subject: [PATCH 07/95] Added TOOL_MANAGER::RunAction() function. --- common/tool/tool_manager.cpp | 6 ++++++ include/tool/tool_manager.h | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index 9fe8715604..9e56e61545 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -194,6 +194,12 @@ void TOOL_MANAGER::UnregisterAction( TOOL_ACTION* aAction ) } +bool TOOL_MANAGER::RunAction( const std::string& aActionName ) +{ + return m_actionMgr->RunAction( aActionName ); +} + + bool TOOL_MANAGER::invokeTool( TOOL_BASE* aTool ) { wxASSERT( aTool != NULL ); diff --git a/include/tool/tool_manager.h b/include/tool/tool_manager.h index 38a2879ccd..57026c2712 100644 --- a/include/tool/tool_manager.h +++ b/include/tool/tool_manager.h @@ -99,6 +99,15 @@ public: */ void UnregisterAction( TOOL_ACTION* aAction ); + /** + * Function RunAction() + * Runs the specified action. The common format is "application.ToolName.Action". + * + * @param aActionName is the name of action to be invoked. + * @return True if the action finished successfully, false otherwise. + */ + bool RunAction( const std::string& aActionName ); + /** * Function FindTool() * Searches for a tool with given ID. From af981b37fe8db44a845116c59e98eec7c0b8199e Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 3 Dec 2013 15:57:09 +0100 Subject: [PATCH 08/95] Split rotate and flip operations into separate functions. Added Properties action (display properties windows) --- pcbnew/tools/common_actions.cpp | 6 +- pcbnew/tools/common_actions.h | 5 +- pcbnew/tools/move_tool.cpp | 144 ++++++++++++++++++++++++-------- pcbnew/tools/move_tool.h | 35 +++++++- pcbnew/tools/pcb_tools.cpp | 1 + pcbnew/tools/selection_tool.cpp | 18 +++- 6 files changed, 164 insertions(+), 45 deletions(-) diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index a61ebc52b0..e1b95141c6 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -36,9 +36,13 @@ TOOL_ACTION COMMON_ACTIONS::moveActivate( "pcbnew.InteractiveMove", "Move", "Moves the selected item(s)" ); TOOL_ACTION COMMON_ACTIONS::rotate( "pcbnew.InteractiveMove.rotate", - AS_CONTEXT, ' ', + AS_CONTEXT, 'R', "Rotate", "Rotates selected item(s)" ); TOOL_ACTION COMMON_ACTIONS::flip( "pcbnew.InteractiveMove.flip", AS_CONTEXT, 'F', "Flip", "Flips selected item(s)" ); + +TOOL_ACTION COMMON_ACTIONS::properties( "pcbnew.InteractiveMove.properties", + AS_GLOBAL, 'E', + "Properties...", "Displays properties window" ); diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 547b86f814..c93dd29220 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -24,7 +24,7 @@ #include -class ACTION_MANAGER; +//class ACTION_MANAGER; /** * Class COMMON_ACTIONS @@ -46,4 +46,7 @@ public: /// Flipping of selected objects static TOOL_ACTION flip; + + /// Activation of the edit tool + static TOOL_ACTION properties; }; diff --git a/pcbnew/tools/move_tool.cpp b/pcbnew/tools/move_tool.cpp index 6750d3e8fd..ccafa2c835 100644 --- a/pcbnew/tools/move_tool.cpp +++ b/pcbnew/tools/move_tool.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -41,38 +42,26 @@ MOVE_TOOL::MOVE_TOOL() : } -MOVE_TOOL::~MOVE_TOOL() -{ -} - - -void MOVE_TOOL::Reset() -{ - // The tool launches upon reception of action event ("pcbnew.InteractiveMove") - Go( &MOVE_TOOL::Main, COMMON_ACTIONS::moveActivate.MakeEvent() ); -} - - bool MOVE_TOOL::Init() { // Find the selection tool, so they can cooperate TOOL_BASE* selectionTool = m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ); - if( selectionTool ) - { - m_selectionTool = static_cast( selectionTool ); - - // Add context menu entries that are displayed when selection tool is active - m_selectionTool->AddMenuItem( COMMON_ACTIONS::moveActivate ); - m_selectionTool->AddMenuItem( COMMON_ACTIONS::rotate ); - m_selectionTool->AddMenuItem( COMMON_ACTIONS::flip ); - } - else + m_selectionTool = static_cast( selectionTool ); + if( !selectionTool ) { DisplayError( NULL, wxT( "pcbnew.InteractiveSelection tool is not available" ) ); return false; } + // Add context menu entries that are displayed when selection tool is active + m_selectionTool->AddMenuItem( COMMON_ACTIONS::moveActivate ); + m_selectionTool->AddMenuItem( COMMON_ACTIONS::rotate ); + m_selectionTool->AddMenuItem( COMMON_ACTIONS::flip ); + m_selectionTool->AddMenuItem( COMMON_ACTIONS::properties ); + + setTransitions(); + return true; } @@ -85,7 +74,7 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent ) return 0; // there are no items to operate on VECTOR2D dragPosition; - bool dragging = false; + m_dragging = false; bool restore = false; // Should items' state be restored when finishing the tool? VIEW_CONTROLS* controls = getViewControls(); @@ -105,23 +94,15 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent ) // Dispatch TOOL_ACTIONs else if( evt->Category() == TC_COMMAND ) { - VECTOR2D cursorPos = getView()->ToWorld( getViewControls()->GetCursorPosition() ); - - if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) // got rotation event? - { - m_state.Rotate( cursorPos, 900.0 ); - selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); - } - else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) // got flip event? - { - m_state.Flip( cursorPos ); - selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); - } + if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) + Rotate( aEvent ); + else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) + Flip( aEvent ); } else if( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) { - if( dragging ) + if( m_dragging ) { // Drag items to the current cursor position VECTOR2D movement = ( evt->Position() - dragPosition ); @@ -138,16 +119,19 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent ) m_state.Save( *it ); } - dragging = true; + m_dragging = true; } selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); dragPosition = evt->Position(); } + else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) break; // Finish } + m_dragging = false; + if( restore ) { // Modifications has to be rollbacked, so restore the previous state of items @@ -165,5 +149,91 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent ) controls->SetSnapping( false ); controls->SetAutoPan( false ); + setTransitions(); + return 0; } + + +int MOVE_TOOL::Properties( TOOL_EVENT& aEvent ) +{ + const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + + // Properties are displayed when there is only one item selected + if( selection.items.size() == 1 ) + { + // Display properties dialog + PCB_EDIT_FRAME* editFrame = static_cast( m_toolMgr->GetEditFrame() ); + BOARD_ITEM* item = *selection.items.begin(); + editFrame->OnEditItemRequest( NULL, item ); + + item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + + setTransitions(); + + return 0; +} + + +int MOVE_TOOL::Rotate( TOOL_EVENT& aEvent ) +{ + const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + VECTOR2D cursorPos = getView()->ToWorld( getViewControls()->GetCursorPosition() ); + + if( m_dragging ) + { + m_state.Rotate( cursorPos, 900.0 ); + selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); + } + else + { + std::set::iterator it; + + for( it = selection.items.begin(); it != selection.items.end(); ++it ) + { + (*it)->Rotate( wxPoint( cursorPos.x, cursorPos.y ), 900.0 ); + (*it)->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + + setTransitions(); + } + + return 0; +} + + +int MOVE_TOOL::Flip( TOOL_EVENT& aEvent ) +{ + const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + VECTOR2D cursorPos = getView()->ToWorld( getViewControls()->GetCursorPosition() ); + + if( m_dragging ) + { + m_state.Flip( cursorPos ); + selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); + } + else + { + std::set::iterator it; + + for( it = selection.items.begin(); it != selection.items.end(); ++it ) + { + (*it)->Flip( wxPoint( cursorPos.x, cursorPos.y ) ); + (*it)->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS ); + } + + setTransitions(); + } + + return 0; +} + + +void MOVE_TOOL::setTransitions() +{ + Go( &MOVE_TOOL::Main, COMMON_ACTIONS::moveActivate.MakeEvent() ); + Go( &MOVE_TOOL::Rotate, COMMON_ACTIONS::rotate.MakeEvent() ); + Go( &MOVE_TOOL::Flip, COMMON_ACTIONS::flip.MakeEvent() ); + Go( &MOVE_TOOL::Properties, COMMON_ACTIONS::properties.MakeEvent() ); +} diff --git a/pcbnew/tools/move_tool.h b/pcbnew/tools/move_tool.h index 1140d0067e..9b7a88012d 100644 --- a/pcbnew/tools/move_tool.h +++ b/pcbnew/tools/move_tool.h @@ -49,10 +49,9 @@ class MOVE_TOOL : public TOOL_INTERACTIVE { public: MOVE_TOOL(); - ~MOVE_TOOL(); /// @copydoc TOOL_INTERACTIVE::Reset() - void Reset(); + void Reset() {}; /// @copydoc TOOL_INTERACTIVE::Init() bool Init(); @@ -61,15 +60,43 @@ public: * Function Main() * * Main loop in which events are handled. + * @param aEvent is the handled event. */ int Main( TOOL_EVENT& aEvent ); + /** + * Function Edit() + * + * Displays properties window for the selected object. + */ + int Properties( TOOL_EVENT& aEvent ); + + /** + * Function Rotate() + * + * Rotates currently selected items. + */ + int Rotate( TOOL_EVENT& aEvent ); + + /** + * Function Flip() + * + * Rotates currently selected items. The rotation point is the current cursor position. + */ + int Flip( TOOL_EVENT& aEvent ); + private: - /// Saves the state of items and allows to restore them + ///> Saves the state of items and allows to restore them ITEM_STATE m_state; - /// Selection tool used for obtaining selected items + ///> Selection tool used for obtaining selected items SELECTION_TOOL* m_selectionTool; + + ///> Flag determining if anything is being dragged right now + bool m_dragging; + + ///> Sets up handlers for various events + void setTransitions(); }; #endif diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index 2f9676cb94..aaccb18978 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -51,6 +51,7 @@ void PCB_EDIT_FRAME::setupTools() m_toolManager->RegisterAction( &COMMON_ACTIONS::selectionActivate ); m_toolManager->RegisterAction( &COMMON_ACTIONS::rotate ); m_toolManager->RegisterAction( &COMMON_ACTIONS::flip ); + m_toolManager->RegisterAction( &COMMON_ACTIONS::properties ); // Register tools m_toolManager->RegisterTool( new SELECTION_TOOL ); diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index decd7fe9e5..e7d56cd291 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -102,11 +102,25 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) } // single click? Select single object - if( evt->IsClick( BUT_LEFT ) ) + else if( evt->IsClick( BUT_LEFT ) ) + { + if( !m_additive && m_selection.Size() > 1 ) + clearSelection(); + selectSingle( evt->Position() ); + } + + else if( evt->IsDblClick( BUT_LEFT ) ) + { + if( m_selection.Empty() ) + selectSingle( evt->Position() ); + + // Display properties window + m_toolMgr->RunAction( "pcbnew.InteractiveMove.properties" ); + } // drag with LMB? Select multiple objects (or at least draw a selection box) or drag them - if( evt->IsDrag( BUT_LEFT ) ) + else if( evt->IsDrag( BUT_LEFT ) ) { if( m_selection.Empty() || m_additive ) { From e1bfcb1816b0508ed9b725239cf83d3ad4c58f5e Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 3 Dec 2013 16:09:03 +0100 Subject: [PATCH 09/95] Renamed MOVE_TOOL to EDIT_TOOL. --- pcbnew/CMakeLists.txt | 2 +- pcbnew/tools/common_actions.cpp | 10 +- pcbnew/tools/common_actions.h | 2 +- pcbnew/tools/move_tool.cpp | 239 -------------------------------- pcbnew/tools/move_tool.h | 102 -------------- pcbnew/tools/pcb_tools.cpp | 6 +- pcbnew/tools/selection_tool.cpp | 4 +- pcbnew/tools/selection_tool.h | 2 +- 8 files changed, 13 insertions(+), 354 deletions(-) delete mode 100644 pcbnew/tools/move_tool.cpp delete mode 100644 pcbnew/tools/move_tool.h diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 360f98a5c3..770554f2c0 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -241,7 +241,7 @@ set( PCBNEW_CLASS_SRCS tools/selection_tool.cpp tools/selection_area.cpp tools/bright_box.cpp - tools/move_tool.cpp + tools/edit_tool.cpp tools/pcb_tools.cpp tools/common_actions.cpp ) diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index e1b95141c6..12aa52cb8f 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -30,19 +30,19 @@ TOOL_ACTION COMMON_ACTIONS::selectionActivate( "pcbnew.InteractiveSelection", AS_GLOBAL, 'S', "Selection tool", "Allows to select items" ); -// Move tool actions -TOOL_ACTION COMMON_ACTIONS::moveActivate( "pcbnew.InteractiveMove", +// Edit tool actions +TOOL_ACTION COMMON_ACTIONS::editActivate( "pcbnew.InteractiveEdit", AS_GLOBAL, 'M', "Move", "Moves the selected item(s)" ); -TOOL_ACTION COMMON_ACTIONS::rotate( "pcbnew.InteractiveMove.rotate", +TOOL_ACTION COMMON_ACTIONS::rotate( "pcbnew.InteractiveEdit.rotate", AS_CONTEXT, 'R', "Rotate", "Rotates selected item(s)" ); -TOOL_ACTION COMMON_ACTIONS::flip( "pcbnew.InteractiveMove.flip", +TOOL_ACTION COMMON_ACTIONS::flip( "pcbnew.InteractiveEdit.flip", AS_CONTEXT, 'F', "Flip", "Flips selected item(s)" ); -TOOL_ACTION COMMON_ACTIONS::properties( "pcbnew.InteractiveMove.properties", +TOOL_ACTION COMMON_ACTIONS::properties( "pcbnew.InteractiveEdit.properties", AS_GLOBAL, 'E', "Properties...", "Displays properties window" ); diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index c93dd29220..5e8bbd7efc 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -36,7 +36,7 @@ class COMMON_ACTIONS { public: /// Activation of the move tool - static TOOL_ACTION moveActivate; + static TOOL_ACTION editActivate; /// Activation of the selection tool static TOOL_ACTION selectionActivate; diff --git a/pcbnew/tools/move_tool.cpp b/pcbnew/tools/move_tool.cpp deleted file mode 100644 index ccafa2c835..0000000000 --- a/pcbnew/tools/move_tool.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2013 CERN - * @author Maciej Suminski - * - * 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 -#include -#include -#include -#include -#include - -#include "common_actions.h" -#include "selection_tool.h" -#include "move_tool.h" - -using namespace KIGFX; -using boost::optional; - -MOVE_TOOL::MOVE_TOOL() : - TOOL_INTERACTIVE( "pcbnew.InteractiveMove" ), m_selectionTool( NULL ) -{ -} - - -bool MOVE_TOOL::Init() -{ - // Find the selection tool, so they can cooperate - TOOL_BASE* selectionTool = m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ); - - m_selectionTool = static_cast( selectionTool ); - if( !selectionTool ) - { - DisplayError( NULL, wxT( "pcbnew.InteractiveSelection tool is not available" ) ); - return false; - } - - // Add context menu entries that are displayed when selection tool is active - m_selectionTool->AddMenuItem( COMMON_ACTIONS::moveActivate ); - m_selectionTool->AddMenuItem( COMMON_ACTIONS::rotate ); - m_selectionTool->AddMenuItem( COMMON_ACTIONS::flip ); - m_selectionTool->AddMenuItem( COMMON_ACTIONS::properties ); - - setTransitions(); - - return true; -} - - -int MOVE_TOOL::Main( TOOL_EVENT& aEvent ) -{ - const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); - - if( selection.Empty() ) - return 0; // there are no items to operate on - - VECTOR2D dragPosition; - m_dragging = false; - bool restore = false; // Should items' state be restored when finishing the tool? - - VIEW_CONTROLS* controls = getViewControls(); - controls->ShowCursor( true ); - controls->SetSnapping( true ); - controls->SetAutoPan( true ); - - // Main loop: keep receiving events - while( OPT_TOOL_EVENT evt = Wait() ) - { - if( evt->IsCancel() ) - { - restore = true; // Cancelling the tool means that items have to be restored - break; // Finish - } - - // Dispatch TOOL_ACTIONs - else if( evt->Category() == TC_COMMAND ) - { - if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) - Rotate( aEvent ); - else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) - Flip( aEvent ); - } - - else if( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) - { - if( m_dragging ) - { - // Drag items to the current cursor position - VECTOR2D movement = ( evt->Position() - dragPosition ); - m_state.Move( movement ); - } - else - { - // Prepare to drag - std::set::iterator it; - - for( it = selection.items.begin(); it != selection.items.end(); ++it ) - { - // Save the state of the selected items, in case it has to be restored - m_state.Save( *it ); - } - - m_dragging = true; - } - - selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); - dragPosition = evt->Position(); - } - - else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) - break; // Finish - } - - m_dragging = false; - - if( restore ) - { - // Modifications has to be rollbacked, so restore the previous state of items - selection.group->ItemsViewUpdate( VIEW_ITEM::APPEARANCE ); - m_state.RestoreAll(); - } - else - { - // Changes are applied, so update the items - selection.group->ItemsViewUpdate( m_state.GetUpdateFlag() ); - m_state.Apply(); - } - - controls->ShowCursor( false ); - controls->SetSnapping( false ); - controls->SetAutoPan( false ); - - setTransitions(); - - return 0; -} - - -int MOVE_TOOL::Properties( TOOL_EVENT& aEvent ) -{ - const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); - - // Properties are displayed when there is only one item selected - if( selection.items.size() == 1 ) - { - // Display properties dialog - PCB_EDIT_FRAME* editFrame = static_cast( m_toolMgr->GetEditFrame() ); - BOARD_ITEM* item = *selection.items.begin(); - editFrame->OnEditItemRequest( NULL, item ); - - item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - - setTransitions(); - - return 0; -} - - -int MOVE_TOOL::Rotate( TOOL_EVENT& aEvent ) -{ - const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); - VECTOR2D cursorPos = getView()->ToWorld( getViewControls()->GetCursorPosition() ); - - if( m_dragging ) - { - m_state.Rotate( cursorPos, 900.0 ); - selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); - } - else - { - std::set::iterator it; - - for( it = selection.items.begin(); it != selection.items.end(); ++it ) - { - (*it)->Rotate( wxPoint( cursorPos.x, cursorPos.y ), 900.0 ); - (*it)->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - - setTransitions(); - } - - return 0; -} - - -int MOVE_TOOL::Flip( TOOL_EVENT& aEvent ) -{ - const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); - VECTOR2D cursorPos = getView()->ToWorld( getViewControls()->GetCursorPosition() ); - - if( m_dragging ) - { - m_state.Flip( cursorPos ); - selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); - } - else - { - std::set::iterator it; - - for( it = selection.items.begin(); it != selection.items.end(); ++it ) - { - (*it)->Flip( wxPoint( cursorPos.x, cursorPos.y ) ); - (*it)->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS ); - } - - setTransitions(); - } - - return 0; -} - - -void MOVE_TOOL::setTransitions() -{ - Go( &MOVE_TOOL::Main, COMMON_ACTIONS::moveActivate.MakeEvent() ); - Go( &MOVE_TOOL::Rotate, COMMON_ACTIONS::rotate.MakeEvent() ); - Go( &MOVE_TOOL::Flip, COMMON_ACTIONS::flip.MakeEvent() ); - Go( &MOVE_TOOL::Properties, COMMON_ACTIONS::properties.MakeEvent() ); -} diff --git a/pcbnew/tools/move_tool.h b/pcbnew/tools/move_tool.h deleted file mode 100644 index 9b7a88012d..0000000000 --- a/pcbnew/tools/move_tool.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2013 CERN - * @author Maciej Suminski - * - * 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 - */ - -#ifndef __MOVE_TOOL_H -#define __MOVE_TOOL_H - -#include -#include -#include -#include "item_state.h" - -class BOARD_ITEM; -class SELECTION_TOOL; - -namespace KIGFX -{ -class VIEW_GROUP; -} - -/** - * Class MOVE_TOOL - * - * Our sample move tool. Allows to move, rotate and flip items selected by - * pcbnew.InteractiveSelection tool. - */ - -class MOVE_TOOL : public TOOL_INTERACTIVE -{ -public: - MOVE_TOOL(); - - /// @copydoc TOOL_INTERACTIVE::Reset() - void Reset() {}; - - /// @copydoc TOOL_INTERACTIVE::Init() - bool Init(); - - /** - * Function Main() - * - * Main loop in which events are handled. - * @param aEvent is the handled event. - */ - int Main( TOOL_EVENT& aEvent ); - - /** - * Function Edit() - * - * Displays properties window for the selected object. - */ - int Properties( TOOL_EVENT& aEvent ); - - /** - * Function Rotate() - * - * Rotates currently selected items. - */ - int Rotate( TOOL_EVENT& aEvent ); - - /** - * Function Flip() - * - * Rotates currently selected items. The rotation point is the current cursor position. - */ - int Flip( TOOL_EVENT& aEvent ); - -private: - ///> Saves the state of items and allows to restore them - ITEM_STATE m_state; - - ///> Selection tool used for obtaining selected items - SELECTION_TOOL* m_selectionTool; - - ///> Flag determining if anything is being dragged right now - bool m_dragging; - - ///> Sets up handlers for various events - void setTransitions(); -}; - -#endif diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index aaccb18978..f6903f6420 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -35,7 +35,7 @@ #include #include "selection_tool.h" -#include "move_tool.h" +#include "edit_tool.h" #include "common_actions.h" #include @@ -47,7 +47,7 @@ void PCB_EDIT_FRAME::setupTools() m_galCanvas->SetEventDispatcher( m_toolDispatcher ); // Register tool actions - m_toolManager->RegisterAction( &COMMON_ACTIONS::moveActivate ); + m_toolManager->RegisterAction( &COMMON_ACTIONS::editActivate ); m_toolManager->RegisterAction( &COMMON_ACTIONS::selectionActivate ); m_toolManager->RegisterAction( &COMMON_ACTIONS::rotate ); m_toolManager->RegisterAction( &COMMON_ACTIONS::flip ); @@ -56,7 +56,7 @@ void PCB_EDIT_FRAME::setupTools() // Register tools m_toolManager->RegisterTool( new SELECTION_TOOL ); m_toolManager->RegisterTool( new ROUTER_TOOL ); - m_toolManager->RegisterTool( new MOVE_TOOL ); + m_toolManager->RegisterTool( new EDIT_TOOL ); } diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index e7d56cd291..23033b02f4 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -116,7 +116,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) selectSingle( evt->Position() ); // Display properties window - m_toolMgr->RunAction( "pcbnew.InteractiveMove.properties" ); + m_toolMgr->RunAction( "pcbnew.InteractiveEdit.properties" ); } // drag with LMB? Select multiple objects (or at least draw a selection box) or drag them @@ -134,7 +134,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) if( containsSelected( evt->Position() ) ) { // Yes -> run the move tool and wait till it finishes - m_toolMgr->InvokeTool( "pcbnew.InteractiveMove" ); + m_toolMgr->InvokeTool( "pcbnew.InteractiveEdit" ); } else { diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h index faf48ef8db..6b3d62ba28 100644 --- a/pcbnew/tools/selection_tool.h +++ b/pcbnew/tools/selection_tool.h @@ -50,7 +50,7 @@ class VIEW_GROUP; * - draw selection box (drag LMB) * - handles MODULEs properly (ie. selects either MODULE or its PADs, TEXTs, etc.) * - takes into account high-contrast & layer visibility settings - * - invokes InteractiveMove tool when user starts to drag selected items + * - invokes InteractiveEdit tool when user starts to drag selected items */ class SELECTION_TOOL : public TOOL_INTERACTIVE From 304d17dd3246361b897139180d6119b4ab8a23d6 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 3 Dec 2013 17:11:22 +0100 Subject: [PATCH 10/95] The Selection Tool is always active. Removed entries for toolbar menu and hotkeys for the tool. --- common/tool/tool_dispatcher.cpp | 5 ----- common/tool/tool_manager.cpp | 5 +++-- pcbnew/menubar_pcbframe.cpp | 5 ----- pcbnew/pcbframe.cpp | 2 -- pcbnew/pcbnew_id.h | 1 - pcbnew/tools/common_actions.cpp | 3 +-- pcbnew/tools/common_actions.h | 6 +++--- pcbnew/tools/pcb_tools.cpp | 7 ++++++- pcbnew/tools/selection_tool.cpp | 27 +++++++++++++++------------ pcbnew/tools/selection_tool.h | 4 ++++ 10 files changed, 32 insertions(+), 33 deletions(-) diff --git a/common/tool/tool_dispatcher.cpp b/common/tool/tool_dispatcher.cpp index 35cefd81a2..6fb5d5f500 100644 --- a/common/tool/tool_dispatcher.cpp +++ b/common/tool/tool_dispatcher.cpp @@ -280,11 +280,6 @@ void TOOL_DISPATCHER::DispatchWxCommand( const wxCommandEvent& aEvent ) toolName = "pcbnew.InteractiveRouter"; activateTool = true; break; - - case ID_SELECTION_TOOL: - toolName = "pcbnew.InteractiveSelection"; - activateTool = true; - break; } // do nothing if the legacy view is active diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index 9e56e61545..695203f447 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -97,7 +97,7 @@ struct TOOL_MANAGER::TOOL_STATE TOOL_MANAGER::TOOL_MANAGER() : - m_model( NULL ), m_view( NULL ) + m_model( NULL ), m_view( NULL ), m_viewControls( NULL ), m_editFrame( NULL ) { m_actionMgr = new ACTION_MANAGER( this ); } @@ -476,7 +476,8 @@ bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent ) if( m_view->IsDirty() ) { PCB_EDIT_FRAME* f = static_cast( GetEditFrame() ); - f->GetGalCanvas()->Refresh(); // fixme: ugly hack, provide a method in TOOL_DISPATCHER. + if( f->IsGalCanvasActive() ) + f->GetGalCanvas()->Refresh(); // fixme: ugly hack, provide a method in TOOL_DISPATCHER. } return false; diff --git a/pcbnew/menubar_pcbframe.cpp b/pcbnew/menubar_pcbframe.cpp index 766b563833..9db3c5e309 100644 --- a/pcbnew/menubar_pcbframe.cpp +++ b/pcbnew/menubar_pcbframe.cpp @@ -310,11 +310,6 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() editMenu->AppendSeparator(); - AddMenuItem( editMenu, ID_SELECTION_TOOL, - _( "Select Tool" ), - _( "Interactive selection and drag&drop tool." ), - KiBitmap( tools_xpm ) ); - AddMenuItem( editMenu, ID_PNS_ROUTER_TOOL, _( "Interactive router" ), _( "Interactive router drag&drop tool." ), diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index b6a2a2c2d5..963581d197 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -121,8 +121,6 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME ) // menu Config /* Tom's hacks start */ - EVT_MENU ( ID_SELECTION_TOOL, PCB_EDIT_FRAME::onGenericCommand ) - EVT_TOOL ( ID_SELECTION_TOOL, PCB_EDIT_FRAME::onGenericCommand ) EVT_MENU ( ID_PNS_ROUTER_TOOL, PCB_EDIT_FRAME::onGenericCommand ) EVT_TOOL ( ID_PNS_ROUTER_TOOL, PCB_EDIT_FRAME::onGenericCommand ) /* Tom's hacks end */ diff --git a/pcbnew/pcbnew_id.h b/pcbnew/pcbnew_id.h index 1a03a3764c..d5a836b93a 100644 --- a/pcbnew/pcbnew_id.h +++ b/pcbnew/pcbnew_id.h @@ -370,7 +370,6 @@ enum pcbnew_ids ID_FOOTPRINT_WIZARD_SELECT_WIZARD, ID_FOOTPRINT_WIZARD_EXPORT_TO_BOARD, - ID_SELECTION_TOOL, ID_PNS_ROUTER_TOOL }; diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 12aa52cb8f..7a7aef37b1 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -27,8 +27,7 @@ // Selection tool actions TOOL_ACTION COMMON_ACTIONS::selectionActivate( "pcbnew.InteractiveSelection", - AS_GLOBAL, 'S', - "Selection tool", "Allows to select items" ); + AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere // Edit tool actions TOOL_ACTION COMMON_ACTIONS::editActivate( "pcbnew.InteractiveEdit", diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 5e8bbd7efc..ae12439870 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -35,12 +35,12 @@ class COMMON_ACTIONS { public: - /// Activation of the move tool - static TOOL_ACTION editActivate; - /// Activation of the selection tool static TOOL_ACTION selectionActivate; + /// Activation of the edit tool + static TOOL_ACTION editActivate; + /// Rotation of selected objects static TOOL_ACTION rotate; diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index f6903f6420..db347e8c4b 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -48,7 +48,6 @@ void PCB_EDIT_FRAME::setupTools() // Register tool actions m_toolManager->RegisterAction( &COMMON_ACTIONS::editActivate ); - m_toolManager->RegisterAction( &COMMON_ACTIONS::selectionActivate ); m_toolManager->RegisterAction( &COMMON_ACTIONS::rotate ); m_toolManager->RegisterAction( &COMMON_ACTIONS::flip ); m_toolManager->RegisterAction( &COMMON_ACTIONS::properties ); @@ -57,6 +56,12 @@ void PCB_EDIT_FRAME::setupTools() m_toolManager->RegisterTool( new SELECTION_TOOL ); m_toolManager->RegisterTool( new ROUTER_TOOL ); m_toolManager->RegisterTool( new EDIT_TOOL ); + + m_toolManager->SetEnvironment( NULL, m_galCanvas->GetView(), + m_galCanvas->GetViewControls(), this ); + + // Run the selection tool, it is supposed to be always active + m_toolManager->InvokeTool( "pcbnew.InteractiveSelection" ); } diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index b175e85b09..918fb8f2aa 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -66,6 +66,8 @@ SELECTION_TOOL::~SELECTION_TOOL() void SELECTION_TOOL::Reset() { + clearSelection(); + // Reinsert the VIEW_GROUP, in case it was removed from the VIEW getView()->Remove( m_selection.group ); getView()->Add( m_selection.group ); @@ -77,12 +79,6 @@ void SELECTION_TOOL::Reset() int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) { - KIGFX::VIEW* view = getView(); - - assert( getModel( PCB_T ) != NULL ); - - view->Add( m_selection.group ); - // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { @@ -94,8 +90,8 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) { if( !m_selection.Empty() ) // Cancel event deselects items... clearSelection(); - else // ...unless there is nothing selected - break; // then exit the tool + + // This tool never exits } // single click? Select single object @@ -142,8 +138,8 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) } } - m_selection.group->Clear(); - view->Remove( m_selection.group ); + // This tool is supposed to be active forever + assert( false ); return 0; } @@ -188,6 +184,7 @@ void SELECTION_TOOL::clearSelection() { KIGFX::VIEW_GROUP::const_iter it, it_end; + // Restore the initial properties for( it = m_selection.group->Begin(), it_end = m_selection.group->End(); it != it_end; ++it ) { BOARD_ITEM* item = static_cast( *it ); @@ -196,8 +193,7 @@ void SELECTION_TOOL::clearSelection() item->ClearSelected(); } - m_selection.group->Clear(); - m_selection.items.clear(); + m_selection.Clear(); // Do not show the context menu when there is nothing selected SetContextMenu( &m_menu, CMENU_OFF ); @@ -609,3 +605,10 @@ bool SELECTION_TOOL::containsSelected( const VECTOR2I& aPoint ) const return false; } + + +void SELECTION_TOOL::SELECTION::Clear() +{ + items.clear(); + group->Clear(); +} diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h index 6b3d62ba28..40806c3b94 100644 --- a/pcbnew/tools/selection_tool.h +++ b/pcbnew/tools/selection_tool.h @@ -78,6 +78,10 @@ public: { return items.size(); } + + /// Clears both the VIEW_GROUP and set of selected items. Please note that it does not + /// change properties of selected items (e.g. selection flag). + void Clear(); }; /// @copydoc TOOL_INTERACTIVE::Reset() From 45291ef571c6c378193d7f3f39195961d96f9730 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 4 Dec 2013 10:58:51 +0100 Subject: [PATCH 11/95] The Selection Tool displays information about selected items. ClearSelection() made public. --- pcbnew/tools/selection_tool.cpp | 110 ++++++++++++++++++-------------- pcbnew/tools/selection_tool.h | 15 ++++- 2 files changed, 73 insertions(+), 52 deletions(-) diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 918fb8f2aa..9538f27c4b 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -66,7 +66,7 @@ SELECTION_TOOL::~SELECTION_TOOL() void SELECTION_TOOL::Reset() { - clearSelection(); + ClearSelection(); // Reinsert the VIEW_GROUP, in case it was removed from the VIEW getView()->Remove( m_selection.group ); @@ -89,7 +89,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) if( evt->IsCancel() ) { if( !m_selection.Empty() ) // Cancel event deselects items... - clearSelection(); + ClearSelection(); // This tool never exits } @@ -98,7 +98,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) else if( evt->IsClick( BUT_LEFT ) ) { if( !m_additive && m_selection.Size() > 1 ) - clearSelection(); + ClearSelection(); selectSingle( evt->Position() ); } @@ -132,7 +132,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) else { // No -> clear the selection list - clearSelection(); + ClearSelection(); } } } @@ -145,42 +145,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) } -void SELECTION_TOOL::AddMenuItem( const TOOL_ACTION& aAction ) -{ - assert( aAction.GetId() > 0 ); // Check if the action was registered before in ACTION_MANAGER - - m_menu.Add( aAction ); -} - - -void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem ) -{ - if( m_selection.items.find( aItem ) != m_selection.items.end() ) - { - deselectItem( aItem ); - - // If there is nothing selected, disable the context menu - if( m_selection.Empty() ) - SetContextMenu( &m_menu, CMENU_OFF ); - } - else - { - if( !m_additive ) - clearSelection(); - - // Prevent selection of invisible or inactive items - if( selectable( aItem ) ) - { - selectItem( aItem ); - - // Now the context menu should be enabled - SetContextMenu( &m_menu, CMENU_BUTTON ); - } - } -} - - -void SELECTION_TOOL::clearSelection() +void SELECTION_TOOL::ClearSelection() { KIGFX::VIEW_GROUP::const_iter it, it_end; @@ -195,11 +160,45 @@ void SELECTION_TOOL::clearSelection() m_selection.Clear(); + getEditFrame()->SetCurItem( NULL ); + // Do not show the context menu when there is nothing selected SetContextMenu( &m_menu, CMENU_OFF ); } +void SELECTION_TOOL::AddMenuItem( const TOOL_ACTION& aAction ) +{ + assert( aAction.GetId() > 0 ); // Check if the action was registered before in ACTION_MANAGER + + m_menu.Add( aAction ); +} + + +void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem ) +{ + if( isSelected( aItem ) ) + { + deselectItem( aItem ); + } + else + { + if( !m_additive ) + ClearSelection(); + + // Prevent selection of invisible or inactive items + if( selectable( aItem ) ) + selectItem( aItem ); + } +} + + +bool SELECTION_TOOL::isSelected( const BOARD_ITEM* aItem ) const +{ + return ( m_selection.items.find( const_cast( aItem ) ) != m_selection.items.end() ); +} + + void SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere ) { BOARD* pcb = getModel( PCB_T ); @@ -214,7 +213,7 @@ void SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere ) { case 0: if( !m_additive ) - clearSelection(); + ClearSelection(); break; @@ -308,7 +307,7 @@ bool SELECTION_TOOL::selectMultiple() if( evt->IsDrag( BUT_LEFT ) ) { if( !m_additive ) - clearSelection(); + ClearSelection(); // Start drawing a selection box m_selArea->SetOrigin( evt->DragOrigin() ); @@ -338,11 +337,10 @@ bool SELECTION_TOOL::selectMultiple() selectItem( item ); } - // Now the context menu should be enabled - if( !m_selection.Empty() ) - SetContextMenu( &m_menu, CMENU_BUTTON ); + // Do not display information about selected item,as there is more than one + getEditFrame()->SetCurItem( NULL ); - break; + break; // Stop waiting for events } } @@ -413,9 +411,6 @@ BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector ) // Removes possible brighten mark getView()->MarkTargetDirty( KIGFX::TARGET_OVERLAY ); - // Restore the original menu - SetContextMenu( &m_menu, CMENU_BUTTON ); - return current; } @@ -542,6 +537,16 @@ void SELECTION_TOOL::selectItem( BOARD_ITEM* aItem ) // Add items to the VIEW_GROUP, so they will be displayed on the overlay selectBase( aItem ); m_selection.items.insert( aItem ); + + // It is enough to do it only for the first selected item + if( m_selection.items.size() == 1 ) + { + // Set as the current item, so the information about selection is displayed + getEditFrame()->SetCurItem( aItem, true ); + + // Now the context menu should be enabled + SetContextMenu( &m_menu, CMENU_BUTTON ); + } } @@ -584,6 +589,13 @@ void SELECTION_TOOL::deselectItem( BOARD_ITEM* aItem ) deselectBase( aItem ); m_selection.items.erase( aItem ); + + // If there is nothing selected, disable the context menu + if( m_selection.Empty() ) + { + SetContextMenu( &m_menu, CMENU_OFF ); + getEditFrame()->SetCurItem( NULL ); + } } diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h index 40806c3b94..fa6ed0f545 100644 --- a/pcbnew/tools/selection_tool.h +++ b/pcbnew/tools/selection_tool.h @@ -104,6 +104,12 @@ public: return m_selection; } + /** + * Function ClearSelection() + * Clears the current selection. + */ + void ClearSelection(); + /** * Function AddAction() * @@ -156,10 +162,13 @@ private: void toggleSelection( BOARD_ITEM* aItem ); /** - * Function clearSelection() - * Clears selections of currently selected items. + * Function isSelected() + * Tests if an item is currently selected. + * + * @param aItem is the item to be checked. + * @return True if the item is selected, false otherwise. */ - void clearSelection(); + bool isSelected( const BOARD_ITEM* aItem ) const; /** * Function selectable() From 0ac6e0614f567674173551bf54e5bbd823b04994 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 5 Dec 2013 14:48:44 +0100 Subject: [PATCH 12/95] ClearHotKey() function. --- common/tool/action_manager.cpp | 12 ++++++++++++ include/tool/action_manager.h | 13 ++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/common/tool/action_manager.cpp b/common/tool/action_manager.cpp index d38ad1eccf..fde03fb510 100644 --- a/common/tool/action_manager.cpp +++ b/common/tool/action_manager.cpp @@ -53,7 +53,13 @@ void ACTION_MANAGER::RegisterAction( TOOL_ACTION* aAction ) m_actionIdIndex[aAction->m_id] = aAction; if( aAction->HasHotKey() ) + { + // Duplication of hot keys leads to unexpected behaviour + // The right way to change a hotkey is to use ACTION_MANAGER::ClearHotKey() first + assert( m_actionHotKeys.find( aAction->m_currentHotKey ) == m_actionHotKeys.end() ); + m_actionHotKeys[aAction->m_currentHotKey] = aAction; + } aAction->setActionMgr( this ); } @@ -107,6 +113,12 @@ bool ACTION_MANAGER::RunHotKey( int aHotKey ) const } +void ACTION_MANAGER::ClearHotKey( int aHotKey ) +{ + m_actionHotKeys.erase( aHotKey ); +} + + void ACTION_MANAGER::runAction( const TOOL_ACTION* aAction ) const { TOOL_EVENT event = aAction->MakeEvent(); diff --git a/include/tool/action_manager.h b/include/tool/action_manager.h index dbcb7b33b6..fa66a23eba 100644 --- a/include/tool/action_manager.h +++ b/include/tool/action_manager.h @@ -81,18 +81,21 @@ public: */ bool RunAction( const std::string& aActionName ) const; - // TODO to be considered - // bool RunAction( int aActionId ) const; - // bool RunAction( TOOL_ACTION* aAction ) const; - /** * Function RunHotKey() * Runs an action associated with a hotkey (if there is one available). - * @param aHotKey is the hotkey to be served. + * @param aHotKey is the hotkey to be handled. * @return True if there was an action associated with the hotkey, false otherwise. */ bool RunHotKey( int aHotKey ) const; + /** + * Function ClearHotKey() + * Removes an action associated with a hotkey. + * @param aHotKey is the hotkey to be cleared. + */ + void ClearHotKey( int aHotKey ); + private: ///> Tool manager needed to run actions TOOL_MANAGER* m_toolMgr; From df5b9a1df0a8649e5cdb3ca77f95e5f37c5d62f5 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 5 Dec 2013 14:52:08 +0100 Subject: [PATCH 13/95] Changed selection rules (pads&modules can be selected depending on the 'modules front/back' visibility instead of corresponding copper layers). Fixed comments. --- pcbnew/tools/selection_tool.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 9538f27c4b..f24dbaffd9 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -458,21 +458,21 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const break; case PCB_PAD_T: - { // Pads are not selectable in multiple selection mode if( m_multiple ) return false; + /* no break */ - // Pads are supposed to be on top, bottom or both at the same time (THT) - if( aItem->IsOnLayer( LAYER_N_FRONT ) && board->IsLayerVisible( LAYER_N_FRONT ) ) + case PCB_MODULE_T: + if( aItem->IsOnLayer( LAYER_N_FRONT ) && board->IsElementVisible( MOD_FR_VISIBLE ) ) return true; - if( aItem->IsOnLayer( LAYER_N_BACK ) && board->IsLayerVisible( LAYER_N_BACK ) ) + if( aItem->IsOnLayer( LAYER_N_BACK ) && board->IsLayerVisible( MOD_BK_VISIBLE ) ) return true; return false; - } - break; + + break; case PCB_MODULE_TEXT_T: // Module texts are not selectable in multiple selection mode @@ -483,7 +483,7 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const // These are not selectable, otherwise silkscreen drawings would be easily destroyed case PCB_MODULE_EDGE_T: - // and some other stuff that should be selected + // and some other stuff that should not be selected case NOT_USED: case TYPE_NOT_INIT: return false; @@ -516,8 +516,8 @@ void SELECTION_TOOL::selectItem( BOARD_ITEM* aItem ) } } selectBase( m_selection ); - // Modules are treated in a special way - when they are moved, we have to - // move all the parts that make the module, not the module itself + // Modules are treated in a special way - when they are selected, we have to + // select all the parts that make the module, not the module itself if( aItem->Type() == PCB_MODULE_T ) { MODULE* module = static_cast( aItem ); @@ -569,8 +569,8 @@ void SELECTION_TOOL::deselectItem( BOARD_ITEM* aItem ) } } deselectBase( m_selection ); - // Modules are treated in a special way - when they are moved, we have to - // move all the parts that make the module, not the module itself + // Modules are treated in a special way - when they are selected, we have to + // select all the parts that make the module, not the module itself if( aItem->Type() == PCB_MODULE_T ) { MODULE* module = static_cast( aItem ); From d72ec51ccfac22abcf11d5953433cecbd0493177 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 6 Dec 2013 13:57:56 +0100 Subject: [PATCH 14/95] Fixed an infinite loop in the destructor of ACTION_MANAGER; --- common/tool/action_manager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/tool/action_manager.cpp b/common/tool/action_manager.cpp index fde03fb510..a00d4d08cc 100644 --- a/common/tool/action_manager.cpp +++ b/common/tool/action_manager.cpp @@ -67,13 +67,13 @@ void ACTION_MANAGER::RegisterAction( TOOL_ACTION* aAction ) void ACTION_MANAGER::UnregisterAction( TOOL_ACTION* aAction ) { + m_actionNameIndex.erase( aAction->m_name ); + m_actionIdIndex.erase( aAction->m_id ); + // Indicate that the ACTION_MANAGER no longer care about the object aAction->setActionMgr( NULL ); aAction->setId( -1 ); - m_actionNameIndex.erase( aAction->m_name ); - m_actionIdIndex.erase( aAction->m_id ); - if( aAction->HasHotKey() ) m_actionHotKeys.erase( aAction->m_currentHotKey ); } From 9b4b5c931e332ce060d959069c154851178e0cfe Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 9 Dec 2013 10:42:38 +0100 Subject: [PATCH 15/95] Moved Init() & Reset() from TOOL_INTERACTIVE to TOOL_BASE. Added REASON enum for Reset() function, so tools will know why a reset occured. Fixed SELECTION_TOOL (it was bailing out, when a new board was loaded and some items were still selected). Added removal of VIEW_ITEM groups after changing layers and removing items. --- common/tool/tool_manager.cpp | 40 +++++++++++++++------------------ common/view/view.cpp | 12 ++++++++++ common/view/view_item.cpp | 6 ----- include/tool/tool_base.h | 27 ++++++++++++++++++++++ include/tool/tool_interactive.h | 18 --------------- include/tool/tool_manager.h | 6 ++--- pcbnew/basepcbframe.cpp | 11 +++++++-- pcbnew/router/router_tool.cpp | 2 +- pcbnew/router/router_tool.h | 2 +- pcbnew/tools/selection_tool.cpp | 11 ++++++--- pcbnew/tools/selection_tool.h | 2 +- 11 files changed, 80 insertions(+), 57 deletions(-) diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index 695203f447..ffc5a2d44b 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -140,22 +140,20 @@ void TOOL_MANAGER::RegisterTool( TOOL_BASE* aTool ) aTool->m_toolMgr = this; - if( aTool->GetType() == INTERACTIVE ) + if( !aTool->Init() ) { - if( !static_cast( aTool )->Init() ) - { - std::string msg = StrPrintf( "Initialization of the %s tool failed", aTool->GetName().c_str() ); + std::string msg = StrPrintf( "Initialization of the %s tool failed", + aTool->GetName().c_str() ); - DisplayError( NULL, wxString::FromUTF8( msg.c_str() ) ); + DisplayError( NULL, wxString::FromUTF8( msg.c_str() ) ); - // Unregister the tool - m_toolState.erase( aTool ); - m_toolNameIndex.erase( aTool->GetName() ); - m_toolIdIndex.erase( aTool->GetId() ); + // Unregister the tool + m_toolState.erase( aTool ); + m_toolNameIndex.erase( aTool->GetName() ); + m_toolIdIndex.erase( aTool->GetId() ); - delete st; - delete aTool; - } + delete st; + delete aTool; } } @@ -251,7 +249,7 @@ bool TOOL_MANAGER::runTool( TOOL_BASE* aTool ) state->idle = false; - static_cast( aTool )->Reset(); + aTool->Reset( TOOL_INTERACTIVE::RUN ); // Add the tool on the front of the processing queue (it gets events first) m_activeTools.push_front( aTool->GetId() ); @@ -282,6 +280,13 @@ TOOL_BASE* TOOL_MANAGER::FindTool( const std::string& aName ) const } +void TOOL_MANAGER::ResetTools( TOOL_BASE::RESET_REASON aReason ) +{ + BOOST_FOREACH( TOOL_BASE* tool, m_toolState | boost::adaptors::map_keys ) + tool->Reset( aReason ); +} + + void TOOL_MANAGER::ScheduleNextState( TOOL_BASE* aTool, TOOL_STATE_FUNC& aHandler, const TOOL_EVENT_LIST& aConditions ) { @@ -513,15 +518,6 @@ void TOOL_MANAGER::SetEnvironment( EDA_ITEM* aModel, KIGFX::VIEW* aView, m_view = aView; m_viewControls = aViewControls; m_editFrame = aFrame; - - // Reset state of the registered tools - BOOST_FOREACH( TOOL_ID toolId, m_activeTools ) - { - TOOL_BASE* tool = m_toolIdIndex[toolId]->theTool; - - if( tool->GetType() == INTERACTIVE ) - static_cast( tool )->Reset(); - } } diff --git a/common/view/view.cpp b/common/view/view.cpp index a68fbc7f71..a607c6112b 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -122,6 +122,12 @@ void VIEW::Remove( VIEW_ITEM* aItem ) { VIEW_LAYER& l = m_layers[layers[i]]; l.items->Remove( aItem ); + MarkTargetDirty( l.target ); + + // Clear the GAL cache + int prevGroup = aItem->getGroup( layers[i] ); + if( prevGroup >= 0 ) + m_gal->DeleteGroup( prevGroup ); } } @@ -930,6 +936,12 @@ void VIEW::updateLayers( VIEW_ITEM* aItem ) VIEW_LAYER& l = m_layers[layers[i]]; l.items->Remove( aItem ); MarkTargetDirty( l.target ); + + // Redraw the item from scratch + int prevGroup = aItem->getGroup( layers[i] ); + + if( prevGroup >= 0 ) + m_gal->DeleteGroup( prevGroup ); } // Add the item to new layer set diff --git a/common/view/view_item.cpp b/common/view/view_item.cpp index e2ddd6a01d..305ab68579 100644 --- a/common/view/view_item.cpp +++ b/common/view/view_item.cpp @@ -34,17 +34,13 @@ void VIEW_ITEM::ViewSetVisible( bool aIsVisible ) bool update = false; if( m_visible != aIsVisible ) - { update = true; - } m_visible = aIsVisible; // update only if the visibility has really changed if( update ) - { ViewUpdate( APPEARANCE ); - } } @@ -60,9 +56,7 @@ void VIEW_ITEM::ViewUpdate( int aUpdateFlags ) void VIEW_ITEM::ViewRelease() { if( m_view && m_view->IsDynamic() ) - { m_view->Remove( this ); - } } diff --git a/include/tool/tool_base.h b/include/tool/tool_base.h index 7425ea8801..681e3099d9 100644 --- a/include/tool/tool_base.h +++ b/include/tool/tool_base.h @@ -70,6 +70,33 @@ public: virtual ~TOOL_BASE() {}; + ///> Determines the reason of reset for a tool + enum RESET_REASON + { + RUN, ///< Tool is invoked after being inactive + MODEL_RELOAD, ///< Model changes + GAL_SWITCH ///< Rendering engine changes + }; + + /** + * Function Init() + * Init() is called once upon a registration of the tool. + * + * @return True if the initialization went fine, false - otherwise. + */ + virtual bool Init() + { + return true; + } + + /** + * Function Reset() + * Brings the tool to a known, initial state. If the tool claimed anything from + * the model or the view, it must release it when its reset. + * @param aReason contains information about the reason of tool reset. + */ + virtual void Reset( RESET_REASON aReason ) = 0; + /** * Function GetType() * Returns the type of the tool. diff --git a/include/tool/tool_interactive.h b/include/tool/tool_interactive.h index 855f84af5c..7e816bd3a4 100644 --- a/include/tool/tool_interactive.h +++ b/include/tool/tool_interactive.h @@ -48,24 +48,6 @@ public: TOOL_INTERACTIVE( const std::string& aName ); virtual ~TOOL_INTERACTIVE(); - /** - * Function Reset() - * Brings the tool to a known, initial state. If the tool claimed anything from - * the model or the view, it must release it when its reset. - */ - virtual void Reset() = 0; - - /** - * Function Init() - * Init() is called once upon a registration of the tool. - * - * @return True if the initialization went fine, false - otherwise. - */ - virtual bool Init() - { - return true; - } - /** * Function SetContextMenu() * diff --git a/include/tool/tool_manager.h b/include/tool/tool_manager.h index 57026c2712..6e9c18acb0 100644 --- a/include/tool/tool_manager.h +++ b/include/tool/tool_manager.h @@ -127,10 +127,10 @@ public: TOOL_BASE* FindTool( const std::string& aName ) const; /** - * Resets the state of a given tool by clearing its wait and - * transition lists and calling tool's internal Reset() method. + * Function ResetTools() + * Resets all tools (i.e. calls their Reset() method). */ - void ResetTool( TOOL_BASE* aTool ); + void ResetTools( TOOL_BASE::RESET_REASON aReason ); /** * Takes an event from the TOOL_DISPATCHER and propagates it to diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index aeda80468a..22983f9063 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -187,7 +187,10 @@ void PCB_BASE_FRAME::SetBoard( BOARD* aBoard ) // update the tool manager with the new board and its view. if( m_toolManager ) + { m_toolManager->SetEnvironment( m_Pcb, view, m_galCanvas->GetViewControls(), this ); + m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD ); + } } } @@ -610,8 +613,12 @@ void PCB_BASE_FRAME::UseGalCanvas( bool aEnable ) ViewReloadBoard( m_Pcb ); - m_toolManager->SetEnvironment( m_Pcb, m_galCanvas->GetView(), - m_galCanvas->GetViewControls(), this ); + if( aEnable ) + { + m_toolManager->SetEnvironment( m_Pcb, m_galCanvas->GetView(), + m_galCanvas->GetViewControls(), this ); + m_toolManager->ResetTools( TOOL_BASE::GAL_SWITCH ); + } } diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index d85b1470ae..19b92a42cf 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -72,7 +72,7 @@ ROUTER_TOOL::~ROUTER_TOOL() } -void ROUTER_TOOL::Reset() +void ROUTER_TOOL::Reset( RESET_REASON aReason ) { if( m_router ) delete m_router; diff --git a/pcbnew/router/router_tool.h b/pcbnew/router/router_tool.h index da2a36601d..c43283a051 100644 --- a/pcbnew/router/router_tool.h +++ b/pcbnew/router/router_tool.h @@ -41,7 +41,7 @@ public: ROUTER_TOOL(); ~ROUTER_TOOL(); - void Reset(); + void Reset( RESET_REASON aReason ); int Main( TOOL_EVENT& aEvent ); private: diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index f24dbaffd9..bf78405612 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -64,9 +64,15 @@ SELECTION_TOOL::~SELECTION_TOOL() } -void SELECTION_TOOL::Reset() +void SELECTION_TOOL::Reset( RESET_REASON aReason ) { - ClearSelection(); + if( aReason == TOOL_BASE::MODEL_RELOAD ) + // Remove pointers to the selected items from containers + // without changing their properties (as they are already deleted) + m_selection.Clear(); + else + // Restore previous properties of selected items and remove them from containers + ClearSelection(); // Reinsert the VIEW_GROUP, in case it was removed from the VIEW getView()->Remove( m_selection.group ); @@ -157,7 +163,6 @@ void SELECTION_TOOL::ClearSelection() item->ViewSetVisible( true ); item->ClearSelected(); } - m_selection.Clear(); getEditFrame()->SetCurItem( NULL ); diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h index fa6ed0f545..33fc4b2494 100644 --- a/pcbnew/tools/selection_tool.h +++ b/pcbnew/tools/selection_tool.h @@ -85,7 +85,7 @@ public: }; /// @copydoc TOOL_INTERACTIVE::Reset() - void Reset(); + void Reset( RESET_REASON aReason ); /** * Function Main() From 283788d91c8048e62caf5b48847bb18d8db7260b Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 9 Dec 2013 11:01:05 +0100 Subject: [PATCH 16/95] Added removal of BOARD_ITEMs for the TOOL_FRAMEWORK. --- pcbnew/tools/common_actions.cpp | 4 + pcbnew/tools/common_actions.h | 3 + pcbnew/tools/edit_tool.cpp | 328 ++++++++++++++++++++++++++++++++ pcbnew/tools/edit_tool.h | 111 +++++++++++ pcbnew/tools/pcb_tools.cpp | 2 + 5 files changed, 448 insertions(+) create mode 100644 pcbnew/tools/edit_tool.cpp create mode 100644 pcbnew/tools/edit_tool.h diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 7a7aef37b1..1a80bd5a9c 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -42,6 +42,10 @@ TOOL_ACTION COMMON_ACTIONS::flip( "pcbnew.InteractiveEdit.flip", AS_CONTEXT, 'F', "Flip", "Flips selected item(s)" ); +TOOL_ACTION COMMON_ACTIONS::remove( "pcbnew.InteractiveEdit.delete", + AS_GLOBAL, 127, // 127 stands for DELETE key + "Remove", "Deletes selected item(s)" ); + TOOL_ACTION COMMON_ACTIONS::properties( "pcbnew.InteractiveEdit.properties", AS_GLOBAL, 'E', "Properties...", "Displays properties window" ); diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index ae12439870..19b0004182 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -49,4 +49,7 @@ public: /// Activation of the edit tool static TOOL_ACTION properties; + + /// Deleting a BOARD_ITEM + static TOOL_ACTION remove; }; diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp new file mode 100644 index 0000000000..c6f46071d5 --- /dev/null +++ b/pcbnew/tools/edit_tool.cpp @@ -0,0 +1,328 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2013 CERN + * @author Maciej Suminski + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include "common_actions.h" +#include "selection_tool.h" +#include "edit_tool.h" + +using namespace KIGFX; +using boost::optional; + +EDIT_TOOL::EDIT_TOOL() : + TOOL_INTERACTIVE( "pcbnew.InteractiveEdit" ), m_selectionTool( NULL ) +{ +} + + +bool EDIT_TOOL::Init() +{ + // Find the selection tool, so they can cooperate + TOOL_BASE* selectionTool = m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ); + + m_selectionTool = static_cast( selectionTool ); + if( !selectionTool ) + { + DisplayError( NULL, wxT( "pcbnew.InteractiveSelection tool is not available" ) ); + return false; + } + + // Add context menu entries that are displayed when selection tool is active + m_selectionTool->AddMenuItem( COMMON_ACTIONS::editActivate ); + m_selectionTool->AddMenuItem( COMMON_ACTIONS::rotate ); + m_selectionTool->AddMenuItem( COMMON_ACTIONS::flip ); + m_selectionTool->AddMenuItem( COMMON_ACTIONS::remove ); + m_selectionTool->AddMenuItem( COMMON_ACTIONS::properties ); + + setTransitions(); + + return true; +} + + +int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) +{ + const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + + if( selection.Empty() ) + return 0; // there are no items to operate on + + VECTOR2D dragPosition; + m_dragging = false; + bool restore = false; // Should items' state be restored when finishing the tool? + + VIEW_CONTROLS* controls = getViewControls(); + controls->ShowCursor( true ); + controls->SetSnapping( true ); + controls->SetAutoPan( true ); + + // Main loop: keep receiving events + while( OPT_TOOL_EVENT evt = Wait() ) + { + if( evt->IsCancel() ) + { + restore = true; // Cancelling the tool means that items have to be restored + break; // Finish + } + + // Dispatch TOOL_ACTIONs + else if( evt->Category() == TC_COMMAND ) + { + if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) + Rotate( aEvent ); + else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) + Flip( aEvent ); + } + + else if( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) + { + if( m_dragging ) + { + // Drag items to the current cursor position + VECTOR2D movement = ( evt->Position() - dragPosition ); + m_state.Move( movement ); + } + else + { + // Prepare to drag + std::set::iterator it; + + for( it = selection.items.begin(); it != selection.items.end(); ++it ) + { + // Save the state of the selected items, in case it has to be restored + m_state.Save( *it ); + } + + m_dragging = true; + } + + selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); + dragPosition = evt->Position(); + } + + else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) + break; // Finish + } + + m_dragging = false; + + if( restore ) + { + // Modifications has to be rollbacked, so restore the previous state of items + selection.group->ItemsViewUpdate( VIEW_ITEM::APPEARANCE ); + m_state.RestoreAll(); + } + else + { + // Changes are applied, so update the items + selection.group->ItemsViewUpdate( m_state.GetUpdateFlag() ); + m_state.Apply(); + } + + controls->ShowCursor( false ); + controls->SetSnapping( false ); + controls->SetAutoPan( false ); + + setTransitions(); + + return 0; +} + + +int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) +{ + const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + + // Properties are displayed when there is only one item selected + if( selection.items.size() == 1 ) + { + // Display properties dialog + PCB_EDIT_FRAME* editFrame = static_cast( m_toolMgr->GetEditFrame() ); + BOARD_ITEM* item = *selection.items.begin(); + editFrame->OnEditItemRequest( NULL, item ); + + item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + + setTransitions(); + + return 0; +} + + +int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) +{ + const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + VECTOR2D cursorPos = getView()->ToWorld( getViewControls()->GetCursorPosition() ); + + if( m_dragging ) + { + m_state.Rotate( cursorPos, 900.0 ); + selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); + } + else + { + std::set::iterator it; + + for( it = selection.items.begin(); it != selection.items.end(); ++it ) + { + (*it)->Rotate( wxPoint( cursorPos.x, cursorPos.y ), 900.0 ); + (*it)->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + + setTransitions(); + } + + return 0; +} + + +int EDIT_TOOL::Flip( TOOL_EVENT& aEvent ) +{ + const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + VECTOR2D cursorPos = getView()->ToWorld( getViewControls()->GetCursorPosition() ); + + if( m_dragging ) + { + m_state.Flip( cursorPos ); + selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); + } + else + { + std::set::iterator it; + + for( it = selection.items.begin(); it != selection.items.end(); ++it ) + { + (*it)->Flip( wxPoint( cursorPos.x, cursorPos.y ) ); + (*it)->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS ); + } + + setTransitions(); + } + + return 0; +} + + +int EDIT_TOOL::Remove( TOOL_EVENT& aEvent ) +{ + // Get a copy of the selected items set + std::set selectedItems = m_selectionTool->GetSelection().items; + + // As we are about to remove items, they have to be removed from the selection + m_selectionTool->ClearSelection(); + + std::set::iterator it; + for( it = selectedItems.begin(); it != selectedItems.end(); ++it ) + remove( *it ); + + BOARD* board = getModel( PCB_T ); + // Rebuild list of pads and nets if necessary + if( !( board->GetStatus() & NET_CODES_OK ) ) + board->BuildListOfNets(); + + setTransitions(); + + return 0; +} + + +void EDIT_TOOL::remove( BOARD_ITEM* aItem ) +{ + BOARD* board = getModel( PCB_T ); + + switch( aItem->Type() ) + { + case PCB_MODULE_T: + { + MODULE* module = static_cast( aItem ); + + for( D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() ) + getView()->Remove( pad ); + + for( BOARD_ITEM* drawing = module->GraphicalItems().GetFirst(); drawing; + drawing = drawing->Next() ) + getView()->Remove( drawing ); + + getView()->Remove( &module->Reference() ); + getView()->Remove( &module->Value() ); + + // Module itself is deleted after the switch scope + // list of pads is rebuild by BOARD::BuildListOfNets() + +// module->ClearFlags(); // TODO is it necessary? clearing ratsnest/list of pads? + // Clear flags to indicate, that the ratsnest, list of nets & pads are not valid anymore + board->m_Status_Pcb = 0; + } + break; + + case PCB_ZONE_AREA_T: + getView()->Remove( aItem ); + getModel( PCB_T )->Delete( aItem ); + return; + + // These are not supposed to be removed + case PCB_PAD_T: + case PCB_MODULE_TEXT_T: + case PCB_MODULE_EDGE_T: + return; + + case PCB_LINE_T: // a segment not on copper layers + case PCB_TEXT_T: // a text on a layer + case PCB_TRACE_T: // a track segment (segment on a copper layer) + case PCB_VIA_T: // a via (like track segment on a copper layer) + case PCB_DIMENSION_T: // a dimension (graphic item) + case PCB_TARGET_T: // a target (graphic item) + case PCB_MARKER_T: // a marker used to show something + case PCB_ZONE_T: // SEG_ZONE items are now deprecated + break; + + // TODO + default: // other types do not need to (or should not) be handled + assert( false ); + return; + break; + } + + getView()->Remove( aItem ); + board->Delete( aItem ); +} + + +void EDIT_TOOL::setTransitions() +{ + Go( &EDIT_TOOL::Main, COMMON_ACTIONS::editActivate.MakeEvent() ); + Go( &EDIT_TOOL::Rotate, COMMON_ACTIONS::rotate.MakeEvent() ); + Go( &EDIT_TOOL::Flip, COMMON_ACTIONS::flip.MakeEvent() ); + Go( &EDIT_TOOL::Remove, COMMON_ACTIONS::remove.MakeEvent() ); + Go( &EDIT_TOOL::Properties, COMMON_ACTIONS::properties.MakeEvent() ); +} diff --git a/pcbnew/tools/edit_tool.h b/pcbnew/tools/edit_tool.h new file mode 100644 index 0000000000..3f823eff7d --- /dev/null +++ b/pcbnew/tools/edit_tool.h @@ -0,0 +1,111 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2013 CERN + * @author Maciej Suminski + * + * 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 + */ + +#ifndef __EDIT_TOOL_H +#define __EDIT_TOOL_H + +#include +#include +#include +#include "item_state.h" + +class BOARD_ITEM; +class SELECTION_TOOL; + +namespace KIGFX +{ +class VIEW_GROUP; +} + +/** + * Class EDIT_TOOL + * + * The interactive edit tool. Allows to move, rotate, flip and change properties of items selected + * using the pcbnew.InteractiveSelection tool. + */ + +class EDIT_TOOL : public TOOL_INTERACTIVE +{ +public: + EDIT_TOOL(); + + /// @copydoc TOOL_INTERACTIVE::Reset() + void Reset( RESET_REASON aReason ) {}; + + /// @copydoc TOOL_INTERACTIVE::Init() + bool Init(); + + /** + * Function Main() + * + * Main loop in which events are handled. + * @param aEvent is the handled event. + */ + int Main( TOOL_EVENT& aEvent ); + + /** + * Function Edit() + * + * Displays properties window for the selected object. + */ + int Properties( TOOL_EVENT& aEvent ); + + /** + * Function Rotate() + * + * Rotates currently selected items. + */ + int Rotate( TOOL_EVENT& aEvent ); + + /** + * Function Flip() + * + * Rotates currently selected items. The rotation point is the current cursor position. + */ + int Flip( TOOL_EVENT& aEvent ); + + /** + * Function Remove() + * + * Deletes currently selected items. The rotation point is the current cursor position. + */ + int Remove( TOOL_EVENT& aEvent ); + +private: + ///> Saves the state of items and allows to restore them + ITEM_STATE m_state; + + ///> Selection tool used for obtaining selected items + SELECTION_TOOL* m_selectionTool; + + ///> Flag determining if anything is being dragged right now + bool m_dragging; + + void remove( BOARD_ITEM* aItem ); + + ///> Sets up handlers for various events + void setTransitions(); +}; + +#endif diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index db347e8c4b..bef26764c5 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -50,6 +50,7 @@ void PCB_EDIT_FRAME::setupTools() m_toolManager->RegisterAction( &COMMON_ACTIONS::editActivate ); m_toolManager->RegisterAction( &COMMON_ACTIONS::rotate ); m_toolManager->RegisterAction( &COMMON_ACTIONS::flip ); + m_toolManager->RegisterAction( &COMMON_ACTIONS::remove ); m_toolManager->RegisterAction( &COMMON_ACTIONS::properties ); // Register tools @@ -59,6 +60,7 @@ void PCB_EDIT_FRAME::setupTools() m_toolManager->SetEnvironment( NULL, m_galCanvas->GetView(), m_galCanvas->GetViewControls(), this ); + m_toolManager->ResetTools( TOOL_BASE::RUN ); // Run the selection tool, it is supposed to be always active m_toolManager->InvokeTool( "pcbnew.InteractiveSelection" ); From b73dc849a51e8d4f7def36bb5f76d743a76ebd80 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 9 Dec 2013 11:07:30 +0100 Subject: [PATCH 17/95] Comments. --- pcbnew/tools/edit_tool.cpp | 7 +++---- pcbnew/tools/edit_tool.h | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index c6f46071d5..f790ca1679 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -238,15 +238,15 @@ int EDIT_TOOL::Remove( TOOL_EVENT& aEvent ) // Get a copy of the selected items set std::set selectedItems = m_selectionTool->GetSelection().items; - // As we are about to remove items, they have to be removed from the selection + // As we are about to remove items, they have to be removed from the selection first m_selectionTool->ClearSelection(); std::set::iterator it; for( it = selectedItems.begin(); it != selectedItems.end(); ++it ) remove( *it ); - BOARD* board = getModel( PCB_T ); // Rebuild list of pads and nets if necessary + BOARD* board = getModel( PCB_T ); if( !( board->GetStatus() & NET_CODES_OK ) ) board->BuildListOfNets(); @@ -276,10 +276,9 @@ void EDIT_TOOL::remove( BOARD_ITEM* aItem ) getView()->Remove( &module->Reference() ); getView()->Remove( &module->Value() ); - // Module itself is deleted after the switch scope + // Module itself is deleted after the switch scope is finished // list of pads is rebuild by BOARD::BuildListOfNets() -// module->ClearFlags(); // TODO is it necessary? clearing ratsnest/list of pads? // Clear flags to indicate, that the ratsnest, list of nets & pads are not valid anymore board->m_Status_Pcb = 0; } diff --git a/pcbnew/tools/edit_tool.h b/pcbnew/tools/edit_tool.h index 3f823eff7d..2e60a21fa3 100644 --- a/pcbnew/tools/edit_tool.h +++ b/pcbnew/tools/edit_tool.h @@ -102,6 +102,7 @@ private: ///> Flag determining if anything is being dragged right now bool m_dragging; + ///> Removes and frees a single BOARD_ITEM. void remove( BOARD_ITEM* aItem ); ///> Sets up handlers for various events From 212f004cad95cbbf096c6441c3d9c82b7b70c42e Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 18 Dec 2013 12:46:18 +0100 Subject: [PATCH 18/95] Removed some debug logs. --- common/gal/opengl/gpu_manager.cpp | 14 ++++++-------- common/view/view.cpp | 12 ++++++------ pcbnew/router/trace.h | 3 ++- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/common/gal/opengl/gpu_manager.cpp b/common/gal/opengl/gpu_manager.cpp index 8b556b32ce..25cd5fa418 100644 --- a/common/gal/opengl/gpu_manager.cpp +++ b/common/gal/opengl/gpu_manager.cpp @@ -34,11 +34,11 @@ #include #include #include -#ifdef __WXDEBUG__ +#ifdef PROFILE #include #include #include -#endif +#endif /* PROFILE */ using namespace KIGFX; @@ -187,10 +187,10 @@ void GPU_CACHED_MANAGER::EndDrawing() void GPU_CACHED_MANAGER::uploadToGpu() { -#ifdef __WXDEBUG__ +#ifdef PROFILE prof_counter totalTime; prof_start( &totalTime ); -#endif /* __WXDEBUG__ */ +#endif /* PROFILE */ if( !m_buffersInitialized ) Initialize(); @@ -207,15 +207,13 @@ void GPU_CACHED_MANAGER::uploadToGpu() m_indices.reset( new GLuint[bufferSize] ); if( glGetError() != GL_NO_ERROR ) - { DisplayError( NULL, wxT( "Error during data upload to the GPU memory" ) ); - } -#ifdef __WXDEBUG__ +#ifdef PROFILE prof_end( &totalTime ); wxLogDebug( wxT( "Uploading %d vertices to GPU / %.1f ms" ), bufferSize, totalTime.msecs() ); -#endif /* __WXDEBUG__ */ +#endif /* PROFILE */ } diff --git a/common/view/view.cpp b/common/view/view.cpp index a607c6112b..0ff8708ed0 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -34,9 +34,9 @@ #include #include -#ifdef __WXDEBUG__ +#ifdef PROFILE #include -#endif /* __WXDEBUG__ */ +#endif /* PROFILE */ using namespace KIGFX; @@ -981,10 +981,10 @@ void VIEW::RecacheAllItems( bool aImmediately ) r.SetMaximum(); -#ifdef __WXDEBUG__ +#ifdef PROFILE prof_counter totalRealTime; prof_start( &totalRealTime ); -#endif /* __WXDEBUG__ */ +#endif /* PROFILE */ for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i ) { @@ -1000,12 +1000,12 @@ void VIEW::RecacheAllItems( bool aImmediately ) } } -#ifdef __WXDEBUG__ +#ifdef PROFILE prof_end( &totalRealTime ); wxLogDebug( wxT( "RecacheAllItems::immediately: %u %.1f ms" ), aImmediately, totalRealTime.msecs() ); -#endif /* __WXDEBUG__ */ +#endif /* PROFILE */ } diff --git a/pcbnew/router/trace.h b/pcbnew/router/trace.h index b1acfd688f..1f8a3e32c9 100644 --- a/pcbnew/router/trace.h +++ b/pcbnew/router/trace.h @@ -21,7 +21,8 @@ #ifndef __TRACE_H #define __TRACE_H -#ifdef DEBUG +// #ifdef DEBUG +#if 0 #include #include From ce1541e915be3fcb37b071b8992deeeebe236469 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 18 Dec 2013 13:27:18 +0100 Subject: [PATCH 19/95] Added const modifiers where applicable (PICKED_ITEMS_LIST). Added PICKED_ITEMS_LIST::FindItem(). --- common/class_undoredo_container.cpp | 26 +++++++++++++++++++------- cvpcb/class_DisplayFootprintsFrame.h | 2 +- eeschema/schematic_undo_redo.cpp | 2 +- gerbview/gerbview_frame.h | 2 +- include/class_undoredo_container.h | 23 +++++++++++++++-------- include/wxBasePcbFrame.h | 2 +- include/wxEeschemaStruct.h | 2 +- include/wxPcbStruct.h | 2 +- pcbnew/board_undo_redo.cpp | 2 +- pcbnew/footprint_wizard_frame.h | 2 +- pcbnew/modedit_undo_redo.cpp | 2 +- pcbnew/module_editor_frame.h | 2 +- pcbnew/modview_frame.h | 2 +- 13 files changed, 45 insertions(+), 26 deletions(-) diff --git a/common/class_undoredo_container.cpp b/common/class_undoredo_container.cpp index e56d765139..2dd862ef01 100644 --- a/common/class_undoredo_container.cpp +++ b/common/class_undoredo_container.cpp @@ -50,7 +50,7 @@ PICKED_ITEMS_LIST::~PICKED_ITEMS_LIST() } -void PICKED_ITEMS_LIST::PushItem( ITEM_PICKER& aItem ) +void PICKED_ITEMS_LIST::PushItem( const ITEM_PICKER& aItem ) { m_ItemsList.push_back( aItem ); } @@ -70,7 +70,7 @@ ITEM_PICKER PICKED_ITEMS_LIST::PopItem() } -bool PICKED_ITEMS_LIST::ContainsItem( EDA_ITEM* aItem ) const +bool PICKED_ITEMS_LIST::ContainsItem( const EDA_ITEM* aItem ) const { for( size_t i = 0; i < m_ItemsList.size(); i++ ) { @@ -82,6 +82,18 @@ bool PICKED_ITEMS_LIST::ContainsItem( EDA_ITEM* aItem ) const } +int PICKED_ITEMS_LIST::FindItem( const EDA_ITEM* aItem ) const +{ + for( size_t i = 0; i < m_ItemsList.size(); i++ ) + { + if( m_ItemsList[i].GetItem() == aItem ) + return i; + } + + return -1; +} + + void PICKED_ITEMS_LIST::ClearItemsList() { m_ItemsList.clear(); @@ -157,7 +169,7 @@ void PICKED_ITEMS_LIST::ClearListAndDeleteItems() } -ITEM_PICKER PICKED_ITEMS_LIST::GetItemWrapper( unsigned int aIdx ) +ITEM_PICKER PICKED_ITEMS_LIST::GetItemWrapper( unsigned int aIdx ) const { ITEM_PICKER picker; @@ -168,7 +180,7 @@ ITEM_PICKER PICKED_ITEMS_LIST::GetItemWrapper( unsigned int aIdx ) } -EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItem( unsigned int aIdx ) +EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItem( unsigned int aIdx ) const { if( aIdx < m_ItemsList.size() ) return m_ItemsList[aIdx].GetItem(); @@ -177,7 +189,7 @@ EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItem( unsigned int aIdx ) } -EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItemLink( unsigned int aIdx ) +EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItemLink( unsigned int aIdx ) const { if( aIdx < m_ItemsList.size() ) return m_ItemsList[aIdx].GetLink(); @@ -186,7 +198,7 @@ EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItemLink( unsigned int aIdx ) } -UNDO_REDO_T PICKED_ITEMS_LIST::GetPickedItemStatus( unsigned int aIdx ) +UNDO_REDO_T PICKED_ITEMS_LIST::GetPickedItemStatus( unsigned int aIdx ) const { if( aIdx < m_ItemsList.size() ) return m_ItemsList[aIdx].GetStatus(); @@ -195,7 +207,7 @@ UNDO_REDO_T PICKED_ITEMS_LIST::GetPickedItemStatus( unsigned int aIdx ) } -STATUS_FLAGS PICKED_ITEMS_LIST::GetPickerFlags( unsigned aIdx ) +STATUS_FLAGS PICKED_ITEMS_LIST::GetPickerFlags( unsigned aIdx ) const { if( aIdx < m_ItemsList.size() ) return m_ItemsList[aIdx].GetFlags(); diff --git a/cvpcb/class_DisplayFootprintsFrame.h b/cvpcb/class_DisplayFootprintsFrame.h index 52b1366813..3244d62325 100644 --- a/cvpcb/class_DisplayFootprintsFrame.h +++ b/cvpcb/class_DisplayFootprintsFrame.h @@ -124,7 +124,7 @@ public: * @param aTransformPoint = the reference point of the transformation, * for commands like move */ - virtual void SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, + virtual void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList, UNDO_REDO_T aTypeCommand, const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ) { diff --git a/eeschema/schematic_undo_redo.cpp b/eeschema/schematic_undo_redo.cpp index 4481e8cce0..1ab8948d78 100644 --- a/eeschema/schematic_undo_redo.cpp +++ b/eeschema/schematic_undo_redo.cpp @@ -160,7 +160,7 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem, } -void SCH_EDIT_FRAME::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, +void SCH_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList, UNDO_REDO_T aTypeCommand, const wxPoint& aTransformPoint ) { diff --git a/gerbview/gerbview_frame.h b/gerbview/gerbview_frame.h index 6a69191706..9cabd38b16 100644 --- a/gerbview/gerbview_frame.h +++ b/gerbview/gerbview_frame.h @@ -676,7 +676,7 @@ public: * @param aTransformPoint = the reference point of the transformation, * for commands like move */ - void SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, + void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList, UNDO_REDO_T aTypeCommand, const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ) { diff --git a/include/class_undoredo_container.h b/include/class_undoredo_container.h index 6c95bae24d..13c9e85b23 100644 --- a/include/class_undoredo_container.h +++ b/include/class_undoredo_container.h @@ -111,7 +111,7 @@ public: void SetStatus( UNDO_REDO_T aStatus ) { m_undoRedoStatus = aStatus; } - UNDO_REDO_T GetStatus() { return m_undoRedoStatus; } + UNDO_REDO_T GetStatus() const { return m_undoRedoStatus; } void SetFlags( STATUS_FLAGS aFlags ) { m_pickerFlags = aFlags; } @@ -148,7 +148,7 @@ public: * pushes \a aItem to the top of the list * @param aItem Picker to push on to the list. */ - void PushItem( ITEM_PICKER& aItem ); + void PushItem( const ITEM_PICKER& aItem ); /** * Function PopItem @@ -160,7 +160,14 @@ public: * Function IsItemInList * @return True if \a aItem is found in the pick list. */ - bool ContainsItem( EDA_ITEM* aItem ) const; + bool ContainsItem( const EDA_ITEM* aItem ) const; + + /** + * Function FindItem + * @return Index of the searched item. If the item is not stored in the list, negative value + * is returned. + */ + int FindItem( const EDA_ITEM* aItem ) const; /** * Function ClearItemsList @@ -201,21 +208,21 @@ public: * if this picker does not exist, a picker is returned, * with its members set to 0 or NULL */ - ITEM_PICKER GetItemWrapper( unsigned int aIdx ); + ITEM_PICKER GetItemWrapper( unsigned int aIdx ) const; /** * Function GetPickedItem * @return A pointer to the picked item * @param aIdx Index of the picked item in the picked list */ - EDA_ITEM* GetPickedItem( unsigned int aIdx ); + EDA_ITEM* GetPickedItem( unsigned int aIdx ) const; /** * Function GetPickedItemLink * @return link of the picked item, or null if does not exist * @param aIdx Index of the picked item in the picked list */ - EDA_ITEM* GetPickedItemLink( unsigned int aIdx ); + EDA_ITEM* GetPickedItemLink( unsigned int aIdx ) const; /** * Function GetPickedItemStatus @@ -223,7 +230,7 @@ public: * or UR_UNSPECIFIED if does not exist * @param aIdx Index of the picked item in the picked list */ - UNDO_REDO_T GetPickedItemStatus( unsigned int aIdx ); + UNDO_REDO_T GetPickedItemStatus( unsigned int aIdx ) const; /** * Function GetPickerFlags @@ -231,7 +238,7 @@ public: * @param aIdx Index of the picker in the picked list * @return The value stored in the picker, if the picker exists, or 0 if does not exist */ - STATUS_FLAGS GetPickerFlags( unsigned aIdx ); + STATUS_FLAGS GetPickerFlags( unsigned aIdx ) const; /** * Function SetPickedItem diff --git a/include/wxBasePcbFrame.h b/include/wxBasePcbFrame.h index ff0db2f2c2..cbc96f31df 100644 --- a/include/wxBasePcbFrame.h +++ b/include/wxBasePcbFrame.h @@ -669,7 +669,7 @@ public: * @param aTransformPoint = the reference point of the transformation, * for commands like move */ - virtual void SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, + virtual void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList, UNDO_REDO_T aTypeCommand, const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ) = 0; diff --git a/include/wxEeschemaStruct.h b/include/wxEeschemaStruct.h index b3f60bac0f..30a5b3827a 100644 --- a/include/wxEeschemaStruct.h +++ b/include/wxEeschemaStruct.h @@ -1080,7 +1080,7 @@ public: * @param aTransformPoint = the reference point of the transformation, * for commands like move */ - void SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, + void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList, UNDO_REDO_T aTypeCommand, const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ); diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index fc7d379a07..33ab87d567 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -659,7 +659,7 @@ public: * @param aTransformPoint = the reference point of the transformation, for * commands like move */ - virtual void SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, + virtual void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList, UNDO_REDO_T aTypeCommand, const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ); diff --git a/pcbnew/board_undo_redo.cpp b/pcbnew/board_undo_redo.cpp index e58e734320..36a073d065 100644 --- a/pcbnew/board_undo_redo.cpp +++ b/pcbnew/board_undo_redo.cpp @@ -346,7 +346,7 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM* aItem, } -void PCB_EDIT_FRAME::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, +void PCB_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList, UNDO_REDO_T aTypeCommand, const wxPoint& aTransformPoint ) { diff --git a/pcbnew/footprint_wizard_frame.h b/pcbnew/footprint_wizard_frame.h index f65ee1d62d..9027e29e73 100644 --- a/pcbnew/footprint_wizard_frame.h +++ b/pcbnew/footprint_wizard_frame.h @@ -198,7 +198,7 @@ private: */ void OnLeftDClick( wxDC*, const wxPoint& ) {} void SaveCopyInUndoList( BOARD_ITEM*, UNDO_REDO_T, const wxPoint& ) {} - void SaveCopyInUndoList( PICKED_ITEMS_LIST&, UNDO_REDO_T, const wxPoint& ) {} + void SaveCopyInUndoList( const PICKED_ITEMS_LIST&, UNDO_REDO_T, const wxPoint& ) {} DECLARE_EVENT_TABLE() diff --git a/pcbnew/modedit_undo_redo.cpp b/pcbnew/modedit_undo_redo.cpp index 4f273eb3c7..613f4d8d2b 100644 --- a/pcbnew/modedit_undo_redo.cpp +++ b/pcbnew/modedit_undo_redo.cpp @@ -46,7 +46,7 @@ void FOOTPRINT_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM* aItem, } -void FOOTPRINT_EDIT_FRAME::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, +void FOOTPRINT_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList, UNDO_REDO_T aTypeCommand, const wxPoint& aTransformPoint ) { diff --git a/pcbnew/module_editor_frame.h b/pcbnew/module_editor_frame.h index 01e9a304ca..49682348e5 100644 --- a/pcbnew/module_editor_frame.h +++ b/pcbnew/module_editor_frame.h @@ -245,7 +245,7 @@ public: * @param aTransformPoint = the reference point of the transformation, for * commands like move */ - virtual void SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList, + virtual void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList, UNDO_REDO_T aTypeCommand, const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ); diff --git a/pcbnew/modview_frame.h b/pcbnew/modview_frame.h index c833e5c10c..0e099e4fea 100644 --- a/pcbnew/modview_frame.h +++ b/pcbnew/modview_frame.h @@ -202,7 +202,7 @@ private: */ void OnLeftDClick( wxDC*, const wxPoint& ) {} void SaveCopyInUndoList( BOARD_ITEM*, UNDO_REDO_T, const wxPoint& ) {} - void SaveCopyInUndoList( PICKED_ITEMS_LIST&, UNDO_REDO_T, const wxPoint &) {} + void SaveCopyInUndoList( const PICKED_ITEMS_LIST&, UNDO_REDO_T, const wxPoint &) {} DECLARE_EVENT_TABLE() From f06c0dc463856e7f55fa54e2e8f3003574bce0c4 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 18 Dec 2013 13:39:11 +0100 Subject: [PATCH 20/95] Added MODULE::RunOnChildren(). --- pcbnew/basepcbframe.cpp | 29 +++-------------------------- pcbnew/class_module.cpp | 13 +++++++++++++ pcbnew/class_module.h | 9 +++++++++ 3 files changed, 25 insertions(+), 26 deletions(-) diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index 22983f9063..95b356d915 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -200,46 +200,25 @@ void PCB_BASE_FRAME::ViewReloadBoard( const BOARD* aBoard ) const KIGFX::VIEW* view = m_galCanvas->GetView(); view->Clear(); - // All of PCB drawing elements should be added to the VIEW - // in order to be displayed + // All the PCB drawable items should be added to the VIEW in order to be displayed // Load zones for( int i = 0; i < aBoard->GetAreaCount(); ++i ) - { view->Add( (KIGFX::VIEW_ITEM*) ( aBoard->GetArea( i ) ) ); - } // Load drawings for( BOARD_ITEM* drawing = aBoard->m_Drawings; drawing; drawing = drawing->Next() ) - { view->Add( drawing ); - } // Load tracks for( TRACK* track = aBoard->m_Track; track; track = track->Next() ) - { view->Add( track ); - } // Load modules and its additional elements for( MODULE* module = aBoard->m_Modules; module; module = module->Next() ) { - // Load module's pads - for( D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() ) - { - view->Add( pad ); - } - - // Load module's drawing (mostly silkscreen) - for( BOARD_ITEM* drawing = module->GraphicalItems().GetFirst(); drawing; - drawing = drawing->Next() ) - { - view->Add( drawing ); - } - - // Load module's texts (name and value) - view->Add( &module->Reference() ); - view->Add( &module->Value() ); + // Load items that belong to a module + module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), view ) ); // Add the module itself view->Add( module ); @@ -247,9 +226,7 @@ void PCB_BASE_FRAME::ViewReloadBoard( const BOARD* aBoard ) const // Segzones (equivalent of ZONE_CONTAINER for legacy boards) for( SEGZONE* zone = aBoard->m_Zone; zone; zone = zone->Next() ) - { view->Add( zone ); - } // Add an entry for the worksheet layout KIGFX::WORKSHEET_VIEWITEM* worksheet = new KIGFX::WORKSHEET_VIEWITEM( diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp index 9694607a39..1885eb16c9 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -728,6 +728,19 @@ EDA_ITEM* MODULE::Clone() const } +void MODULE::RunOnChildren( boost::function aFunction ) +{ + for( D_PAD* pad = m_Pads.GetFirst(); pad; pad = pad->Next() ) + aFunction( static_cast( pad ) ); + + for( BOARD_ITEM* drawing = m_Drawings.GetFirst(); drawing; drawing = drawing->Next() ) + aFunction( drawing ); + + aFunction( static_cast( m_Reference ) ); + aFunction( static_cast( m_Value ) ); +} + + void MODULE::ViewUpdate( int aUpdateFlags ) { if( !m_view ) diff --git a/pcbnew/class_module.h b/pcbnew/class_module.h index a1564db05e..dbea0179d9 100644 --- a/pcbnew/class_module.h +++ b/pcbnew/class_module.h @@ -41,6 +41,7 @@ #include #include "zones.h" +#include class LINE_READER; class EDA_3D_CANVAS; @@ -447,6 +448,14 @@ public: EDA_ITEM* Clone() const; + /** + * Function RunOnChildren + * + * Invokes a function on all BOARD_ITEMs that belong to the module (pads, drawings, texts). + * @param aFunction is the function to be invoked. + */ + void RunOnChildren( boost::function aFunction ); + /// @copydoc VIEW_ITEM::ViewUpdate() void ViewUpdate( int aUpdateFlags ); From 2fb36a9144e6bd1b0d31d25b512d06b01e97ccf7 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 18 Dec 2013 14:33:34 +0100 Subject: [PATCH 21/95] SELECTION_TOOL uses ITEMS_PICKED_LIST to store selected items. Modifications done using the EDIT_TOOL are saved using the default KiCad's undo buffer. If there is only one item selected, info about the item is displayed in the bottom status bar. --- pcbnew/board_undo_redo.cpp | 58 +++++++ pcbnew/tools/edit_tool.cpp | 144 ++++++++++------ pcbnew/tools/edit_tool.h | 14 +- pcbnew/tools/item_state.h | 284 -------------------------------- pcbnew/tools/selection_tool.cpp | 132 ++++++--------- pcbnew/tools/selection_tool.h | 38 +++-- 6 files changed, 231 insertions(+), 439 deletions(-) delete mode 100644 pcbnew/tools/item_state.h diff --git a/pcbnew/board_undo_redo.cpp b/pcbnew/board_undo_redo.cpp index 36a073d065..fb8578fa4f 100644 --- a/pcbnew/board_undo_redo.cpp +++ b/pcbnew/board_undo_redo.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -40,6 +41,8 @@ #include #include +#include +#include /* Functions to undo and redo edit commands. * commands to undo are stored in CurrentScreen->m_UndoList @@ -424,6 +427,7 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed BOARD_ITEM* item; bool not_found = false; bool reBuild_ratsnest = false; + KIGFX::VIEW* view = m_galCanvas->GetView(); // Undo in the reverse order of list creation: (this can allow stacked changes // like the same item can be changes and deleted in the same complex command @@ -484,35 +488,80 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed case UR_CHANGED: /* Exchange old and new data for each item */ { BOARD_ITEM* image = (BOARD_ITEM*) aList->GetPickedItemLink( ii ); + + // Remove all pads/drawings/texts, as they become invalid + // for the VIEW after SwapData() called for modules + if( item->Type() == PCB_MODULE_T ) + { + MODULE* oldModule = static_cast( item ); + oldModule->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Remove ), + view ) ); + } + item->SwapData( image ); + + // Update all pads/drawings/texts, as they become invalid + // for the VIEW after SwapData() called for modules + if( item->Type() == PCB_MODULE_T ) + { + MODULE* newModule = static_cast( item ); + newModule->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), + view ) ); + } + + item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS ); } break; case UR_NEW: /* new items are deleted */ aList->SetPickedItemStatus( UR_DELETED, ii ); GetBoard()->Remove( item ); + + if( item->Type() == PCB_MODULE_T ) + { + MODULE* module = static_cast( item ); + module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Remove ), + view ) ); + } + view->Remove( item ); + + item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); break; case UR_DELETED: /* deleted items are put in List, as new items */ aList->SetPickedItemStatus( UR_NEW, ii ); GetBoard()->Add( item ); + + if( item->Type() == PCB_MODULE_T ) + { + MODULE* module = static_cast( item ); + module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), + view ) ); + } + view->Add( item ); + + item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); build_item_list = true; break; case UR_MOVED: item->Move( aRedoCommand ? aList->m_TransformPoint : -aList->m_TransformPoint ); + item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); break; case UR_ROTATED: item->Rotate( aList->m_TransformPoint, aRedoCommand ? 900 : -900 ); + item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); break; case UR_ROTATED_CLOCKWISE: item->Rotate( aList->m_TransformPoint, aRedoCommand ? -900 : 900 ); + item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); break; case UR_FLIPPED: item->Flip( aList->m_TransformPoint ); + item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS ); break; default: @@ -540,6 +589,11 @@ void PCB_EDIT_FRAME::GetBoardFromUndoList( wxCommandEvent& event ) if( GetScreen()->GetUndoCommandCount() <= 0 ) return; + // Clear the selection, as it may be altered with undone items + SELECTION_TOOL* selectionTool = static_cast( m_toolManager->FindTool( + "pcbnew.InteractiveSelection" ) ); + selectionTool->ClearSelection(); + /* Get the old list */ PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList(); /* Undo the command */ @@ -559,6 +613,10 @@ void PCB_EDIT_FRAME::GetBoardFromRedoList( wxCommandEvent& event ) if( GetScreen()->GetRedoCommandCount() == 0 ) return; + // Clear the selection, as it may be altered with redone items + SELECTION_TOOL* selectionTool = static_cast( m_toolManager->FindTool( + "pcbnew.InteractiveSelection" ) ); + selectionTool->ClearSelection(); /* Get the old list */ PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromRedoList(); diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index f790ca1679..e8accb4ca7 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -72,11 +72,15 @@ bool EDIT_TOOL::Init() int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) { const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + PCB_EDIT_FRAME* editFrame = static_cast( m_toolMgr->GetEditFrame() ); + + // By default, modified items need to update their geometry + m_updateFlag = KIGFX::VIEW_ITEM::GEOMETRY; if( selection.Empty() ) return 0; // there are no items to operate on - VECTOR2D dragPosition; + VECTOR2D dragPosition; // The last position of the cursor while dragging m_dragging = false; bool restore = false; // Should items' state be restored when finishing the tool? @@ -98,9 +102,16 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) else if( evt->Category() == TC_COMMAND ) { if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) + { Rotate( aEvent ); + } else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) + { Flip( aEvent ); + + // Flip causes change of layers + enableUpdateFlag( KIGFX::VIEW_ITEM::LAYERS ); + } } else if( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) @@ -109,19 +120,24 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) { // Drag items to the current cursor position VECTOR2D movement = ( evt->Position() - dragPosition ); - m_state.Move( movement ); + for( unsigned int i = 0; i < selection.items.GetCount(); ++i ) + { + BOARD_ITEM* item = static_cast( selection.items.GetPickedItem( i ) ); + item->Move( wxPoint( movement.x, movement.y ) ); + } } else { - // Prepare to drag - std::set::iterator it; - - for( it = selection.items.begin(); it != selection.items.end(); ++it ) + // Prepare to drag - save items, so changes can be undone + for( unsigned int i = 0; i < selection.items.GetCount(); ++i ) { - // Save the state of the selected items, in case it has to be restored - m_state.Save( *it ); + BOARD_ITEM* item = static_cast( selection.items.GetPickedItem( i ) ); + std::cout << "saved " << (unsigned long) item << std::endl; } + editFrame->OnModify(); + editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED ); + m_dragging = true; } @@ -138,14 +154,13 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) if( restore ) { // Modifications has to be rollbacked, so restore the previous state of items - selection.group->ItemsViewUpdate( VIEW_ITEM::APPEARANCE ); - m_state.RestoreAll(); + wxCommandEvent dummy; + editFrame->GetBoardFromUndoList( dummy ); } else { // Changes are applied, so update the items - selection.group->ItemsViewUpdate( m_state.GetUpdateFlag() ); - m_state.Apply(); + selection.group->ItemsViewUpdate( m_updateFlag ); } controls->ShowCursor( false ); @@ -161,13 +176,20 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) { const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + PCB_EDIT_FRAME* editFrame = static_cast( m_toolMgr->GetEditFrame() ); // Properties are displayed when there is only one item selected - if( selection.items.size() == 1 ) + if( selection.Size() == 1 ) { // Display properties dialog - PCB_EDIT_FRAME* editFrame = static_cast( m_toolMgr->GetEditFrame() ); - BOARD_ITEM* item = *selection.items.begin(); + BOARD_ITEM* item = static_cast( selection.items.GetPickedItem( 0 ) ); + + if( !m_dragging ) // If it is being dragged, then it is already saved with UR_CHANGED flag + { + editFrame->SaveCopyInUndoList( item, UR_CHANGED ); + editFrame->OnModify(); + } + editFrame->OnEditItemRequest( NULL, item ); item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); @@ -182,25 +204,28 @@ int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) { const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); - VECTOR2D cursorPos = getView()->ToWorld( getViewControls()->GetCursorPosition() ); + VECTOR2D cursor = getView()->ToWorld( getViewControls()->GetCursorPosition() ); + PCB_EDIT_FRAME* editFrame = static_cast( m_toolMgr->GetEditFrame() ); + + if( !m_dragging ) // If it is being dragged, then it is already saved with UR_CHANGED flag + { + editFrame->OnModify(); + editFrame->SaveCopyInUndoList( selection.items, UR_ROTATED, wxPoint( cursor.x, cursor.y ) ); + } + + for( unsigned int i = 0; i < selection.items.GetCount(); ++i ) + { + BOARD_ITEM* item = static_cast( selection.items.GetPickedItem( i ) ); + + item->Rotate( wxPoint( cursor.x, cursor.y ), 900.0 ); + if( !m_dragging ) + item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } if( m_dragging ) - { - m_state.Rotate( cursorPos, 900.0 ); - selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); - } - else - { - std::set::iterator it; + selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - for( it = selection.items.begin(); it != selection.items.end(); ++it ) - { - (*it)->Rotate( wxPoint( cursorPos.x, cursorPos.y ), 900.0 ); - (*it)->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - - setTransitions(); - } + setTransitions(); return 0; } @@ -209,25 +234,28 @@ int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) int EDIT_TOOL::Flip( TOOL_EVENT& aEvent ) { const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); - VECTOR2D cursorPos = getView()->ToWorld( getViewControls()->GetCursorPosition() ); + VECTOR2D cursor = getView()->ToWorld( getViewControls()->GetCursorPosition() ); + PCB_EDIT_FRAME* editFrame = static_cast( m_toolMgr->GetEditFrame() ); + + if( !m_dragging ) // If it is being dragged, then it is already saved with UR_CHANGED flag + { + editFrame->OnModify(); + editFrame->SaveCopyInUndoList( selection.items, UR_FLIPPED, wxPoint( cursor.x, cursor.y ) ); + } + + for( unsigned int i = 0; i < selection.items.GetCount(); ++i ) + { + BOARD_ITEM* item = static_cast( selection.items.GetPickedItem( i ) ); + + item->Flip( wxPoint( cursor.x, cursor.y ) ); + if( !m_dragging ) + item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS ); + } if( m_dragging ) - { - m_state.Flip( cursorPos ); - selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); - } - else - { - std::set::iterator it; + selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - for( it = selection.items.begin(); it != selection.items.end(); ++it ) - { - (*it)->Flip( wxPoint( cursorPos.x, cursorPos.y ) ); - (*it)->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS ); - } - - setTransitions(); - } + setTransitions(); return 0; } @@ -236,14 +264,24 @@ int EDIT_TOOL::Flip( TOOL_EVENT& aEvent ) int EDIT_TOOL::Remove( TOOL_EVENT& aEvent ) { // Get a copy of the selected items set - std::set selectedItems = m_selectionTool->GetSelection().items; + PICKED_ITEMS_LIST selectedItems = m_selectionTool->GetSelection().items; + PCB_EDIT_FRAME* editFrame = static_cast( m_toolMgr->GetEditFrame() ); // As we are about to remove items, they have to be removed from the selection first m_selectionTool->ClearSelection(); - std::set::iterator it; - for( it = selectedItems.begin(); it != selectedItems.end(); ++it ) - remove( *it ); + // Save them + for( unsigned int i = 0; i < selectedItems.GetCount(); ++i ) + selectedItems.SetPickedItemStatus( UR_DELETED, i ); + editFrame->OnModify(); + editFrame->SaveCopyInUndoList( selectedItems, UR_DELETED ); + + // And now remove + for( unsigned int i = 0; i < selectedItems.GetCount(); ++i ) + { + BOARD_ITEM* item = static_cast( selectedItems.GetPickedItem( i ) ); + remove( item ); + } // Rebuild list of pads and nets if necessary BOARD* board = getModel( PCB_T ); @@ -265,6 +303,7 @@ void EDIT_TOOL::remove( BOARD_ITEM* aItem ) case PCB_MODULE_T: { MODULE* module = static_cast( aItem ); + module->ClearFlags(); for( D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() ) getView()->Remove( pad ); @@ -305,7 +344,6 @@ void EDIT_TOOL::remove( BOARD_ITEM* aItem ) case PCB_ZONE_T: // SEG_ZONE items are now deprecated break; - // TODO default: // other types do not need to (or should not) be handled assert( false ); return; @@ -313,7 +351,7 @@ void EDIT_TOOL::remove( BOARD_ITEM* aItem ) } getView()->Remove( aItem ); - board->Delete( aItem ); + board->Remove( aItem ); } diff --git a/pcbnew/tools/edit_tool.h b/pcbnew/tools/edit_tool.h index 2e60a21fa3..5ddcb84f5d 100644 --- a/pcbnew/tools/edit_tool.h +++ b/pcbnew/tools/edit_tool.h @@ -28,7 +28,6 @@ #include #include #include -#include "item_state.h" class BOARD_ITEM; class SELECTION_TOOL; @@ -93,9 +92,6 @@ public: int Remove( TOOL_EVENT& aEvent ); private: - ///> Saves the state of items and allows to restore them - ITEM_STATE m_state; - ///> Selection tool used for obtaining selected items SELECTION_TOOL* m_selectionTool; @@ -107,6 +103,16 @@ private: ///> Sets up handlers for various events void setTransitions(); + + ///> The required update flag for modified items + KIGFX::VIEW_ITEM::VIEW_UPDATE_FLAGS m_updateFlag; + + ///> Enables higher order update flag + void enableUpdateFlag( KIGFX::VIEW_ITEM::VIEW_UPDATE_FLAGS aFlag ) + { + if( m_updateFlag < aFlag ) + m_updateFlag = aFlag; + } }; #endif diff --git a/pcbnew/tools/item_state.h b/pcbnew/tools/item_state.h deleted file mode 100644 index ed562c623d..0000000000 --- a/pcbnew/tools/item_state.h +++ /dev/null @@ -1,284 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2013 CERN - * @author Maciej Suminski - * - * 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 - */ - -#ifndef ITEM_STATE_H_ -#define ITEM_STATE_H_ - -#include -#include - -/** - * Class ITEM_STATE - * - * Provides means for modifying properties of groups of items and gives possibility of rolling back - * the introduced changes. Does not take ownership of modified items, neither takes care of - * refreshing. - */ -class ITEM_STATE -{ -public: - ITEM_STATE() : - m_movement( 0.0, 0.0 ), m_flips( 0 ), m_rotation( 0.0 ) - { -#ifdef __WXDEBUG__ - m_canSave = true; -#endif - } - - /** - * Function Save() - * - * Adds an item and saves it's state. - * @param aItem is the item to be added. - */ - void Save( BOARD_ITEM* aItem ) - { -#ifdef __WXDEBUG__ - wxASSERT_MSG( m_canSave, wxT( "You cannot save items after issuing commands. You have " - "either RestoreAll() or Apply() before adding items!" ) ); -#endif - m_items.push_back( aItem ); - } - - /** - * Function RestoreAll() - * - * Rollbacks all the changes to the initial state. - */ - void RestoreAll() - { - // Check if there is a not saved movement command - saveMovement(); - - std::deque::iterator it, it_end; - std::deque::iterator cmd, cmd_end; - - for( it = m_items.begin(), it_end = m_items.end(); it != it_end; ++it ) - { - for( cmd = m_commands.begin(), cmd_end = m_commands.end(); cmd != cmd_end; ++cmd ) - cmd->Revert( *it ); - } - - reset(); - } - - /** - * Function Apply() - * - * Resets the state, clears the list of items & changes, so the object can be reused for - * other items. - */ - void Apply() - { - reset(); - } - - /** - * Function Move() - * - * Moves stored items by a given vector. - * @param aMovement is the movement vector. - */ - void Move( const VECTOR2D& aMovement ) - { -#ifdef __WXDEBUG__ - m_canSave = false; -#endif - std::deque::iterator it, it_end; - - for( it = m_items.begin(), it_end = m_items.end(); it != it_end; ++it ) - (*it)->Move( wxPoint( aMovement.x, aMovement.y ) ); - - m_movement += aMovement; - } - - /** - * Function Rotate() - * - * Rotates stored items by a given angle. - * @param aAngle is the angle (in decidegrees). - */ - void Rotate( const VECTOR2D& aPoint, double aAngle ) - { -#ifdef __WXDEBUG__ - m_canSave = false; -#endif - saveMovement(); - m_commands.push_front( COMMAND( COMMAND::ROTATE, aPoint, aAngle ) ); - - std::deque::iterator it, it_end; - - for( it = m_items.begin(), it_end = m_items.end(); it != it_end; ++it ) - (*it)->Rotate( wxPoint( aPoint.x, aPoint.y ), aAngle ); - - m_rotation += aAngle; - } - - /** - * Function Flip() - * - * Changes the board side for stored items. - * @param aPoint is the rotation point. - */ - void Flip( const VECTOR2D& aPoint ) - { -#ifdef __WXDEBUG__ - m_canSave = false; -#endif - saveMovement(); - m_commands.push_front( COMMAND( COMMAND::FLIP, aPoint ) ); - - std::deque::iterator it, it_end; - - for( it = m_items.begin(), it_end = m_items.end(); it != it_end; ++it ) - (*it)->Flip( wxPoint( aPoint.x, aPoint.y ) ); - - m_flips++; - } - - /** - * Function ToggleVisibility() - * - * Switches the visibility property of stored items. - */ - void ToggleVisibility() - { -#ifdef __WXDEBUG__ - m_canSave = false; -#endif - m_commands.push_front( COMMAND( COMMAND::VISIBILITY ) ); - - std::deque::iterator it, it_end; - - for( it = m_items.begin(), it_end = m_items.end(); it != it_end; ++it ) - (*it)->ViewSetVisible( !(*it)->ViewIsVisible() ); - } - - /** - * Function GetUpdateFlag() - * - * Returns information on what kind of update should be applied to items in order to display - * them properly. - * @return Flag required to refresh items. - */ - KIGFX::VIEW_ITEM::VIEW_UPDATE_FLAGS GetUpdateFlag() const - { - if( m_flips % 2 == 1 ) // If number of flips is odd, then we need to change layers - return KIGFX::VIEW_ITEM::LAYERS; - else if( m_movement.x != 0.0 || m_movement.y != 0.0 || m_rotation != 0.0 ) - return KIGFX::VIEW_ITEM::GEOMETRY; - - return KIGFX::VIEW_ITEM::APPEARANCE; - } - -private: - /// COMMAND stores modifications that were done to items - struct COMMAND - { - /// Type of command - enum TYPE { MOVE, ROTATE, FLIP, VISIBILITY }; - TYPE m_type; - - /// Point where flip/rotation occurred or movement vector - VECTOR2D m_point; - - /// Used only for rotation - double m_angle; - - COMMAND( TYPE aType, VECTOR2D aPoint = VECTOR2D( 0.0, 0.0 ), double aAngle = 0.0 ) : - m_type( aType ), m_point( aPoint ), m_angle( aAngle ) {}; - - void Revert( BOARD_ITEM* aItem ) - { - switch( m_type ) - { - case MOVE: - aItem->Move( wxPoint( -m_point.x, -m_point.y ) ); - break; - - case ROTATE: - aItem->Rotate( wxPoint( m_point.x, m_point.y ), -m_angle ); - break; - - case FLIP: - aItem->Flip( wxPoint( m_point.x, m_point.y ) ); - break; - - case VISIBILITY: - aItem->ViewSetVisible( !aItem->ViewIsVisible() ); - break; - } - } - }; - - /// Adds a MOVEMENT command basing on the current movement vector - void saveMovement() - { - if( m_movement.x != 0.0 || m_movement.y != 0.0 ) - { - m_commands.push_front( COMMAND( COMMAND::MOVE, m_movement ) ); - - m_movement.x = 0.0; - m_movement.y = 0.0; - } - } - - /// Restores the initial state - void reset() - { - m_movement.x = 0.0; - m_movement.y = 0.0; - m_flips = 0; - m_rotation = 0.0; - - m_items.clear(); - m_commands.clear(); - -#ifdef __WXDEBUG__ - m_canSave = true; -#endif - } - - /// List of issued commands - std::deque m_items; - - /// List of items that are affected by commands - std::deque m_commands; - - /// Current movement vector (updated by Move() command) - VECTOR2D m_movement; - - /// Number of flips applied to items - unsigned int m_flips; - - /// Total rotation applied to items - double m_rotation; - -#ifdef __WXDEBUG__ - /// Debug flag assuring that functions are called in proper order - bool m_canSave; -#endif -}; - -#endif /* ITEM_STATE_H_ */ diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index bf78405612..dabf03dda8 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -182,9 +182,9 @@ void SELECTION_TOOL::AddMenuItem( const TOOL_ACTION& aAction ) void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem ) { - if( isSelected( aItem ) ) + if( aItem->IsSelected() ) { - deselectItem( aItem ); + deselect( aItem ); } else { @@ -193,17 +193,11 @@ void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem ) // Prevent selection of invisible or inactive items if( selectable( aItem ) ) - selectItem( aItem ); + select( aItem ); } } -bool SELECTION_TOOL::isSelected( const BOARD_ITEM* aItem ) const -{ - return ( m_selection.items.find( const_cast( aItem ) ) != m_selection.items.end() ); -} - - void SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere ) { BOARD* pcb = getModel( PCB_T ); @@ -219,7 +213,6 @@ void SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere ) case 0: if( !m_additive ) ClearSelection(); - break; case 1: @@ -231,7 +224,7 @@ void SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere ) // contain anything but module footprint and not selectable items for( int i = collector.GetCount() - 1; i >= 0 ; --i ) { - BOARD_ITEM* boardItem = ( collector )[i]; + BOARD_ITEM* boardItem = collector[i]; if( boardItem->Type() == PCB_MODULE_T || !selectable( boardItem ) ) collector.Remove( i ); @@ -338,8 +331,8 @@ bool SELECTION_TOOL::selectMultiple() BOARD_ITEM* item = static_cast( it->first ); // Add only those items that are visible and fully within the selection box - if( selectable( item ) && selectionBox.Contains( item->ViewBBox() ) ) - selectItem( item ); + if( !item->IsSelected() && selectable( item ) && selectionBox.Contains( item->ViewBBox() ) ) + select( item ); } // Do not display information about selected item,as there is more than one @@ -502,49 +495,23 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const } -void SELECTION_TOOL::selectItem( BOARD_ITEM* aItem ) +void SELECTION_TOOL::select( BOARD_ITEM* aItem ) { - /// Selecting an item needs a few operations, so they are wrapped in a functor - class selectBase_ - { - SELECTION& s; - - public: - selectBase_( SELECTION& s_ ) : s( s_ ) {} - - void operator()( BOARD_ITEM* item ) - { - s.group->Add( item ); - // Hide the original item, so it is shown only on overlay - item->ViewSetVisible( false ); - item->SetSelected(); - } - } selectBase( m_selection ); - - // Modules are treated in a special way - when they are selected, we have to - // select all the parts that make the module, not the module itself + // Modules are treated in a special way - when they are selected, we have to mark + // all the parts that make the module as selected if( aItem->Type() == PCB_MODULE_T ) { MODULE* module = static_cast( aItem ); + module->RunOnChildren( std::bind1st( std::mem_fun( &SELECTION_TOOL::selectVisually ), this ) ); - // Add everything that belongs to the module (besides the module itself) - for( D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() ) - selectBase( pad ); - - for( BOARD_ITEM* drawing = module->GraphicalItems().GetFirst(); drawing; - drawing = drawing->Next() ) - selectBase( drawing ); - - selectBase( &module->Reference() ); - selectBase( &module->Value() ); } - // Add items to the VIEW_GROUP, so they will be displayed on the overlay - selectBase( aItem ); - m_selection.items.insert( aItem ); + selectVisually( aItem ); + ITEM_PICKER picker( aItem ); + m_selection.items.PushItem( picker ); // It is enough to do it only for the first selected item - if( m_selection.items.size() == 1 ) + if( m_selection.Size() == 1 ) { // Set as the current item, so the information about selection is displayed getEditFrame()->SetCurItem( aItem, true ); @@ -552,48 +519,30 @@ void SELECTION_TOOL::selectItem( BOARD_ITEM* aItem ) // Now the context menu should be enabled SetContextMenu( &m_menu, CMENU_BUTTON ); } + else + { + // If multiple items are selected, do not show the information about the selected item + getEditFrame()->SetCurItem( NULL, true ); + } } -void SELECTION_TOOL::deselectItem( BOARD_ITEM* aItem ) +void SELECTION_TOOL::deselect( BOARD_ITEM* aItem ) { - /// Deselecting an item needs a few operations, so they are wrapped in a functor - class deselectBase_ - { - SELECTION& s; - - public: - deselectBase_( SELECTION& s_ ) : s( s_ ) {} - - void operator()( BOARD_ITEM* item ) - { - s.group->Remove( item ); - // Restore original item visibility - item->ViewSetVisible( true ); - item->ClearSelected(); - } - } deselectBase( m_selection ); - // Modules are treated in a special way - when they are selected, we have to - // select all the parts that make the module, not the module itself + // deselect all the parts that make the module, not the module itself if( aItem->Type() == PCB_MODULE_T ) { MODULE* module = static_cast( aItem ); + module->RunOnChildren( std::bind1st( std::mem_fun( &SELECTION_TOOL::deselectVisually ), this ) ); - // Add everything that belongs to the module (besides the module itself) - for( D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() ) - deselectBase( pad ); - - for( BOARD_ITEM* drawing = module->GraphicalItems().GetFirst(); drawing; - drawing = drawing->Next() ) - deselectBase( drawing ); - - deselectBase( &module->Reference() ); - deselectBase( &module->Value() ); } - deselectBase( aItem ); - m_selection.items.erase( aItem ); + deselectVisually( aItem ); + + int itemIdx = m_selection.items.FindItem( aItem ); + if( itemIdx >= 0 ) + m_selection.items.RemovePicker( itemIdx ); // If there is nothing selected, disable the context menu if( m_selection.Empty() ) @@ -604,6 +553,26 @@ void SELECTION_TOOL::deselectItem( BOARD_ITEM* aItem ) } +void SELECTION_TOOL::selectVisually( BOARD_ITEM* aItem ) const +{ + m_selection.group->Add( aItem ); + + // Hide the original item, so it is shown only on overlay + aItem->ViewSetVisible( false ); + aItem->SetSelected(); +} + + +void SELECTION_TOOL::deselectVisually( BOARD_ITEM* aItem ) const +{ + m_selection.group->Remove( aItem ); + + // Restore original item visibility + aItem->ViewSetVisible( true ); + aItem->ClearSelected(); +} + + bool SELECTION_TOOL::containsSelected( const VECTOR2I& aPoint ) const { const unsigned GRIP_MARGIN = 500000; @@ -611,9 +580,10 @@ bool SELECTION_TOOL::containsSelected( const VECTOR2I& aPoint ) const // Check if the point is located within any of the currently selected items bounding boxes std::set::iterator it, it_end; - for( it = m_selection.items.begin(), it_end = m_selection.items.end(); it != it_end; ++it ) + for( unsigned int i = 0; i < m_selection.items.GetCount(); ++i ) { - BOX2I itemBox = (*it)->ViewBBox(); + BOARD_ITEM* item = static_cast( m_selection.items.GetPickedItem( i ) ); + BOX2I itemBox = item->ViewBBox(); itemBox.Inflate( GRIP_MARGIN ); // Give some margin for gripping an item if( itemBox.Contains( aPoint ) ) @@ -626,6 +596,6 @@ bool SELECTION_TOOL::containsSelected( const VECTOR2I& aPoint ) const void SELECTION_TOOL::SELECTION::Clear() { - items.clear(); + items.ClearItemsList(); group->Clear(); } diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h index 33fc4b2494..168f2288da 100644 --- a/pcbnew/tools/selection_tool.h +++ b/pcbnew/tools/selection_tool.h @@ -26,11 +26,10 @@ #ifndef __SELECTION_TOOL_H #define __SELECTION_TOOL_H -#include - #include #include #include +#include class SELECTION_AREA; class BOARD_ITEM; @@ -62,7 +61,7 @@ public: struct SELECTION { /// Set of selected items - std::set items; + PICKED_ITEMS_LIST items; /// VIEW_GROUP that holds currently selected items KIGFX::VIEW_GROUP* group; @@ -70,13 +69,13 @@ public: /// Checks if there is anything selected bool Empty() const { - return items.empty(); + return ( items.GetCount() == 0 ); } /// Returns the number of selected parts int Size() const { - return items.size(); + return items.GetCount(); } /// Clears both the VIEW_GROUP and set of selected items. Please note that it does not @@ -111,7 +110,7 @@ public: void ClearSelection(); /** - * Function AddAction() + * Function AddMenuItem() * * Adds a menu entry to run a TOOL_ACTION on selected items. * @param aAction is a menu entry to be added. @@ -161,15 +160,6 @@ private: */ void toggleSelection( BOARD_ITEM* aItem ); - /** - * Function isSelected() - * Tests if an item is currently selected. - * - * @param aItem is the item to be checked. - * @return True if the item is selected, false otherwise. - */ - bool isSelected( const BOARD_ITEM* aItem ) const; - /** * Function selectable() * Checks conditions for an item to be selected. @@ -184,7 +174,7 @@ private: * * @param aItem is an item to be selected. */ - void selectItem( BOARD_ITEM* aItem ); + void select( BOARD_ITEM* aItem ); /** * Function deselectItem() @@ -192,7 +182,21 @@ private: * * @param aItem is an item to be deselected. */ - void deselectItem( BOARD_ITEM* aItem ); + void deselect( BOARD_ITEM* aItem ); + + /** + * Function deselectVisually() + * Marks item as selected, but does not add it to the ITEMS_PICKED_LIST. + * @param aItem is an item to be be marked. + */ + void selectVisually( BOARD_ITEM* aItem ) const; + + /** + * Function deselectVisually() + * Marks item as selected, but does not add it to the ITEMS_PICKED_LIST. + * @param aItem is an item to be be marked. + */ + void deselectVisually( BOARD_ITEM* aItem ) const; /** * Function containsSelected() From b67c56854574c76ee0c39c066d5e2102cfb80f8c Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 18 Dec 2013 15:09:09 +0100 Subject: [PATCH 22/95] Speed optimization during selection of multiple items. Removed debug output. --- pcbnew/tools/edit_tool.cpp | 6 ------ pcbnew/tools/selection_tool.cpp | 6 ++---- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index e8accb4ca7..a51d9dccf9 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -129,12 +129,6 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) else { // Prepare to drag - save items, so changes can be undone - for( unsigned int i = 0; i < selection.items.GetCount(); ++i ) - { - BOARD_ITEM* item = static_cast( selection.items.GetPickedItem( i ) ); - std::cout << "saved " << (unsigned long) item << std::endl; - } - editFrame->OnModify(); editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED ); diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index dabf03dda8..540ea5cb3d 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -503,7 +503,6 @@ void SELECTION_TOOL::select( BOARD_ITEM* aItem ) { MODULE* module = static_cast( aItem ); module->RunOnChildren( std::bind1st( std::mem_fun( &SELECTION_TOOL::selectVisually ), this ) ); - } selectVisually( aItem ); @@ -519,8 +518,8 @@ void SELECTION_TOOL::select( BOARD_ITEM* aItem ) // Now the context menu should be enabled SetContextMenu( &m_menu, CMENU_BUTTON ); } - else - { + 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 getEditFrame()->SetCurItem( NULL, true ); } @@ -535,7 +534,6 @@ void SELECTION_TOOL::deselect( BOARD_ITEM* aItem ) { MODULE* module = static_cast( aItem ); module->RunOnChildren( std::bind1st( std::mem_fun( &SELECTION_TOOL::deselectVisually ), this ) ); - } deselectVisually( aItem ); From 667dd177ce823c8841ae914f03986dd5c0137213 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 18 Dec 2013 15:11:12 +0100 Subject: [PATCH 23/95] More elegant way of handling interruption of current modifications. --- pcbnew/tools/edit_tool.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index a51d9dccf9..f1f7c75f0b 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -148,8 +148,8 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) if( restore ) { // Modifications has to be rollbacked, so restore the previous state of items - wxCommandEvent dummy; - editFrame->GetBoardFromUndoList( dummy ); + wxCommandEvent undoEvent( wxEVT_TOOL, wxID_UNDO ); + wxPostEvent( editFrame, undoEvent ); } else { From 64c093109dd6972253df33fc999cdb4a52928114 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 18 Dec 2013 15:38:38 +0100 Subject: [PATCH 24/95] Added possibility of removing selected items while dragging. --- pcbnew/tools/common_actions.cpp | 5 +++-- pcbnew/tools/edit_tool.cpp | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 1a80bd5a9c..6756e10a9d 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -24,6 +24,7 @@ #include "common_actions.h" #include +#include // Selection tool actions TOOL_ACTION COMMON_ACTIONS::selectionActivate( "pcbnew.InteractiveSelection", @@ -42,8 +43,8 @@ TOOL_ACTION COMMON_ACTIONS::flip( "pcbnew.InteractiveEdit.flip", AS_CONTEXT, 'F', "Flip", "Flips selected item(s)" ); -TOOL_ACTION COMMON_ACTIONS::remove( "pcbnew.InteractiveEdit.delete", - AS_GLOBAL, 127, // 127 stands for DELETE key +TOOL_ACTION COMMON_ACTIONS::remove( "pcbnew.InteractiveEdit.remove", + AS_GLOBAL, WXK_DELETE, "Remove", "Deletes selected item(s)" ); TOOL_ACTION COMMON_ACTIONS::properties( "pcbnew.InteractiveEdit.properties", diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index f1f7c75f0b..99f44b9dfb 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -112,6 +112,11 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) // Flip causes change of layers enableUpdateFlag( KIGFX::VIEW_ITEM::LAYERS ); } + else if( evt->IsAction( &COMMON_ACTIONS::remove ) ) + { + Remove( aEvent ); + break; + } } else if( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) From 9cd30339e16fdd59c449041bfa8db009f9e26569 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 18 Dec 2013 16:26:21 +0100 Subject: [PATCH 25/95] Made pads & module texts unselectable --- pcbnew/tools/selection_tool.cpp | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 540ea5cb3d..fe7568c873 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -220,13 +220,10 @@ void SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere ) break; default: - // Remove modules, they have to be selected by clicking on area that does not - // contain anything but module footprint and not selectable items + // Remove unselectable items for( int i = collector.GetCount() - 1; i >= 0 ; --i ) { - BOARD_ITEM* boardItem = collector[i]; - - if( boardItem->Type() == PCB_MODULE_T || !selectable( boardItem ) ) + if( !selectable( collector[i] ) ) collector.Remove( i ); } @@ -455,12 +452,6 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const } break; - case PCB_PAD_T: - // Pads are not selectable in multiple selection mode - if( m_multiple ) - return false; - /* no break */ - case PCB_MODULE_T: if( aItem->IsOnLayer( LAYER_N_FRONT ) && board->IsElementVisible( MOD_FR_VISIBLE ) ) return true; @@ -472,16 +463,10 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const break; - case PCB_MODULE_TEXT_T: - // Module texts are not selectable in multiple selection mode - if( m_multiple ) - return false; - - break; - - // These are not selectable, otherwise silkscreen drawings would be easily destroyed + // These are not selectable case PCB_MODULE_EDGE_T: - // and some other stuff that should not be selected + case PCB_MODULE_TEXT_T: + case PCB_PAD_T: case NOT_USED: case TYPE_NOT_INIT: return false; From 85aa4057f89136c73cb6d3231cd8a1c294ecacb2 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 18 Dec 2013 17:16:15 +0100 Subject: [PATCH 26/95] Fixed zone area removal (& undoing) using the EDIT_TOOL. --- pcbnew/tools/edit_tool.cpp | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 99f44b9dfb..3d2191f5a8 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -303,16 +303,7 @@ void EDIT_TOOL::remove( BOARD_ITEM* aItem ) { MODULE* module = static_cast( aItem ); module->ClearFlags(); - - for( D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() ) - getView()->Remove( pad ); - - for( BOARD_ITEM* drawing = module->GraphicalItems().GetFirst(); drawing; - drawing = drawing->Next() ) - getView()->Remove( drawing ); - - getView()->Remove( &module->Reference() ); - getView()->Remove( &module->Value() ); + module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Remove ), getView() ) ); // Module itself is deleted after the switch scope is finished // list of pads is rebuild by BOARD::BuildListOfNets() @@ -322,11 +313,6 @@ void EDIT_TOOL::remove( BOARD_ITEM* aItem ) } break; - case PCB_ZONE_AREA_T: - getView()->Remove( aItem ); - getModel( PCB_T )->Delete( aItem ); - return; - // These are not supposed to be removed case PCB_PAD_T: case PCB_MODULE_TEXT_T: @@ -341,6 +327,7 @@ void EDIT_TOOL::remove( BOARD_ITEM* aItem ) case PCB_TARGET_T: // a target (graphic item) case PCB_MARKER_T: // a marker used to show something case PCB_ZONE_T: // SEG_ZONE items are now deprecated + case PCB_ZONE_AREA_T: break; default: // other types do not need to (or should not) be handled From 93c3a648395d5d9147849c45445cfdcf5ac23b9b Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 19 Dec 2013 10:10:42 +0100 Subject: [PATCH 27/95] Module texts are undo/redoable. --- pcbnew/board_undo_redo.cpp | 25 +++++++++++++++++++++++++ pcbnew/tools/selection_tool.cpp | 6 +++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/pcbnew/board_undo_redo.cpp b/pcbnew/board_undo_redo.cpp index fb8578fa4f..85b8e5b194 100644 --- a/pcbnew/board_undo_redo.cpp +++ b/pcbnew/board_undo_redo.cpp @@ -295,6 +295,17 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM* aItem, if( aItem == NULL ) // Nothing to save return; + // For texts belonging to modules, we need to save state of the parent module + if( aItem->Type() == PCB_MODULE_TEXT_T ) + { + aItem = aItem->GetParent(); + wxASSERT( aItem->Type() == PCB_MODULE_T ); + aCommandType = UR_CHANGED; + + if( aItem == NULL ) + return; + } + PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST(); commandToUndo->m_TransformPoint = aTransformPoint; @@ -364,6 +375,20 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList, for( unsigned ii = 0; ii < commandToUndo->GetCount(); ii++ ) { BOARD_ITEM* item = (BOARD_ITEM*) commandToUndo->GetPickedItem( ii ); + + // For texts belonging to modules, we need to save state of the parent module + if( item->Type() == PCB_MODULE_TEXT_T ) + { + item = item->GetParent(); + wxASSERT( item->Type() == PCB_MODULE_T ); + + if( item == NULL ) + continue; + + commandToUndo->SetPickedItem( item, ii ); + commandToUndo->SetPickedItemStatus( UR_CHANGED, ii ); + } + UNDO_REDO_T command = commandToUndo->GetPickedItemStatus( ii ); if( command == UR_UNSPECIFIED ) diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index fe7568c873..4d4d8e5404 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -463,9 +463,13 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const break; + case PCB_MODULE_TEXT_T: + if( m_multiple ) + return false; + break; + // These are not selectable case PCB_MODULE_EDGE_T: - case PCB_MODULE_TEXT_T: case PCB_PAD_T: case NOT_USED: case TYPE_NOT_INIT: From 292a50f8c00785c0ff5ef6452893d44c81113020 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 20 Dec 2013 16:07:58 +0100 Subject: [PATCH 28/95] Fixed cursor force position option. --- common/tool/tool_dispatcher.cpp | 2 +- common/view/wx_view_controls.cpp | 11 ----------- include/view/wx_view_controls.h | 5 ++++- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/common/tool/tool_dispatcher.cpp b/common/tool/tool_dispatcher.cpp index 6fb5d5f500..66efcc2581 100644 --- a/common/tool/tool_dispatcher.cpp +++ b/common/tool/tool_dispatcher.cpp @@ -221,7 +221,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) // but changes in world coordinates (e.g. autopanning) type == KIGFX::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE ) { - VECTOR2D screenPos = m_toolMgr->GetViewControls()->GetCursorPosition(); + VECTOR2D screenPos = m_toolMgr->GetViewControls()->GetMousePosition(); VECTOR2D pos = getView()->ToWorld( screenPos ); if( pos != m_lastMousePos || type == KIGFX::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE ) diff --git a/common/view/wx_view_controls.cpp b/common/view/wx_view_controls.cpp index 7f7308d935..20778c7d3e 100644 --- a/common/view/wx_view_controls.cpp +++ b/common/view/wx_view_controls.cpp @@ -83,9 +83,7 @@ void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent ) bool isAutoPanning = false; if( m_autoPanEnabled ) - { isAutoPanning = handleAutoPanning( aEvent ); - } if( !isAutoPanning && aEvent.Dragging() ) { @@ -243,15 +241,6 @@ const VECTOR2D WX_VIEW_CONTROLS::GetMousePosition() const } -const VECTOR2D WX_VIEW_CONTROLS::GetCursorPosition() const -{ - if( m_snappingEnabled ) - return m_view->GetGAL()->GetGridPoint( GetMousePosition() ); - else - return GetMousePosition(); -} - - bool WX_VIEW_CONTROLS::handleAutoPanning( const wxMouseEvent& aEvent ) { VECTOR2D p( aEvent.GetX(), aEvent.GetY() ); diff --git a/include/view/wx_view_controls.h b/include/view/wx_view_controls.h index f5561f7d2d..cfec3eac9b 100644 --- a/include/view/wx_view_controls.h +++ b/include/view/wx_view_controls.h @@ -84,7 +84,10 @@ public: const VECTOR2D GetMousePosition() const; /// @copydoc VIEW_CONTROLS::GetCursorPosition() - const VECTOR2D GetCursorPosition() const; + const VECTOR2D GetCursorPosition() const + { + return m_cursorPosition; + } /// Event that forces mouse move event in the dispatcher (eg. used in autopanning, when mouse /// cursor does not move in screen coordinates, but does in world coordinates) From 980dec08cf6e229bed31aa3e20f7cd5ae1b3b676 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 7 Jan 2014 14:09:27 +0100 Subject: [PATCH 29/95] Fixed bounding box for module texts. --- pcbnew/class_text_mod.cpp | 12 ++++++++++++ pcbnew/class_text_mod.h | 3 +++ 2 files changed, 15 insertions(+) diff --git a/pcbnew/class_text_mod.cpp b/pcbnew/class_text_mod.cpp index fbebde39bd..71deb4a462 100644 --- a/pcbnew/class_text_mod.cpp +++ b/pcbnew/class_text_mod.cpp @@ -415,6 +415,18 @@ EDA_ITEM* TEXTE_MODULE::Clone() const } +const BOX2I TEXTE_MODULE::ViewBBox() const +{ + double angle = GetDrawRotation(); + EDA_RECT text_area = GetTextBox( -1, -1 ); + + if( angle ) + text_area = text_area.GetBoundingBoxRotated( m_Pos, angle ); + + return BOX2I( text_area.GetPosition(), text_area.GetSize() ); +} + + void TEXTE_MODULE::ViewGetLayers( int aLayers[], int& aCount ) const { switch( m_Type ) diff --git a/pcbnew/class_text_mod.h b/pcbnew/class_text_mod.h index 3452d4f316..97e15ab202 100644 --- a/pcbnew/class_text_mod.h +++ b/pcbnew/class_text_mod.h @@ -165,6 +165,9 @@ public: EDA_ITEM* Clone() const; + /// @copydoc VIEW_ITEM::ViewBBox() + virtual const BOX2I ViewBBox() const; + /// @copydoc VIEW_ITEM::ViewGetLayers() virtual void ViewGetLayers( int aLayers[], int& aCount ) const; From 8626e906cbf785f51d5a881851c7a3e5f472da81 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 7 Jan 2014 14:11:53 +0100 Subject: [PATCH 30/95] Removed TOOL_STATE.idle field, as it was redundant. --- common/tool/tool_manager.cpp | 23 ++-- pcbnew/tools/move_tool.cpp | 204 ----------------------------------- pcbnew/tools/move_tool.h | 76 ------------- 3 files changed, 9 insertions(+), 294 deletions(-) delete mode 100644 pcbnew/tools/move_tool.cpp delete mode 100644 pcbnew/tools/move_tool.h diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index 937a178653..f36d0cb343 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -127,7 +127,6 @@ void TOOL_MANAGER::RegisterTool( TOOL_BASE* aTool ) TOOL_STATE* st = new TOOL_STATE; st->theTool = aTool; - st->idle = true; st->pendingWait = false; st->pendingContextMenu = false; st->cofunc = NULL; @@ -240,14 +239,10 @@ bool TOOL_MANAGER::runTool( TOOL_BASE* aTool ) return false; } - TOOL_STATE* state = m_toolState[aTool]; - // If the tool is already active, do not invoke it again - if( state->idle == false ) + if( isActive( aTool ) ) return false; - state->idle = false; - aTool->Reset( TOOL_INTERACTIVE::RUN ); // Add the tool on the front of the processing queue (it gets events first) @@ -417,19 +412,18 @@ bool TOOL_MANAGER::dispatchActivation( TOOL_EVENT& aEvent ) void TOOL_MANAGER::finishTool( TOOL_STATE* aState ) { - // Find the tool to be deactivated - std::deque::iterator it, it_end; + std::deque::iterator it, itEnd; - for( it = m_activeTools.begin(), it_end = m_activeTools.end(); it != it_end; ++it ) + // Find the tool and deactivate it + for( it = m_activeTools.begin(), itEnd = m_activeTools.end(); it != itEnd; ++it ) { if( aState == m_toolIdIndex[*it] ) + { + m_activeTools.erase( it ); break; + } } - if( it != m_activeTools.end() ) - m_activeTools.erase( it ); - - aState->idle = true; delete aState->cofunc; aState->cofunc = NULL; } @@ -525,5 +519,6 @@ bool TOOL_MANAGER::isActive( TOOL_BASE* aTool ) if( !isRegistered( aTool ) ) return false; - return !m_toolState[aTool]->idle; + // Just check if the tool is on the active tools stack + return std::find( m_activeTools.begin(), m_activeTools.end(), aTool->GetId() ) != m_activeTools.end(); } diff --git a/pcbnew/tools/move_tool.cpp b/pcbnew/tools/move_tool.cpp deleted file mode 100644 index 2cc3b0752e..0000000000 --- a/pcbnew/tools/move_tool.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2013 CERN - * @author Maciej Suminski - * - * 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 -#include -#include -#include -#include -#include - -#include - -#include "common_actions.h" -#include "selection_tool.h" -#include "move_tool.h" - -using namespace KIGFX; -using boost::optional; - -MOVE_TOOL::MOVE_TOOL() : - TOOL_INTERACTIVE( "pcbnew.InteractiveMove" ), m_selectionTool( NULL ) -{ -} - - -void MOVE_TOOL::Reset() -{ - // The tool launches upon reception of action event ("pcbnew.InteractiveMove") - Go( &MOVE_TOOL::Main, COMMON_ACTIONS::moveActivate.MakeEvent() ); -} - - -bool MOVE_TOOL::Init() -{ - // Find the selection tool, so they can cooperate - TOOL_BASE* selectionTool = m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ); - - if( selectionTool ) - { - m_selectionTool = static_cast( selectionTool ); - - // Add context menu entries that are displayed when selection tool is active - m_selectionTool->AddMenuItem( COMMON_ACTIONS::moveActivate ); - m_selectionTool->AddMenuItem( COMMON_ACTIONS::rotate ); - m_selectionTool->AddMenuItem( COMMON_ACTIONS::flip ); - } - else - { - DisplayError( NULL, wxT( "pcbnew.InteractiveSelection tool is not available" ) ); - return false; - } - - return true; -} - - -int MOVE_TOOL::Main( TOOL_EVENT& aEvent ) -{ - const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); - - if( selection.Empty() ) - return 0; // there are no items to operate on - - VECTOR2D dragPosition; - bool dragging = false; - bool restore = false; // Should items' state be restored when finishing the tool? - - VIEW_CONTROLS* controls = getViewControls(); - controls->ShowCursor( true ); - controls->SetSnapping( true ); - controls->SetAutoPan( true ); - - // Main loop: keep receiving events - while( OPT_TOOL_EVENT evt = Wait() ) - { - if( evt->IsCancel() ) - { - restore = true; // Cancelling the tool means that items have to be restored - break; // Finish - } - - // Dispatch TOOL_ACTIONs - else if( evt->Category() == TC_COMMAND ) - { - VECTOR2D cursorPos = getView()->ToWorld( getViewControls()->GetCursorPosition() ); - - if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) // got rotation event? - { - m_state.Rotate( cursorPos, 900.0 ); - selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); - updateRatsnest( true ); - } - else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) // got flip event? - { - m_state.Flip( cursorPos ); - selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); - updateRatsnest( true ); - } - } - - else if( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) - { - if( dragging ) - { - // Drag items to the current cursor position - VECTOR2D movement = ( evt->Position() - dragPosition ); - m_state.Move( movement ); - - updateRatsnest( true ); - } - else - { - // Prepare to drag - std::set::iterator it; - - for( it = selection.items.begin(); it != selection.items.end(); ++it ) - { - // Save the state of the selected items, in case it has to be restored - m_state.Save( *it ); - } - - dragging = true; - } - - selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); - dragPosition = evt->Position(); - } - else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) - break; // Finish - } - - if( restore ) - { - // Modifications has to be rollbacked, so restore the previous state of items - selection.group->ItemsViewUpdate( VIEW_ITEM::APPEARANCE ); - m_state.RestoreAll(); - - updateRatsnest( false ); - } - else - { - // Changes are applied, so update the items - selection.group->ItemsViewUpdate( m_state.GetUpdateFlag() ); - m_state.Apply(); - - } - - RN_DATA* ratsnest = static_cast( m_toolMgr->GetModel() )->GetRatsnest(); - ratsnest->Recalculate(); - - controls->ShowCursor( false ); - controls->SetSnapping( false ); - controls->SetAutoPan( false ); - - return 0; -} - - -void MOVE_TOOL::updateRatsnest( bool aRedraw ) -{ - const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); - RN_DATA* ratsnest = static_cast( m_toolMgr->GetModel() )->GetRatsnest(); - - ratsnest->ClearSimple(); - BOOST_FOREACH( BOARD_ITEM* item, selection.items ) - { - if( item->Type() == PCB_PAD_T || item->Type() == PCB_TRACE_T || - item->Type() == PCB_VIA_T || item->Type() == PCB_ZONE_AREA_T ) - { - ratsnest->Update( static_cast( item ) ); - - if( aRedraw ) - ratsnest->AddSimple( static_cast( item ) ); - } - else if( item->Type() == PCB_MODULE_T ) - { - ratsnest->Update( static_cast( item ) ); - - if( aRedraw ) - ratsnest->AddSimple( static_cast( item ) ); - } - } -} diff --git a/pcbnew/tools/move_tool.h b/pcbnew/tools/move_tool.h deleted file mode 100644 index 10783a5ed4..0000000000 --- a/pcbnew/tools/move_tool.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2013 CERN - * @author Maciej Suminski - * - * 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 - */ - -#ifndef __MOVE_TOOL_H -#define __MOVE_TOOL_H - -#include -#include -#include -#include "item_state.h" - -class BOARD_ITEM; -class SELECTION_TOOL; - -namespace KIGFX -{ -class VIEW_GROUP; -} - -/** - * Class MOVE_TOOL - * - * Our sample move tool. Allows to move, rotate and flip items selected by - * pcbnew.InteractiveSelection tool. - */ - -class MOVE_TOOL : public TOOL_INTERACTIVE -{ -public: - MOVE_TOOL(); - - /// @copydoc TOOL_INTERACTIVE::Reset() - void Reset(); - - /// @copydoc TOOL_INTERACTIVE::Init() - bool Init(); - - /** - * Function Main() - * - * Main loop in which events are handled. - */ - int Main( TOOL_EVENT& aEvent ); - -private: - void updateRatsnest( bool aRedraw ); - - /// Saves the state of items and allows to restore them - ITEM_STATE m_state; - - /// Selection tool used for obtaining selected items - SELECTION_TOOL* m_selectionTool; -}; - -#endif From a22364f54508408bca43eacf31b338ba15a4a6e4 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 7 Jan 2014 14:15:40 +0100 Subject: [PATCH 31/95] Items removed from board are removed from ratsnest as well. Corrected the way of items removal from ratsnest. --- pcbnew/class_board.cpp | 27 +++++++--- pcbnew/ratsnest_data.cpp | 113 ++++++++++++++++++++++++--------------- pcbnew/ratsnest_data.h | 5 +- 3 files changed, 94 insertions(+), 51 deletions(-) diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index a56c226d63..c046fb70fd 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -867,26 +867,41 @@ BOARD_ITEM* BOARD::Remove( BOARD_ITEM* aBoardItem ) break; case PCB_ZONE_AREA_T: // this one uses a vector + { + ZONE_CONTAINER* zone = static_cast( aBoardItem ); + // find the item in the vector, then delete then erase it. - for( unsigned i = 0; iGetNets()[zone->GetNet()].RemoveItem( zone ); + } + break; case PCB_MODULE_T: + { + MODULE* module = static_cast( aBoardItem ); m_Modules.Remove( (MODULE*) aBoardItem ); - break; + + for( D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() ) + m_ratsnest->GetNets()[pad->GetNet()].RemoveItem( pad ); + } + break; case PCB_TRACE_T: case PCB_VIA_T: - m_Track.Remove( (TRACK*) aBoardItem ); - break; + { + TRACK* track = static_cast( aBoardItem ); + m_Track.Remove( track ); + m_ratsnest->GetNets()[track->GetNet()].RemoveItem( track ); + } + break; case PCB_ZONE_T: m_Zone.Remove( (SEGZONE*) aBoardItem ); diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index e66451b86b..a5f708e0fe 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -201,12 +201,18 @@ const RN_NODE_PTR& RN_LINKS::AddNode( int aX, int aY ) } -void RN_LINKS::RemoveNode( const RN_NODE_PTR& aNode ) +bool RN_LINKS::RemoveNode( const RN_NODE_PTR& aNode ) { aNode->DecRefCount(); // TODO use the shared_ptr use_count if( aNode->GetRefCount() == 0 ) + { m_nodes.erase( aNode ); + + return true; + } + + return false; } @@ -270,6 +276,9 @@ void RN_NET::compute() void RN_NET::clearNode( const RN_NODE_PTR& aNode ) { + if( !m_rnEdges ) + return; + std::vector::iterator newEnd; // Remove all ratsnest edges for associated with the node @@ -430,75 +439,92 @@ void RN_NET::AddItem( const ZONE_CONTAINER* aZone ) void RN_NET::RemoveItem( const D_PAD* aPad ) { - RN_NODE_PTR& node = m_pads[aPad]; - if( !node ) - return; + try + { + RN_NODE_PTR node = m_pads.at( aPad ); - // Remove edges associated with the node - clearNode( node ); - m_links.RemoveNode( node ); + if( m_links.RemoveNode( node ) ) + clearNode( node ); - m_pads.erase( aPad ); + m_pads.erase( aPad ); - m_dirty = true; + m_dirty = true; + } + catch( ... ) + { + } } void RN_NET::RemoveItem( const SEGVIA* aVia ) { - RN_NODE_PTR& node = m_vias[aVia]; - if( !node ) - return; + try + { + RN_NODE_PTR node = m_vias.at( aVia ); - // Remove edges associated with the node - clearNode( node ); - m_links.RemoveNode( node ); + if( m_links.RemoveNode( node ) ) + clearNode( node ); - m_vias.erase( aVia ); + m_vias.erase( aVia ); - m_dirty = true; + m_dirty = true; + } + catch( ... ) + { + } } void RN_NET::RemoveItem( const TRACK* aTrack ) { - RN_EDGE_PTR& edge = m_tracks[aTrack]; - if( !edge ) - return; + try + { + RN_EDGE_PTR& edge = m_tracks.at( aTrack ); - // Save nodes, so they can be cleared later - const RN_NODE_PTR& aBegin = edge->getSourceNode(); - const RN_NODE_PTR& aEnd = edge->getTargetNode(); - m_links.RemoveConnection( edge ); + // Save nodes, so they can be cleared later + RN_NODE_PTR aBegin = edge->getSourceNode(); + RN_NODE_PTR aEnd = edge->getTargetNode(); + m_links.RemoveConnection( edge ); - // Remove nodes associated with the edge. It is done in a safe way, there is a check - // if nodes are not used by other edges. - clearNode( aBegin ); - clearNode( aEnd ); - m_links.RemoveNode( aBegin ); - m_links.RemoveNode( aEnd ); + // Remove nodes associated with the edge. It is done in a safe way, there is a check + // if nodes are not used by other edges. + if( m_links.RemoveNode( aBegin ) ) + clearNode( aBegin ); - m_tracks.erase( aTrack ); + if( m_links.RemoveNode( aEnd ) ) + clearNode( aEnd ); - m_dirty = true; + m_tracks.erase( aTrack ); + + m_dirty = true; + } + catch( ... ) + { + } } void RN_NET::RemoveItem( const ZONE_CONTAINER* aZone ) { - // Remove all subpolygons that make the zone - std::deque& polygons = m_zonePolygons[aZone]; - BOOST_FOREACH( RN_POLY& polygon, polygons ) - m_links.RemoveNode( polygon.GetNode() ); - polygons.clear(); + try + { + // Remove all subpolygons that make the zone + std::deque& polygons = m_zonePolygons.at( aZone ); + BOOST_FOREACH( RN_POLY& polygon, polygons ) + m_links.RemoveNode( polygon.GetNode() ); + polygons.clear(); - // Remove all connections added by the zone - std::deque& edges = m_zoneConnections[aZone]; - BOOST_FOREACH( RN_EDGE_PTR& edge, edges ) - m_links.RemoveConnection( edge ); - edges.clear(); + // Remove all connections added by the zone + std::deque& edges = m_zoneConnections.at( aZone ); + BOOST_FOREACH( RN_EDGE_PTR& edge, edges ) + m_links.RemoveConnection( edge ); + edges.clear(); - m_dirty = true; + m_dirty = true; + } + catch( ... ) + { + } } @@ -832,6 +858,7 @@ void RN_DATA::Recalculate( int aNet ) // Start with net number 1, as 0 stand for not connected for( unsigned int i = 1; i < m_board->GetNetCount(); ++i ) { + // Recompute only nets that require it if( m_nets[i].IsDirty() ) updateNet( i ); } diff --git a/pcbnew/ratsnest_data.h b/pcbnew/ratsnest_data.h index 6d0e7ee896..f8ffbf2406 100644 --- a/pcbnew/ratsnest_data.h +++ b/pcbnew/ratsnest_data.h @@ -129,8 +129,9 @@ public: * Function RemoveNode() * Removes a node described by a given node pointer. * @param aNode is a pointer to node to be removed. + * @return True if node was removed, false if there were other references, so it was kept. */ - void RemoveNode( const RN_NODE_PTR& aNode ); + bool RemoveNode( const RN_NODE_PTR& aNode ); /** * Function GetNodes() @@ -577,7 +578,7 @@ public: * Returns ratsnest grouped by net numbers. * @return Vector of ratsnest grouped by net numbers. */ - const std::vector& GetNets() const + std::vector& GetNets() { return m_nets; } From e8b7c6df54987fd1dbfa06b929e171a160996715 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 7 Jan 2014 14:16:47 +0100 Subject: [PATCH 32/95] Tools have possibility to react to GAL switching or model (board) reload. --- pcbnew/pcbframe.cpp | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 56e80d84bc..32e8c27ba7 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -334,16 +334,6 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( wxWindow* parent, const wxString& title, SetBoard( new BOARD() ); - if( GetGalCanvas() ) - { - ViewReloadBoard( m_Pcb ); - - // update the tool manager with the new board and its view. - if( m_toolManager ) - m_toolManager->SetEnvironment( m_Pcb, GetGalCanvas()->GetView(), - GetGalCanvas()->GetViewControls(), this ); - } - // Create the PCB_LAYER_WIDGET *after* SetBoard(): wxFont font = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ); @@ -543,8 +533,11 @@ void PCB_EDIT_FRAME::SetBoard( BOARD* aBoard ) // update the tool manager with the new board and its view. if( m_toolManager ) + { m_toolManager->SetEnvironment( aBoard, GetGalCanvas()->GetView(), GetGalCanvas()->GetViewControls(), this ); + m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD ); + } } } @@ -749,10 +742,14 @@ void PCB_EDIT_FRAME::UseGalCanvas( bool aEnable ) { EDA_DRAW_FRAME::UseGalCanvas( aEnable ); - m_toolManager->SetEnvironment( m_Pcb, GetGalCanvas()->GetView(), - GetGalCanvas()->GetViewControls(), this ); - ViewReloadBoard( m_Pcb ); + + if( aEnable ) + { + m_toolManager->SetEnvironment( m_Pcb, GetGalCanvas()->GetView(), + GetGalCanvas()->GetViewControls(), this ); + m_toolManager->ResetTools( TOOL_BASE::GAL_SWITCH ); + } } From 3177f74540c789e3899b0a882daeac74f918306e Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 7 Jan 2014 14:21:37 +0100 Subject: [PATCH 33/95] Fixed snapping for Push and Shove router. --- pcbnew/router/router_tool.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index d43ea3ece4..6e8d732040 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -278,7 +278,7 @@ void ROUTER_TOOL::updateEndItem( TOOL_EVENT& aEvent ) else { m_endItem = NULL; - m_endSnapPoint = p; + m_endSnapPoint = getView()->ToWorld( ctls->GetCursorPosition() ); ctls->ForceCursorPosition( false ); } @@ -407,6 +407,7 @@ int ROUTER_TOOL::Main( TOOL_EVENT& aEvent ) // Restore the default settings ctls->SetAutoPan( false ); ctls->ShowCursor( false ); + ctls->ForceCursorPosition( false ); return 0; } From aee4f33c096d117ee4eda6609954588aed984096 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 7 Jan 2014 14:22:37 +0100 Subject: [PATCH 34/95] Fixed Push and Shove and ratsnest cooperation (tracks added by PNS are taken into account while calculating ratsnest). --- pcbnew/router/pns_router.cpp | 9 ++++----- pcbnew/router/router_tool.cpp | 3 +-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/pcbnew/router/pns_router.cpp b/pcbnew/router/pns_router.cpp index 151b28ffa1..33a512b451 100644 --- a/pcbnew/router/pns_router.cpp +++ b/pcbnew/router/pns_router.cpp @@ -263,7 +263,7 @@ void PNS_ROUTER::SyncWorld() if( type == PCB_TRACE_T ) item = syncTrack( t ); else if( type == PCB_VIA_T ) - item = syncVia( static_cast (t) ); + item = syncVia( static_cast( t ) ); if( item ) m_world->Add( item ); @@ -754,13 +754,12 @@ bool PNS_ROUTER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem ) void PNS_ROUTER::StopRouting() { + // Update the ratsnest with new changes + m_board->GetRatsnest()->Recalculate( m_currentNet ); + if( !RoutingInProgress() ) return; - // highlightCurrent(false); - - // Update the ratsnest - m_board->GetRatsnest()->Recalculate( m_currentNet ); EraseView(); m_state = IDLE; diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 6e8d732040..b301901048 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -369,8 +369,7 @@ void ROUTER_TOOL::startRouting() } } - if( m_router->RoutingInProgress() ) - m_router->StopRouting(); + m_router->StopRouting(); ctls->SetAutoPan( false ); ctls->ForceCursorPosition( false ); From 56cd8264006dd6d7e04d20a7f28aa0b3f6e5a9b9 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 7 Jan 2014 14:23:46 +0100 Subject: [PATCH 35/95] Safer way for syncing pads in Push and Shover router. --- pcbnew/router/pns_router.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/pcbnew/router/pns_router.cpp b/pcbnew/router/pns_router.cpp index 33a512b451..e70fe550bf 100644 --- a/pcbnew/router/pns_router.cpp +++ b/pcbnew/router/pns_router.cpp @@ -47,7 +47,7 @@ #include #include -#include +#include #include #include #include @@ -248,11 +248,15 @@ void PNS_ROUTER::SyncWorld() m_world->SetMaxClearance( 1000000 ); // m_board->GetBiggestClearanceValue()); pads = m_board->GetPads(); - BOOST_FOREACH( D_PAD * pad, pads ) { - PNS_ITEM* solid = syncPad( pad ); + for( MODULE* module = m_board->m_Modules; module; module = module->Next() ) + { + for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() ) + { + PNS_ITEM* solid = syncPad( pad ); - if( solid ) - m_world->Add( solid ); + if( solid ) + m_world->Add( solid ); + } } for( TRACK* t = m_board->m_Track; t; t = t->Next() ) From 92816e4689c68c25e2d84a8224a43600702212f0 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 7 Jan 2014 15:52:10 +0100 Subject: [PATCH 36/95] Delaunau triangulation algorithm was bailing out if run on an emprty container. --- pcbnew/ratsnest_data.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index a5f708e0fe..f33d5e96e6 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -246,7 +246,7 @@ void RN_NET::compute() return; } - else if( boardNodes.size() == 1 ) // This case is even simpler + else if( boardNodes.size() == 1 || boardNodes.empty() ) // This case is even simpler { m_rnEdges.reset( new std::vector( 0 ) ); From a49015a3177347566930223244d7a3366c0b7270 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 7 Jan 2014 17:23:17 +0100 Subject: [PATCH 37/95] Fixed snapping and ratsnest update for EDIT_TOOL. --- pcbnew/tools/edit_tool.cpp | 50 +++++++++++++++++++++++++++++++++++--- pcbnew/tools/edit_tool.h | 2 ++ 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 7f35d8a01e..277fefa8c1 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -28,8 +28,10 @@ #include #include #include +#include #include #include +#include #include "common_actions.h" #include "selection_tool.h" @@ -88,6 +90,7 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) controls->ShowCursor( true ); controls->SetSnapping( true ); controls->SetAutoPan( true ); + controls->ForceCursorPosition( false ); // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) @@ -115,6 +118,7 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) else if( evt->IsAction( &COMMON_ACTIONS::remove ) ) { Remove( aEvent ); + break; } } @@ -124,12 +128,15 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) if( m_dragging ) { // Drag items to the current cursor position - VECTOR2D movement = ( evt->Position() - dragPosition ); + VECTOR2D movement = ( getView()->ToWorld( controls->GetCursorPosition() ) - + dragPosition ); for( unsigned int i = 0; i < selection.items.GetCount(); ++i ) { BOARD_ITEM* item = static_cast( selection.items.GetPickedItem( i ) ); item->Move( wxPoint( movement.x, movement.y ) ); } + + updateRatsnest( true ); } else { @@ -141,7 +148,7 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) } selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); - dragPosition = evt->Position(); + dragPosition = getView()->ToWorld( controls->GetCursorPosition() ); } else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) @@ -162,6 +169,10 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) selection.group->ItemsViewUpdate( m_updateFlag ); } + RN_DATA* ratsnest = getModel( PCB_T )->GetRatsnest(); + ratsnest->ClearSimple(); + ratsnest->Recalculate(); + controls->ShowCursor( false ); controls->SetSnapping( false ); controls->SetAutoPan( false ); @@ -195,6 +206,7 @@ int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) } setTransitions(); + updateRatsnest( true ); return 0; } @@ -225,6 +237,7 @@ int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); setTransitions(); + updateRatsnest( true ); return 0; } @@ -255,6 +268,7 @@ int EDIT_TOOL::Flip( TOOL_EVENT& aEvent ) selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); setTransitions(); + updateRatsnest( true ); return 0; } @@ -284,10 +298,11 @@ int EDIT_TOOL::Remove( TOOL_EVENT& aEvent ) // Rebuild list of pads and nets if necessary BOARD* board = getModel( PCB_T ); - if( !( board->GetStatus() & NET_CODES_OK ) ) + if( !( board->m_Status_Pcb & NET_CODES_OK ) ) board->BuildListOfNets(); setTransitions(); + board->GetRatsnest()->Recalculate(); return 0; } @@ -349,3 +364,32 @@ void EDIT_TOOL::setTransitions() Go( &EDIT_TOOL::Remove, COMMON_ACTIONS::remove.MakeEvent() ); Go( &EDIT_TOOL::Properties, COMMON_ACTIONS::properties.MakeEvent() ); } + + +void EDIT_TOOL::updateRatsnest( bool aRedraw ) +{ + const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + RN_DATA* ratsnest = getModel( PCB_T )->GetRatsnest(); + + ratsnest->ClearSimple(); + for( unsigned int i = 0; i < selection.items.GetCount(); ++i ) + { + BOARD_ITEM* item = static_cast( selection.items.GetPickedItem( i ) ); + + if( item->Type() == PCB_PAD_T || item->Type() == PCB_TRACE_T || + item->Type() == PCB_VIA_T || item->Type() == PCB_ZONE_AREA_T ) + { + ratsnest->Update( static_cast( item ) ); + + if( aRedraw ) + ratsnest->AddSimple( static_cast( item ) ); + } + else if( item->Type() == PCB_MODULE_T ) + { + ratsnest->Update( static_cast( item ) ); + + if( aRedraw ) + ratsnest->AddSimple( static_cast( item ) ); + } + } +} diff --git a/pcbnew/tools/edit_tool.h b/pcbnew/tools/edit_tool.h index 5ddcb84f5d..0079d332b3 100644 --- a/pcbnew/tools/edit_tool.h +++ b/pcbnew/tools/edit_tool.h @@ -113,6 +113,8 @@ private: if( m_updateFlag < aFlag ) m_updateFlag = aFlag; } + + void updateRatsnest( bool aRedraw ); }; #endif From f075166a215a8b6a0f30ea5f21cb7df82c2ac4a2 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 9 Jan 2014 15:51:47 +0100 Subject: [PATCH 38/95] Removed NETINFO_ITEM::SetNet() and NETINFO_ITEM::SetNetname() methods. NETINFO_ITEM::m_Net and NETINFO_ITEM::m_Netname are const. Changes to be verified: - pcbnew/minimun_spanning_tree.cpp: It segfaults is m_Size == 0 - pcbnew/exporters/export_gencad.cpp: I removed the SetNetname() call, as it changes only the unconnected net and in the next line it returns if the net is unconnected. Still, I wonder if name for the unconnected net matters. What about tests that check if a net name is empty to decide if it is unconnected net or not. --- pcbnew/class_netinfo.h | 39 ++++++++++++++++++-------- pcbnew/class_netinfo_item.cpp | 19 ++----------- pcbnew/class_netinfolist.cpp | 45 ++++++++---------------------- pcbnew/exporters/export_gencad.cpp | 1 - pcbnew/legacy_plugin.cpp | 7 ++--- pcbnew/minimun_spanning_tree.cpp | 2 +- pcbnew/pcb_parser.cpp | 4 +-- 7 files changed, 45 insertions(+), 72 deletions(-) diff --git a/pcbnew/class_netinfo.h b/pcbnew/class_netinfo.h index 427a7b5685..a3c1807e14 100644 --- a/pcbnew/class_netinfo.h +++ b/pcbnew/class_netinfo.h @@ -228,14 +228,14 @@ private: class NETINFO_ITEM { private: - int m_NetCode; ///< A number equivalent to the net name. + const int m_NetCode; ///< A number equivalent to the net name. ///< Used for fast comparisons in ratsnest and DRC computations. - wxString m_Netname; ///< Full net name like /mysheet/mysubsheet/vout + const wxString m_Netname; ///< Full net name like /mysheet/mysubsheet/vout ///< used by Eeschema - wxString m_ShortNetname; // short net name, like vout from - // /mysheet/mysubsheet/vout + const wxString m_ShortNetname; // short net name, like vout from + // /mysheet/mysubsheet/vout wxString m_NetClassName; // Net Class name. if void this is equivalent // to "default" (the first @@ -386,8 +386,10 @@ public: */ int GetNet() const { return m_NetCode; } - void SetNet( int aNetCode ) { m_NetCode = aNetCode; } - + /** + * Function GetNodesCount + * @return int - number of nodes in the net + */ int GetNodesCount() const { return m_PadInNetList.size(); } /** @@ -402,12 +404,6 @@ public: */ wxString GetShortNetname() const { return m_ShortNetname; } - /** - * Function SetNetname - * @param aNetname : the new netname - */ - void SetNetname( const wxString& aNetname ); - /** * Function GetMsgPanelInfo * returns the information about the #NETINFO_ITEM in \a aList to display in the @@ -416,6 +412,25 @@ public: * @param aList is the list in which to place the status information. */ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ); + + /** + * Function Clear + * sets all fields to their defaults values. + */ + void Clear() + { + m_PadInNetList.clear(); + + m_NbNodes = 0; + m_NbLink = 0; + m_NbNoconn = 0; + m_Flag = 0; + m_RatsnestStartIdx = 0; // Starting point of ratsnests of this net in a + // general buffer of ratsnest + m_RatsnestEndIdx = 0; // Ending point of ratsnests of this net + + SetClass( NULL ); + } }; diff --git a/pcbnew/class_netinfo_item.cpp b/pcbnew/class_netinfo_item.cpp index f96132dfc1..05bcabb1bc 100644 --- a/pcbnew/class_netinfo_item.cpp +++ b/pcbnew/class_netinfo_item.cpp @@ -49,13 +49,9 @@ /* class NETINFO_ITEM: handle data relative to a given net */ /*********************************************************/ -NETINFO_ITEM::NETINFO_ITEM( BOARD_ITEM* aParent, const wxString& aNetName, int aNetCode ) +NETINFO_ITEM::NETINFO_ITEM( BOARD_ITEM* aParent, const wxString& aNetName, int aNetCode ) : + m_NetCode( aNetCode ), m_Netname( aNetName ), m_ShortNetname( m_Netname.AfterLast( '/' ) ) { - SetNet( aNetCode ); - - if( aNetName.size() ) - SetNetname( aNetName ); - m_parent = aParent; m_NbNodes = 0; m_NbLink = 0; @@ -77,17 +73,6 @@ NETINFO_ITEM::~NETINFO_ITEM() } -/** - * Function SetNetname - * @param aNetname : the new netname - */ -void NETINFO_ITEM::SetNetname( const wxString& aNetname ) -{ - m_Netname = aNetname; - m_ShortNetname = m_Netname.AfterLast( '/' ); -} - - /** * Function Draw (TODO) */ diff --git a/pcbnew/class_netinfolist.cpp b/pcbnew/class_netinfolist.cpp index df5f8039de..75bad023a2 100644 --- a/pcbnew/class_netinfolist.cpp +++ b/pcbnew/class_netinfolist.cpp @@ -37,10 +37,6 @@ void NETINFO_LIST::clear() } -/** - * Function Append - * adds \a aNewElement to the end of the list. - */ void NETINFO_LIST::AppendNet( NETINFO_ITEM* aNewElement ) { m_NetBuffer.push_back( aNewElement ); @@ -80,46 +76,29 @@ void NETINFO_LIST::buildListOfNets() int nodes_count = 0; NETINFO_ITEM* net_item; - clear(); // Remove all nets info and free memory - - // Create and add the "unconnected net", always existing, - // used to handle pads and tracks that are not member of a "real" net - net_item = new NETINFO_ITEM( m_Parent ); - AppendNet( net_item ); - // Build the PAD list, sorted by net buildPadsFullList(); - // Build netnames list, and create a netcode for each netname - D_PAD* last_pad = NULL; - int netcode = 0; + // Restore the initial state of NETINFO_ITEMs + for( unsigned i = 0; i < GetNetCount(); ++i ) + { + GetNetItem( i )->Clear(); + } + std::cout << m_PadsFullList.size() << std::endl; + + // Assign pads to appropriate NETINFO_ITEMs for( unsigned ii = 0; ii < m_PadsFullList.size(); ii++ ) { pad = m_PadsFullList[ii]; - if( pad->GetNetname().IsEmpty() ) // pad not connected - { - pad->SetNet( 0 ); + if( pad->GetNet() == 0 ) // pad not connected continue; - } - /* if the current netname was already found: add pad to the current net_item , - * else create a new net_code and a new net_item - */ - if( last_pad == NULL || ( pad->GetNetname() != last_pad->GetNetname() ) ) - { - netcode++; - net_item = new NETINFO_ITEM( m_Parent, pad->GetNetname(), netcode ); - AppendNet( net_item ); - } - - pad->SetNet( netcode ); + net_item = GetNetItem( pad->GetNet() ); net_item->m_PadInNetList.push_back( pad ); - nodes_count++; - - last_pad = pad; + ++nodes_count; } m_Parent->SetNodeCount( nodes_count ); @@ -129,8 +108,6 @@ void NETINFO_LIST::buildListOfNets() m_Parent->m_Status_Pcb |= NET_CODES_OK; m_Parent->SetAreasNetCodesFromNetNames(); - - // D( Show(); ) } #if defined(DEBUG) diff --git a/pcbnew/exporters/export_gencad.cpp b/pcbnew/exporters/export_gencad.cpp index f04496ff7c..394a39f808 100644 --- a/pcbnew/exporters/export_gencad.cpp +++ b/pcbnew/exporters/export_gencad.cpp @@ -647,7 +647,6 @@ static void CreateSignalsSection( FILE* aFile, BOARD* aPcb ) if( net->GetNetname() == wxEmptyString ) // dummy netlist (no connection) { wxString msg; msg << wxT( "NoConnection" ) << NbNoConn++; - net->SetNetname( msg ); } if( net->GetNet() <= 0 ) // dummy netlist (no connection) diff --git a/pcbnew/legacy_plugin.cpp b/pcbnew/legacy_plugin.cpp index 4bc6e4550a..ab5a4fe34f 100644 --- a/pcbnew/legacy_plugin.cpp +++ b/pcbnew/legacy_plugin.cpp @@ -1811,7 +1811,7 @@ void LEGACY_PLUGIN::loadNETINFO_ITEM() { char buf[1024]; - NETINFO_ITEM* net = new NETINFO_ITEM( m_board ); + NETINFO_ITEM* net; char* line; while( ( line = READLINE( m_reader ) ) != NULL ) @@ -1822,11 +1822,10 @@ void LEGACY_PLUGIN::loadNETINFO_ITEM() { // e.g. "Na 58 "/cpu.sch/PAD7"\r\n" - int tmp = intParse( line + SZ( "Na" ), &data ); - net->SetNet( tmp ); + int netCode = intParse( line + SZ( "Na" ), &data ); ReadDelimitedText( buf, data, sizeof(buf) ); - net->SetNetname( FROM_UTF8( buf ) ); + net = new NETINFO_ITEM( m_board, FROM_UTF8( buf ), netCode ); } else if( TESTLINE( "$EndEQUIPOT" ) ) diff --git a/pcbnew/minimun_spanning_tree.cpp b/pcbnew/minimun_spanning_tree.cpp index f107590d6c..8d683f7786 100644 --- a/pcbnew/minimun_spanning_tree.cpp +++ b/pcbnew/minimun_spanning_tree.cpp @@ -69,7 +69,7 @@ MIN_SPAN_TREE::MIN_SPAN_TREE() void MIN_SPAN_TREE::MSP_Init( int aNodesCount ) { - m_Size = aNodesCount; + m_Size = std::max( aNodesCount, 1 ); inTree.clear(); linkedTo.clear(); distTo.clear(); diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index 1b47c69158..f1eaa3026c 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -1066,9 +1066,7 @@ void PCB_PARSER::parseNETINFO_ITEM() throw( IO_ERROR, PARSE_ERROR ) // (TODO: a better test.) if( number > 0 || m_board->FindNet( 0 ) == NULL ) { - NETINFO_ITEM* net = new NETINFO_ITEM( m_board ); - net->SetNet( number ); - net->SetNetname( name ); + NETINFO_ITEM* net = new NETINFO_ITEM( m_board, name, number ); m_board->AppendNet( net ); } } From 3c79ed375cd51b642011bc9bd4a0278826a1f4b5 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 10 Jan 2014 17:19:33 +0100 Subject: [PATCH 39/95] Made two functions immune to empty containers. --- pcbnew/ratsnest.cpp | 5 ++++- pcbnew/ratsnest_data.cpp | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pcbnew/ratsnest.cpp b/pcbnew/ratsnest.cpp index 00cec1cea0..b5347d3e85 100644 --- a/pcbnew/ratsnest.cpp +++ b/pcbnew/ratsnest.cpp @@ -70,7 +70,10 @@ public: void MIN_SPAN_TREE_PADS::AddTreeToRatsnest( std::vector &aRatsnestList ) { - std::vector & padsBuffer = *m_PadsList; + std::vector& padsBuffer = *m_PadsList; + if( padsBuffer.empty() ) + return; + int netcode = padsBuffer[0]->GetNet(); // Note: to get edges in minimum spanning tree, // the index value 0 is not used: it is just diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index e66451b86b..6ed72cfbe0 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -240,7 +240,7 @@ void RN_NET::compute() return; } - else if( boardNodes.size() == 1 ) // This case is even simpler + else if( boardNodes.size() == 1 || boardNodes.empty() ) // This case is even simpler { m_rnEdges.reset( new std::vector( 0 ) ); From c39b56891e8182b9fc33f1146d490866501e73e7 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 10 Jan 2014 18:04:07 +0100 Subject: [PATCH 40/95] Changed the way of looking up NETINFO_ITEM using net names (using boost::unordered_map). Added a hash function (wxString) for that. Introduced NETINFO_ITEM::GetNetItem( wxString ). BOARD::FindNet() uses the map. Net codes are updated upon net list update. (BOARD::ReplaceNetlist()) Added in some places (mostly class_board.cpp) pad->SetNet() calls to synchronize net codes. On creation of NETINFO_LIST, the first NETINFO_ITEM is added (the unconnected items net). Removed COMPONENT_NET::m_netNumber, as it was not used anywhere. Added an assert to D_PAD::GetNetname(), checking if net code and net name is consistent for unconnected pads. Added an assert for NETINFO_LIST::AppendNet() to assure that appended nets are unique. It seems that at this point: - Updating net lists works fine. The only difference between the file ouput is that after changes it contains empty nets as well. - Nets are not saved in the lexical order. Still, net names and net codes are properly assigned to all items in the .kicad_pcb file. It is going to be addressed in the next commit. I believe it should not create any problems, as pads are sorted by their net names anyway (NETINFO_LIST::buildPadsFullList()) Performed tests: - Created a blank PCB, saved as pic_programmer.kicad_pcb (from demos folder). Updated net lists. .kicad_pcb file (comparing to the results from master branch) differ with net order (as mentioned before), net codes and timestamps. - Removed some of components from the above .kicad_pcb file and updated net lists. Modules reappeared. .kicad_pcb file differs in the same way as described above. - Trying to change a pad net name (via properties dialog) results in assert being fired. It is done on purpose (as there is a call to GetNetname() and net name and net code do not match). This will not happen after the next commit. - Prepared a simple project (starting with schematics). Imported net list, changed schematic, reimported net list - changes are applied. - Eagle & KiCad legacy boards seem to load without any problem. --- include/hashtables.h | 18 +++++++ pcbnew/class_board.cpp | 93 +++++++------------------------- pcbnew/class_netinfo.h | 28 ++++++++-- pcbnew/class_netinfolist.cpp | 22 ++++---- pcbnew/class_pad.cpp | 1 + pcbnew/class_pad.h | 8 ++- pcbnew/pad_edition_functions.cpp | 1 + pcbnew/pcb_netlist.h | 6 +-- 8 files changed, 84 insertions(+), 93 deletions(-) diff --git a/include/hashtables.h b/include/hashtables.h index edb3f798e0..ed319ec64c 100644 --- a/include/hashtables.h +++ b/include/hashtables.h @@ -98,6 +98,24 @@ struct fnv_1a }; +/// Hash function for wxString, counterpart of std::string hash +struct WXSTRING_HASH : std::unary_function +{ + std::size_t operator()( const wxString& aString ) const + { + std::size_t hash = 2166136261u; + + for( wxString::const_iterator it = aString.begin(); it != aString.end(); ++it ) + { + hash ^= (unsigned char) *it; + hash *= 16777619; + } + + return hash; + } +}; + + /** * Type KEYWORD_MAP * is a hashtable made of a const char* and an int. Note that use of this diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index a56c226d63..214e78f5de 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -1355,79 +1355,7 @@ NETINFO_ITEM* BOARD::FindNet( int aNetcode ) const NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const { - // the first valid netcode is 1. - // zero is reserved for "no connection" and is not used. - if( aNetname.IsEmpty() ) - return NULL; - - int ncount = m_NetInfo.GetNetCount(); - - // Search for a netname = aNetname -#if 0 - - // Use a sequential search: easy to understand, but slow - for( int ii = 1; ii < ncount; ii++ ) - { - NETINFO_ITEM* item = m_NetInfo.GetNetItem( ii ); - - if( item && item->GetNetname() == aNetname ) - { - return item; - } - } - -#else - - // Use a fast binary search, - // this is possible because Nets are alphabetically ordered in list - // see NETINFO_LIST::BuildListOfNets() and - // NETINFO_LIST::Build_Pads_Full_List() - int imax = ncount - 1; - int index = imax; - - while( ncount > 0 ) - { - int ii = ncount; - ncount >>= 1; - - if( (ii & 1) && ( ii > 1 ) ) - ncount++; - - NETINFO_ITEM* item = m_NetInfo.GetNetItem( index ); - - if( item == NULL ) - return NULL; - - int icmp = item->GetNetname().Cmp( aNetname ); - - if( icmp == 0 ) // found ! - { - return item; - } - - if( icmp < 0 ) // must search after item - { - index += ncount; - - if( index > imax ) - index = imax; - - continue; - } - - if( icmp > 0 ) // must search before item - { - index -= ncount; - - if( index < 1 ) - index = 1; - - continue; - } - } - -#endif - return NULL; + return m_NetInfo.GetNetItem( aNetname ); } @@ -2618,7 +2546,10 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, } if( !aNetlist.IsDryRun() ) + { pad->SetNetname( wxEmptyString ); + pad->SetNet( 0 ); + } } } else // Footprint pad has a net. @@ -2638,7 +2569,19 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, } if( !aNetlist.IsDryRun() ) + { pad->SetNetname( net.GetNetName() ); + + NETINFO_ITEM* netinfo = FindNet( net.GetNetName() ); + if( netinfo == NULL ) + { + // It is a new net, we have to add it + netinfo = new NETINFO_ITEM( this, net.GetNetName(), m_NetInfo.GetNetCount() ); + m_NetInfo.AppendNet( netinfo ); + } + + pad->SetNet( netinfo->GetNet() ); + } } } } @@ -2711,6 +2654,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, aReporter->Report( msg ); } previouspad->SetNetname( wxEmptyString ); + previouspad->SetNet( 0 ); } netname = pad->GetNetname(); count = 1; @@ -2723,7 +2667,10 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, // Examine last pad if( pad && count == 1 ) + { pad->SetNetname( wxEmptyString ); + pad->SetNet( 0 ); + } } // Last step: Some tests: diff --git a/pcbnew/class_netinfo.h b/pcbnew/class_netinfo.h index a3c1807e14..c0e81a684e 100644 --- a/pcbnew/class_netinfo.h +++ b/pcbnew/class_netinfo.h @@ -37,6 +37,8 @@ #include #include #include +#include +#include class wxDC; @@ -115,7 +117,6 @@ public: }; - /** * Class NETINFO * is a container class for NETINFO_ITEM elements, which are the nets. That makes @@ -141,6 +142,20 @@ public: return m_NetBuffer[aNetcode]; } + /** + * Function GetItem + * @param aNetName = net name to identify a given NETINFO_ITEM + * @return NETINFO_ITEM* - by \a aNetName, or NULL if not found + */ + NETINFO_ITEM* GetNetItem( const wxString& aNetName ) const + { + NETNAMES_MAP::const_iterator result = m_netNames.find( aNetName ); + if( result != m_netNames.end() ) + return (*result).second; + + return NULL; + } + /** * Function GetNetCount * @return the number of nets ( always >= 1 ) @@ -188,6 +203,8 @@ public: void Show() const; #endif + typedef boost::unordered_map NETNAMES_MAP; + private: /** @@ -214,6 +231,7 @@ private: void buildPadsFullList(); BOARD* m_Parent; + NETNAMES_MAP m_netNames; ///< map for a fast look up by net names std::vector m_NetBuffer; ///< net list (name, design constraints ..) std::vector m_PadsFullList; ///< contains all pads, sorted by pad's netname. @@ -394,15 +412,15 @@ public: /** * Function GetNetname - * @return const wxString * , a pointer to the full netname + * @return const wxString&, a reference to the full netname */ - wxString GetNetname() const { return m_Netname; } + const wxString& GetNetname() const { return m_Netname; } /** * Function GetShortNetname - * @return const wxString * , a pointer to the short netname + * @return const wxString &, a reference to the short netname */ - wxString GetShortNetname() const { return m_ShortNetname; } + const wxString& GetShortNetname() const { return m_ShortNetname; } /** * Function GetMsgPanelInfo diff --git a/pcbnew/class_netinfolist.cpp b/pcbnew/class_netinfolist.cpp index 75bad023a2..561e845e21 100644 --- a/pcbnew/class_netinfolist.cpp +++ b/pcbnew/class_netinfolist.cpp @@ -15,9 +15,10 @@ // Constructor and destructor -NETINFO_LIST::NETINFO_LIST( BOARD* aParent ) +NETINFO_LIST::NETINFO_LIST( BOARD* aParent ) : m_Parent( aParent ) { - m_Parent = aParent; + // Make sure that the unconnected net has number 0 + AppendNet( new NETINFO_ITEM( aParent, wxEmptyString, 0 ) ); } @@ -34,14 +35,20 @@ void NETINFO_LIST::clear() m_NetBuffer.clear(); m_PadsFullList.clear(); + m_netNames.clear(); } void NETINFO_LIST::AppendNet( NETINFO_ITEM* aNewElement ) { + // net names & codes are supposed to be unique + assert( GetNetItem( aNewElement->GetNetname() ) == NULL ); + assert( GetNetItem( aNewElement->GetNet() ) == NULL ); + m_NetBuffer.push_back( aNewElement ); - // D(Show();) + // add an entry for fast look up by a net name using a map + m_netNames.insert( std::make_pair( aNewElement->GetNetname(), aNewElement ) ); } @@ -74,18 +81,13 @@ void NETINFO_LIST::buildListOfNets() { D_PAD* pad; int nodes_count = 0; - NETINFO_ITEM* net_item; // Build the PAD list, sorted by net buildPadsFullList(); // Restore the initial state of NETINFO_ITEMs for( unsigned i = 0; i < GetNetCount(); ++i ) - { GetNetItem( i )->Clear(); - } - - std::cout << m_PadsFullList.size() << std::endl; // Assign pads to appropriate NETINFO_ITEMs for( unsigned ii = 0; ii < m_PadsFullList.size(); ii++ ) @@ -95,8 +97,8 @@ void NETINFO_LIST::buildListOfNets() if( pad->GetNet() == 0 ) // pad not connected continue; - net_item = GetNetItem( pad->GetNet() ); - net_item->m_PadInNetList.push_back( pad ); + // Add pad to the appropriate list of pads + GetNetItem( pad->GetNet() )->m_PadInNetList.push_back( pad ); ++nodes_count; } diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index f984e4aa9b..2b707ead14 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -413,6 +413,7 @@ void D_PAD::CopyNetlistSettings( D_PAD* aPad ) wxCHECK_RET( aPad != NULL && aPad != this, wxT( "Cannot copy to NULL or yourself." ) ); aPad->SetNetname( GetNetname() ); + aPad->SetNet( GetNet() ); aPad->SetLocalClearance( m_LocalClearance ); aPad->SetLocalSolderMaskMargin( m_LocalSolderMaskMargin ); diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h index 5a385ea917..3c0b567c28 100644 --- a/pcbnew/class_pad.h +++ b/pcbnew/class_pad.h @@ -128,7 +128,13 @@ public: * Function GetNetname * @return const wxString& - the full netname */ - const wxString& GetNetname() const { return m_Netname; } + const wxString& GetNetname() const + { + assert( ( GetNet() == 0 ) == m_Netname.IsEmpty() ); + // assert( GetBoard()->FindNet( GetNet() ) == GetBoard()->FindNet( m_Netname ) ); + + return m_Netname; + } /** * Function GetShortNetname diff --git a/pcbnew/pad_edition_functions.cpp b/pcbnew/pad_edition_functions.cpp index b99bd1580a..3e890af710 100644 --- a/pcbnew/pad_edition_functions.cpp +++ b/pcbnew/pad_edition_functions.cpp @@ -142,6 +142,7 @@ void PCB_BASE_FRAME::AddPad( MODULE* aModule, bool draw ) // Update the pad properties. Import_Pad_Settings( pad, false ); pad->SetNetname( wxEmptyString ); + pad->SetNet( 0 ); pad->SetPosition( GetCrossHairPosition() ); diff --git a/pcbnew/pcb_netlist.h b/pcbnew/pcb_netlist.h index ff9544e10f..58ab9bf17d 100644 --- a/pcbnew/pcb_netlist.h +++ b/pcbnew/pcb_netlist.h @@ -47,16 +47,14 @@ class REPORTER; class COMPONENT_NET { wxString m_pinName; - wxString m_netNumber; wxString m_netName; public: COMPONENT_NET() {} - COMPONENT_NET( const wxString& aPinName, const wxString& aNetName ) + COMPONENT_NET( const wxString& aPinName, const wxString& aNetName ) : + m_pinName( aPinName ), m_netName( aNetName ) { - m_pinName = aPinName; - m_netName = aNetName; } const wxString& GetPinName() const { return m_pinName; } From 08367867b9bf5b7fbf0ea975d3a67498d9fa6a1c Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 14 Jan 2014 10:41:52 +0100 Subject: [PATCH 41/95] Removed D_PAD::SetNetname() function and D_PAD::m_Netname, D_PAD::m_ShortNetname fields. D_PAD::GetNetname() and D_PAD::GetShortNetname() were moved to BOARD_CONNECTED_ITEM. Now they use the net name stored in NETINFO_ITEM. Moved some one-line functions from class_board_connected_item.cpp to class_board_connected_item.h. Added a copyright notice, moved Doxygen comments from class_board_connected_item.cpp to class_board_connected_item.h. I have some doubts if changes introduced pcbnew/dialogs/dialog_pad_properties.cpp do not break anything, but I could not find a test case that breaks the pcbnew. Performed tests: - changed pad's net name from empty to existent - ok, name was changed - changed pad's net name from empty to nonexistent - ok, error message is displayed, net name stays empty - changed pad's net name from existent to empty - ok, net name became empty - changed pad's net name from existent to nonexistent - ok, error message is displayed, net name is not changed - (re)reading netlists, including net changes - fine, changes are applied, but empty nets are still kept - loaded pcbnew/pcad2kicadpcb_plugin/examples/CK1202_V1.pcb to test P-CAD import plugin - ok, net names are correct - imported an Eagle 6.0 board (Arduino Uno; http://arduino.cc/en/uploads/Main/arduino_Uno_Rev3-02-TH.zip) then saved in .kicad_pcb format and reloaded - ok, net names are correct - saved demos/video/video.kicad_pcb in legacy format and then loaded it again - ok, net names are correct --- pcbnew/class_board.cpp | 10 +-- pcbnew/class_board_connected_item.cpp | 78 ++++++------------------ pcbnew/class_board_connected_item.h | 75 ++++++++++++++++++++--- pcbnew/class_pad.cpp | 12 +--- pcbnew/class_pad.h | 28 --------- pcbnew/class_pad_draw_functions.cpp | 6 +- pcbnew/dialogs/dialog_pad_properties.cpp | 32 +++++----- pcbnew/eagle_plugin.cpp | 1 - pcbnew/legacy_plugin.cpp | 2 +- pcbnew/pad_edition_functions.cpp | 1 - pcbnew/pcad2kicadpcb_plugin/pcb.cpp | 10 +-- pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp | 12 +++- pcbnew/pcb_parser.cpp | 2 +- pcbnew/xchgmod.cpp | 4 -- 14 files changed, 122 insertions(+), 151 deletions(-) diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 214e78f5de..dfcebd69e8 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -2546,10 +2546,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, } if( !aNetlist.IsDryRun() ) - { - pad->SetNetname( wxEmptyString ); pad->SetNet( 0 ); - } } } else // Footprint pad has a net. @@ -2570,8 +2567,6 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, if( !aNetlist.IsDryRun() ) { - pad->SetNetname( net.GetNetName() ); - NETINFO_ITEM* netinfo = FindNet( net.GetNetName() ); if( netinfo == NULL ) { @@ -2653,7 +2648,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, GetChars( previouspad->GetPadName() ) ); aReporter->Report( msg ); } - previouspad->SetNetname( wxEmptyString ); + previouspad->SetNet( 0 ); } netname = pad->GetNetname(); @@ -2667,10 +2662,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, // Examine last pad if( pad && count == 1 ) - { - pad->SetNetname( wxEmptyString ); pad->SetNet( 0 ); - } } // Last step: Some tests: diff --git a/pcbnew/class_board_connected_item.cpp b/pcbnew/class_board_connected_item.cpp index eaf793f9b7..cf44e1dc7a 100644 --- a/pcbnew/class_board_connected_item.cpp +++ b/pcbnew/class_board_connected_item.cpp @@ -1,8 +1,3 @@ -/** - * @file class_board_connected_item.cpp - * @brief BOARD_CONNECTED_ITEM class functions. - */ - /* * This program source code file is part of KiCad, a free EDA CAD application. * @@ -28,6 +23,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * @file class_board_connected_item.cpp + * @brief BOARD_CONNECTED_ITEM class functions. + */ + #include #include @@ -36,68 +36,32 @@ BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( BOARD_ITEM* aParent, KICAD_T idtype ) : - BOARD_ITEM( aParent, idtype ) + BOARD_ITEM( aParent, idtype ), m_NetCode( 0 ), m_Subnet( 0 ), m_ZoneSubnet( 0 ) { - m_NetCode = 0; - m_Subnet = 0; - m_ZoneSubnet = 0; } BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( const BOARD_CONNECTED_ITEM& aItem ) : - BOARD_ITEM( aItem ) + BOARD_ITEM( aItem ), m_NetCode( aItem.m_NetCode ), m_Subnet( aItem.m_Subnet ), + m_ZoneSubnet( aItem.m_ZoneSubnet ) { - m_NetCode = aItem.m_NetCode; - m_Subnet = aItem.m_Subnet; - m_ZoneSubnet = aItem.m_ZoneSubnet; } -/** - * Function GetNet - * @return int - the net code. - */ -int BOARD_CONNECTED_ITEM::GetNet() const +const wxString& BOARD_CONNECTED_ITEM::GetNetname() const { - return m_NetCode; + BOARD* board = GetBoard(); + NETINFO_ITEM* netinfo = board->FindNet( m_NetCode ); + + return netinfo->GetNetname(); } -void BOARD_CONNECTED_ITEM::SetNet( int aNetCode ) +const wxString& BOARD_CONNECTED_ITEM::GetShortNetname() const { - m_NetCode = aNetCode; -} + NETINFO_ITEM* netinfo = GetBoard()->FindNet( m_NetCode ); - -/** - * Function GetSubNet - * @return int - the sub net code. - */ -int BOARD_CONNECTED_ITEM::GetSubNet() const -{ - return m_Subnet; -} - - -void BOARD_CONNECTED_ITEM::SetSubNet( int aSubNetCode ) -{ - m_Subnet = aSubNetCode; -} - - -/** - * Function GetZoneSubNet - * @return int - the sub net code in zone connections. - */ -int BOARD_CONNECTED_ITEM::GetZoneSubNet() const -{ - return m_ZoneSubnet; -} - - -void BOARD_CONNECTED_ITEM::SetZoneSubNet( int aSubNetCode ) -{ - m_ZoneSubnet = aSubNetCode; + return netinfo->GetShortNetname(); } @@ -132,11 +96,6 @@ int BOARD_CONNECTED_ITEM::GetClearance( BOARD_CONNECTED_ITEM* aItem ) const } -/** return a pointer to the netclass of the zone - * if the net is not found (can happen when a netlist is reread, - * and the net name is not existant, return the default net class - * So should not return a null pointer - */ NETCLASS* BOARD_CONNECTED_ITEM::GetNetClass() const { // It is important that this be implemented without any sequential searching. @@ -176,10 +135,7 @@ NETCLASS* BOARD_CONNECTED_ITEM::GetNetClass() const return board->m_NetClasses.GetDefault(); } -/** - * Function GetNetClassName - * @return the Net Class name of this item - */ + wxString BOARD_CONNECTED_ITEM::GetNetClassName() const { wxString name; diff --git a/pcbnew/class_board_connected_item.h b/pcbnew/class_board_connected_item.h index 67cd457398..9b2f5df7b8 100644 --- a/pcbnew/class_board_connected_item.h +++ b/pcbnew/class_board_connected_item.h @@ -1,3 +1,28 @@ +/* + * 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 + * Copyright (C) 1992-2012 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 class_board_connected_item.h * @brief Class BOARD_CONNECTED_ITEM. @@ -6,7 +31,6 @@ #ifndef BOARD_CONNECTED_ITEM_H #define BOARD_CONNECTED_ITEM_H - #include class NETCLASS; @@ -48,22 +72,55 @@ public: * Function GetNet * @return int - the net code. */ - int GetNet() const; - virtual void SetNet( int aNetCode ); + int GetNet() const + { + return m_NetCode; + } + + virtual void SetNet( int aNetCode ) + { + m_NetCode = aNetCode; + } /** * Function GetSubNet * @return int - the sub net code. */ - int GetSubNet() const; - void SetSubNet( int aSubNetCode ); + int GetSubNet() const + { + return m_Subnet; + } + + void SetSubNet( int aSubNetCode ) + { + m_Subnet = aSubNetCode; + } /** * Function GetZoneSubNet * @return int - the sub net code in zone connections. */ - int GetZoneSubNet() const; - void SetZoneSubNet( int aSubNetCode ); + int GetZoneSubNet() const + { + return m_ZoneSubnet; + } + + void SetZoneSubNet( int aSubNetCode ) + { + m_ZoneSubnet = aSubNetCode; + } + + /** + * Function GetNetname + * @return const wxString& - the full netname + */ + const wxString& GetNetname() const; + + /** + * Function GetShortNetname + * @return const wxString& - the short netname + */ + const wxString& GetShortNetname() const; /** * Function GetClearance @@ -84,6 +141,10 @@ public: /** * Function GetNetClassName + * returns a pointer to the netclass of the zone. + * If the net is not found (can happen when a netlist is reread, + * and the net name does not exist, return the default net class + * (should not return a null pointer). * @return the Net Class name of this item */ wxString GetNetClassName() const; diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index 2b707ead14..b9877c4a56 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -364,13 +364,6 @@ void D_PAD::SetPadName( const wxString& name ) } -void D_PAD::SetNetname( const wxString& aNetname ) -{ - m_Netname = aNetname; - m_ShortNetname = m_Netname.AfterLast( '/' ); -} - - void D_PAD::Copy( D_PAD* source ) { if( source == NULL ) @@ -402,8 +395,6 @@ void D_PAD::Copy( D_PAD* source ) SetSubRatsnest( 0 ); SetSubNet( 0 ); - m_Netname = source->m_Netname; - m_ShortNetname = source->m_ShortNetname; } @@ -412,7 +403,6 @@ void D_PAD::CopyNetlistSettings( D_PAD* aPad ) // Don't do anything foolish like trying to copy to yourself. wxCHECK_RET( aPad != NULL && aPad != this, wxT( "Cannot copy to NULL or yourself." ) ); - aPad->SetNetname( GetNetname() ); aPad->SetNet( GetNet() ); aPad->SetLocalClearance( m_LocalClearance ); @@ -578,7 +568,7 @@ void D_PAD::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM>& aList ) aList.push_back( MSG_PANEL_ITEM( _( "Pad" ), Line, BROWN ) ); } - aList.push_back( MSG_PANEL_ITEM( _( "Net" ), m_Netname, DARKCYAN ) ); + aList.push_back( MSG_PANEL_ITEM( _( "Net" ), GetNetname(), DARKCYAN ) ); /* For test and debug only: display m_physical_connexion and * m_logical_connexion */ diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h index 3c0b567c28..579b4bbeef 100644 --- a/pcbnew/class_pad.h +++ b/pcbnew/class_pad.h @@ -118,30 +118,6 @@ public: return m_NumPadName == other->m_NumPadName; // hide tricks behind sensible API } - /** - * Function SetNetname - * @param aNetname: the new netname - */ - void SetNetname( const wxString& aNetname ); - - /** - * Function GetNetname - * @return const wxString& - the full netname - */ - const wxString& GetNetname() const - { - assert( ( GetNet() == 0 ) == m_Netname.IsEmpty() ); - // assert( GetBoard()->FindNet( GetNet() ) == GetBoard()->FindNet( m_Netname ) ); - - return m_Netname; - } - - /** - * Function GetShortNetname - * @return const wxString& - the short netname - */ - const wxString& GetShortNetname() const { return m_ShortNetname; } - /** * Function GetShape * @return the shape of this pad. @@ -475,10 +451,6 @@ private: int m_boundingRadius; ///< radius of the circle containing the pad shape - - wxString m_Netname; ///< Full net name like /mysheet/mysubsheet/vout used by Eeschema - wxString m_ShortNetname; ///< short net name, like vout from /mysheet/mysubsheet/vout - /// Pad name (4 char) or a long identifier (used in pad name /// comparisons because this is faster than string comparison) union diff --git a/pcbnew/class_pad_draw_functions.cpp b/pcbnew/class_pad_draw_functions.cpp index c590d55e99..346a4980e6 100644 --- a/pcbnew/class_pad_draw_functions.cpp +++ b/pcbnew/class_pad_draw_functions.cpp @@ -473,7 +473,7 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo ) GRSetDrawMode( aDC, aDrawInfo.m_DrawMode ); // Draw "No connect" ( / or \ or cross X ) if necessary - if( m_Netname.IsEmpty() && aDrawInfo.m_ShowNCMark ) + if( GetNet() == 0 && aDrawInfo.m_ShowNCMark ) { int dx0 = std::min( halfsize.x, halfsize.y ); EDA_COLOR_T nc_color = BLUE; @@ -499,7 +499,7 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo ) wxPoint tpos0 = shape_pos; // Position of the centre of text wxPoint tpos = tpos0; wxSize AreaSize; // size of text area, normalized to AreaSize.y < AreaSize.x - int shortname_len = m_ShortNetname.Len(); + int shortname_len = GetShortNetname().Len(); if( !aDrawInfo.m_Display_netname ) shortname_len = 0; @@ -583,7 +583,7 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo ) tsize = ( tsize * 7 ) / 10; DrawGraphicHaloText( clipBox, aDC, tpos, aDrawInfo.m_Color, BLACK, WHITE, - m_ShortNetname, t_angle, + GetShortNetname(), t_angle, wxSize( tsize, tsize ), GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, tsize / 7, false, false ); } diff --git a/pcbnew/dialogs/dialog_pad_properties.cpp b/pcbnew/dialogs/dialog_pad_properties.cpp index 7dc306a063..ae1e93036f 100644 --- a/pcbnew/dialogs/dialog_pad_properties.cpp +++ b/pcbnew/dialogs/dialog_pad_properties.cpp @@ -151,7 +151,8 @@ DIALOG_PAD_PROPERTIES::DIALOG_PAD_PROPERTIES( PCB_BASE_FRAME* aParent, D_PAD* aP m_parent = aParent; m_currentPad = aPad; m_board = m_parent->GetBoard(); - m_dummyPad = new D_PAD( (MODULE*) NULL ); + m_dummyPad = new D_PAD( aPad->GetParent() ); + m_padMaster.SetParent( aPad->GetParent() ); if( aPad ) m_dummyPad->Copy( aPad ); @@ -809,25 +810,16 @@ void DIALOG_PAD_PROPERTIES::PadPropertiesAccept( wxCommandEvent& event ) m_currentPad->SetPadName( m_padMaster.GetPadName() ); - if( m_currentPad->GetNetname() != m_padMaster.GetNetname() ) + if( m_currentPad->GetNetname() != m_PadNetNameCtrl->GetValue() ) { - if( m_padMaster.GetNetname().IsEmpty() ) + if( !m_PadNetNameCtrl->GetValue().IsEmpty() && m_padMaster.GetNet() == 0 ) { - rastnestIsChanged = true; - m_currentPad->SetNet( 0 ); - m_currentPad->SetNetname( wxEmptyString ); + DisplayError( NULL, _( "Unknown netname, netname not changed" ) ); } else { - const NETINFO_ITEM* net = m_board->FindNet( m_padMaster.GetNetname() ); - if( net ) - { - rastnestIsChanged = true; - m_currentPad->SetNetname( m_padMaster.GetNetname() ); - m_currentPad->SetNet( net->GetNet() ); - } - else - DisplayError( NULL, _( "Unknown netname, netname not changed" ) ); + rastnestIsChanged = true; + m_currentPad->SetNet( m_padMaster.GetNet() ); } } @@ -986,7 +978,13 @@ bool DIALOG_PAD_PROPERTIES::transferDataToPad( D_PAD* aPad ) msg = m_PadNumCtrl->GetValue().Left( 4 ); aPad->SetPadName( msg ); - aPad->SetNetname( m_PadNetNameCtrl->GetValue() ); + + // Check if user has set an existing net name + const NETINFO_ITEM* netinfo = m_board->FindNet( m_PadNetNameCtrl->GetValue() ); + if( netinfo != NULL ) + aPad->SetNet( netinfo->GetNet() ); + else + aPad->SetNet( 0 ); // Clear some values, according to the pad type and shape switch( aPad->GetShape() ) @@ -1034,7 +1032,7 @@ bool DIALOG_PAD_PROPERTIES::transferDataToPad( D_PAD* aPad ) // no offset, no net name, no pad name allowed aPad->SetOffset( wxPoint( 0, 0 ) ); aPad->SetPadName( wxEmptyString ); - aPad->SetNetname( wxEmptyString ); + aPad->SetNet( 0 ); break; default: diff --git a/pcbnew/eagle_plugin.cpp b/pcbnew/eagle_plugin.cpp index 80b2fe78c5..6fec2fbdb2 100644 --- a/pcbnew/eagle_plugin.cpp +++ b/pcbnew/eagle_plugin.cpp @@ -1696,7 +1696,6 @@ void EAGLE_PLUGIN::loadElements( CPTREE& aElements ) if( ni != m_pads_to_nets.end() ) { const ENET* enet = &ni->second; - pad->SetNetname( FROM_UTF8( enet->netname.c_str() ) ); pad->SetNet( enet->netcode ); } } diff --git a/pcbnew/legacy_plugin.cpp b/pcbnew/legacy_plugin.cpp index ab5a4fe34f..532750329c 100644 --- a/pcbnew/legacy_plugin.cpp +++ b/pcbnew/legacy_plugin.cpp @@ -1303,7 +1303,7 @@ void LEGACY_PLUGIN::loadPAD( MODULE* aModule ) // read Netname ReadDelimitedText( buf, data, sizeof(buf) ); - pad->SetNetname( FROM_UTF8( StrPurge( buf ) ) ); + assert( m_board->FindNet( netcode )->GetNetname() == FROM_UTF8( StrPurge( buf ) ) ); } else if( TESTLINE( "Po" ) ) // (Po)sition diff --git a/pcbnew/pad_edition_functions.cpp b/pcbnew/pad_edition_functions.cpp index 3e890af710..839d1f39fc 100644 --- a/pcbnew/pad_edition_functions.cpp +++ b/pcbnew/pad_edition_functions.cpp @@ -141,7 +141,6 @@ void PCB_BASE_FRAME::AddPad( MODULE* aModule, bool draw ) // Update the pad properties. Import_Pad_Settings( pad, false ); - pad->SetNetname( wxEmptyString ); pad->SetNet( 0 ); pad->SetPosition( GetCrossHairPosition() ); diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb.cpp index 39a65ebf33..6afde99801 100644 --- a/pcbnew/pcad2kicadpcb_plugin/pcb.cpp +++ b/pcbnew/pcad2kicadpcb_plugin/pcb.cpp @@ -914,17 +914,17 @@ void PCB::AddToBoard() m_board->SetCopperLayerCount( m_layersStackup.GetCount() ); - for( i = 0; i < (int) m_pcbComponents.GetCount(); i++ ) - { - m_pcbComponents[i]->AddToBoard(); - } - for( i = 0; i < (int) m_pcbNetlist.GetCount(); i++ ) { net = m_pcbNetlist[i]; m_board->AppendNet( new NETINFO_ITEM( m_board, net->m_name, net->m_netCode ) ); } + + for( i = 0; i < (int) m_pcbComponents.GetCount(); i++ ) + { + m_pcbComponents[i]->AddToBoard(); + } } } // namespace PCAD2KICAD diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp index 4ec4338efa..c3cd2e34af 100644 --- a/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp +++ b/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp @@ -273,8 +273,16 @@ void PCB_PAD::AddToModule( MODULE* aModule, int aRotation, bool aEncapsulatedPad pad->SetAttribute( padType ); - pad->SetNet( 0 ); - pad->SetNetname( m_net ); + // Set the proper net code + NETINFO_ITEM* netinfo = m_board->FindNet( m_net ); + if( netinfo == NULL ) // I believe this should not happen, but just in case + { + // It is a new net + netinfo = new NETINFO_ITEM( m_board, m_net, m_board->GetNetCount() ); + m_board->AppendNet( netinfo ); + } + + pad->SetNet( netinfo->GetNet() ); } if( !aEncapsulatedPad ) diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index f1eaa3026c..b25251a5db 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -2191,7 +2191,7 @@ D_PAD* PCB_PARSER::parseD_PAD() throw( IO_ERROR, PARSE_ERROR ) case T_net: pad->SetNet( parseInt( "net number" ) ); NeedSYMBOLorNUMBER(); - pad->SetNetname( FromUTF8() ); + assert( FromUTF8() == m_board->FindNet( pad->GetNet() )->GetNetname() ); NeedRIGHT(); break; diff --git a/pcbnew/xchgmod.cpp b/pcbnew/xchgmod.cpp index a4ce86869f..e983a0d6ee 100644 --- a/pcbnew/xchgmod.cpp +++ b/pcbnew/xchgmod.cpp @@ -455,17 +455,13 @@ void PCB_EDIT_FRAME::Exchange_Module( MODULE* aOldModule, // Update pad netnames ( when possible) for( D_PAD* pad = aNewModule->Pads(); pad != NULL; pad = pad->Next() ) { - pad->SetNetname( wxEmptyString ); pad->SetNet( 0 ); D_PAD* old_pad = aOldModule->Pads(); for( ; old_pad != NULL; old_pad = old_pad->Next() ) { if( pad->PadNameEqual( old_pad ) ) - { - pad->SetNetname( old_pad->GetNetname() ); pad->SetNet( old_pad->GetNet() ); - } } } From 8571e3608c9f4b64e93a25e03bba5478e4741014 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 14 Jan 2014 11:41:06 +0100 Subject: [PATCH 42/95] Removed: - ZONE_CONTAINER::m_Netname field - ZONE_CONTAINER::SetNetName() - ZONE_CONTAINER::SetNet() [it uses the one in BOARD_CONNECTED_ITEM] - ZONE_CONTAINER::GetNetName() [instead BOARD_CONNECTED_ITEM::GetNetname is used] - ZONE_CONTAINER::SetNetNameFromNetCode() Performed tests: - Drawn a zone that belongs to a net, then modified schematics so the net does not exist anymore. After reloading the net list, all pads/tracks are updated. Zones still belongs to the net that does not exist in the schematic (but still exists in .kicad_pcb file). After running DRC, the zone becomes not filled. - Undo & redo affects assignment of a polygon to a specific net (you may change net of a polygon, refill it and undo/redo the changes). --- pcbnew/class_board.cpp | 4 +- pcbnew/class_zone.cpp | 43 +-------------------- pcbnew/class_zone.h | 26 ------------- pcbnew/eagle_plugin.cpp | 5 --- pcbnew/kicad_plugin.cpp | 2 +- pcbnew/legacy_plugin.cpp | 16 +++----- pcbnew/pcad2kicadpcb_plugin/pcb_polygon.cpp | 1 - pcbnew/pcb_parser.cpp | 7 +--- pcbnew/specctra_export.cpp | 2 +- pcbnew/zones_by_polygon.cpp | 4 +- pcbnew/zones_by_polygon_fill_functions.cpp | 4 +- pcbnew/zones_functions_for_undo_redo.cpp | 2 +- 12 files changed, 18 insertions(+), 98 deletions(-) diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index dfcebd69e8..af7cc3e4f0 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -1535,7 +1535,7 @@ int BOARD::SetAreasNetCodesFromNetNames( void ) if( GetArea( ii )->GetNet() != 0 ) // i.e. if this zone is connected to a net { - const NETINFO_ITEM* net = FindNet( GetArea( ii )->GetNetName() ); + const NETINFO_ITEM* net = FindNet( GetArea( ii )->GetNetname() ); if( net ) { @@ -2720,7 +2720,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, " has non-existent net name \"%s\" **\n" ), GetChars( coord ), GetChars( zone->GetLayerName() ), - GetChars( zone->GetNetName() ) ); + GetChars( zone->GetNetname() ) ); aReporter->Report( msg ); } } diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index b1d8405c81..941f95f3b5 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -138,31 +138,6 @@ const wxPoint& ZONE_CONTAINER::GetPosition() const } -void ZONE_CONTAINER::SetNet( int aNetCode ) -{ - BOARD_CONNECTED_ITEM::SetNet( aNetCode ); - - if( aNetCode < 0 ) - return; - - BOARD* board = GetBoard(); - - if( board ) - { - NETINFO_ITEM* net = board->FindNet( aNetCode ); - - if( net ) - m_Netname = net->GetNetname(); - else - m_Netname.Empty(); - } - else - { - m_Netname.Empty(); - } -} - - void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMode, const wxPoint& offset ) { @@ -658,7 +633,7 @@ void ZONE_CONTAINER::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) else // a netcode < 0 is an error { msg = wxT( " [" ); - msg << m_Netname + wxT( "]" ); + msg << GetNetname() + wxT( "]" ); msg << wxT( " <" ) << _( "Not Found" ) << wxT( ">" ); } @@ -849,20 +824,6 @@ void ZONE_CONTAINER::Copy( ZONE_CONTAINER* src ) } -bool ZONE_CONTAINER::SetNetNameFromNetCode( void ) -{ - NETINFO_ITEM* net; - - if( m_Parent && ( net = ( (BOARD*) m_Parent )->FindNet( GetNet() ) ) ) - { - m_Netname = net->GetNetname(); - return true; - } - - return false; -} - - ZoneConnection ZONE_CONTAINER::GetPadConnection( D_PAD* aPad ) const { if( aPad == NULL || aPad->GetZoneConnection() == UNDEFINED_CONNECTION ) @@ -928,7 +889,7 @@ wxString ZONE_CONTAINER::GetSelectMenuText() const else { // A netcode < 0 is an error: // Netname not found or area not initialised - text << wxT( " [" ) << m_Netname << wxT( "]" ); + text << wxT( " [" ) << GetNetname() << wxT( "]" ); text << wxT( " <" ) << _( "Not Found" ) << wxT( ">" ); } } diff --git a/pcbnew/class_zone.h b/pcbnew/class_zone.h index 513859b9d8..6423d85396 100644 --- a/pcbnew/class_zone.h +++ b/pcbnew/class_zone.h @@ -186,31 +186,6 @@ public: return ( GetLayer() < FIRST_NON_COPPER_LAYER ) ? true : false; } - /** - * Function SetNet - * sets the netcode and the netname. - * - * @param aNetCode The net code of the zone container if greater than or equal to - * zero. Otherwise the current net code is kept and set the net - * code error flag. - */ - virtual void SetNet( int aNetCode ); - - /** - * Function SetNetNameFromNetCode - * Find the net name corresponding to the net code. - * @return bool - true if net found, else false - */ - bool SetNetNameFromNetCode( void ); - - /** - * Function GetNetName - * returns the net name. - * @return const wxString& - The net name. - */ - const wxString& GetNetName() const { return m_Netname; }; - void SetNetName( const wxString& aName ) { m_Netname = aName; } - /// How to fill areas: 0 = use filled polygons, 1 => fill with segments. void SetFillMode( int aFillMode ) { m_FillMode = aFillMode; } int GetFillMode() const { return m_FillMode; } @@ -607,7 +582,6 @@ public: private: CPolyLine* m_Poly; ///< Outline of the zone. - wxString m_Netname; ///< Name of the net assigned to the zone. CPolyLine* m_smoothedPoly; // Corner-smoothed version of m_Poly int m_cornerSmoothingType; unsigned int m_cornerRadius; diff --git a/pcbnew/eagle_plugin.cpp b/pcbnew/eagle_plugin.cpp index 6fec2fbdb2..14405e9753 100644 --- a/pcbnew/eagle_plugin.cpp +++ b/pcbnew/eagle_plugin.cpp @@ -2259,7 +2259,6 @@ void EAGLE_PLUGIN::packageHole( MODULE* aModule, CPTREE& aTree ) const // no offset, no net name, no pad name allowed // pad->SetOffset( wxPoint( 0, 0 ) ); // pad->SetPadName( wxEmptyString ); - // pad->SetNetname( wxEmptyString ); wxPoint padpos( kicad_x( e.x ), kicad_y( e.y ) ); @@ -2496,7 +2495,6 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals ) zone->SetTimeStamp( timeStamp( it->second ) ); zone->SetLayer( layer ); zone->SetNet( netCode ); - zone->SetNetName( netName ); CPolyLine::HATCH_STYLE outline_hatch = CPolyLine::DIAGONAL_EDGE; @@ -2552,10 +2550,7 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals ) // KiCad does not support an unconnected zone with its own non-zero netcode, // but only when assigned netcode = 0 w/o a name... for( ZONES::iterator it = zones.begin(); it != zones.end(); ++it ) - { (*it)->SetNet( 0 ); - (*it)->SetNetName( wxEmptyString ); - } // therefore omit this signal/net. } diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index d18c32edaa..ed6d7c062e 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -1406,7 +1406,7 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const // (perhaps netcode and netname should be not stored) m_out->Print( aNestLevel, "(zone (net %d) (net_name %s)", aZone->GetIsKeepout() ? 0 : aZone->GetNet(), - m_out->Quotew( aZone->GetIsKeepout() ? wxT("") : aZone->GetNetName() ).c_str() ); + m_out->Quotew( aZone->GetIsKeepout() ? wxT("") : aZone->GetNetname() ).c_str() ); formatLayer( aZone ); diff --git a/pcbnew/legacy_plugin.cpp b/pcbnew/legacy_plugin.cpp index 532750329c..ade83543f1 100644 --- a/pcbnew/legacy_plugin.cpp +++ b/pcbnew/legacy_plugin.cpp @@ -2238,7 +2238,6 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER() // the zone net name is the name read in file. // (When mismatch, the user will be prompted in DRC, to fix the actual name) zc->BOARD_CONNECTED_ITEM::SetNet( netcode ); - zc->SetNetName( FROM_UTF8( buf ) ); // init the net name here } else if( TESTLINE( "ZLayer" ) ) // layer found @@ -2255,7 +2254,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER() if( !hopt ) { - m_error.Printf( wxT( "Bad ZAux for CZONE_CONTAINER '%s'" ), zc->GetNetName().GetData() ); + m_error.Printf( wxT( "Bad ZAux for CZONE_CONTAINER '%s'" ), zc->GetNetname().GetData() ); THROW_IO_ERROR( m_error ); } @@ -2266,7 +2265,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER() case 'F': outline_hatch = CPolyLine::DIAGONAL_FULL; break; default: - m_error.Printf( wxT( "Bad ZAux for CZONE_CONTAINER '%s'" ), zc->GetNetName().GetData() ); + m_error.Printf( wxT( "Bad ZAux for CZONE_CONTAINER '%s'" ), zc->GetNetname().GetData() ); THROW_IO_ERROR( m_error ); } @@ -2283,7 +2282,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER() if( smoothing >= ZONE_SETTINGS::SMOOTHING_LAST || smoothing < 0 ) { - m_error.Printf( wxT( "Bad ZSmoothing for CZONE_CONTAINER '%s'" ), zc->GetNetName().GetData() ); + m_error.Printf( wxT( "Bad ZSmoothing for CZONE_CONTAINER '%s'" ), zc->GetNetname().GetData() ); THROW_IO_ERROR( m_error ); } @@ -2358,7 +2357,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER() default: m_error.Printf( wxT( "Bad ZClearance padoption for CZONE_CONTAINER '%s'" ), - zc->GetNetName().GetData() ); + zc->GetNetname().GetData() ); THROW_IO_ERROR( m_error ); } @@ -2422,10 +2421,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER() // Ensure keepout does not have a net // (which have no sense for a keepout zone) if( zc->GetIsKeepout() ) - { - zc->SetNet(0); - zc->SetNetName( wxEmptyString ); - } + zc->SetNet( 0 ); // should always occur, but who knows, a zone without two corners // is no zone at all, it's a spot? @@ -3644,7 +3640,7 @@ void LEGACY_PLUGIN::saveZONE_CONTAINER( const ZONE_CONTAINER* me ) const fprintf( m_fp, "ZInfo %lX %d %s\n", me->GetTimeStamp(), me->GetIsKeepout() ? 0 : me->GetNet(), - EscapedUTF8( me->GetIsKeepout() ? wxT("") : me->GetNetName() ).c_str() ); + EscapedUTF8( me->GetIsKeepout() ? wxT("") : me->GetNetname() ).c_str() ); // Save the outline layer info fprintf( m_fp, "ZLayer %d\n", me->GetLayer() ); diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_polygon.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_polygon.cpp index d64f626bf9..5fab0055e8 100644 --- a/pcbnew/pcad2kicadpcb_plugin/pcb_polygon.cpp +++ b/pcbnew/pcad2kicadpcb_plugin/pcb_polygon.cpp @@ -172,7 +172,6 @@ void PCB_POLYGON::AddToBoard() zone->SetTimeStamp( m_timestamp ); zone->SetLayer( m_KiCadLayer ); zone->SetNet( m_netCode ); - zone->SetNetName( m_net ); // add outline int outline_hatch = CPolyLine::DIAGONAL_EDGE; diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index b25251a5db..0fd7f55b64 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -2423,7 +2423,7 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR ) case T_net_name: NeedSYMBOLorNUMBER(); - zone->SetNetName( FromUTF8() ); + assert( m_board->FindNet( zone->GetNet() )->GetNetname() == FromUTF8() ); NeedRIGHT(); break; @@ -2699,10 +2699,7 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR ) // Ensure keepout does not have a net (which have no sense for a keepout zone) if( zone->GetIsKeepout() ) - { - zone->SetNet(0); - zone->SetNetName( wxEmptyString ); - } + zone->SetNet( 0 ); return zone.release(); } diff --git a/pcbnew/specctra_export.cpp b/pcbnew/specctra_export.cpp index 535d6834fa..dee6c8be03 100644 --- a/pcbnew/specctra_export.cpp +++ b/pcbnew/specctra_export.cpp @@ -1557,7 +1557,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) plane->SetShape( mainPolygon ); - plane->name = TO_UTF8( item->GetNetName() ); + plane->name = TO_UTF8( item->GetNetname() ); if( plane->name.size() == 0 ) { diff --git a/pcbnew/zones_by_polygon.cpp b/pcbnew/zones_by_polygon.cpp index 19dcfe5f2a..977fef6e29 100644 --- a/pcbnew/zones_by_polygon.cpp +++ b/pcbnew/zones_by_polygon.cpp @@ -550,7 +550,6 @@ int PCB_EDIT_FRAME::Begin_Zone( wxDC* DC ) zoneInfo.m_NetcodeSelection = GetBoard()->GetHighLightNetCode(); zone->SetNet( zoneInfo.m_NetcodeSelection ); - zone->SetNetNameFromNetCode( ); } double tmp = ZONE_THERMAL_RELIEF_GAP_MIL; wxGetApp().GetSettings()->Read( ZONE_THERMAL_RELIEF_GAP_STRING_KEY, &tmp ); @@ -579,7 +578,6 @@ int PCB_EDIT_FRAME::Begin_Zone( wxDC* DC ) // Netcode and netname are irrelevant, // so ensure they are cleared zone->SetNet( 0 ); - zone->SetNetName( wxEmptyString ); edited = InvokeKeepoutAreaEditor( this, &zoneInfo ); } else @@ -904,7 +902,7 @@ void PCB_EDIT_FRAME::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* aZone ) NETINFO_ITEM* net = GetBoard()->FindNet( zoneInfo.m_NetcodeSelection ); if( net ) // net == NULL should not occur - aZone->SetNetName( net->GetNetname() ); + aZone->SetNet( net->GetNet() ); // Combine zones if possible GetBoard()->OnAreaPolygonModified( &s_AuxiliaryList, aZone ); diff --git a/pcbnew/zones_by_polygon_fill_functions.cpp b/pcbnew/zones_by_polygon_fill_functions.cpp index 61324cb6c7..73ca2a8217 100644 --- a/pcbnew/zones_by_polygon_fill_functions.cpp +++ b/pcbnew/zones_by_polygon_fill_functions.cpp @@ -103,7 +103,7 @@ int PCB_EDIT_FRAME::Fill_Zone( ZONE_CONTAINER* aZone ) zoneInfo.m_NetcodeSelection = aZone->GetNet(); SetZoneSettings( zoneInfo ); - msg = aZone->GetNetName(); + msg = aZone->GetNetname(); if( msg.IsEmpty() ) msg = wxT( "No net" ); @@ -150,7 +150,7 @@ int PCB_EDIT_FRAME::Fill_All_Zones( wxWindow * aActiveWindow, bool aVerbose ) if( zoneContainer->GetIsKeepout() ) continue; - msg.Printf( FORMAT_STRING, ii+1, areaCount, GetChars( zoneContainer->GetNetName() ) ); + msg.Printf( FORMAT_STRING, ii + 1, areaCount, GetChars( zoneContainer->GetNetname() ) ); if( progressDialog ) { diff --git a/pcbnew/zones_functions_for_undo_redo.cpp b/pcbnew/zones_functions_for_undo_redo.cpp index 52166bc5db..8abd5b6306 100644 --- a/pcbnew/zones_functions_for_undo_redo.cpp +++ b/pcbnew/zones_functions_for_undo_redo.cpp @@ -67,7 +67,7 @@ bool ZONE_CONTAINER::IsSame( const ZONE_CONTAINER& aZoneToCompare ) if( GetLayer() != aZoneToCompare.GetLayer() ) return false; - if( m_Netname != aZoneToCompare.m_Netname ) + if( GetNet() != aZoneToCompare.GetNet() ) return false; if( GetPriority() != aZoneToCompare.GetPriority() ) From d191e5038c9455e5ba69555c76a5c1f854f28642 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 15 Jan 2014 09:34:16 +0100 Subject: [PATCH 43/95] Added NETINFO_LIST::UNCONNECTED constant. --- pcbnew/class_board.cpp | 8 ++++---- pcbnew/class_netinfo.h | 3 +++ pcbnew/class_netinfolist.cpp | 3 +++ pcbnew/class_track.cpp | 4 ++-- pcbnew/connect.cpp | 2 +- pcbnew/eagle_plugin.cpp | 4 ++-- pcbnew/legacy_plugin.cpp | 4 ++-- pcbnew/pad_edition_functions.cpp | 2 +- pcbnew/pcb_parser.cpp | 4 ++-- pcbnew/ratsnest.cpp | 2 +- pcbnew/xchgmod.cpp | 2 +- pcbnew/zones_by_polygon.cpp | 2 +- 12 files changed, 23 insertions(+), 17 deletions(-) diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index af7cc3e4f0..416044cc5d 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -1529,7 +1529,7 @@ int BOARD::SetAreasNetCodesFromNetNames( void ) { if( !GetArea( ii )->IsOnCopperLayer() ) { - GetArea( ii )->SetNet( 0 ); + GetArea( ii )->SetNet( NETINFO_LIST::UNCONNECTED ); continue; } @@ -2546,7 +2546,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, } if( !aNetlist.IsDryRun() ) - pad->SetNet( 0 ); + pad->SetNet( NETINFO_LIST::UNCONNECTED ); } } else // Footprint pad has a net. @@ -2649,7 +2649,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, aReporter->Report( msg ); } - previouspad->SetNet( 0 ); + previouspad->SetNet( NETINFO_LIST::UNCONNECTED ); } netname = pad->GetNetname(); count = 1; @@ -2662,7 +2662,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, // Examine last pad if( pad && count == 1 ) - pad->SetNet( 0 ); + pad->SetNet( NETINFO_LIST::UNCONNECTED ); } // Last step: Some tests: diff --git a/pcbnew/class_netinfo.h b/pcbnew/class_netinfo.h index c0e81a684e..8ea47c3676 100644 --- a/pcbnew/class_netinfo.h +++ b/pcbnew/class_netinfo.h @@ -199,6 +199,9 @@ public: return NULL; } + ///> Constant that holds the unconnected net number + static const int UNCONNECTED; + #if defined(DEBUG) void Show() const; #endif diff --git a/pcbnew/class_netinfolist.cpp b/pcbnew/class_netinfolist.cpp index 561e845e21..590cd352ce 100644 --- a/pcbnew/class_netinfolist.cpp +++ b/pcbnew/class_netinfolist.cpp @@ -162,3 +162,6 @@ void NETINFO_LIST::buildPadsFullList() m_Parent->m_Status_Pcb = LISTE_PAD_OK; } + + +const int NETINFO_LIST::UNCONNECTED = 0; diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index 21cca65517..89c52bb9f9 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -690,7 +690,7 @@ void TRACK::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, if( aDC->LogicalToDeviceXRel( m_Width ) < MIN_TEXT_SIZE ) return; - if( GetNet() == 0 ) + if( GetNet() == NETINFO_LIST::UNCONNECTED ) return; NETINFO_ITEM* net = ( (BOARD*) GetParent() )->FindNet( GetNet() ); @@ -952,7 +952,7 @@ void SEGVIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, } // Display the short netname: - if( GetNet() == 0 ) + if( GetNet() == NETINFO_LIST::UNCONNECTED ) return; if( DisplayOpt.DisplayNetNamesMode == 0 || DisplayOpt.DisplayNetNamesMode == 1 ) diff --git a/pcbnew/connect.cpp b/pcbnew/connect.cpp index aa8d4867e6..1833bd0d65 100644 --- a/pcbnew/connect.cpp +++ b/pcbnew/connect.cpp @@ -842,7 +842,7 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode() curr_track->end = NULL; curr_track->SetState( BUSY | IN_EDIT | BEGIN_ONPAD | END_ONPAD, false ); curr_track->SetZoneSubNet( 0 ); - curr_track->SetNet( 0 ); // net code = 0 means not connected + curr_track->SetNet( NETINFO_LIST::UNCONNECTED ); } // If no pad, reset pointers and netcode, and do nothing else diff --git a/pcbnew/eagle_plugin.cpp b/pcbnew/eagle_plugin.cpp index 14405e9753..cc60db125f 100644 --- a/pcbnew/eagle_plugin.cpp +++ b/pcbnew/eagle_plugin.cpp @@ -1493,7 +1493,7 @@ void EAGLE_PLUGIN::loadPlain( CPTREE& aGraphics ) zone->SetTimeStamp( timeStamp( gr->second ) ); zone->SetLayer( layer ); - zone->SetNet( 0 ); + zone->SetNet( NETINFO_LIST::UNCONNECTED ); CPolyLine::HATCH_STYLE outline_hatch = CPolyLine::DIAGONAL_EDGE; @@ -2550,7 +2550,7 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals ) // KiCad does not support an unconnected zone with its own non-zero netcode, // but only when assigned netcode = 0 w/o a name... for( ZONES::iterator it = zones.begin(); it != zones.end(); ++it ) - (*it)->SetNet( 0 ); + (*it)->SetNet( NETINFO_LIST::UNCONNECTED ); // therefore omit this signal/net. } diff --git a/pcbnew/legacy_plugin.cpp b/pcbnew/legacy_plugin.cpp index ade83543f1..8b09403302 100644 --- a/pcbnew/legacy_plugin.cpp +++ b/pcbnew/legacy_plugin.cpp @@ -2421,7 +2421,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER() // Ensure keepout does not have a net // (which have no sense for a keepout zone) if( zc->GetIsKeepout() ) - zc->SetNet( 0 ); + zc->SetNet( NETINFO_LIST::UNCONNECTED ); // should always occur, but who knows, a zone without two corners // is no zone at all, it's a spot? @@ -2431,7 +2431,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER() if( !zc->IsOnCopperLayer() ) { zc->SetFillMode( 0 ); - zc->SetNet( 0 ); + zc->SetNet( NETINFO_LIST::UNCONNECTED ); } // Hatch here, after outlines corners are read diff --git a/pcbnew/pad_edition_functions.cpp b/pcbnew/pad_edition_functions.cpp index 839d1f39fc..e73e8d829a 100644 --- a/pcbnew/pad_edition_functions.cpp +++ b/pcbnew/pad_edition_functions.cpp @@ -141,7 +141,7 @@ void PCB_BASE_FRAME::AddPad( MODULE* aModule, bool draw ) // Update the pad properties. Import_Pad_Settings( pad, false ); - pad->SetNet( 0 ); + pad->SetNet( NETINFO_LIST::UNCONNECTED ); pad->SetPosition( GetCrossHairPosition() ); diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index 0fd7f55b64..b05ce179f2 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -2687,7 +2687,7 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR ) if( !zone->IsOnCopperLayer() ) { zone->SetFillMode( 0 ); - zone->SetNet( 0 ); + zone->SetNet( NETINFO_LIST::UNCONNECTED ); } // Set hatch here, after outlines corners are read @@ -2699,7 +2699,7 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR ) // Ensure keepout does not have a net (which have no sense for a keepout zone) if( zone->GetIsKeepout() ) - zone->SetNet( 0 ); + zone->SetNet( NETINFO_LIST::UNCONNECTED ); return zone.release(); } diff --git a/pcbnew/ratsnest.cpp b/pcbnew/ratsnest.cpp index b5347d3e85..32dba7213d 100644 --- a/pcbnew/ratsnest.cpp +++ b/pcbnew/ratsnest.cpp @@ -540,7 +540,7 @@ void PCB_BASE_FRAME::build_ratsnest_module( MODULE* aModule ) // collect active pads of the module: for( pad_ref = aModule->Pads(); pad_ref != NULL; pad_ref = pad_ref->Next() ) { - if( pad_ref->GetNet() == 0 ) + if( pad_ref->GetNet() == NETINFO_LIST::UNCONNECTED ) continue; localPadList.push_back( pad_ref ); diff --git a/pcbnew/xchgmod.cpp b/pcbnew/xchgmod.cpp index e983a0d6ee..af46b91592 100644 --- a/pcbnew/xchgmod.cpp +++ b/pcbnew/xchgmod.cpp @@ -455,7 +455,7 @@ void PCB_EDIT_FRAME::Exchange_Module( MODULE* aOldModule, // Update pad netnames ( when possible) for( D_PAD* pad = aNewModule->Pads(); pad != NULL; pad = pad->Next() ) { - pad->SetNet( 0 ); + pad->SetNet( NETINFO_LIST::UNCONNECTED ); D_PAD* old_pad = aOldModule->Pads(); for( ; old_pad != NULL; old_pad = old_pad->Next() ) diff --git a/pcbnew/zones_by_polygon.cpp b/pcbnew/zones_by_polygon.cpp index 977fef6e29..9eddd5f7bb 100644 --- a/pcbnew/zones_by_polygon.cpp +++ b/pcbnew/zones_by_polygon.cpp @@ -577,7 +577,7 @@ int PCB_EDIT_FRAME::Begin_Zone( wxDC* DC ) zoneInfo.SetIsKeepout( true ); // Netcode and netname are irrelevant, // so ensure they are cleared - zone->SetNet( 0 ); + zone->SetNet( NETINFO_LIST::UNCONNECTED ); edited = InvokeKeepoutAreaEditor( this, &zoneInfo ); } else From 41e43799246c75e6761ec3f64eef24eec1505ada Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 15 Jan 2014 18:03:06 +0100 Subject: [PATCH 44/95] BOARD_CONNECTED_ITEMs do not store net code anymore (m_NetCode field), instead net info is stored using a pointer to NETINFO_ITEM. GetNet() refers to the net code stored in the NETINFO_ITEM. SetNet() finds an appropriate NETINFO_ITEM and uses it. Removing GetNet() & SetNet() (and the whole net code idea) requires too many changes in the code (~250 references to the mentioned functions). BOARD_CONNECTED_ITEMs by default get a pointer to NETINFO_ITEM that stores unconnected items. This requires for all BOARD_CONNECTED_ITEMs to have a parent (so BOARD* is accessible). The only orphaned item is BOARD_DESIGN_SETTINGS::m_Pad_Master, but it does not cause any issues so far. Items that do not have access to a BOARD (do not have set parents) and therefore cannot get net assigned, by default get const static NETINFO_LIST::ORPHANED. Performed tests: - loaded .kicad_pcb, KiCad legacy board, Eagle 6.0 board, P-CAD board - all ok - load a simple project, reload netlist after changing connections in eeschema - ok - save & reload a board - ok, but still contain empty nets - remove everything, restore with undo - ok - remove everything, reload netlist - ok - changing net names (all possibilites: empty->existing, empty->not existing, existing->empty, existing->not existing) - all ok - zones: when net is changed to a net that does not have any nodes besides the zone itself, it does not get filled --- include/class_board_item.h | 3 +- pcbnew/class_board.cpp | 3 +- pcbnew/class_board_connected_item.cpp | 38 ++++++++++++++++++-------- pcbnew/class_board_connected_item.h | 26 ++++++++++-------- pcbnew/class_board_design_settings.cpp | 2 +- pcbnew/class_netinfo.h | 4 +++ pcbnew/class_netinfolist.cpp | 1 + pcbnew/class_zone.cpp | 1 - pcbnew/eagle_plugin.cpp | 5 ++-- pcbnew/pcb_parser.cpp | 6 ++-- pcbnew/pcb_parser.h | 2 +- 11 files changed, 57 insertions(+), 34 deletions(-) diff --git a/include/class_board_item.h b/include/class_board_item.h index 6f6bf201d6..b6e5e905a6 100644 --- a/include/class_board_item.h +++ b/include/class_board_item.h @@ -83,8 +83,7 @@ protected: public: BOARD_ITEM( BOARD_ITEM* aParent, KICAD_T idtype ) : - EDA_ITEM( aParent, idtype ) - , m_Layer( FIRST_LAYER ) + EDA_ITEM( aParent, idtype ), m_Layer( FIRST_LAYER ) { } diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 416044cc5d..691e379cc7 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -2571,7 +2571,8 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, if( netinfo == NULL ) { // It is a new net, we have to add it - netinfo = new NETINFO_ITEM( this, net.GetNetName(), m_NetInfo.GetNetCount() ); + netinfo = new NETINFO_ITEM( this, net.GetNetName(), + m_NetInfo.GetNetCount() ); m_NetInfo.AppendNet( netinfo ); } diff --git a/pcbnew/class_board_connected_item.cpp b/pcbnew/class_board_connected_item.cpp index cf44e1dc7a..69bcfacb7e 100644 --- a/pcbnew/class_board_connected_item.cpp +++ b/pcbnew/class_board_connected_item.cpp @@ -34,34 +34,50 @@ #include #include - BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( BOARD_ITEM* aParent, KICAD_T idtype ) : - BOARD_ITEM( aParent, idtype ), m_NetCode( 0 ), m_Subnet( 0 ), m_ZoneSubnet( 0 ) + BOARD_ITEM( aParent, idtype ), m_Subnet( 0 ), m_ZoneSubnet( 0 ), + m_netinfo( &NETINFO_LIST::ORPHANED ) { + // The unconnected is set only in case the item belongs to a BOARD + SetNet( NETINFO_LIST::UNCONNECTED ); } BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( const BOARD_CONNECTED_ITEM& aItem ) : - BOARD_ITEM( aItem ), m_NetCode( aItem.m_NetCode ), m_Subnet( aItem.m_Subnet ), - m_ZoneSubnet( aItem.m_ZoneSubnet ) + BOARD_ITEM( aItem ), m_Subnet( aItem.m_Subnet ), m_ZoneSubnet( aItem.m_ZoneSubnet ), + m_netinfo( aItem.m_netinfo ) { } +int BOARD_CONNECTED_ITEM::GetNet() const +{ + return m_netinfo->GetNet(); +} + + +void BOARD_CONNECTED_ITEM::SetNet( int aNetCode ) +{ + BOARD* board = GetBoard(); + if( board ) + { + m_netinfo = board->FindNet( aNetCode ); + + if( m_netinfo == NULL ) + m_netinfo = board->FindNet( NETINFO_LIST::UNCONNECTED ); + } +} + + const wxString& BOARD_CONNECTED_ITEM::GetNetname() const { - BOARD* board = GetBoard(); - NETINFO_ITEM* netinfo = board->FindNet( m_NetCode ); - - return netinfo->GetNetname(); + return m_netinfo->GetNetname(); } const wxString& BOARD_CONNECTED_ITEM::GetShortNetname() const { - NETINFO_ITEM* netinfo = GetBoard()->FindNet( m_NetCode ); - - return netinfo->GetShortNetname(); + return m_netinfo->GetShortNetname(); } diff --git a/pcbnew/class_board_connected_item.h b/pcbnew/class_board_connected_item.h index 9b2f5df7b8..b7a059c9f4 100644 --- a/pcbnew/class_board_connected_item.h +++ b/pcbnew/class_board_connected_item.h @@ -33,6 +33,7 @@ #include +class NETINFO_ITEM; class NETCLASS; class TRACK; class D_PAD; @@ -54,8 +55,6 @@ public: std::vector m_PadsConnected; // list of other pads connected to me private: - int m_NetCode; // Net number - int m_Subnet; /* In rastnest routines : for the current net, block number * (number common to the current connected items found) */ @@ -63,6 +62,9 @@ private: int m_ZoneSubnet; // used in rastnest computations : for the current net, // handle cluster number in zone connection + /// Stores all informations about the net that item belongs to + const NETINFO_ITEM* m_netinfo; + public: BOARD_CONNECTED_ITEM( BOARD_ITEM* aParent, KICAD_T idtype ); @@ -72,15 +74,15 @@ public: * Function GetNet * @return int - the net code. */ - int GetNet() const - { - return m_NetCode; - } + int GetNet() const; - virtual void SetNet( int aNetCode ) - { - m_NetCode = aNetCode; - } + /** + * Function SetNet + * sets net using a net code. + * @param aNetCode is a net code for the new net. It has to exist in NETINFO_LIST held by BOARD. + * Otherwise, item is assigned to the unconnected net. + */ + void SetNet( int aNetCode ); /** * Function GetSubNet @@ -112,13 +114,13 @@ public: /** * Function GetNetname - * @return const wxString& - the full netname + * @return wxString - the full netname */ const wxString& GetNetname() const; /** * Function GetShortNetname - * @return const wxString& - the short netname + * @return wxString - the short netname */ const wxString& GetShortNetname() const; diff --git a/pcbnew/class_board_design_settings.cpp b/pcbnew/class_board_design_settings.cpp index e98dc81ef1..a24e6bf94e 100644 --- a/pcbnew/class_board_design_settings.cpp +++ b/pcbnew/class_board_design_settings.cpp @@ -52,7 +52,7 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS() : - m_Pad_Master( 0 ) + m_Pad_Master( NULL ) { m_EnabledLayers = ALL_LAYERS; // All layers enabled at first. // SetCopperLayerCount() will adjust this. diff --git a/pcbnew/class_netinfo.h b/pcbnew/class_netinfo.h index 8ea47c3676..3e836d0b95 100644 --- a/pcbnew/class_netinfo.h +++ b/pcbnew/class_netinfo.h @@ -202,6 +202,10 @@ public: ///> Constant that holds the unconnected net number static const int UNCONNECTED; + ///> NETINFO_ITEM meaning that there was no net assigned for an item, as there was no + ///> board storing net list available. + static const NETINFO_ITEM ORPHANED; + #if defined(DEBUG) void Show() const; #endif diff --git a/pcbnew/class_netinfolist.cpp b/pcbnew/class_netinfolist.cpp index 590cd352ce..e2f16a014b 100644 --- a/pcbnew/class_netinfolist.cpp +++ b/pcbnew/class_netinfolist.cpp @@ -164,4 +164,5 @@ void NETINFO_LIST::buildPadsFullList() } +const NETINFO_ITEM NETINFO_LIST::ORPHANED = NETINFO_ITEM( NULL, wxString( "orphaned" ), -1 ); const int NETINFO_LIST::UNCONNECTED = 0; diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index 941f95f3b5..cf5ab48ff7 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -53,7 +53,6 @@ ZONE_CONTAINER::ZONE_CONTAINER( BOARD* aBoard ) : BOARD_CONNECTED_ITEM( aBoard, PCB_ZONE_AREA_T ) { - SetNet( -1 ); // Net number for fast comparisons m_CornerSelection = -1; m_IsFilled = false; // fill status : true when the zone is filled m_FillMode = 0; // How to fill areas: 0 = use filled polygons, != 0 fill with segments diff --git a/pcbnew/eagle_plugin.cpp b/pcbnew/eagle_plugin.cpp index cc60db125f..078600f081 100644 --- a/pcbnew/eagle_plugin.cpp +++ b/pcbnew/eagle_plugin.cpp @@ -1879,7 +1879,7 @@ void EAGLE_PLUGIN::orientModuleText( MODULE* m, const EELEMENT& e, MODULE* EAGLE_PLUGIN::makeModule( CPTREE& aPackage, const string& aPkgName ) const { - std::auto_ptr m( new MODULE( NULL ) ); + std::auto_ptr m( new MODULE( m_board ) ); m->SetFPID( FPID( aPkgName ) ); @@ -2351,6 +2351,7 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals ) const string& nname = net->second.get( ".name" ); wxString netName = FROM_UTF8( nname.c_str() ); + m_board->AppendNet( new NETINFO_ITEM( m_board, netName, netCode ) ); m_xpath->Value( nname.c_str() ); @@ -2555,7 +2556,7 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals ) // therefore omit this signal/net. } else - m_board->AppendNet( new NETINFO_ITEM( m_board, netName, netCode++ ) ); + netCode++; } m_xpath->pop(); // "signals.signal" diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index b05ce179f2..db9ed25acf 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -1731,7 +1731,7 @@ MODULE* PCB_PARSER::parseMODULE( wxArrayString* aInitialComments ) throw( IO_ERR case T_pad: { - D_PAD* pad = parseD_PAD(); + D_PAD* pad = parseD_PAD( module.get() ); wxPoint pt = pad->GetPos0(); RotatePoint( &pt, module->GetOrientation() ); pad->SetPosition( pt + module->GetPosition() ); @@ -2011,14 +2011,14 @@ EDGE_MODULE* PCB_PARSER::parseEDGE_MODULE() throw( IO_ERROR, PARSE_ERROR ) } -D_PAD* PCB_PARSER::parseD_PAD() throw( IO_ERROR, PARSE_ERROR ) +D_PAD* PCB_PARSER::parseD_PAD( MODULE* aParent ) throw( IO_ERROR, PARSE_ERROR ) { wxCHECK_MSG( CurTok() == T_pad, NULL, wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as D_PAD." ) ); wxSize sz; wxPoint pt; - std::auto_ptr< D_PAD > pad( new D_PAD( NULL ) ); + std::auto_ptr< D_PAD > pad( new D_PAD( aParent ) ); NeedSYMBOLorNUMBER(); pad->SetPadName( FromUTF8() ); diff --git a/pcbnew/pcb_parser.h b/pcbnew/pcb_parser.h index 233acb1291..0dfb0bbdc5 100644 --- a/pcbnew/pcb_parser.h +++ b/pcbnew/pcb_parser.h @@ -99,7 +99,7 @@ class PCB_PARSER : public PCB_LEXER MODULE* parseMODULE( wxArrayString* aInitialComments = 0 ) throw( IO_ERROR, PARSE_ERROR ); TEXTE_MODULE* parseTEXTE_MODULE() throw( IO_ERROR, PARSE_ERROR ); EDGE_MODULE* parseEDGE_MODULE() throw( IO_ERROR, PARSE_ERROR ); - D_PAD* parseD_PAD() throw( IO_ERROR, PARSE_ERROR ); + D_PAD* parseD_PAD( MODULE* aParent = NULL ) throw( IO_ERROR, PARSE_ERROR ); TRACK* parseTRACK() throw( IO_ERROR, PARSE_ERROR ); SEGVIA* parseSEGVIA() throw( IO_ERROR, PARSE_ERROR ); ZONE_CONTAINER* parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR ); From babd441b7e3317262d7a6434ade536170adf5f14 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 16 Jan 2014 14:20:51 +0100 Subject: [PATCH 45/95] NETINFO_ITEMs are not stored in a vector anymore, instead they are held in a unordered_map. Now, the net codes may be not consecutive. There is another way for assigning net codes (using a static int that holds a possible empty net code and a function that makes sure it is not used [getFreeNetCode()]). Removed some unused fields (NETINFO_ITEM::m_NbNodes, m_NbLink, m_NbNoconn, m_Flag). --- pcbnew/class_board.cpp | 3 +- pcbnew/class_netinfo.h | 46 ++++++++++++++----------- pcbnew/class_netinfo_item.cpp | 4 --- pcbnew/class_netinfolist.cpp | 34 +++++++++++++----- pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp | 2 +- 5 files changed, 53 insertions(+), 36 deletions(-) diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 691e379cc7..acde874db3 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -2571,8 +2571,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, if( netinfo == NULL ) { // It is a new net, we have to add it - netinfo = new NETINFO_ITEM( this, net.GetNetName(), - m_NetInfo.GetNetCount() ); + netinfo = new NETINFO_ITEM( this, net.GetNetName() ); m_NetInfo.AppendNet( netinfo ); } diff --git a/pcbnew/class_netinfo.h b/pcbnew/class_netinfo.h index 3e836d0b95..34f38188ae 100644 --- a/pcbnew/class_netinfo.h +++ b/pcbnew/class_netinfo.h @@ -34,7 +34,6 @@ #define __CLASSES_NETINFO__ -#include #include #include #include @@ -132,14 +131,16 @@ public: /** * Function GetItem - * @param aNetcode = netcode to identify a given NETINFO_ITEM - * @return NETINFO_ITEM* - by \a aNetcode, or NULL if not found + * @param aNetCode = netcode to identify a given NETINFO_ITEM + * @return NETINFO_ITEM* - by \a aNetCode, or NULL if not found */ - NETINFO_ITEM* GetNetItem( int aNetcode ) const + NETINFO_ITEM* GetNetItem( int aNetCode ) const { - if( unsigned( aNetcode ) >= GetNetCount() ) // catches < 0 too - return NULL; - return m_NetBuffer[aNetcode]; + NETCODES_MAP::const_iterator result = m_netCodes.find( aNetCode ); + if( result != m_netCodes.end() ) + return (*result).second; + + return NULL; } /** @@ -161,7 +162,7 @@ public: * @return the number of nets ( always >= 1 ) * because the first net is the "not connected" net and always exists */ - unsigned GetNetCount() const { return m_NetBuffer.size(); } + unsigned GetNetCount() const { return m_netNames.size(); } /** * Function Append @@ -211,9 +212,9 @@ public: #endif typedef boost::unordered_map NETNAMES_MAP; + typedef boost::unordered_map NETCODES_MAP; private: - /** * Function DeleteData * deletes the list of nets (and free memory) @@ -237,9 +238,20 @@ private: */ void buildPadsFullList(); + /** + * Function getFreeNetCode + * returns the first available net code that is not used by any other net. + */ + int getFreeNetCode() const; + BOARD* m_Parent; + NETNAMES_MAP m_netNames; ///< map for a fast look up by net names - std::vector m_NetBuffer; ///< net list (name, design constraints ..) + NETCODES_MAP m_netCodes; ///< map for a fast look up by net codes + + static int m_newNetCode; ///< number that has a *high* chance to be unused + ///< (to be sure, it is advised to use + ///< getFreeNetCode() function) std::vector m_PadsFullList; ///< contains all pads, sorted by pad's netname. ///< can be used in ratsnest calculations. @@ -252,6 +264,8 @@ private: */ class NETINFO_ITEM { + friend class NETINFO_LIST; + private: const int m_NetCode; ///< A number equivalent to the net name. ///< Used for fast comparisons in ratsnest and DRC computations. @@ -271,12 +285,6 @@ private: BOARD_ITEM* m_parent; ///< The parent board item object the net belongs to. public: - int m_NbNodes; // Pads count for this net - int m_NbLink; // Ratsnets count for this net - int m_NbNoconn; // Ratsnets remaining to route count - int m_Flag; // used in some calculations. Had no - // special meaning - std::vector m_PadInNetList; // List of pads connected to this net unsigned m_RatsnestStartIdx; /* Starting point of ratsnests of this @@ -287,7 +295,7 @@ public: unsigned m_RatsnestEndIdx; // Ending point of ratsnests of this net // (excluded) in this buffer - NETINFO_ITEM( BOARD_ITEM* aParent, const wxString& aNetName = wxEmptyString, int aNetCode = 0 ); + NETINFO_ITEM( BOARD_ITEM* aParent, const wxString& aNetName = wxEmptyString, int aNetCode = -1 ); ~NETINFO_ITEM(); /** @@ -446,10 +454,6 @@ public: { m_PadInNetList.clear(); - m_NbNodes = 0; - m_NbLink = 0; - m_NbNoconn = 0; - m_Flag = 0; m_RatsnestStartIdx = 0; // Starting point of ratsnests of this net in a // general buffer of ratsnest m_RatsnestEndIdx = 0; // Ending point of ratsnests of this net diff --git a/pcbnew/class_netinfo_item.cpp b/pcbnew/class_netinfo_item.cpp index 05bcabb1bc..1ca37ec3a1 100644 --- a/pcbnew/class_netinfo_item.cpp +++ b/pcbnew/class_netinfo_item.cpp @@ -53,10 +53,6 @@ NETINFO_ITEM::NETINFO_ITEM( BOARD_ITEM* aParent, const wxString& aNetName, int a m_NetCode( aNetCode ), m_Netname( aNetName ), m_ShortNetname( m_Netname.AfterLast( '/' ) ) { m_parent = aParent; - m_NbNodes = 0; - m_NbLink = 0; - m_NbNoconn = 0; - m_Flag = 0; m_RatsnestStartIdx = 0; // Starting point of ratsnests of this net in a // general buffer of ratsnest m_RatsnestEndIdx = 0; // Ending point of ratsnests of this net diff --git a/pcbnew/class_netinfolist.cpp b/pcbnew/class_netinfolist.cpp index e2f16a014b..4c5221f372 100644 --- a/pcbnew/class_netinfolist.cpp +++ b/pcbnew/class_netinfolist.cpp @@ -30,25 +30,29 @@ NETINFO_LIST::~NETINFO_LIST() void NETINFO_LIST::clear() { - for( unsigned ii = 0; ii < GetNetCount(); ii++ ) - delete m_NetBuffer[ii]; + NETNAMES_MAP::iterator it, itEnd; + for( it = m_netNames.begin(), itEnd = m_netNames.end(); it != itEnd; ++it ) + delete it->second; - m_NetBuffer.clear(); m_PadsFullList.clear(); m_netNames.clear(); + m_netCodes.clear(); } void NETINFO_LIST::AppendNet( NETINFO_ITEM* aNewElement ) { + // negative net code means that it has to be auto assigned + if( aNewElement->m_NetCode < 0 ) + const_cast( aNewElement->m_NetCode ) = getFreeNetCode(); + // net names & codes are supposed to be unique assert( GetNetItem( aNewElement->GetNetname() ) == NULL ); assert( GetNetItem( aNewElement->GetNet() ) == NULL ); - m_NetBuffer.push_back( aNewElement ); - // add an entry for fast look up by a net name using a map m_netNames.insert( std::make_pair( aNewElement->GetNetname(), aNewElement ) ); + m_netCodes.insert( std::make_pair( aNewElement->GetNet(), aNewElement ) ); } @@ -115,11 +119,13 @@ void NETINFO_LIST::buildListOfNets() #if defined(DEBUG) void NETINFO_LIST::Show() const { - for( unsigned i=0; i < m_NetBuffer.size(); ++i ) + int i = 0; + NETNAMES_MAP::const_iterator it, itEnd; + for( it = m_netNames.begin(), itEnd = m_netNames.end(); it != itEnd; ++it ) { printf( "[%d]: netcode:%d netname:<%s>\n", - i, m_NetBuffer[i]->GetNet(), - TO_UTF8( m_NetBuffer[i]->GetNetname() ) ); + i++, it->second->GetNet(), + TO_UTF8( it->second->GetNetname() ) ); } } #endif @@ -164,5 +170,17 @@ void NETINFO_LIST::buildPadsFullList() } +int NETINFO_LIST::getFreeNetCode() const +{ + do { + if( m_newNetCode < 0 ) + m_newNetCode = 0; + } while( m_netCodes.count( ++NETINFO_LIST::m_newNetCode ) != 0 ); + + return m_newNetCode; +} + + const NETINFO_ITEM NETINFO_LIST::ORPHANED = NETINFO_ITEM( NULL, wxString( "orphaned" ), -1 ); const int NETINFO_LIST::UNCONNECTED = 0; +int NETINFO_LIST::m_newNetCode = 0; diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp index c3cd2e34af..c5c05d849b 100644 --- a/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp +++ b/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp @@ -278,7 +278,7 @@ void PCB_PAD::AddToModule( MODULE* aModule, int aRotation, bool aEncapsulatedPad if( netinfo == NULL ) // I believe this should not happen, but just in case { // It is a new net - netinfo = new NETINFO_ITEM( m_board, m_net, m_board->GetNetCount() ); + netinfo = new NETINFO_ITEM( m_board, m_net ); m_board->AppendNet( netinfo ); } From 17027286bd8f3d395819a4b0caf1453331624f05 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 16 Jan 2014 14:36:09 +0100 Subject: [PATCH 46/95] wxWidgets 2.8 fix --- pcbnew/class_netinfolist.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcbnew/class_netinfolist.cpp b/pcbnew/class_netinfolist.cpp index 4c5221f372..556ed1d3d7 100644 --- a/pcbnew/class_netinfolist.cpp +++ b/pcbnew/class_netinfolist.cpp @@ -181,6 +181,6 @@ int NETINFO_LIST::getFreeNetCode() const } -const NETINFO_ITEM NETINFO_LIST::ORPHANED = NETINFO_ITEM( NULL, wxString( "orphaned" ), -1 ); +const NETINFO_ITEM NETINFO_LIST::ORPHANED = NETINFO_ITEM( NULL, wxString::FromUTF8( "orphaned" ), -1 ); const int NETINFO_LIST::UNCONNECTED = 0; int NETINFO_LIST::m_newNetCode = 0; From d8ee9b8bca64b8c3e0cb04503aba18767178f167 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 16 Jan 2014 16:47:31 +0100 Subject: [PATCH 47/95] Added iterators for NETINFO_LIST (as net codes for existing net codes may be not consecutive). --- pcbnew/class_board.cpp | 7 +++-- pcbnew/class_board.h | 18 +++++++++++ pcbnew/class_netclass.cpp | 38 ++++++++++++----------- pcbnew/class_netinfo.h | 60 ++++++++++++++++++++++++++++++++++++ pcbnew/class_netinfolist.cpp | 4 +-- pcbnew/kicad_plugin.cpp | 17 ++++++---- 6 files changed, 115 insertions(+), 29 deletions(-) diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index acde874db3..5c435f634a 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -1440,10 +1440,11 @@ int BOARD::ReturnSortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCoun netBuffer.reserve( m_NetInfo.GetNetCount() ); - for( unsigned ii = 1; ii < m_NetInfo.GetNetCount(); ii++ ) + for( NETINFO_LIST::iterator net( m_NetInfo.begin() ), netEnd( m_NetInfo.end() ); + net != netEnd; ++net ) { - if( m_NetInfo.GetNetItem( ii )->GetNet() > 0 ) - netBuffer.push_back( m_NetInfo.GetNetItem( ii ) ); + if( net->GetNet() > 0 ) + netBuffer.push_back( *net ); } // sort the list diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h index cd20413baa..c32d1d90e7 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -845,6 +845,24 @@ public: m_NetInfo.AppendNet( aNewNet ); } + /** + * Function BeginNets + * @return iterator to the first element of the NETINFO_ITEMs list + */ + NETINFO_LIST::iterator BeginNets() const + { + return m_NetInfo.begin(); + } + + /** + * Function EndNets + * @return iterator to the last element of the NETINFO_ITEMs list + */ + NETINFO_LIST::iterator EndNets() const + { + return m_NetInfo.end(); + } + /** * Function GetNetCount * @return the number of nets (NETINFO_ITEM) diff --git a/pcbnew/class_netclass.cpp b/pcbnew/class_netclass.cpp index f945963a95..655595a41d 100644 --- a/pcbnew/class_netclass.cpp +++ b/pcbnew/class_netclass.cpp @@ -203,12 +203,10 @@ void BOARD::SynchronizeNetsAndNetClasses() // set all NETs to the default NETCLASS, then later override some // as we go through the NETCLASSes. - int count = m_NetInfo.GetNetCount(); - for( int i=0; iSetClass( m_NetClasses.GetDefault() ); + net->SetClass( m_NetClasses.GetDefault() ); } // Add netclass name and pointer to nets. If a net is in more than one netclass, @@ -248,21 +246,18 @@ void BOARD::SynchronizeNetsAndNetClasses() m_NetClasses.GetDefault()->Clear(); - for( int i=0; iGetClassName(); + const wxString& classname = net->GetClassName(); - // because of the std:map<> this should be fast, and because of - // prior logic, netclass should not be NULL. - NETCLASS* netclass = m_NetClasses.Find( classname ); + // because of the std:map<> this should be fast, and because of + // prior logic, netclass should not be NULL. + NETCLASS* netclass = m_NetClasses.Find( classname ); - wxASSERT( netclass ); + wxASSERT( netclass ); - netclass->Add( net->GetNetname() ); - } + netclass->Add( net->GetNetname() ); } // D(printf("stop\n");) @@ -337,8 +332,15 @@ void NETCLASS::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControl aFormatter->Print( aNestLevel+1, "(uvia_dia %s)\n", FMT_IU( GetuViaDiameter() ).c_str() ); aFormatter->Print( aNestLevel+1, "(uvia_drill %s)\n", FMT_IU( GetuViaDrill() ).c_str() ); - for( NETCLASS::const_iterator it = begin(); it!= end(); ++it ) - aFormatter->Print( aNestLevel+1, "(add_net %s)\n", aFormatter->Quotew( *it ).c_str() ); + for( NETCLASS::const_iterator it = begin(); it != end(); ++it ) + { + NETINFO_ITEM* netinfo = m_Parent->FindNet( *it ); + + if( netinfo && netinfo->GetNodesCount() > 0 ) + { + aFormatter->Print( aNestLevel+1, "(add_net %s)\n", aFormatter->Quotew( *it ).c_str() ); + } + } aFormatter->Print( aNestLevel, ")\n\n" ); } diff --git a/pcbnew/class_netinfo.h b/pcbnew/class_netinfo.h index 34f38188ae..326a0fa3b4 100644 --- a/pcbnew/class_netinfo.h +++ b/pcbnew/class_netinfo.h @@ -214,6 +214,66 @@ public: typedef boost::unordered_map NETNAMES_MAP; typedef boost::unordered_map NETCODES_MAP; + ///> Wrapper class, so you can iterate through NETINFO_ITEM*s, not + ///> std::pair + class iterator + { + public: + iterator( NETNAMES_MAP::const_iterator aIter ) : m_iterator( aIter ) + { + } + + /// pre-increment operator + const iterator& operator++() + { + ++m_iterator; + + return *this; + } + + /// post-increment operator + iterator operator++( int ) + { + iterator ret = *this; + ++m_iterator; + + return ret; + } + + NETINFO_ITEM* operator*() const + { + return m_iterator->second; + } + + NETINFO_ITEM* operator->() const + { + return m_iterator->second; + } + + bool operator!=( const iterator& aOther ) const + { + return m_iterator != aOther.m_iterator; + } + + bool operator==( const iterator& aOther ) const + { + return m_iterator == aOther.m_iterator; + } + + private: + NETNAMES_MAP::const_iterator m_iterator; + }; + + iterator begin() const + { + return iterator( m_netNames.begin() ); + } + + iterator end() const + { + return iterator( m_netNames.end() ); + } + private: /** * Function DeleteData diff --git a/pcbnew/class_netinfolist.cpp b/pcbnew/class_netinfolist.cpp index 556ed1d3d7..e57bbfed8b 100644 --- a/pcbnew/class_netinfolist.cpp +++ b/pcbnew/class_netinfolist.cpp @@ -90,8 +90,8 @@ void NETINFO_LIST::buildListOfNets() buildPadsFullList(); // Restore the initial state of NETINFO_ITEMs - for( unsigned i = 0; i < GetNetCount(); ++i ) - GetNetItem( i )->Clear(); + for( NETINFO_LIST::iterator net( begin() ), netEnd( end() ); net != netEnd; ++net ) + net->Clear(); // Assign pads to appropriate NETINFO_ITEMs for( unsigned ii = 0; ii < m_PadsFullList.size(); ii++ ) diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index ed6d7c062e..3cda985754 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -654,14 +654,19 @@ void PCB_IO::format( BOARD* aBoard, int aNestLevel ) const m_out->Print( aNestLevel, ")\n\n" ); - int netcount = aBoard->GetNetCount(); + // Unconditionally save the unconnected net + m_out->Print( aNestLevel, "(net 0 \"\")\n" ); - for( int i = 0; i < netcount; ++i ) + // and now the rest of nets + for( NETINFO_LIST::iterator net( aBoard->BeginNet() ), netEnd( aBoard->EndNet() ); + net != netEnd; ++net ) { - NETINFO_ITEM* net = aBoard->FindNet( i ); - m_out->Print( aNestLevel, "(net %d %s)\n", - net->GetNet(), - m_out->Quotew( net->GetNetname() ).c_str() ); + if( net->GetNodesCount() > 0 ) // save only not empty nets + { + m_out->Print( aNestLevel, "(net %d %s)\n", + net->GetNet(), + m_out->Quotew( net->GetNetname() ).c_str() ); + } } m_out->Print( 0, "\n" ); From 04ff538d119116d9d13db6ea42d96ee6670da51a Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 27 Jan 2014 11:42:47 +0100 Subject: [PATCH 48/95] Thread-safe version of Delaunay triangulation. --- common/geometry/hetriang.cpp | 72 ++++++-- include/ttl/halfedge/hetraits.h | 124 ------------- include/ttl/halfedge/hetriang.h | 78 +++++++-- include/ttl/ttl.h | 297 +++++++++++++++++--------------- include/ttl/ttl_constr.h | 65 +++---- pcbnew/ratsnest_data.cpp | 2 +- 6 files changed, 317 insertions(+), 321 deletions(-) diff --git a/common/geometry/hetriang.cpp b/common/geometry/hetriang.cpp index c1523ac347..175e80dbd5 100644 --- a/common/geometry/hetriang.cpp +++ b/common/geometry/hetriang.cpp @@ -51,8 +51,6 @@ using namespace hed; using namespace std; -Triangulation* TTLtraits::triang_ = NULL; - #ifdef TTL_USE_NODE_ID int Node::id_count = 0; #endif @@ -164,11 +162,30 @@ EdgePtr Triangulation::initTwoEnclosingTriangles(NodesContainer::iterator first, } +//-------------------------------------------------------------------------------------------------- +Triangulation::Triangulation() { + helper = new ttl::TriangulationHelper( *this ); +} + + +//-------------------------------------------------------------------------------------------------- +Triangulation::Triangulation(const Triangulation& tr) { + std::cout << "Triangulation: Copy constructor not present - EXIT."; + exit(-1); +} + + +//-------------------------------------------------------------------------------------------------- +Triangulation::~Triangulation() { + cleanAll(); + delete helper; +} + + //-------------------------------------------------------------------------------------------------- void Triangulation::createDelaunay(NodesContainer::iterator first, NodesContainer::iterator last) { - - TTLtraits::triang_ = this; + cleanAll(); EdgePtr bedge = initTwoEnclosingTriangles(first, last); @@ -178,7 +195,7 @@ void Triangulation::createDelaunay(NodesContainer::iterator first, NodesContainer::iterator it; for (it = first; it != last; ++it) { - ttl::insertNode(d_iter, *it); + helper->insertNode(d_iter, *it); } // In general (e.g. for the triangle based data structure), the initial dart @@ -189,7 +206,7 @@ void Triangulation::createDelaunay(NodesContainer::iterator first, // triangle "outside" the triangulation.) // Assumes rectangular domain - ttl::removeRectangularBoundary(dc); + helper->removeRectangularBoundary(dc); } @@ -269,7 +286,7 @@ cout << "Iterate boundary 2" << endl; Dart dart_iter = dart; do { - if (ttl::isBoundaryEdge(dart_iter)) + if (helper->isBoundaryEdge(dart_iter)) dart_iter.alpha0().alpha1(); else dart_iter.alpha2().alpha1(); @@ -322,6 +339,31 @@ void Triangulation::cleanAll() { } +//-------------------------------------------------------------------------------------------------- +void Triangulation::swapEdge(Dart& dart) { + if (!dart.getEdge()->isConstrained()) swapEdge(dart.getEdge()); +} + + +//-------------------------------------------------------------------------------------------------- +void Triangulation::splitTriangle(Dart& dart, NodePtr point) { + EdgePtr edge = splitTriangle(dart.getEdge(), point); + dart.init(edge); +} + + +//-------------------------------------------------------------------------------------------------- +void Triangulation::reverse_splitTriangle(Dart& dart) { + reverse_splitTriangle(dart.getEdge()); +} + + +//-------------------------------------------------------------------------------------------------- +void Triangulation::removeBoundaryTriangle(Dart& d) { + removeTriangle(d.getEdge()); +} + + #ifdef TTL_USE_NODE_FLAG //-------------------------------------------------------------------------------------------------- // This is a "template" for accessing all nodes (but multiple tests) @@ -486,7 +528,7 @@ void Triangulation::swapEdge(EdgePtr& diagonal) { // Note that diagonal is both input and output and it is always // kept in counterclockwise direction (this is not required by all - // finctions in ttl:: now) + // functions in TriangulationHelper now) // Swap by rotating counterclockwise // Use the same objects - no deletion or new objects @@ -567,7 +609,7 @@ bool Triangulation::checkDelaunay() const { // only one of the half-edges if (!twinedge || (size_t)edge.get() > (size_t)twinedge.get()) { Dart dart(edge); - if (ttl::swapTestDelaunay(dart)) { + if (helper->swapTestDelaunay(dart)) { noNotDelaunay++; //printEdge(dart,os); os << "\n"; @@ -610,7 +652,7 @@ void Triangulation::optimizeDelaunay() { Dart dart(edge); // Constrained edges should not be swapped - if (!edge->isConstrained() && ttl::swapTestDelaunay(dart, cycling_check)) { + if (!edge->isConstrained() && helper->swapTestDelaunay(dart, cycling_check)) { optimal = false; swapEdge(edge); } @@ -632,7 +674,7 @@ EdgePtr Triangulation::getInteriorNode() const { for (int i = 0; i < 3; ++i) { if (edge->getTwinEdge()) { - if (!ttl::isBoundaryNode(Dart(edge))) + if (!helper->isBoundaryNode(Dart(edge))) return edge; } edge = edge->getNextEdgeInFace(); @@ -643,18 +685,18 @@ EdgePtr Triangulation::getInteriorNode() const { //-------------------------------------------------------------------------------------------------- -static EdgePtr getBoundaryEdgeInTriangle(const EdgePtr& e) { +EdgePtr Triangulation::getBoundaryEdgeInTriangle(const EdgePtr& e) const { EdgePtr edge = e; - if (ttl::isBoundaryEdge(Dart(edge))) + if (helper->isBoundaryEdge(Dart(edge))) return edge; edge = edge->getNextEdgeInFace(); - if (ttl::isBoundaryEdge(Dart(edge))) + if (helper->isBoundaryEdge(Dart(edge))) return edge; edge = edge->getNextEdgeInFace(); - if (ttl::isBoundaryEdge(Dart(edge))) + if (helper->isBoundaryEdge(Dart(edge))) return edge; return EdgePtr(); diff --git a/include/ttl/halfedge/hetraits.h b/include/ttl/halfedge/hetraits.h index e25e993e0e..e24cd0697d 100644 --- a/include/ttl/halfedge/hetraits.h +++ b/include/ttl/halfedge/hetraits.h @@ -69,9 +69,6 @@ namespace hed { struct TTLtraits { - // The actual triangulation object - static Triangulation* triang_; - /** The floating point type used in calculations * involving scalar products and cross products. */ @@ -172,127 +169,6 @@ namespace hed { } //@} // End of Geometric Predicates Group - - - // A rationale for directing these functions to traits is: - // e.g., constraints - - //---------------------------------------------------------------------------------------------- - /* Checks if the edge associated with \e dart should be swapped - * according to the Delaunay criterion.
- * - * \note - * This function is also present in the TTL as ttl::swapTestDelaunay.
- * Thus, the function can be implemented simply as: - * \code - * { return ttl::swapTestDelaunay(dart); } - * \endcode - */ - //static bool swapTestDelaunay(const Dart& dart) { - // return ttl::swapTestDelaunay(dart); - //} - - - //---------------------------------------------------------------------------------------------- - /* Checks if the edge associated with \e dart can be swapped, i.e., - * if the edge is a diagonal in a (strictly) convex quadrilateral. - * This function is also present as ttl::swappableEdge. - */ - //static bool swappableEdge(const Dart& dart) { - // return ttl::swappableEdge(dart); - //} - - - //---------------------------------------------------------------------------------------------- - /* Checks if the edge associated with \e dart should be \e fixed, meaning - * that it should never be swapped. ??? Use when constraints. - */ - //static bool fixedEdge(const Dart& dart) { - // return dart.getEdge()->isConstrained(); - //} - - - //---------------------------------------------------------------------------------------------- - // ----------------------- Functions for Delaunay Triangulation Group ------------------------- - //---------------------------------------------------------------------------------------------- - - /** @name Functions for Delaunay Triangulation */ - //@{ - - //---------------------------------------------------------------------------------------------- - /** Swaps the edge associated with \e dart in the actual data structure. - * - *
- * \image html swapEdge.gif - *
- * - * \param dart - * Some of the functions require a dart as output. - * If this is required by the actual function, the dart should be delivered - * back in a position as seen if it was glued to the edge when swapping (rotating) - * the edge CCW; see the figure. - * - * \note - * - If the edge is \e constrained, or if it should not be swapped for - * some other reason, this function need not do the actual swap of the edge. - * - Some functions in TTL require that \c swapEdge is implemented such that - * darts outside the quadrilateral are not affected by the swap. - */ - static void swapEdge(Dart& dart) { - if (!dart.getEdge()->isConstrained()) triang_->swapEdge(dart.getEdge()); - } - - - //---------------------------------------------------------------------------------------------- - /** Splits the triangle associated with \e dart in the actual data structure into - * three new triangles joining at \e point. - * - *
- * \image html splitTriangle.gif - *
- * - * \param dart - * Output: A CCW dart incident with the new node; see the figure. - */ - static void splitTriangle(Dart& dart, NodePtr point) { - EdgePtr edge = triang_->splitTriangle(dart.getEdge(), point); - dart.init(edge); - } - - //@} // End of Functions for Delaunay Triangulation group - - - //---------------------------------------------------------------------------------------------- - // --------------------------- Functions for removing nodes Group ----------------------------- - //---------------------------------------------------------------------------------------------- - - /** @name Functions for removing nodes */ - //@{ - - //---------------------------------------------------------------------------------------------- - /** The reverse operation of TTLtraits::splitTriangle. - * This function is only required for functions that involve - * removal of interior nodes; see for example ttl::removeInteriorNode. - * - *
- * \image html reverse_splitTriangle.gif - *
- */ - static void reverse_splitTriangle(Dart& dart) { - triang_->reverse_splitTriangle(dart.getEdge()); - } - - - //---------------------------------------------------------------------------------------------- - /** Removes a triangle with an edge at the boundary of the triangulation - * in the actual data structure - */ - static void removeBoundaryTriangle(Dart& d) { - triang_->removeTriangle(d.getEdge()); - } - - //@} // End of Functions for removing nodes Group - }; }; // End of hed namespace diff --git a/include/ttl/halfedge/hetriang.h b/include/ttl/halfedge/hetriang.h index ccee31bc0c..c8326a417d 100644 --- a/include/ttl/halfedge/hetriang.h +++ b/include/ttl/halfedge/hetriang.h @@ -51,10 +51,13 @@ #include #include #include -#include #include #include +namespace ttl { + class TriangulationHelper; +}; + //-------------------------------------------------------------------------------------------------- // The half-edge data structure //-------------------------------------------------------------------------------------------------- @@ -242,26 +245,75 @@ public: class Triangulation { protected: - list leadingEdges_; // one half-edge for each arc + std::list leadingEdges_; // one half-edge for each arc + + ttl::TriangulationHelper* helper; + void addLeadingEdge(EdgePtr& edge) { edge->setAsLeadingEdge(); leadingEdges_.push_front( edge ); } + bool removeLeadingEdgeFromList(EdgePtr& leadingEdge); + void cleanAll(); + /** Swaps the edge associated with \e dart in the actual data structure. + * + *
+ * \image html swapEdge.gif + *
+ * + * \param dart + * Some of the functions require a dart as output. + * If this is required by the actual function, the dart should be delivered + * back in a position as seen if it was glued to the edge when swapping (rotating) + * the edge CCW; see the figure. + * + * \note + * - If the edge is \e constrained, or if it should not be swapped for + * some other reason, this function need not do the actual swap of the edge. + * - Some functions in TTL require that \c swapEdge is implemented such that + * darts outside the quadrilateral are not affected by the swap. + */ + void swapEdge(Dart& dart); + + /** Splits the triangle associated with \e dart in the actual data structure into + * three new triangles joining at \e point. + * + *
+ * \image html splitTriangle.gif + *
+ * + * \param dart + * Output: A CCW dart incident with the new node; see the figure. + */ + void splitTriangle(Dart& dart, NodePtr point); + + /** The reverse operation of TTLtraits::splitTriangle. + * This function is only required for functions that involve + * removal of interior nodes; see for example TrinagulationHelper::removeInteriorNode. + * + *
+ * \image html reverse_splitTriangle.gif + *
+ */ + void reverse_splitTriangle(Dart& dart); + + /** Removes a triangle with an edge at the boundary of the triangulation + * in the actual data structure + */ + void removeBoundaryTriangle(Dart& d); + public: /// Default constructor - Triangulation() {} + Triangulation(); /// Copy constructor - Triangulation(const Triangulation& tr) { - std::cout << "Triangulation: Copy constructor not present - EXIT."; - exit(-1); - } + Triangulation(const Triangulation& tr); /// Destructor - ~Triangulation() { cleanAll(); } + ~Triangulation(); /// Creates a Delaunay triangulation from a set of points void createDelaunay(NodesContainer::iterator first, @@ -295,20 +347,20 @@ public: Dart createDart(); /// Returns a list of "triangles" (one leading half-edge for each triangle) - const list& getLeadingEdges() const { return leadingEdges_; } + const std::list& getLeadingEdges() const { return leadingEdges_; } /// Returns the number of triangles int noTriangles() const { return (int)leadingEdges_.size(); } /// Returns a list of half-edges (one half-edge for each arc) - list* getEdges(bool skip_boundary_edges = false) const; + std::list* getEdges(bool skip_boundary_edges = false) const; #ifdef TTL_USE_NODE_FLAG /// Sets flag in all the nodes void flagNodes(bool flag) const; /// Returns a list of nodes. This function requires TTL_USE_NODE_FLAG to be defined. \see Node. - list* getNodes() const; + std::list* getNodes() const; #endif /// Swaps edges until the triangulation is Delaunay (constrained edges are not swapped) @@ -320,12 +372,16 @@ public: /// Returns an arbitrary interior node (as the source node of the returned edge) EdgePtr getInteriorNode() const; + EdgePtr getBoundaryEdgeInTriangle(const EdgePtr& e) const; + /// Returns an arbitrary boundary edge EdgePtr getBoundaryEdge() const; /// Print edges for plotting with, e.g., gnuplot void printEdges(std::ofstream& os) const; + friend class ttl::TriangulationHelper; + }; // End of class Triangulation diff --git a/include/ttl/ttl.h b/include/ttl/ttl.h index 003e0d81c6..7d7c655843 100644 --- a/include/ttl/ttl.h +++ b/include/ttl/ttl.h @@ -52,8 +52,6 @@ } #endif - using std::list; - // Next on TOPOLOGY: // - get triangle strips @@ -102,7 +100,7 @@ * - \e CW - clockwise * - \e 0_orbit, \e 1_orbit and \e 2_orbit: A sequence of darts around * a node, around an edge and in a triangle respectively; -* see ttl::get_0_orbit_interior and ttl::get_0_orbit_boundary +* see get_0_orbit_interior and get_0_orbit_boundary * - \e arc - In a triangulation an arc is equivalent with an edge * * \see @@ -115,15 +113,15 @@ namespace ttl { - +class TriangulationHelper +{ #ifndef DOXYGEN_SHOULD_SKIP_THIS - //------------------------------------------------------------------------------------------------ - // ----------------------------------- Forward declarations ------------------------------------- - //------------------------------------------------------------------------------------------------ -#if ((_MSC_VER > 0) && (_MSC_VER < 1300)) -#else - +public: + TriangulationHelper(hed::Triangulation& triang) : triangulation(triang) + { + } + // Delaunay Triangulation // ---------------------- template @@ -145,55 +143,55 @@ namespace ttl { // Topological and Geometric Queries // --------------------------------- template - bool locateFaceSimplest(const PointType& point, DartType& dart); + static bool locateFaceSimplest(const PointType& point, DartType& dart); template - bool locateTriangle(const PointType& point, DartType& dart); + static bool locateTriangle(const PointType& point, DartType& dart); template - bool inTriangleSimplest(const PointType& point, const DartType& dart); + static bool inTriangleSimplest(const PointType& point, const DartType& dart); template - bool inTriangle(const PointType& point, const DartType& dart); + static bool inTriangle(const PointType& point, const DartType& dart); template - void getBoundary(const DartType& dart, DartListType& boundary); + static void getBoundary(const DartType& dart, DartListType& boundary); template - bool isBoundaryEdge(const DartType& dart); + static bool isBoundaryEdge(const DartType& dart); template - bool isBoundaryFace(const DartType& dart); + static bool isBoundaryFace(const DartType& dart); template - bool isBoundaryNode(const DartType& dart); + static bool isBoundaryNode(const DartType& dart); template - int getDegreeOfNode(const DartType& dart); + static int getDegreeOfNode(const DartType& dart); template - void get_0_orbit_interior(const DartType& dart, DartListType& orbit); + static void get_0_orbit_interior(const DartType& dart, DartListType& orbit); template - void get_0_orbit_boundary(const DartType& dart, DartListType& orbit); + static void get_0_orbit_boundary(const DartType& dart, DartListType& orbit); template - bool same_0_orbit(const DartType& d1, const DartType& d2); + static bool same_0_orbit(const DartType& d1, const DartType& d2); template - bool same_1_orbit(const DartType& d1, const DartType& d2); + static bool same_1_orbit(const DartType& d1, const DartType& d2); template - bool same_2_orbit(const DartType& d1, const DartType& d2); + static bool same_2_orbit(const DartType& d1, const DartType& d2); template - bool swappableEdge(const DartType& dart, bool allowDegeneracy = false); + static bool swappableEdge(const DartType& dart, bool allowDegeneracy = false); template - void positionAtNextBoundaryEdge(DartType& dart); + static void positionAtNextBoundaryEdge(DartType& dart); template - bool convexBoundary(const DartType& dart); + static bool convexBoundary(const DartType& dart); // Utilities for Delaunay Triangulation @@ -205,7 +203,7 @@ namespace ttl { void optimizeDelaunay(DartListType& elist, const typename DartListType::iterator end); template - bool swapTestDelaunay(const DartType& dart, bool cycling_check = false); + bool swapTestDelaunay(const DartType& dart, bool cycling_check = false) const; template void recSwapDelaunay(DartType& diagonal); @@ -223,9 +221,29 @@ namespace ttl { // Constrained Triangulation // ------------------------- template - DartType insertConstraint(DartType& dstart, DartType& dend, bool optimize_delaunay); - -#endif + static DartType insertConstraint(DartType& dstart, DartType& dend, bool optimize_delaunay); + +private: + hed::Triangulation& triangulation; + + template + void insertNodes(ForwardIterator first, ForwardIterator last, DartType& dart); + + template + static bool isMemberOfFace(const TopologyElementType& topologyElement, const DartType& dart); + + template + static bool locateFaceWithNode(const NodeType& node, DartType& dart_iter); + + template + static void getAdjacentTriangles(const DartType& dart, DartType& t1, DartType& t2, DartType& t3); + + template + static void getNeighborNodes(const DartType& dart, std::list& node_list, bool& boundary); + + template + static bool degenerateTriangle(const DartType& dart); +}; #endif // DOXYGEN_SHOULD_SKIP_THIS @@ -245,7 +263,7 @@ namespace ttl { * can be created as two triangles forming a rectangle that contains * all the points. * After \c insertNode has been called repeatedly with all the points, - * ttl::removeRectangularBoundary can be called to remove triangles + * removeRectangularBoundary can be called to remove triangles * at the boundary of the triangulation so that the boundary * form the convex hull of the points. * @@ -268,19 +286,19 @@ namespace ttl { * - \ref hed::TTLtraits::splitTriangle "TraitsType::splitTriangle" (DartType&, const PointType&) * * \using - * - ttl::locateTriangle - * - ttl::recSwapDelaunay + * - locateTriangle + * - recSwapDelaunay * * \note * - For efficiency reasons \e dart should be close to the insertion \e point. * * \see - * ttl::removeRectangularBoundary + * removeRectangularBoundary */ template - bool insertNode(DartType& dart, PointType& point) { + bool TriangulationHelper::insertNode(DartType& dart, PointType& point) { - bool found = ttl::locateTriangle(point, dart); + bool found = locateTriangle(point, dart); if (!found) { #ifdef DEBUG_TTL cout << "ERROR: Triangulation::insertNode: NO triangle found. /n"; @@ -289,7 +307,7 @@ namespace ttl { } // ??? can we hide the dart? this is not possible if one triangle only - TraitsType::splitTriangle(dart, point); + triangulation.splitTriangle(dart, point); DartType d1 = dart; d1.alpha2().alpha1().alpha2().alpha0().alpha1(); @@ -304,14 +322,14 @@ namespace ttl { //DartType dsav = d3; d3.alpha0().alpha1(); - //if (!TraitsType::fixedEdge(d1) && !ttl::isBoundaryEdge(d1)) { - if (!ttl::isBoundaryEdge(d1)) { + //if (!TraitsType::fixedEdge(d1) && !isBoundaryEdge(d1)) { + if (!isBoundaryEdge(d1)) { d1.alpha2(); recSwapDelaunay(d1); } - //if (!TraitsType::fixedEdge(d2) && !ttl::isBoundaryEdge(d2)) { - if (!ttl::isBoundaryEdge(d2)) { + //if (!TraitsType::fixedEdge(d2) && !isBoundaryEdge(d2)) { + if (!isBoundaryEdge(d2)) { d2.alpha2(); recSwapDelaunay(d2); } @@ -319,8 +337,8 @@ namespace ttl { // Preserve the incoming dart as output incident to the node and CCW //d = dsav.alpha2(); dart.alpha2(); - //if (!TraitsType::fixedEdge(d3) && !ttl::isBoundaryEdge(d3)) { - if (!ttl::isBoundaryEdge(d3)) { + //if (!TraitsType::fixedEdge(d3) && !isBoundaryEdge(d3)) { + if (!isBoundaryEdge(d3)) { d3.alpha2(); recSwapDelaunay(d3); } @@ -332,7 +350,7 @@ namespace ttl { //------------------------------------------------------------------------------------------------ // Private/Hidden function (might change later) template - void insertNodes(ForwardIterator first, ForwardIterator last, DartType& dart) { + void TriangulationHelper::insertNodes(ForwardIterator first, ForwardIterator last, DartType& dart) { // Assumes that the dereferenced point objects are pointers. // References to the point objects are then passed to TTL. @@ -355,14 +373,14 @@ namespace ttl { * Output: A CCW dart at the new boundary * * \using - * - ttl::removeBoundaryNode + * - removeBoundaryNode * * \note * - This function requires that the boundary of the triangulation is * a rectangle with four nodes (one in each corner). */ template - void removeRectangularBoundary(DartType& dart) { + void TriangulationHelper::removeRectangularBoundary(DartType& dart) { DartType d_next = dart; DartType d_iter; @@ -370,8 +388,8 @@ namespace ttl { for (int i = 0; i < 4; i++) { d_iter = d_next; d_next.alpha0(); - ttl::positionAtNextBoundaryEdge(d_next); - ttl::removeBoundaryNode(d_iter); + positionAtNextBoundaryEdge(d_next); + removeBoundaryNode(d_iter); } dart = d_next; // Return a dart at the new boundary @@ -383,20 +401,20 @@ namespace ttl { * updates the triangulation to be Delaunay. * * \using - * - ttl::removeBoundaryNode if \e dart represents a node at the boundary - * - ttl::removeInteriorNode if \e dart represents an interior node + * - removeBoundaryNode if \e dart represents a node at the boundary + * - removeInteriorNode if \e dart represents an interior node * * \note * - The node cannot belong to a fixed (constrained) edge that is not * swappable. (An endless loop is likely to occur in this case). */ template - void removeNode(DartType& dart) { + void TriangulationHelper::removeNode(DartType& dart) { - if (ttl::isBoundaryNode(dart)) - ttl::removeBoundaryNode(dart); + if (isBoundaryNode(dart)) + removeBoundaryNode(dart); else - ttl::removeInteriorNode(dart); + removeInteriorNode(dart); } @@ -405,14 +423,14 @@ namespace ttl { * updates the triangulation to be Delaunay. * * \using - * - ttl::swapEdgesAwayFromBoundaryNode - * - ttl::optimizeDelaunay + * - swapEdgesAwayFromBoundaryNode + * - optimizeDelaunay * * \require * - \ref hed::TTLtraits::removeBoundaryTriangle "TraitsType::removeBoundaryTriangle" (Dart&) */ template - void removeBoundaryNode(DartType& dart) { + void TriangulationHelper::removeBoundaryNode(DartType& dart) { // ... and update Delaunay // - CCW dart must be given (for remove) @@ -420,13 +438,13 @@ namespace ttl { // we assume that there is not only one triangle left in the triangulation. // Position at boundary edge and CCW - if (!ttl::isBoundaryEdge(dart)) { + if (!isBoundaryEdge(dart)) { dart.alpha1(); // ensures that next function delivers back a CCW dart (if the given dart is CCW) - ttl::positionAtNextBoundaryEdge(dart); + positionAtNextBoundaryEdge(dart); } - list swapped_edges; - ttl::swapEdgesAwayFromBoundaryNode(dart, swapped_edges); + std::list swapped_edges; + swapEdgesAwayFromBoundaryNode(dart, swapped_edges); // Remove boundary triangles and remove the new boundary from the list // of swapped edges, see below. @@ -435,7 +453,7 @@ namespace ttl { bool bend = false; while (bend == false) { dnext.alpha1().alpha2(); - if (ttl::isBoundaryEdge(dnext)) + if (isBoundaryEdge(dnext)) bend = true; // Stop when boundary // Generic: Also remove the new boundary from the list of swapped edges @@ -443,20 +461,20 @@ namespace ttl { n_bedge.alpha1().alpha0().alpha1().alpha2(); // new boundary edge // ??? can we avoid find if we do this in swap away? - typename list::iterator it; + typename std::list::iterator it; it = find(swapped_edges.begin(), swapped_edges.end(), n_bedge); if (it != swapped_edges.end()) swapped_edges.erase(it); // Remove the boundary triangle - TraitsType::removeBoundaryTriangle(d_iter); + triangulation.removeBoundaryTriangle(d_iter); d_iter = dnext; } // Optimize Delaunay - typedef list DartListType; - ttl::optimizeDelaunay(swapped_edges); + typedef std::list DartListType; + optimizeDelaunay(swapped_edges); } @@ -465,8 +483,8 @@ namespace ttl { * updates the triangulation to be Delaunay. * * \using - * - ttl::swapEdgesAwayFromInteriorNode - * - ttl::optimizeDelaunay + * - swapEdgesAwayFromInteriorNode + * - optimizeDelaunay * * \require * - \ref hed::TTLtraits::reverse_splitTriangle "TraitsType::reverse_splitTriangle" (Dart&) @@ -476,7 +494,7 @@ namespace ttl { * swappable. (An endless loop is likely to occur in this case). */ template - void removeInteriorNode(DartType& dart) { + void TriangulationHelper::removeInteriorNode(DartType& dart) { // ... and update to Delaunay. // Must allow degeneracy temporarily, see comments in swap edges away @@ -492,13 +510,13 @@ namespace ttl { // Assumes dart is counterclockwise - list swapped_edges; - ttl::swapEdgesAwayFromInteriorNode(dart, swapped_edges); + std::list swapped_edges; + swapEdgesAwayFromInteriorNode(dart, swapped_edges); // The reverse operation of split triangle: // Make one triangle of the three triangles at the node associated with dart // TraitsType:: - TraitsType::reverse_splitTriangle(dart); + triangulation.reverse_splitTriangle(dart); // ???? Not generic yet if we are very strict: // When calling unsplit triangle, darts at the three opposite sides may @@ -511,7 +529,7 @@ namespace ttl { // Note the theoretical result: if there are no edges in the list, // the triangulation is Delaunay already - ttl::optimizeDelaunay(swapped_edges); + optimizeDelaunay(swapped_edges); } //@} // End of Delaunay Triangulation Group @@ -527,7 +545,7 @@ namespace ttl { //------------------------------------------------------------------------------------------------ // Private/Hidden function (might change later) template - bool isMemberOfFace(const TopologyElementType& topologyElement, const DartType& dart) { + bool TriangulationHelper::isMemberOfFace(const TopologyElementType& topologyElement, const DartType& dart) { // Check if the given topology element (node, edge or face) is a member of the face // Assumes: @@ -547,7 +565,7 @@ namespace ttl { //------------------------------------------------------------------------------------------------ // Private/Hidden function (might change later) template - bool locateFaceWithNode(const NodeType& node, DartType& dart_iter) { + bool TriangulationHelper::locateFaceWithNode(const NodeType& node, DartType& dart_iter) { // Locate a face in the topology structure with the given node as a member // Assumes: // - TraitsType::orient2d(DartType, DartType, NodeType) @@ -594,10 +612,10 @@ namespace ttl { * \e regular as explained above. * * \see - * ttl::locateTriangle + * locateTriangle */ template - bool locateFaceSimplest(const PointType& point, DartType& dart) { + bool TriangulationHelper::locateFaceSimplest(const PointType& point, DartType& dart) { // Not degenerate triangles if point is on the extension of the edges // But inTriangle may be called in case of true (may update to inFace2) // Convex boundary @@ -660,11 +678,11 @@ namespace ttl { * then the edge associated with \e dart will be at the boundary of the triangulation. * * \using - * - ttl::locateFaceSimplest - * - ttl::inTriangle + * - locateFaceSimplest + * - inTriangle */ template - bool locateTriangle(const PointType& point, DartType& dart) { + bool TriangulationHelper::locateTriangle(const PointType& point, DartType& dart) { // The purpose is to have a fast and stable procedure that // i) avoids concluding that a point is inside a triangle if it is not inside // ii) avoids infinite loops @@ -713,10 +731,10 @@ namespace ttl { * - \ref hed::TTLtraits::orient2d "TraitsType::orient2d" (DartType&, DartType&, PointType&) * * \see - * ttl::inTriangle for a more robust function + * inTriangle for a more robust function */ template - bool inTriangleSimplest(const PointType& point, const DartType& dart) { + bool TriangulationHelper::inTriangleSimplest(const PointType& point, const DartType& dart) { // Fast and simple: Do not deal with degenerate faces, i.e., if there is // degeneracy, true will be returned if the point is on the extension of the @@ -757,10 +775,10 @@ namespace ttl { * - \ref hed::TTLtraits::scalarProduct2d "TraitsType::scalarProduct2d" (DartType&, PointType&) * * \see - * ttl::inTriangleSimplest + * inTriangleSimplest */ template - bool inTriangle(const PointType& point, const DartType& dart) { + bool TriangulationHelper::inTriangle(const PointType& point, const DartType& dart) { // SHOULD WE INCLUDE A STRATEGY WITH EDGE X e_1 ETC? TO GUARANTEE THAT // ONLY ON ONE EDGE? BUT THIS DOES NOT SOLVE PROBLEMS WITH @@ -841,7 +859,7 @@ namespace ttl { //------------------------------------------------------------------------------------------------ // Private/Hidden function (might change later) template - void getAdjacentTriangles(const DartType& dart, DartType& t1, DartType& t2, DartType& t3) { + void TriangulationHelper::getAdjacentTriangles(const DartType& dart, DartType& t1, DartType& t2, DartType& t3) { DartType dart_iter = dart; @@ -886,7 +904,7 @@ namespace ttl { * - DartListType::push_back (DartType&) */ template - void getBoundary(const DartType& dart, DartListType& boundary) { + void TriangulationHelper::getBoundary(const DartType& dart, DartListType& boundary) { // assumes the given dart is at the boundary (by edge) DartType dart_iter(dart); @@ -932,7 +950,7 @@ namespace ttl { * \endcode */ template - bool isBoundaryEdge(const DartType& dart) { + bool TriangulationHelper::isBoundaryEdge(const DartType& dart) { DartType dart_iter = dart; if (dart_iter.alpha2() == dart) @@ -947,7 +965,7 @@ namespace ttl { * the boundary of the triangulation. */ template - bool isBoundaryFace(const DartType& dart) { + bool TriangulationHelper::isBoundaryFace(const DartType& dart) { // Strategy: boundary if alpha2(d)=d @@ -976,7 +994,7 @@ namespace ttl { * the boundary of the triangulation. */ template - bool isBoundaryNode(const DartType& dart) { + bool TriangulationHelper::isBoundaryNode(const DartType& dart) { // Strategy: boundary if alpha2(d)=d @@ -1009,7 +1027,7 @@ namespace ttl { * the number of edges joining \e V with another node in the triangulation. */ template - int getDegreeOfNode(const DartType& dart) { + int TriangulationHelper::getDegreeOfNode(const DartType& dart) { DartType dart_iter(dart); DartType dart_prev; @@ -1069,7 +1087,8 @@ namespace ttl { // Private/Hidden function template - void getNeighborNodes(const DartType& dart, std::list& node_list, bool& boundary) { + void TriangulationHelper::getNeighborNodes(const DartType& dart, + std::list& node_list, bool& boundary) { DartType dart_iter(dart); @@ -1131,10 +1150,10 @@ namespace ttl { * - DartListType::push_back (DartType&) * * \see - * ttl::get_0_orbit_boundary + * get_0_orbit_boundary */ template - void get_0_orbit_interior(const DartType& dart, DartListType& orbit) { + void TriangulationHelper::get_0_orbit_interior(const DartType& dart, DartListType& orbit) { DartType d_iter = dart; orbit.push_back(d_iter); @@ -1165,10 +1184,10 @@ namespace ttl { * - The last dart in the sequence have opposite orientation compared to the others! * * \see - * ttl::get_0_orbit_interior + * get_0_orbit_interior */ template - void get_0_orbit_boundary(const DartType& dart, DartListType& orbit) { + void TriangulationHelper::get_0_orbit_boundary(const DartType& dart, DartListType& orbit) { DartType dart_prev; DartType d_iter = dart; @@ -1195,17 +1214,17 @@ namespace ttl { * own version.) */ template - bool same_0_orbit(const DartType& d1, const DartType& d2) { + bool TriangulationHelper::same_0_orbit(const DartType& d1, const DartType& d2) { // Two copies of the same dart DartType d_iter = d2; DartType d_end = d2; - if (ttl::isBoundaryNode(d_iter)) { + if (isBoundaryNode(d_iter)) { // position at both boundary edges - ttl::positionAtNextBoundaryEdge(d_iter); + positionAtNextBoundaryEdge(d_iter); d_end.alpha1(); - ttl::positionAtNextBoundaryEdge(d_end); + positionAtNextBoundaryEdge(d_end); } for (;;) { @@ -1229,7 +1248,7 @@ namespace ttl { * \e d1 and/or \e d2 can be CCW or CW. */ template - bool same_1_orbit(const DartType& d1, const DartType& d2) { + bool TriangulationHelper::same_1_orbit(const DartType& d1, const DartType& d2) { DartType d_iter = d2; // (Also works at the boundary) @@ -1245,7 +1264,7 @@ namespace ttl { * \e d1 and/or \e d2 can be CCW or CW */ template - bool same_2_orbit(const DartType& d1, const DartType& d2) { + bool TriangulationHelper::same_2_orbit(const DartType& d1, const DartType& d2) { DartType d_iter = d2; if (d_iter == d1 || d_iter.alpha0() == d1 || @@ -1259,7 +1278,7 @@ namespace ttl { //------------------------------------------------------------------------------------------------ // Private/Hidden function template - bool degenerateTriangle(const DartType& dart) { + bool TriangulationHelper::degenerateTriangle(const DartType& dart) { // Check if triangle is degenerate // Assumes CCW dart @@ -1287,7 +1306,7 @@ namespace ttl { * - \ref hed::TTLtraits::crossProduct2d "TraitsType::crossProduct2d" (Dart&, Dart&) */ template - bool swappableEdge(const DartType& dart, bool allowDegeneracy) { + bool TriangulationHelper::swappableEdge(const DartType& dart, bool allowDegeneracy) { // How "safe" is it? @@ -1340,7 +1359,7 @@ namespace ttl { * infinit loop occurs. */ template - void positionAtNextBoundaryEdge(DartType& dart) { + void TriangulationHelper::positionAtNextBoundaryEdge(DartType& dart) { DartType dart_prev; @@ -1365,14 +1384,14 @@ namespace ttl { * - \ref hed::TTLtraits::crossProduct2d "TraitsType::crossProduct2d" (const Dart&, const Dart&) */ template - bool convexBoundary(const DartType& dart) { + bool TriangulationHelper::convexBoundary(const DartType& dart) { - list blist; - ttl::getBoundary(dart, blist); + std::list blist; + getBoundary(dart, blist); int no; no = (int)blist.size(); - typename list::const_iterator bit = blist.begin(); + typename std::list::const_iterator bit = blist.begin(); DartType d1 = *bit; ++bit; DartType d2; @@ -1428,17 +1447,17 @@ namespace ttl { * seen if it was glued to the edge when swapping (rotating) the edge CCW * * \using - * - ttl::swapTestDelaunay + * - swapTestDelaunay */ template - void optimizeDelaunay(DartListType& elist) { + void TriangulationHelper::optimizeDelaunay(DartListType& elist) { optimizeDelaunay(elist, elist.end()); } //------------------------------------------------------------------------------------------------ template - void optimizeDelaunay(DartListType& elist, const typename DartListType::iterator end) { + void TriangulationHelper::optimizeDelaunay(DartListType& elist, const typename DartListType::iterator end) { // CCW darts // Optimize here means Delaunay, but could be any criterion by @@ -1481,14 +1500,14 @@ namespace ttl { while(!optimal) { optimal = true; for (it = elist.begin(); it != end_opt; ++it) { - if (ttl::swapTestDelaunay(*it, cycling_check)) { + if (swapTestDelaunay(*it, cycling_check)) { // Preserve darts. Potential darts in the list are: // - The current dart // - the four CCW darts on the boundary of the quadrilateral // (the current arc has only one dart) - ttl::swapEdgeInList(it, elist); + swapEdgeInList(it, elist); optimal = false; } // end if should swap @@ -1513,9 +1532,9 @@ namespace ttl { */ template #if ((_MSC_VER > 0) && (_MSC_VER < 1300))//#ifdef _MSC_VER - bool swapTestDelaunay(const DartType& dart, bool cycling_check = false) { + bool TriangulationHelper::swapTestDelaunay(const DartType& dart, bool cycling_check = false) const { #else - bool swapTestDelaunay(const DartType& dart, bool cycling_check) { + bool TriangulationHelper::swapTestDelaunay(const DartType& dart, bool cycling_check) const { #endif // The general strategy is taken from Cline & Renka. They claim that @@ -1627,17 +1646,17 @@ namespace ttl { * - Calls itself recursively */ template - void recSwapDelaunay(DartType& diagonal) { + void TriangulationHelper::recSwapDelaunay(DartType& diagonal) { - if (!ttl::swapTestDelaunay(diagonal)) - // ??? ttl::swapTestDelaunay also checks if boundary, so this can be optimized + if (!swapTestDelaunay(diagonal)) + // ??? swapTestDelaunay also checks if boundary, so this can be optimized return; // Get the other "edges" of the current triangle; see illustration above. DartType oppEdge1 = diagonal; oppEdge1.alpha1(); bool b1; - if (ttl::isBoundaryEdge(oppEdge1)) + if (isBoundaryEdge(oppEdge1)) b1 = true; else { b1 = false; @@ -1648,7 +1667,7 @@ namespace ttl { DartType oppEdge2 = diagonal; oppEdge2.alpha0().alpha1().alpha0(); bool b2; - if (ttl::isBoundaryEdge(oppEdge2)) + if (isBoundaryEdge(oppEdge2)) b2 = true; else { b2 = false; @@ -1656,7 +1675,7 @@ namespace ttl { } // Swap the given diagonal - TraitsType::swapEdge(diagonal); + triangulation.swapEdge(diagonal); if (!b1) recSwapDelaunay(oppEdge1); @@ -1669,7 +1688,7 @@ namespace ttl { /** Swaps edges away from the (interior) node associated with * \e dart such that that exactly three edges remain incident * with the node. - * This function is used as a first step in ttl::removeInteriorNode + * This function is used as a first step in removeInteriorNode * * \retval dart * A CCW dart incident with the node @@ -1689,10 +1708,10 @@ namespace ttl { * at the node that is given as input. * * \see - * ttl::swapEdgesAwayFromBoundaryNode + * swapEdgesAwayFromBoundaryNode */ template - void swapEdgesAwayFromInteriorNode(DartType& dart, ListType& swapped_edges) { + void TriangulationHelper::swapEdgesAwayFromInteriorNode(DartType& dart, ListType& swapped_edges) { // Same iteration as in fixEdgesAtCorner, but not boundary DartType dnext = dart; @@ -1706,14 +1725,14 @@ namespace ttl { // infinite loop with degree > 3. bool allowDegeneracy = true; - int degree = ttl::getDegreeOfNode(dart); + int degree = getDegreeOfNode(dart); DartType d_iter; while (degree > 3) { d_iter = dnext; dnext.alpha1().alpha2(); - if (ttl::swappableEdge(d_iter, allowDegeneracy)) { - TraitsType::swapEdge(d_iter); // swap the edge away + if (swappableEdge(d_iter, allowDegeneracy)) { + triangulation.swapEdge(d_iter); // swap the edge away // Collect swapped edges in the list // "Hide" the dart on the other side of the edge to avoid it being changed for // other swaps @@ -1733,7 +1752,7 @@ namespace ttl { /** Swaps edges away from the (boundary) node associated with * \e dart in such a way that when removing the edges that remain incident * with the node, the boundary of the triangulation will be convex. - * This function is used as a first step in ttl::removeBoundaryNode + * This function is used as a first step in removeBoundaryNode * * \retval dart * A CCW dart incident with the node @@ -1747,10 +1766,10 @@ namespace ttl { * - The node associated with \e dart is at the boundary of the triangulation. * * \see - * ttl::swapEdgesAwayFromInteriorNode + * swapEdgesAwayFromInteriorNode */ template - void swapEdgesAwayFromBoundaryNode(DartType& dart, ListType& swapped_edges) { + void TriangulationHelper::swapEdgesAwayFromBoundaryNode(DartType& dart, ListType& swapped_edges) { // All darts that are swappable. // To treat collinear nodes at an existing boundary, we must allow degeneracy @@ -1762,7 +1781,7 @@ namespace ttl { // - A dart on the swapped edge is delivered back in a position as // seen if it was glued to the edge when swapping (rotating) the edge CCW - //int degree = ttl::getDegreeOfNode(dart); + //int degree = getDegreeOfNode(dart); passes: @@ -1780,7 +1799,7 @@ passes: while (!bend) { d_next.alpha1().alpha2(); - if (ttl::isBoundaryEdge(d_next)) + if (isBoundaryEdge(d_next)) bend = true; // then it is CW since alpha2 // To allow removing among collinear nodes at the boundary, @@ -1789,13 +1808,13 @@ passes: tmp1 = d_iter; tmp1.alpha1(); tmp2 = d_iter; tmp2.alpha2().alpha1(); // don't bother with boundary (checked later) - if (ttl::isBoundaryEdge(tmp1) && ttl::isBoundaryEdge(tmp2)) + if (isBoundaryEdge(tmp1) && isBoundaryEdge(tmp2)) allowDegeneracy = true; else allowDegeneracy = false; - if (ttl::swappableEdge(d_iter, allowDegeneracy)) { - TraitsType::swapEdge(d_iter); + if (swappableEdge(d_iter, allowDegeneracy)) { + triangulation.swapEdge(d_iter); // Collect swapped edges in the list // "Hide" the dart on the other side of the edge to avoid it being changed for @@ -1821,7 +1840,7 @@ passes: else { d_iter.alpha1(); // CW and see below } - ttl::positionAtNextBoundaryEdge(d_iter); // CCW + positionAtNextBoundaryEdge(d_iter); // CCW dart = d_iter; // for next pass or output @@ -1839,7 +1858,7 @@ passes: * keep them in \e elist. */ template - void swapEdgeInList(const typename DartListType::iterator& it, DartListType& elist) { + void TriangulationHelper::swapEdgeInList(const typename DartListType::iterator& it, DartListType& elist) { typename DartListType::iterator it1, it2, it3, it4; DartType dart(*it); @@ -1867,7 +1886,7 @@ passes: it3 = find(elist.begin(), elist.end(), d3); it4 = find(elist.begin(), elist.end(), d4); - TraitsType::swapEdge(dart); + triangulation.swapEdge(dart); // Update the current dart which may have changed *it = dart; diff --git a/include/ttl/ttl_constr.h b/include/ttl/ttl_constr.h index 67b46fcbf0..125bddeb23 100644 --- a/include/ttl/ttl_constr.h +++ b/include/ttl/ttl_constr.h @@ -51,9 +51,6 @@ static ofstream ofile_constr("qweCons.dat"); #endif - -//using namespace std; - /** \brief Constrained Delaunay triangulation * * Basic generic algorithms in TTL for inserting a constrained edge between two existing nodes.\n @@ -61,7 +58,7 @@ * See documentation for the namespace ttl for general requirements and assumptions. * * \author -* Øyvind Hjelle, oyvindhj@ifi.uio.no +* �yvind Hjelle, oyvindhj@ifi.uio.no */ namespace ttl_constr { @@ -73,6 +70,9 @@ namespace ttl_constr { #endif +class ConstrainedTriangulation +{ + public: //------------------------------------------------------------------------------------------------ /* Checks if \e dart has start and end points in \e dstart and \e dend. * @@ -89,14 +89,14 @@ namespace ttl_constr { * A bool confirming that it's the constraint or not * * \using - * ttl::same_0_orbit + * same_0_orbit */ template - bool isTheConstraint(const DartType& dart, const DartType& dstart, const DartType& dend) { + static bool isTheConstraint(const DartType& dart, const DartType& dstart, const DartType& dend) { DartType d0 = dart; d0.alpha0(); // CW - if ((ttl::same_0_orbit(dstart, dart) && ttl::same_0_orbit(dend, d0)) || - (ttl::same_0_orbit(dstart, d0) && ttl::same_0_orbit(dend, dart))) { + if ((ttl::TriangulationHelper::same_0_orbit(dstart, dart) && ttl::TriangulationHelper::same_0_orbit(dend, d0)) || + (ttl::TriangulationHelper::same_0_orbit(dstart, d0) && ttl::TriangulationHelper::same_0_orbit(dend, dart))) { return true; } return false; @@ -123,7 +123,7 @@ namespace ttl_constr { * TraitsType::orient2d */ template - bool crossesConstraint(DartType& dstart, DartType& dend, DartType& d1, DartType& d2) { + static bool crossesConstraint(DartType& dstart, DartType& dend, DartType& d1, DartType& d2) { typename TraitsType::real_type orient_1 = TraitsType::orient2d(dstart,d1,dend); typename TraitsType::real_type orient_2 = TraitsType::orient2d(dstart,d2,dend); @@ -156,12 +156,12 @@ namespace ttl_constr { * The dart \e d making the smallest positive (or == 0) angle * * \using - * ttl::isBoundaryNode - * ttl::positionAtNextBoundaryEdge + * isBoundaryNode + * positionAtNextBoundaryEdge * TraitsType::orient2d */ template - DartType getAtSmallestAngle(const DartType& dstart, const DartType& dend) { + static DartType getAtSmallestAngle(const DartType& dstart, const DartType& dend) { // - Must boundary be convex??? // - Handle the case where the constraint is already present??? @@ -169,9 +169,9 @@ namespace ttl_constr { // (dstart and dend may define a boundary edge) DartType d_iter = dstart; - if (ttl::isBoundaryNode(d_iter)) { + if (ttl::TriangulationHelper::isBoundaryNode(d_iter)) { d_iter.alpha1(); // CW - ttl::positionAtNextBoundaryEdge(d_iter); // CCW (was rotated CW to the boundary) + ttl::TriangulationHelper::positionAtNextBoundaryEdge(d_iter); // CCW (was rotated CW to the boundary) } // assume convex boundary; see comments @@ -273,7 +273,7 @@ namespace ttl_constr { * Returns the next "collinear" starting node such that dend is returned when done. */ template - DartType findCrossingEdges(const DartType& dstart, const DartType& dend, ListType& elist) { + static DartType findCrossingEdges(const DartType& dstart, const DartType& dend, ListType& elist) { const DartType my_start = getAtSmallestAngle(dstart, dend); DartType my_end = getAtSmallestAngle(dend, dstart); @@ -387,15 +387,16 @@ namespace ttl_constr { * A list containing all the edges crossing the spesified constraint * * \using - * ttl::swappableEdge - * ttl::swapEdgeInList - * ttl::crossesConstraint - * ttl::isTheConstraint + * swappableEdge + * swapEdgeInList + * crossesConstraint + * isTheConstraint */ template - void transformToConstraint(DartType& dstart, DartType& dend, std::list& elist) { + void transformToConstraint(ttl::TriangulationHelper helper, DartType& dstart, DartType& dend, + std::list& elist) const { - typename list::iterator it, used; + typename std::list::iterator it, used; // We may enter in a situation where dstart and dend are altered because of a swap. // (The general rule is that darts inside the actual quadrilateral can be changed, @@ -423,7 +424,7 @@ namespace ttl_constr { if (counter > dartsInList) break; - if (ttl::swappableEdge(*it, true)) { + if (ttl::TriangulationHelper::swappableEdge(*it, true)) { // Dyn & Goren & Rippa 's notation: // The node assosiated with dart *it is denoted u_m. u_m has edges crossing the constraint // named w_1, ... , w_r . The other node to the edge assosiated with dart *it is w_s. @@ -456,7 +457,7 @@ namespace ttl_constr { end = true; // This is the only place swapping is called when inserting a constraint - ttl::swapEdgeInList(it,elist); + helper.swapEdgeInList(it,elist); // If we, during look-ahead, found that dstart and/or dend were in the quadrilateral, // we update them. @@ -512,6 +513,8 @@ namespace ttl_constr { } +}; // End of ConstrainedTriangulation class + }; // End of ttl_constr namespace scope @@ -546,14 +549,14 @@ namespace ttl { // (extension) * - \ref hed::TTLtraits::swapEdge "TraitsType::swapEdge" (DartType&) * * \using - * - ttl::optimizeDelaunay if \e optimize_delaunay is set to \c true + * - optimizeDelaunay if \e optimize_delaunay is set to \c true * * \par Assumes: * - The constrained edge must be inside the existing triangulation (and it cannot * cross the boundary of the triangulation). */ template - DartType insertConstraint(DartType& dstart, DartType& dend, bool optimize_delaunay) { + DartType TriangulationHelper::insertConstraint(DartType& dstart, DartType& dend, bool optimize_delaunay) { // Assumes: // - It is the users responsibility to avoid crossing constraints @@ -567,8 +570,8 @@ namespace ttl { // (extension) // calls itself recursively. // RECURSION - list elist; - DartType next_start = ttl_constr::findCrossingEdges(dstart, dend, elist); + std::list elist; + DartType next_start = ttl_constr::ConstrainedTriangulation::findCrossingEdges(dstart, dend, elist); // If there are no crossing edges (elist is empty), we assume that the constraint // is an existing edge. @@ -583,7 +586,7 @@ namespace ttl { // (extension) // findCrossingEdges stops if it finds a node lying on the constraint. // A dart with this node as start node is returned // We call insertConstraint recursivly until the received dart is dend - if (!ttl::same_0_orbit(next_start, dend)) { + if (!same_0_orbit(next_start, dend)) { #ifdef DEBUG_TTL_CONSTR_PLOT cout << "RECURSION due to collinearity along constraint" << endl; @@ -594,7 +597,7 @@ namespace ttl { // (extension) // Swap edges such that the constraint edge is present in the transformed triangulation. if (elist.size() > 0) // by Thomas Sevaldrud - ttl_constr::transformToConstraint(dstart, next_start, elist); + ttl_constr::ConstrainedTriangulation::transformToConstraint(dstart, next_start, elist); #ifdef DEBUG_TTL_CONSTR_PLOT cout << "size of elist = " << elist.size() << endl; @@ -607,13 +610,13 @@ namespace ttl { // (extension) #endif // Optimize to constrained Delaunay triangulation if required. - typename list::iterator end_opt = elist.end(); + typename std::list::iterator end_opt = elist.end(); if (optimize_delaunay) { // Indicate that the constrained edge, which is the last element in the list, // should not be swapped --end_opt; - ttl::optimizeDelaunay(elist, end_opt); + optimizeDelaunay(elist, end_opt); } if(elist.size() == 0) // by Thomas Sevaldrud diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index e66451b86b..af5f6932fd 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -240,7 +240,7 @@ void RN_NET::compute() return; } - else if( boardNodes.size() == 1 ) // This case is even simpler + else if( boardNodes.size() <= 1 ) // This case is even simpler { m_rnEdges.reset( new std::vector( 0 ) ); From 58f813b6e897bb3b2684652ead7a9abbc7f1bcbf Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 28 Jan 2014 10:19:51 +0100 Subject: [PATCH 49/95] Added NETINFO_MAPPING, to ease saving nets with consecutive net codes (without modifying the net codes during the run time). Now, nets are saved with consecutive net codes (both modern & legacy plugins). Zones are saved together with their nets, without depending on the fact if there are any pads with such net. Therefore validation of zone net names was removed (pcbnew/class_board.cpp). Performed tests: - Changed a pad's net name from empty to existent - ok, name was changed. - Changed a pad's net name from empty to nonexistent - ok, error message is displayed, net name stays empty. - Changed a pad's net name from existent to empty - ok, net name became empty - Changed a pad's net name from existent to nonexistent - ok, error message is displayed, net name is not changed. - Drawn a zone that belongs to a net, then modified schematics so the net does not exist anymore. After reloading the net list, all pads/tracks are updated. Zones still belongs to the net that does not exist in the schematic (but still exists in .kicad_pcb file). After running DRC, the zone becomes not filled. - Undo & redo affects assignment of a polygon to a specific net (you may change net of a polygon, refill it and undo/redo the changes). - KiCad s-expr & legacy, Eagle, P-CAD boards seem to load without any problem (they also contain correct net names assigned to the appropriate pads). All types of board file formats were loaded, then saved in sexpr format and reopened with a KiCad built from the master branch (without my modifications). - A few boards were also saved using the legacy format and were opened with the master KiCad without any issues. - Change a net name for a pad, restore with undo/redo - ok - Remove everything, restore with undo - ok - Remove everything, reload netlist - ok Differences observed between files saved by the master branch KiCad and this one: - list of nets are not saved in any particular order, so net codes may differ - the default net class does not contain the unconnected net --- pcbnew/class_board.cpp | 25 ------ pcbnew/class_board_connected_item.cpp | 6 ++ pcbnew/class_netinfo.h | 123 ++++++++++++++++++++++++-- pcbnew/class_netinfolist.cpp | 73 ++++++++++++++- pcbnew/kicad_plugin.cpp | 44 ++++----- pcbnew/kicad_plugin.h | 7 +- pcbnew/legacy_plugin.cpp | 19 ++-- pcbnew/legacy_plugin.h | 4 + pcbnew/pcb_parser.cpp | 11 ++- 9 files changed, 240 insertions(+), 72 deletions(-) diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 5c435f634a..b32e48ae22 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -2700,31 +2700,6 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, } } } - - // Verify zone net names validity: - // After schematic changes, a zone can have a non existing net name. - // It should be reported - if( aReporter && aReporter->ReportErrors() ) - { - //Loop through all copper zones - for( i = 0; i < m_ZoneDescriptorList.size(); i++ ) - { - ZONE_CONTAINER* zone = m_ZoneDescriptorList[i]; - - if( zone->GetNet() >= 0 || !zone->IsOnCopperLayer() ) - continue; - - // Net name not valid, report error - wxString coord; - coord << zone->GetPosition(); - msg.Printf( _( "** Error: Zone '%s' layer '%s'" - " has non-existent net name \"%s\" **\n" ), - GetChars( coord ), - GetChars( zone->GetLayerName() ), - GetChars( zone->GetNetname() ) ); - aReporter->Report( msg ); - } - } } /* Extracts the board outlines and build a closed polygon diff --git a/pcbnew/class_board_connected_item.cpp b/pcbnew/class_board_connected_item.cpp index 69bcfacb7e..26cca19772 100644 --- a/pcbnew/class_board_connected_item.cpp +++ b/pcbnew/class_board_connected_item.cpp @@ -63,9 +63,15 @@ void BOARD_CONNECTED_ITEM::SetNet( int aNetCode ) { m_netinfo = board->FindNet( aNetCode ); + // The requested net does not exist, mark it as unconnected if( m_netinfo == NULL ) m_netinfo = board->FindNet( NETINFO_LIST::UNCONNECTED ); } + else + { + // There is no board that contains list of nets, the item is orphaned + m_netinfo = &NETINFO_LIST::ORPHANED; + } } diff --git a/pcbnew/class_netinfo.h b/pcbnew/class_netinfo.h index 326a0fa3b4..50bb30457d 100644 --- a/pcbnew/class_netinfo.h +++ b/pcbnew/class_netinfo.h @@ -116,6 +116,121 @@ public: }; +class NETINFO_MAPPING +{ +public: + /** + * Function SetBoard + * Sets a BOARD object that is used to prepare the net code map. + */ + void SetBoard( const BOARD* aBoard ) + { + m_board = aBoard; + Update(); + } + + /** + * Function Update + * Prepares a mapping for net codes so they can be saved as consecutive numbers. + * To retrieve a mapped net code, use translateNet() function after calling this. + */ + void Update(); + + /** + * Function Translate + * Translates net number according to the map prepared by Update() function. It + * allows to have items stored with consecutive net codes. + * @param aNetCode is an old net code. + * @return Net code that follows the mapping. + */ + int Translate( int aNetCode ) const; + + ///> Wrapper class, so you can iterate through NETINFO_ITEM*s, not + ///> std::pair + class iterator + { + public: + iterator( std::map::const_iterator aIter, const NETINFO_MAPPING* aMapping ) : + m_iterator( aIter ), m_mapping( aMapping ) + { + } + + /// pre-increment operator + const iterator& operator++() + { + ++m_iterator; + + return *this; + } + + /// post-increment operator + iterator operator++( int ) + { + iterator ret = *this; + ++m_iterator; + + return ret; + } + + NETINFO_ITEM* operator*() const; + + NETINFO_ITEM* operator->() const; + + bool operator!=( const iterator& aOther ) const + { + return m_iterator != aOther.m_iterator; + } + + bool operator==( const iterator& aOther ) const + { + return m_iterator == aOther.m_iterator; + } + + private: + std::map::const_iterator m_iterator; + const NETINFO_MAPPING* m_mapping; + }; + + /** + * Function begin() + * Returns iterator to the first entry in the mapping. + * NOTE: The entry is a pointer to the original NETINFO_ITEM object, this it contains + * not mapped net code. + */ + iterator begin() const + { + return iterator( m_netMapping.begin(), this ); + } + + /** + * Function end() + * Returns iterator to the last entry in the mapping. + * NOTE: The entry is a pointer to the original NETINFO_ITEM object, this it contains + * not mapped net code. + */ + iterator end() const + { + return iterator( m_netMapping.end(), this ); + } + + /** + * Function GetSize + * @return Number of mapped nets (i.e. not empty nets for a given BOARD object). + */ + int GetSize() const + { + return m_netMapping.size(); + } + +private: + ///> Board for which mapping is prepared + const BOARD* m_board; + + ///> Map that allows saving net codes with consecutive numbers (for compatibility reasons) + std::map m_netMapping; +}; + + /** * Class NETINFO * is a container class for NETINFO_ITEM elements, which are the nets. That makes @@ -304,16 +419,12 @@ private: */ int getFreeNetCode() const; - BOARD* m_Parent; + BOARD* m_Parent; NETNAMES_MAP m_netNames; ///< map for a fast look up by net names NETCODES_MAP m_netCodes; ///< map for a fast look up by net codes - static int m_newNetCode; ///< number that has a *high* chance to be unused - ///< (to be sure, it is advised to use - ///< getFreeNetCode() function) - - std::vector m_PadsFullList; ///< contains all pads, sorted by pad's netname. + std::vector m_PadsFullList; ///< contains all pads, sorted by pad's netname. ///< can be used in ratsnest calculations. }; diff --git a/pcbnew/class_netinfolist.cpp b/pcbnew/class_netinfolist.cpp index e57bbfed8b..34b2eded9a 100644 --- a/pcbnew/class_netinfolist.cpp +++ b/pcbnew/class_netinfolist.cpp @@ -11,6 +11,9 @@ #include #include +#include +#include +#include #include @@ -98,7 +101,7 @@ void NETINFO_LIST::buildListOfNets() { pad = m_PadsFullList[ii]; - if( pad->GetNet() == 0 ) // pad not connected + if( pad->GetNet() == NETINFO_LIST::UNCONNECTED ) // pad not connected continue; // Add pad to the appropriate list of pads @@ -172,15 +175,79 @@ void NETINFO_LIST::buildPadsFullList() int NETINFO_LIST::getFreeNetCode() const { + static int m_newNetCode = 0; + do { if( m_newNetCode < 0 ) m_newNetCode = 0; - } while( m_netCodes.count( ++NETINFO_LIST::m_newNetCode ) != 0 ); + } while( m_netCodes.count( ++m_newNetCode ) != 0 ); return m_newNetCode; } +int NETINFO_MAPPING::Translate( int aNetCode ) const +{ + std::map::const_iterator value = m_netMapping.find( aNetCode ); + + if( value != m_netMapping.end() ) + return value->second; + + // There was no entry for the given net code + return aNetCode; +} + + +void NETINFO_MAPPING::Update() +{ + // Collect all the used nets + std::set nets; + + // Be sure that the unconnected gets 0 and is mapped as 0 + nets.insert( 0 ); + + // Zones + for( int i = 0; i < m_board->GetAreaCount(); ++i ) + nets.insert( m_board->GetArea( i )->GetNet() ); + + // Tracks + for( TRACK* track = m_board->m_Track; track; track = track->Next() ) + nets.insert( track->GetNet() ); + + // Modules/pads + for( MODULE* module = m_board->m_Modules; module; module = module->Next() ) + { + for( D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() ) + { + nets.insert( pad->GetNet() ); + } + } + + // Segzones + for( SEGZONE* zone = m_board->m_Zone; zone; zone = zone->Next() ) + nets.insert( zone->GetNet() ); + + // Prepare the new mapping + m_netMapping.clear(); + + // Now the nets variable stores all the used net codes (not only for pads) + int newNetCode = 0; + for( std::set::const_iterator it = nets.begin(), itEnd = nets.end(); it != itEnd; ++it ) + m_netMapping[*it] = newNetCode++; +} + + +NETINFO_ITEM* NETINFO_MAPPING::iterator::operator*() const +{ + return m_mapping->m_board->FindNet( m_iterator->first ); +} + + +NETINFO_ITEM* NETINFO_MAPPING::iterator::operator->() const +{ + return m_mapping->m_board->FindNet( m_iterator->first ); +} + + const NETINFO_ITEM NETINFO_LIST::ORPHANED = NETINFO_ITEM( NULL, wxString::FromUTF8( "orphaned" ), -1 ); const int NETINFO_LIST::UNCONNECTED = 0; -int NETINFO_LIST::m_newNetCode = 0; diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index 3cda985754..fbdcf0fd3e 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -380,6 +380,9 @@ void PCB_IO::Save( const wxString& aFileName, BOARD* aBoard, const PROPERTIES* a m_board = aBoard; // after init() + // Prepare net mapping that assures that net codes saved in a file are consecutive integers + m_mapping->SetBoard( aBoard ); + FILE_OUTPUTFORMATTER formatter( aFileName ); m_out = &formatter; // no ownership @@ -499,7 +502,7 @@ void PCB_IO::format( BOARD* aBoard, int aNestLevel ) const m_out->Print( aNestLevel+1, "(tracks %d)\n", aBoard->GetNumSegmTrack() ); m_out->Print( aNestLevel+1, "(zones %d)\n", aBoard->GetNumSegmZone() ); m_out->Print( aNestLevel+1, "(modules %d)\n", aBoard->m_Modules.GetCount() ); - m_out->Print( aNestLevel+1, "(nets %d)\n", aBoard->GetNetCount() ); + m_out->Print( aNestLevel+1, "(nets %d)\n", (int) m_mapping->GetSize() ); m_out->Print( aNestLevel, ")\n\n" ); aBoard->GetPageSettings().Format( m_out, aNestLevel, m_ctl ); @@ -654,20 +657,14 @@ void PCB_IO::format( BOARD* aBoard, int aNestLevel ) const m_out->Print( aNestLevel, ")\n\n" ); - // Unconditionally save the unconnected net - m_out->Print( aNestLevel, "(net 0 \"\")\n" ); - - // and now the rest of nets - for( NETINFO_LIST::iterator net( aBoard->BeginNet() ), netEnd( aBoard->EndNet() ); + // Save net codes and names + for( NETINFO_MAPPING::iterator net = m_mapping->begin(), netEnd = m_mapping->end(); net != netEnd; ++net ) { - if( net->GetNodesCount() > 0 ) // save only not empty nets - { - m_out->Print( aNestLevel, "(net %d %s)\n", - net->GetNet(), - m_out->Quotew( net->GetNetname() ).c_str() ); - } - } + m_out->Print( aNestLevel, "(net %d %s)\n", + m_mapping->Translate( net->GetNet() ), + m_out->Quotew( net->GetNetname() ).c_str() ); + } m_out->Print( 0, "\n" ); @@ -1234,7 +1231,8 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const // Unconnected pad is default net so don't save it. if( !(m_ctl & CTL_OMIT_NETS) && aPad->GetNet() != 0 ) - StrPrintf( &output, " (net %d %s)", aPad->GetNet(), m_out->Quotew( aPad->GetNetname() ).c_str() ); + StrPrintf( &output, " (net %d %s)", m_mapping->Translate( aPad->GetNet() ), + m_out->Quotew( aPad->GetNetname() ).c_str() ); if( aPad->GetPadToDieLength() != 0 ) StrPrintf( &output, " (die_length %s)", FMT_IU( aPad->GetPadToDieLength() ).c_str() ); @@ -1391,7 +1389,7 @@ void PCB_IO::format( TRACK* aTrack, int aNestLevel ) const m_out->Print( 0, " (layer %s)", m_out->Quotew( aTrack->GetLayerName() ).c_str() ); } - m_out->Print( 0, " (net %d)", aTrack->GetNet() ); + m_out->Print( 0, " (net %d)", m_mapping->Translate( aTrack->GetNet() ) ); if( aTrack->GetTimeStamp() != 0 ) m_out->Print( 0, " (tstamp %lX)", aTrack->GetTimeStamp() ); @@ -1410,7 +1408,7 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const // so be sure a dummy value is stored, just for ZONE_CONTAINER compatibility // (perhaps netcode and netname should be not stored) m_out->Print( aNestLevel, "(zone (net %d) (net_name %s)", - aZone->GetIsKeepout() ? 0 : aZone->GetNet(), + aZone->GetIsKeepout() ? 0 : m_mapping->Translate( aZone->GetNet() ), m_out->Quotew( aZone->GetIsKeepout() ? wxT("") : aZone->GetNetname() ).c_str() ); formatLayer( aZone ); @@ -1627,20 +1625,11 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const } -PCB_IO::PCB_IO() : - m_cache( 0 ), - m_ctl( CTL_FOR_BOARD ), // expecting to OUTPUTFORMAT into BOARD files. - m_parser( new PCB_PARSER() ) -{ - init( 0 ); - m_out = &m_sf; -} - - PCB_IO::PCB_IO( int aControlFlags ) : m_cache( 0 ), m_ctl( aControlFlags ), - m_parser( new PCB_PARSER() ) + m_parser( new PCB_PARSER() ), + m_mapping( new NETINFO_MAPPING() ) { init( 0 ); m_out = &m_sf; @@ -1651,6 +1640,7 @@ PCB_IO::~PCB_IO() { delete m_cache; delete m_parser; + delete m_mapping; } diff --git a/pcbnew/kicad_plugin.h b/pcbnew/kicad_plugin.h index ce7c40ef38..95986e7531 100644 --- a/pcbnew/kicad_plugin.h +++ b/pcbnew/kicad_plugin.h @@ -32,6 +32,7 @@ class BOARD; class BOARD_ITEM; class FP_CACHE; class PCB_PARSER; +class NETINFO_MAPPING; /// Current s-expression file format version. 2 was the last legacy format version. @@ -122,9 +123,7 @@ public: //------------------------------------------------------------- - PCB_IO(); - - PCB_IO( int aControlFlags ); + PCB_IO( int aControlFlags = CTL_FOR_BOARD ); ~PCB_IO(); @@ -171,6 +170,8 @@ protected: OUTPUTFORMATTER* m_out; ///< output any Format()s to this, no ownership int m_ctl; PCB_PARSER* m_parser; + NETINFO_MAPPING* m_mapping; ///< mapping for net codes, so only not empty net codes + ///< are stored with consecutive integers as net codes /// we only cache one footprint library, this determines which one. void cacheLib( const wxString& aLibraryPath, const wxString& aFootprintName = wxEmptyString ); diff --git a/pcbnew/legacy_plugin.cpp b/pcbnew/legacy_plugin.cpp index 8b09403302..6e08682234 100644 --- a/pcbnew/legacy_plugin.cpp +++ b/pcbnew/legacy_plugin.cpp @@ -2899,6 +2899,8 @@ do { \ void LEGACY_PLUGIN::SaveBOARD( const BOARD* aBoard ) const { + m_mapping->SetBoard( aBoard ); + saveGENERAL( aBoard ); saveSHEET( aBoard ); @@ -2947,7 +2949,7 @@ void LEGACY_PLUGIN::saveGENERAL( const BOARD* aBoard ) const fprintf( m_fp, "Nzone %d\n", aBoard->GetNumSegmZone() ); fprintf( m_fp, "BoardThickness %s\n", fmtBIU( aBoard->GetDesignSettings().GetBoardThickness() ).c_str() ); fprintf( m_fp, "Nmodule %d\n", aBoard->m_Modules.GetCount() ); - fprintf( m_fp, "Nnets %d\n", aBoard->GetNetCount() ); + fprintf( m_fp, "Nnets %d\n", m_mapping->GetSize() ); fprintf( m_fp, "$EndGENERAL\n\n" ); } @@ -3088,9 +3090,11 @@ void LEGACY_PLUGIN::saveSETUP( const BOARD* aBoard ) const void LEGACY_PLUGIN::saveBOARD_ITEMS( const BOARD* aBoard ) const { // save the nets - int netcount = aBoard->GetNetCount(); - for( int i = 0; i < netcount; ++i ) - saveNETINFO_ITEM( aBoard->FindNet( i ) ); + for( NETINFO_MAPPING::iterator net = m_mapping->begin(), netEnd = m_mapping->end(); + net != netEnd; ++net ) + { + saveNETINFO_ITEM( *net ); + } // Saved nets do not include netclass names, so save netclasses after nets. saveNETCLASSES( &aBoard->m_NetClasses ); @@ -3148,7 +3152,8 @@ void LEGACY_PLUGIN::saveBOARD_ITEMS( const BOARD* aBoard ) const void LEGACY_PLUGIN::saveNETINFO_ITEM( const NETINFO_ITEM* aNet ) const { fprintf( m_fp, "$EQUIPOT\n" ); - fprintf( m_fp, "Na %d %s\n", aNet->GetNet(), EscapedUTF8( aNet->GetNetname() ).c_str() ); + fprintf( m_fp, "Na %d %s\n", m_mapping->Translate( aNet->GetNet() ), + EscapedUTF8( aNet->GetNetname() ).c_str() ); fprintf( m_fp, "St %s\n", "~" ); fprintf( m_fp, "$EndEQUIPOT\n" ); @@ -4417,7 +4422,8 @@ LEGACY_PLUGIN::LEGACY_PLUGIN() : m_props( 0 ), m_reader( 0 ), m_fp( 0 ), - m_cache( 0 ) + m_cache( 0 ), + m_mapping( new NETINFO_MAPPING() ) { init( NULL ); } @@ -4426,4 +4432,5 @@ LEGACY_PLUGIN::LEGACY_PLUGIN() : LEGACY_PLUGIN::~LEGACY_PLUGIN() { delete m_cache; + delete m_mapping; } diff --git a/pcbnew/legacy_plugin.h b/pcbnew/legacy_plugin.h index c5eba40083..dec3bfcbac 100644 --- a/pcbnew/legacy_plugin.h +++ b/pcbnew/legacy_plugin.h @@ -44,6 +44,7 @@ class NETCLASSES; class ZONE_CONTAINER; class DIMENSION; class NETINFO_ITEM; +class NETINFO_MAPPING; class TEXTE_MODULE; class EDGE_MODULE; class TRACK; @@ -124,6 +125,9 @@ protected: int m_loading_format_version; ///< which BOARD_FORMAT_VERSION am I Load()ing? LP_CACHE* m_cache; + NETINFO_MAPPING* m_mapping; ///< mapping for net codes, so only not empty net codes + ///< are stored with consecutive integers as net codes + /// initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed. void init( const PROPERTIES* aProperties ); diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index db9ed25acf..d7456b06ea 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -2417,13 +2418,19 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR ) // Init the net code only, not the netname, to be sure // the zone net name is the name read in file. // (When mismatch, the user will be prompted in DRC, to fix the actual name) - zone->BOARD_CONNECTED_ITEM::SetNet( parseInt( "net number" ) ); + zone->SetNet( parseInt( "net number" ) ); NeedRIGHT(); break; case T_net_name: NeedSYMBOLorNUMBER(); - assert( m_board->FindNet( zone->GetNet() )->GetNetname() == FromUTF8() ); + if( m_board->FindNet( zone->GetNet() )->GetNetname() != FromUTF8() ) + { + DisplayError( NULL, wxString::Format( _( "There is a zone that belongs to a not " + "existing net (%s), you should verify it." ), + FromUTF8() ) ); + zone->SetNet( NETINFO_LIST::UNCONNECTED ); + } NeedRIGHT(); break; From cd0d91a611c967cb3e9aff7b7a0bd5e0f45a97d6 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 28 Jan 2014 16:23:08 +0100 Subject: [PATCH 50/95] Added BOARD_[CONNECTED_]ITEM::IsConnected() for checking if a BOARD_ITEM is BOARD_CONNECTED_ITEM as well. --- include/class_board_item.h | 10 ++++++++++ pcbnew/class_board_connected_item.h | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/include/class_board_item.h b/include/class_board_item.h index b6e5e905a6..ceb428af5e 100644 --- a/include/class_board_item.h +++ b/include/class_board_item.h @@ -93,6 +93,16 @@ public: virtual void SetPosition( const wxPoint& aPos ) = 0; + /** + * Function IsConnected() + * Returns information if the object is derived from BOARD_CONNECTED_ITEM. + * @return True if the object is of BOARD_CONNECTED_ITEM type, false otherwise. + */ + virtual bool IsConnected() const + { + return false; + } + /** * A value of wxPoint(0,0) which can be passed to the Draw() functions. */ diff --git a/pcbnew/class_board_connected_item.h b/pcbnew/class_board_connected_item.h index b7a059c9f4..eab6d310fd 100644 --- a/pcbnew/class_board_connected_item.h +++ b/pcbnew/class_board_connected_item.h @@ -70,6 +70,12 @@ public: BOARD_CONNECTED_ITEM( const BOARD_CONNECTED_ITEM& aItem ); + ///> @copydoc BOARD_ITEM::IsConnected() + bool IsConnected() const + { + return true; + } + /** * Function GetNet * @return int - the net code. From 6e28e5bdf0902af26cdbf7ecb1710ec19eba174e Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 28 Jan 2014 16:30:58 +0100 Subject: [PATCH 51/95] Added RN_DATA::Add()/Remove() methods. RN_DATA::Update()/AddSimple() take BOARD_ITEM* as the parameter (instead of being split to versions with BOARD_CONNECTED_ITEM* and MODULE*), to make the code look clearer. --- pcbnew/ratsnest_data.cpp | 177 +++++++++++++++++++++++------------ pcbnew/ratsnest_data.h | 35 ++++--- pcbnew/router/pns_router.cpp | 2 +- pcbnew/tools/edit_tool.cpp | 17 +--- 4 files changed, 140 insertions(+), 91 deletions(-) diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index f33d5e96e6..ea9d8a7c57 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -673,6 +673,39 @@ std::list RN_NET::GetNodes( const BOARD_CONNECTED_ITEM* aItem ) con } +void RN_DATA::AddSimple( const BOARD_ITEM* aItem ) +{ + int net; + + if( aItem->IsConnected() ) + { + const BOARD_CONNECTED_ITEM* item = static_cast( aItem ); + net = item->GetNet(); + + if( net < 1 ) // do not process unconnected items + return; + + // Get list of nodes responding to the item + std::list nodes = m_nets[net].GetNodes( item ); + std::list::iterator it, itEnd; + + for( it = nodes.begin(), itEnd = nodes.end(); it != itEnd; ++it ) + m_nets[net].AddSimpleNode( *it ); + } + else if( aItem->Type() == PCB_MODULE_T ) + { + const MODULE* module = static_cast( aItem ); + + for( const D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() ) + AddSimple( pad ); + + return; + } + else + return; +} + + void RN_NET::ClearSimple() { BOOST_FOREACH( const RN_NODE_PTR& node, m_simpleNodes ) @@ -682,28 +715,6 @@ void RN_NET::ClearSimple() } -void RN_DATA::AddSimple( const BOARD_CONNECTED_ITEM* aItem ) -{ - int net = aItem->GetNet(); - if( net < 1 ) // do not process unconnected items - return; - - // Get list of nodes responding to the item - std::list nodes = m_nets[net].GetNodes( aItem ); - std::list::iterator it, itEnd; - - for( it = nodes.begin(), itEnd = nodes.end(); it != itEnd; ++it ) - m_nets[net].AddSimpleNode( *it ); -} - - -void RN_DATA::AddSimple( const MODULE* aModule ) -{ - for( const D_PAD* pad = aModule->Pads().GetFirst(); pad; pad = pad->Next() ) - AddSimple( pad ); -} - - void RN_NET::processZones() { BOOST_FOREACH( std::deque& edges, m_zoneConnections | boost::adaptors::map_values ) @@ -762,45 +773,51 @@ void RN_DATA::updateNet( int aNetCode ) } -void RN_DATA::Update( const BOARD_CONNECTED_ITEM* aItem ) +void RN_DATA::Add( const BOARD_ITEM* aItem ) { - int net = aItem->GetNet(); - if( net < 1 ) // do not process unconnected items + int net; + + if( aItem->IsConnected() ) + { + net = static_cast( aItem )->GetNet(); + if( net < 1 ) // do not process unconnected items + return; + } + else if( aItem->Type() == PCB_MODULE_T ) + { + const MODULE* module = static_cast( aItem ); + for( const D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() ) + { + net = pad->GetNet(); + + if( net < 1 ) // do not process unconnected items + continue; + + m_nets[net].AddItem( pad ); + } + + return; + } + else return; switch( aItem->Type() ) { case PCB_PAD_T: - { - const D_PAD* pad = static_cast( aItem ); - m_nets[net].RemoveItem( pad ); - m_nets[net].AddItem( pad ); - } - break; + m_nets[net].AddItem( static_cast( aItem ) ); + break; case PCB_TRACE_T: - { - const TRACK* track = static_cast( aItem ); - m_nets[net].RemoveItem( track ); - m_nets[net].AddItem( track ); - } - break; + m_nets[net].AddItem( static_cast( aItem ) ); + break; case PCB_VIA_T: - { - const SEGVIA* via = static_cast( aItem ); - m_nets[net].RemoveItem( via ); - m_nets[net].AddItem( via ); - } - break; + m_nets[net].AddItem( static_cast( aItem ) ); + break; case PCB_ZONE_AREA_T: - { - const ZONE_CONTAINER* zone = static_cast( aItem ); - m_nets[net].RemoveItem( zone); - m_nets[net].AddItem( zone ); - } - break; + m_nets[net].AddItem( static_cast( aItem ) ); + break; default: break; @@ -808,18 +825,62 @@ void RN_DATA::Update( const BOARD_CONNECTED_ITEM* aItem ) } -void RN_DATA::Update( const MODULE* aModule ) +void RN_DATA::Remove( const BOARD_ITEM* aItem ) { - for( const D_PAD* pad = aModule->Pads().GetFirst(); pad; pad = pad->Next() ) - { - int net = pad->GetNet(); + int net; - if( net > 0 ) // do not process unconnected items - { - m_nets[net].RemoveItem( pad ); - m_nets[net].AddItem( pad ); - } + if( aItem->IsConnected() ) + { + net = static_cast( aItem )->GetNet(); + if( net < 1 ) // do not process unconnected items + return; } + else if( aItem->Type() == PCB_MODULE_T ) + { + const MODULE* module = static_cast( aItem ); + for( const D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() ) + { + net = pad->GetNet(); + + if( net < 1 ) // do not process unconnected items + continue; + + m_nets[net].RemoveItem( pad ); + } + + return; + } + else + return; + + switch( aItem->Type() ) + { + case PCB_PAD_T: + m_nets[net].RemoveItem( static_cast( aItem ) ); + break; + + case PCB_TRACE_T: + m_nets[net].RemoveItem( static_cast( aItem ) ); + break; + + case PCB_VIA_T: + m_nets[net].RemoveItem( static_cast( aItem ) ); + break; + + case PCB_ZONE_AREA_T: + m_nets[net].RemoveItem( static_cast( aItem ) ); + break; + + default: + break; + } +} + + +void RN_DATA::Update( const BOARD_ITEM* aItem ) +{ + Remove( aItem ); + Add( aItem ); } diff --git a/pcbnew/ratsnest_data.h b/pcbnew/ratsnest_data.h index f8ffbf2406..860fffa5fa 100644 --- a/pcbnew/ratsnest_data.h +++ b/pcbnew/ratsnest_data.h @@ -524,34 +524,33 @@ public: RN_DATA( const BOARD* aBoard ) : m_board( aBoard ) {} /** - * Function UpdateItem() - * Updates ratsnest data for an item. - * @param aItem is an item to be updated. + * Function Add() + * Adds an item to the ratsnest data. + * @param aItem is an item to be added. */ - void Update( const BOARD_CONNECTED_ITEM* aItem ); + void Add( const BOARD_ITEM* aItem ); /** - * Function UpdateItem() - * Updates ratsnest data for a module. - * @param aItem is a module to be updated. + * Function Remove() + * Removes an item from the ratsnest data. + * @param aItem is an item to be updated. */ - void Update( const MODULE* aModule ); + void Remove( const BOARD_ITEM* aItem ); + + /** + * Function Update() + * Updates the ratsnest data for an item. + * @param aItem is an item to be updated. + */ + void Update( const BOARD_ITEM* aItem ); /** * Function AddSimple() * Sets an item to be drawn in simple mode (ie. one line per node, instead of full ratsnest). - * It is used for drawing temporary ratsnest, eg. while moving an item. + * It is used for drawing quick, temporary ratsnest, eg. while moving an item. * @param aItem is an item to be drawn in simple node. */ - void AddSimple( const BOARD_CONNECTED_ITEM* aItem ); - - /** - * Function AddSimple() - * Sets a module to be drawn in simple mode (ie. one line per node, instead of full ratsnest). - * It is used for drawing temporary ratsnest, eg. while moving a module. - * @param aModule is a module to be drawn in simple node. - */ - void AddSimple( const MODULE* aModule ); + void AddSimple( const BOARD_ITEM* aItem ); /** * Function ClearSimple() diff --git a/pcbnew/router/pns_router.cpp b/pcbnew/router/pns_router.cpp index e70fe550bf..9373ff985f 100644 --- a/pcbnew/router/pns_router.cpp +++ b/pcbnew/router/pns_router.cpp @@ -631,7 +631,7 @@ void PNS_ROUTER::commitRouting( PNS_NODE* aNode ) newBI->ClearFlags(); m_view->Add( newBI ); m_board->Add( newBI ); - m_board->GetRatsnest()->Update( static_cast( newBI ) ); + m_board->GetRatsnest()->Update( newBI ); newBI->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } } diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 277fefa8c1..706134d1bc 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -376,20 +376,9 @@ void EDIT_TOOL::updateRatsnest( bool aRedraw ) { BOARD_ITEM* item = static_cast( selection.items.GetPickedItem( i ) ); - if( item->Type() == PCB_PAD_T || item->Type() == PCB_TRACE_T || - item->Type() == PCB_VIA_T || item->Type() == PCB_ZONE_AREA_T ) - { - ratsnest->Update( static_cast( item ) ); + ratsnest->Update( static_cast( item ) ); - if( aRedraw ) - ratsnest->AddSimple( static_cast( item ) ); - } - else if( item->Type() == PCB_MODULE_T ) - { - ratsnest->Update( static_cast( item ) ); - - if( aRedraw ) - ratsnest->AddSimple( static_cast( item ) ); - } + if( aRedraw ) + ratsnest->AddSimple( item ); } } From a0518879716860274b37a68a8d6a0a71b80356fe Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 29 Jan 2014 10:17:14 +0100 Subject: [PATCH 52/95] Ratsnest is updated after rotation, flip, undo/redo operations. Fixed crashes of ratsnest when a pointer for an item has changed after undo/redo operations. Vias are properly removed from ratsnest (pcbnew/class_board.cpp). --- pcbnew/board_undo_redo.cpp | 24 ++++++++++++++++++------ pcbnew/class_board.cpp | 9 ++++++++- pcbnew/tools/edit_tool.cpp | 19 ++++++++++++------- 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/pcbnew/board_undo_redo.cpp b/pcbnew/board_undo_redo.cpp index a0bb32575c..484b76fa05 100644 --- a/pcbnew/board_undo_redo.cpp +++ b/pcbnew/board_undo_redo.cpp @@ -41,6 +41,8 @@ #include #include +#include + #include #include @@ -453,13 +455,14 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed bool not_found = false; bool reBuild_ratsnest = false; KIGFX::VIEW* view = GetGalCanvas()->GetView(); + RN_DATA* ratsnest = GetBoard()->GetRatsnest(); // Undo in the reverse order of list creation: (this can allow stacked changes // like the same item can be changes and deleted in the same complex command bool build_item_list = true; // if true the list of existing items must be rebuilt - for( int ii = aList->GetCount()-1; ii >= 0 ; ii-- ) + for( int ii = aList->GetCount() - 1; ii >= 0 ; ii-- ) { item = (BOARD_ITEM*) aList->GetPickedItem( ii ); wxASSERT( item ); @@ -519,8 +522,8 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed if( item->Type() == PCB_MODULE_T ) { MODULE* oldModule = static_cast( item ); - oldModule->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Remove ), - view ) ); + oldModule->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Remove ), view ) ); + oldModule->RunOnChildren( std::bind1st( std::mem_fun( &RN_DATA::Remove ), ratsnest ) ); } item->SwapData( image ); @@ -530,8 +533,8 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed if( item->Type() == PCB_MODULE_T ) { MODULE* newModule = static_cast( item ); - newModule->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), - view ) ); + newModule->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), view ) ); + newModule->RunOnChildren( std::bind1st( std::mem_fun( &RN_DATA::Add ), ratsnest ) ); } item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS ); @@ -577,11 +580,13 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed case UR_ROTATED: item->Rotate( aList->m_TransformPoint, aRedoCommand ? m_rotationAngle : -m_rotationAngle ); + item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); break; case UR_ROTATED_CLOCKWISE: item->Rotate( aList->m_TransformPoint, aRedoCommand ? -m_rotationAngle : m_rotationAngle ); + item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); break; case UR_FLIPPED: @@ -598,6 +603,8 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed } break; } + + ratsnest->Update( item ); } if( not_found ) @@ -605,7 +612,12 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed // Rebuild pointers and ratsnest that can be changed. if( reBuild_ratsnest && aRebuildRatsnet ) - Compile_Ratsnest( NULL, true ); + { + if( IsGalCanvasActive() ) + ratsnest->Recalculate(); + else + Compile_Ratsnest( NULL, true ); + } } diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 446f1f5bf3..5c32b53881 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -895,7 +895,6 @@ BOARD_ITEM* BOARD::Remove( BOARD_ITEM* aBoardItem ) break; case PCB_TRACE_T: - case PCB_VIA_T: { TRACK* track = static_cast( aBoardItem ); m_Track.Remove( track ); @@ -903,6 +902,14 @@ BOARD_ITEM* BOARD::Remove( BOARD_ITEM* aBoardItem ) } break; + case PCB_VIA_T: + { + SEGVIA* via = static_cast( aBoardItem ); + m_Track.Remove( via ); + m_ratsnest->GetNets()[via->GetNet()].RemoveItem( via ); + } + break; + case PCB_ZONE_T: m_Zone.Remove( (SEGZONE*) aBoardItem ); break; diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 706134d1bc..451164bf23 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -119,7 +119,7 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) { Remove( aEvent ); - break; + break; // exit the loop, as there is no further processing for removed items } } @@ -207,6 +207,7 @@ int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) setTransitions(); updateRatsnest( true ); + getModel( PCB_T )->GetRatsnest()->Recalculate(); return 0; } @@ -233,12 +234,14 @@ int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } - if( m_dragging ) - selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - setTransitions(); updateRatsnest( true ); + if( m_dragging ) + selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + else + getModel( PCB_T )->GetRatsnest()->Recalculate(); + return 0; } @@ -264,12 +267,14 @@ int EDIT_TOOL::Flip( TOOL_EVENT& aEvent ) item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS ); } - if( m_dragging ) - selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - setTransitions(); updateRatsnest( true ); + if( m_dragging ) + selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + else + getModel( PCB_T )->GetRatsnest()->Recalculate(); + return 0; } From 2171fd0b1825d35059a095e270eeef90af4b2439 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 29 Jan 2014 14:51:50 +0100 Subject: [PATCH 53/95] Ratsnest lines are drawn using a more transparent color. BOARD::chainMarkedSegments() uses a safer method for gettings pads. --- pcbnew/class_board.cpp | 2 +- pcbnew/ratsnest_viewitem.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 5c32b53881..90d8ad7b20 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -206,7 +206,7 @@ void BOARD::chainMarkedSegments( wxPoint aPosition, LAYER_MSK aLayerMask, TRACK_ */ for( ; ; ) { - if( GetPadFast( aPosition, aLayerMask ) != NULL ) + if( GetPad( aPosition, aLayerMask ) != NULL ) return; /* Test for a via: a via changes the layer mask and can connect a lot diff --git a/pcbnew/ratsnest_viewitem.cpp b/pcbnew/ratsnest_viewitem.cpp index 282c0998a0..634a0d57c9 100644 --- a/pcbnew/ratsnest_viewitem.cpp +++ b/pcbnew/ratsnest_viewitem.cpp @@ -57,7 +57,7 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const aGal->SetIsStroke( true ); aGal->SetIsFill( false ); aGal->SetLineWidth( 1.0 ); - aGal->SetStrokeColor( COLOR4D( 1.0, 1.0, 1.0, 0.4 ) ); + aGal->SetStrokeColor( COLOR4D( 0.8, 0.8, 0.8, 0.2 ) ); // Draw the temporary ratsnest BOOST_FOREACH( const RN_NET& net, m_data->GetNets() ) From c2a12d903f94f96faf68b838858579d356f8b6c3 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 29 Jan 2014 15:24:19 +0100 Subject: [PATCH 54/95] RN_DATA::GetNets() -> RN_DATA::GetNet() with an assert to check if someone calls it for the unconnected net. Only items that belong to a net are removed from ratsnest. --- pcbnew/class_board.cpp | 16 ++++++++++++---- pcbnew/ratsnest_data.h | 23 ++++++++++++++++++----- pcbnew/ratsnest_viewitem.cpp | 6 ++++-- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 90d8ad7b20..896e44b8f6 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -880,7 +880,8 @@ BOARD_ITEM* BOARD::Remove( BOARD_ITEM* aBoardItem ) } } - m_ratsnest->GetNets()[zone->GetNet()].RemoveItem( zone ); + if( zone->GetNet() > 0 ) + m_ratsnest->GetNet( zone->GetNet() ).RemoveItem( zone ); } break; @@ -890,7 +891,10 @@ BOARD_ITEM* BOARD::Remove( BOARD_ITEM* aBoardItem ) m_Modules.Remove( (MODULE*) aBoardItem ); for( D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() ) - m_ratsnest->GetNets()[pad->GetNet()].RemoveItem( pad ); + { + if( pad->GetNet() > 0 ) + m_ratsnest->GetNet( pad->GetNet() ).RemoveItem( pad ); + } } break; @@ -898,7 +902,9 @@ BOARD_ITEM* BOARD::Remove( BOARD_ITEM* aBoardItem ) { TRACK* track = static_cast( aBoardItem ); m_Track.Remove( track ); - m_ratsnest->GetNets()[track->GetNet()].RemoveItem( track ); + + if( track->GetNet() > 0 ) + m_ratsnest->GetNet( track->GetNet() ).RemoveItem( track ); } break; @@ -906,7 +912,9 @@ BOARD_ITEM* BOARD::Remove( BOARD_ITEM* aBoardItem ) { SEGVIA* via = static_cast( aBoardItem ); m_Track.Remove( via ); - m_ratsnest->GetNets()[via->GetNet()].RemoveItem( via ); + + if( via->GetNet() > 0 ) + m_ratsnest->GetNet( via->GetNet() ).RemoveItem( via ); } break; diff --git a/pcbnew/ratsnest_data.h b/pcbnew/ratsnest_data.h index 860fffa5fa..4340c74e78 100644 --- a/pcbnew/ratsnest_data.h +++ b/pcbnew/ratsnest_data.h @@ -573,13 +573,26 @@ public: void Recalculate( int aNet = -1 ); /** - * Function GetNets() - * Returns ratsnest grouped by net numbers. - * @return Vector of ratsnest grouped by net numbers. + * Function GetNetCount() + * Returns the number of nets handled by the ratsnest. + * @return Number of the nets. */ - std::vector& GetNets() + int GetNetCount() const { - return m_nets; + return m_nets.size(); + } + + /** + * Function GetNet() + * Returns ratsnest grouped by net numbers. + * @param aNetCode is the net code. + * @return Ratsnest data for a specified net. + */ + RN_NET& GetNet( int aNetCode ) + { + assert( aNetCode > 0 ); // ratsnest does not handle the unconnected net + + return m_nets[aNetCode]; } protected: diff --git a/pcbnew/ratsnest_viewitem.cpp b/pcbnew/ratsnest_viewitem.cpp index 634a0d57c9..0e23b00306 100644 --- a/pcbnew/ratsnest_viewitem.cpp +++ b/pcbnew/ratsnest_viewitem.cpp @@ -59,9 +59,11 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const aGal->SetLineWidth( 1.0 ); aGal->SetStrokeColor( COLOR4D( 0.8, 0.8, 0.8, 0.2 ) ); - // Draw the temporary ratsnest - BOOST_FOREACH( const RN_NET& net, m_data->GetNets() ) + // Draw the temporary ratsnest (skip the unconnected net [net code == 0]) + for( int i = 1; i < m_data->GetNetCount(); ++i ) { + const RN_NET& net = m_data->GetNet( i ); + if( !net.IsVisible() ) continue; From 4566d8717aa2fcb03d9178b708baa142d41192a9 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 29 Jan 2014 15:35:25 +0100 Subject: [PATCH 55/95] PNS_ITEM::m_parent: BOARD_ITEM->BOARD_CONNECTED_ITEM --- pcbnew/router/pns_item.h | 8 ++++---- pcbnew/router/pns_router.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pcbnew/router/pns_item.h b/pcbnew/router/pns_item.h index e9c856e086..c375a7ada5 100644 --- a/pcbnew/router/pns_item.h +++ b/pcbnew/router/pns_item.h @@ -28,7 +28,7 @@ #include "pns_layerset.h" -class BOARD_ITEM; +class BOARD_CONNECTED_ITEM; class PNS_NODE; /** @@ -94,8 +94,8 @@ public: const std::string GetKindStr() const; ///> Gets/Sets the corresponding parent object in the host application's model (pcbnew) - void SetParent( BOARD_ITEM* aParent ) { m_parent = aParent; } - BOARD_ITEM* GetParent() const { return m_parent; } + void SetParent( BOARD_CONNECTED_ITEM* aParent ) { m_parent = aParent; } + BOARD_CONNECTED_ITEM* GetParent() const { return m_parent; } ///> Net accessors int GetNet() const { return m_net; } @@ -145,7 +145,7 @@ private: protected: PnsKind m_kind; - BOARD_ITEM* m_parent; + BOARD_CONNECTED_ITEM* m_parent; PNS_NODE* m_world; PNS_NODE* m_owner; PNS_LAYERSET m_layers; diff --git a/pcbnew/router/pns_router.cpp b/pcbnew/router/pns_router.cpp index 9373ff985f..991dd71e84 100644 --- a/pcbnew/router/pns_router.cpp +++ b/pcbnew/router/pns_router.cpp @@ -580,7 +580,7 @@ void PNS_ROUTER::commitRouting( PNS_NODE* aNode ) for( unsigned int i = 0; i < removed.size(); i++ ) { - BOARD_ITEM* parent = removed[i]->GetParent(); + BOARD_CONNECTED_ITEM* parent = removed[i]->GetParent(); if( parent ) { @@ -591,7 +591,7 @@ void PNS_ROUTER::commitRouting( PNS_NODE* aNode ) BOOST_FOREACH( PNS_ITEM* item, added ) { - BOARD_ITEM* newBI = NULL; + BOARD_CONNECTED_ITEM* newBI = NULL; switch( item->GetKind() ) { From d2e865146b3664d4301721e28682f3e69e89591a Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 30 Jan 2014 11:18:58 +0100 Subject: [PATCH 56/95] Added a new tool event: TA_UNDO_REDO, sent after undo/redo operation is issued. --- common/tool/tool_event.cpp | 1 + include/tool/tool_event.h | 5 ++++- include/wxPcbStruct.h | 4 ++-- pcbnew/board_undo_redo.cpp | 22 ++++++++++------------ pcbnew/tools/selection_tool.cpp | 6 ++++++ 5 files changed, 23 insertions(+), 15 deletions(-) diff --git a/common/tool/tool_event.cpp b/common/tool/tool_event.cpp index 481b8c1b95..07460f3571 100644 --- a/common/tool/tool_event.cpp +++ b/common/tool/tool_event.cpp @@ -91,6 +91,7 @@ const std::string TOOL_EVENT::Format() const { TA_CANCEL_TOOL, "cancel-tool" }, { TA_CONTEXT_MENU_UPDATE, "context-menu-update" }, { TA_CONTEXT_MENU_CHOICE, "context-menu-choice" }, + { TA_UNDO_REDO, "undo-redo" }, { TA_ACTION, "action" }, { 0, "" } }; diff --git a/include/tool/tool_event.h b/include/tool/tool_event.h index a2815035d2..9acc1f8f87 100644 --- a/include/tool/tool_event.h +++ b/include/tool/tool_event.h @@ -89,8 +89,11 @@ enum TOOL_ACTIONS // closed it without selecting anything. TA_CONTEXT_MENU_CHOICE = 0x10000, + // This event is sent *after* undo/redo command is finished. + TA_UNDO_REDO = 0x20000, + // Tool action (allows to control tools) - TA_ACTION = 0x20000, + TA_ACTION = 0x40000, TA_ANY = 0xffffffff }; diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index 0ce0ef4ac4..1b5bc4b299 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -704,7 +704,7 @@ public: * - Get an old version of the board from Redo list * @return none */ - void GetBoardFromRedoList( wxCommandEvent& event ); + void GetBoardFromRedoList( wxCommandEvent& aEvent ); /** * Function GetBoardFromUndoList @@ -713,7 +713,7 @@ public: * - Get an old version of the board from Undo list * @return none */ - void GetBoardFromUndoList( wxCommandEvent& event ); + void GetBoardFromUndoList( wxCommandEvent& aEvent ); /* Block operations: */ diff --git a/pcbnew/board_undo_redo.cpp b/pcbnew/board_undo_redo.cpp index 484b76fa05..3112bc5e27 100644 --- a/pcbnew/board_undo_redo.cpp +++ b/pcbnew/board_undo_redo.cpp @@ -621,16 +621,11 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed } -void PCB_EDIT_FRAME::GetBoardFromUndoList( wxCommandEvent& event ) +void PCB_EDIT_FRAME::GetBoardFromUndoList( wxCommandEvent& aEvent ) { if( GetScreen()->GetUndoCommandCount() <= 0 ) return; - // Clear the selection, as it may be altered with undone items - SELECTION_TOOL* selectionTool = static_cast( m_toolManager->FindTool( - "pcbnew.InteractiveSelection" ) ); - selectionTool->ClearSelection(); - /* Get the old list */ PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList(); /* Undo the command */ @@ -640,21 +635,20 @@ void PCB_EDIT_FRAME::GetBoardFromUndoList( wxCommandEvent& event ) List->ReversePickersListOrder(); GetScreen()->PushCommandToRedoList( List ); + // Inform tools that undo has just occurred + TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL ); + m_toolManager->ProcessEvent( event ); + OnModify(); m_canvas->Refresh(); } -void PCB_EDIT_FRAME::GetBoardFromRedoList( wxCommandEvent& event ) +void PCB_EDIT_FRAME::GetBoardFromRedoList( wxCommandEvent& aEvent ) { if( GetScreen()->GetRedoCommandCount() == 0 ) return; - // Clear the selection, as it may be altered with redone items - SELECTION_TOOL* selectionTool = static_cast( m_toolManager->FindTool( - "pcbnew.InteractiveSelection" ) ); - selectionTool->ClearSelection(); - /* Get the old list */ PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromRedoList(); @@ -665,6 +659,10 @@ void PCB_EDIT_FRAME::GetBoardFromRedoList( wxCommandEvent& event ) List->ReversePickersListOrder(); GetScreen()->PushCommandToUndoList( List ); + // Inform tools that redo has just occurred + TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL ); + m_toolManager->ProcessEvent( event ); + OnModify(); m_canvas->Refresh(); } diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 4d4d8e5404..324bb50032 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -100,6 +100,12 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) // This tool never exits } + else if( evt->Action() == TA_UNDO_REDO ) + { + // Clear the selection, as it may be altered with undone items + ClearSelection(); + } + // single click? Select single object else if( evt->IsClick( BUT_LEFT ) ) { From 89463b0d2d804107f7a9d6a1fac594a59b036f12 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 30 Jan 2014 11:32:08 +0100 Subject: [PATCH 57/95] Undo buffer for the PNS router. Still, it has a bug - it crashes when an undo/redo operation is performed while routing a track. --- pcbnew/router/pns_router.cpp | 5 +++-- pcbnew/router/pns_router.h | 16 ++++++++++++++++ pcbnew/router/router_tool.cpp | 11 +++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/pcbnew/router/pns_router.cpp b/pcbnew/router/pns_router.cpp index 991dd71e84..3046c13f6e 100644 --- a/pcbnew/router/pns_router.cpp +++ b/pcbnew/router/pns_router.cpp @@ -241,7 +241,6 @@ void PNS_ROUTER::SyncWorld() ClearWorld(); - m_clearanceFunc = new PCBNEW_CLEARANCE_FUNC( m_board ); m_world = new PNS_NODE(); m_world->SetClearanceFunctor( m_clearanceFunc ); @@ -584,8 +583,9 @@ void PNS_ROUTER::commitRouting( PNS_NODE* aNode ) if( parent ) { - m_view->Remove( parent ); + m_undoBuffer.PushItem( ITEM_PICKER( parent, UR_DELETED ) ); m_board->Remove( parent ); + m_view->Remove( parent ); } } @@ -632,6 +632,7 @@ void PNS_ROUTER::commitRouting( PNS_NODE* aNode ) m_view->Add( newBI ); m_board->Add( newBI ); m_board->GetRatsnest()->Update( newBI ); + m_undoBuffer.PushItem( ITEM_PICKER( newBI, UR_NEW ) ); newBI->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } } diff --git a/pcbnew/router/pns_router.h b/pcbnew/router/pns_router.h index 0bb882fa25..3ba7be0125 100644 --- a/pcbnew/router/pns_router.h +++ b/pcbnew/router/pns_router.h @@ -27,6 +27,7 @@ #include #include +#include #include "pns_routing_settings.h" #include "pns_item.h" @@ -137,6 +138,18 @@ public: const PNS_ITEMSET QueryHoverItems( const VECTOR2I& aP ); const VECTOR2I SnapToItem( PNS_ITEM* item, VECTOR2I aP, bool& aSplitsSegment ); + /** + * Returns the last changes introduced by the router. After calling the method the list of + * changes is cleared, so only the latest changes are stored. + */ + PICKED_ITEMS_LIST GetLastChanges() + { + PICKED_ITEMS_LIST copy = m_undoBuffer; + m_undoBuffer.ClearItemsList(); // TODO and delete? + + return copy; + } + private: void clearViewFlags(); @@ -188,6 +201,9 @@ private: PNS_CLEARANCE_FUNC* m_clearanceFunc; boost::unordered_set m_hiddenItems; + + ///> Stores list of modified items in the current operation + PICKED_ITEMS_LIST m_undoBuffer; }; #endif diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index b301901048..ed3eb18092 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -322,6 +322,11 @@ void ROUTER_TOOL::startRouting() updateEndItem( *evt ); m_router->Move( m_endSnapPoint, m_endItem ); } + else if( evt->Action() == TA_UNDO_REDO ) + { + std::cout << "syncing the world while routing, I am going to craaaaaaaaaaaash!" << std::endl; + m_router->SyncWorld(); + } else if( evt->IsClick( BUT_LEFT ) ) { updateEndItem( *evt ); @@ -371,6 +376,10 @@ void ROUTER_TOOL::startRouting() m_router->StopRouting(); + // Save the recent changes in the undo buffer + getEditFrame()->SaveCopyInUndoList( m_router->GetLastChanges(), UR_UNSPECIFIED ); + getEditFrame()->OnModify(); + ctls->SetAutoPan( false ); ctls->ForceCursorPosition( false ); highlightNet( false ); @@ -392,6 +401,8 @@ int ROUTER_TOOL::Main( TOOL_EVENT& aEvent ) { if( evt->IsCancel() ) break; // Finish + else if( evt->Action() == TA_UNDO_REDO ) + m_router->SyncWorld(); else if( evt->IsMotion() ) updateStartItem( *evt ); else if( evt->IsClick( BUT_LEFT ) ) From 48c10f9e5b231aff2933bfe35790f15a2e638937 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 30 Jan 2014 15:46:39 +0100 Subject: [PATCH 58/95] Another way of handling items for the ratsnest (clearer and now finally supports undo/redo of the PNS created tracks). --- pcbnew/board_undo_redo.cpp | 12 +++++----- pcbnew/class_board.cpp | 46 +++++++++----------------------------- pcbnew/pcb_parser.cpp | 4 ++-- pcbnew/pcbframe.cpp | 1 - pcbnew/ratsnest_data.cpp | 14 ++++++++---- 5 files changed, 28 insertions(+), 49 deletions(-) diff --git a/pcbnew/board_undo_redo.cpp b/pcbnew/board_undo_redo.cpp index 3112bc5e27..68d008bebb 100644 --- a/pcbnew/board_undo_redo.cpp +++ b/pcbnew/board_undo_redo.cpp @@ -548,8 +548,7 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed if( item->Type() == PCB_MODULE_T ) { MODULE* module = static_cast( item ); - module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Remove ), - view ) ); + module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Remove ), view ) ); } view->Remove( item ); @@ -563,8 +562,7 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed if( item->Type() == PCB_MODULE_T ) { MODULE* module = static_cast( item ); - module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), - view ) ); + module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), view ) ); } view->Add( item ); @@ -575,23 +573,27 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed case UR_MOVED: item->Move( aRedoCommand ? aList->m_TransformPoint : -aList->m_TransformPoint ); item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + ratsnest->Update( item ); break; case UR_ROTATED: item->Rotate( aList->m_TransformPoint, aRedoCommand ? m_rotationAngle : -m_rotationAngle ); item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + ratsnest->Update( item ); break; case UR_ROTATED_CLOCKWISE: item->Rotate( aList->m_TransformPoint, aRedoCommand ? -m_rotationAngle : m_rotationAngle ); item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + ratsnest->Update( item ); break; case UR_FLIPPED: item->Flip( aList->m_TransformPoint ); item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS ); + ratsnest->Update( item ); break; default: @@ -603,8 +605,6 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed } break; } - - ratsnest->Update( item ); } if( not_found ) diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 896e44b8f6..da3bd81fa9 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -842,6 +842,8 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, int aControl ) } break; } + + m_ratsnest->Add( aBoardItem ); } @@ -867,56 +869,26 @@ BOARD_ITEM* BOARD::Remove( BOARD_ITEM* aBoardItem ) break; case PCB_ZONE_AREA_T: // this one uses a vector - { - ZONE_CONTAINER* zone = static_cast( aBoardItem ); - // find the item in the vector, then delete then erase it. - for( unsigned i = 0; i < m_ZoneDescriptorList.size(); ++i ) + for( unsigned i = 0; iGetNet() > 0 ) - m_ratsnest->GetNet( zone->GetNet() ).RemoveItem( zone ); - } - break; + break; case PCB_MODULE_T: - { - MODULE* module = static_cast( aBoardItem ); m_Modules.Remove( (MODULE*) aBoardItem ); - - for( D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() ) - { - if( pad->GetNet() > 0 ) - m_ratsnest->GetNet( pad->GetNet() ).RemoveItem( pad ); - } - } - break; + break; case PCB_TRACE_T: - { - TRACK* track = static_cast( aBoardItem ); - m_Track.Remove( track ); - - if( track->GetNet() > 0 ) - m_ratsnest->GetNet( track->GetNet() ).RemoveItem( track ); - } - break; - case PCB_VIA_T: - { - SEGVIA* via = static_cast( aBoardItem ); - m_Track.Remove( via ); - - if( via->GetNet() > 0 ) - m_ratsnest->GetNet( via->GetNet() ).RemoveItem( via ); - } - break; + m_Track.Remove( (TRACK*) aBoardItem ); + break; case PCB_ZONE_T: m_Zone.Remove( (SEGZONE*) aBoardItem ); @@ -935,6 +907,8 @@ BOARD_ITEM* BOARD::Remove( BOARD_ITEM* aBoardItem ) wxFAIL_MSG( wxT( "BOARD::Remove() needs more ::Type() support" ) ); } + m_ratsnest->Remove( aBoardItem ); + return aBoardItem; } diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index 41fb0037e5..1f06ac2ed1 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -428,11 +428,11 @@ BOARD* PCB_PARSER::parseBOARD() throw( IO_ERROR, PARSE_ERROR ) break; case T_segment: - m_board->m_Track.Append( parseTRACK() ); + m_board->Add( parseTRACK(), ADD_APPEND ); break; case T_via: - m_board->m_Track.Append( parseSEGVIA() ); + m_board->Add( parseSEGVIA(), ADD_APPEND ); break; case T_zone: diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 8823dcf4c3..72930927ca 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -612,7 +612,6 @@ void PCB_EDIT_FRAME::ViewReloadBoard( const BOARD* aBoard ) const // Add an entry for the ratsnest RN_DATA* ratsnest = aBoard->GetRatsnest(); - ratsnest->ProcessBoard(); ratsnest->Recalculate(); view->Add( new KIGFX::RATSNEST_VIEWITEM( ratsnest ) ); diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index ea9d8a7c57..99c84d05eb 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -782,6 +782,10 @@ void RN_DATA::Add( const BOARD_ITEM* aItem ) net = static_cast( aItem )->GetNet(); if( net < 1 ) // do not process unconnected items return; + + // Autoresize + if( net >= (int) m_nets.size() ) + m_nets.resize( net + 1 ); } else if( aItem->Type() == PCB_MODULE_T ) { @@ -789,10 +793,13 @@ void RN_DATA::Add( const BOARD_ITEM* aItem ) for( const D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() ) { net = pad->GetNet(); - if( net < 1 ) // do not process unconnected items continue; + // Autoresize + if( net >= (int) m_nets.size() ) + m_nets.resize( net + 1 ); + m_nets[net].AddItem( pad ); } @@ -841,7 +848,6 @@ void RN_DATA::Remove( const BOARD_ITEM* aItem ) for( const D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() ) { net = pad->GetNet(); - if( net < 1 ) // do not process unconnected items continue; @@ -916,8 +922,8 @@ void RN_DATA::Recalculate( int aNet ) { if( aNet < 0 ) // Recompute everything { - // Start with net number 1, as 0 stand for not connected - for( unsigned int i = 1; i < m_board->GetNetCount(); ++i ) + // Start with net number 1, as 0 stands for not connected + for( unsigned int i = 1; i < m_nets.size(); ++i ) { // Recompute only nets that require it if( m_nets[i].IsDirty() ) From ecf6698d4f515cad1eb0e46d9f127cd87711b32f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 30 Jan 2014 17:11:40 +0100 Subject: [PATCH 59/95] Fixed undo/redo while routing with the PNS error. --- pcbnew/router/router_tool.cpp | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index ed3eb18092..d7c29d10ff 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -290,6 +290,7 @@ void ROUTER_TOOL::updateEndItem( TOOL_EVENT& aEvent ) void ROUTER_TOOL::startRouting() { + bool saveUndoBuffer = true; VIEW_CONTROLS* ctls = getViewControls(); int width = getDefaultWidth( m_startItem ? m_startItem->GetNet() : -1 ); @@ -317,16 +318,16 @@ void ROUTER_TOOL::startRouting() { if( evt->IsCancel() ) break; + else if( evt->Action() == TA_UNDO_REDO ) + { + saveUndoBuffer = false; + break; + } else if( evt->IsMotion() ) { updateEndItem( *evt ); m_router->Move( m_endSnapPoint, m_endItem ); } - else if( evt->Action() == TA_UNDO_REDO ) - { - std::cout << "syncing the world while routing, I am going to craaaaaaaaaaaash!" << std::endl; - m_router->SyncWorld(); - } else if( evt->IsClick( BUT_LEFT ) ) { updateEndItem( *evt ); @@ -376,9 +377,17 @@ void ROUTER_TOOL::startRouting() m_router->StopRouting(); - // Save the recent changes in the undo buffer - getEditFrame()->SaveCopyInUndoList( m_router->GetLastChanges(), UR_UNSPECIFIED ); - getEditFrame()->OnModify(); + if( saveUndoBuffer ) + { + // Save the recent changes in the undo buffer + getEditFrame()->SaveCopyInUndoList( m_router->GetLastChanges(), UR_UNSPECIFIED ); + getEditFrame()->OnModify(); + } + else + { + // It was interrupted by TA_UNDO_REDO event, so we have to sync the world now + m_router->SyncWorld(); + } ctls->SetAutoPan( false ); ctls->ForceCursorPosition( false ); From 7caeff6af980cac95d06710c1db58d72a2886855 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 31 Jan 2014 11:16:01 +0100 Subject: [PATCH 60/95] Ratsnest color is saved in RENDER_SETTINGS. Temporary ratsnest is drawn using a brightened color. --- include/gal/color4d.h | 2 +- pcbnew/pcb_painter.cpp | 1 + pcbnew/ratsnest_viewitem.cpp | 10 ++++++++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/include/gal/color4d.h b/include/gal/color4d.h index c476f10e0e..fb4d9d9cf3 100644 --- a/include/gal/color4d.h +++ b/include/gal/color4d.h @@ -136,7 +136,7 @@ public: * Function Brightened * Returns a color that is brighter by a given factor, without modifying object. * @param aFactor Specifies how bright the color should become (valid values: 0.0 .. 1.0). - * @return COLOR4D Highlightedd color. + * @return COLOR4D Highlighted color. */ COLOR4D Brightened( double aFactor ) const { diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 105362f83c..4ffdfa4667 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -75,6 +75,7 @@ void PCB_RENDER_SETTINGS::ImportLegacyColors( COLORS_DESIGN_SETTINGS* aSettings m_layerColors[ITEM_GAL_LAYER( PADS_NETNAMES_VISIBLE )] = COLOR4D( 0.8, 0.8, 0.8, 0.7 ); m_layerColors[ITEM_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE )] = COLOR4D( 0.8, 0.8, 0.8, 0.7 ); m_layerColors[ITEM_GAL_LAYER( PAD_BK_NETNAMES_VISIBLE )] = COLOR4D( 0.8, 0.8, 0.8, 0.7 ); + m_layerColors[ITEM_GAL_LAYER( RATSNEST_VISIBLE )] = COLOR4D( 0.4, 0.4, 0.4, 0.7 ); m_layerColors[ITEM_GAL_LAYER( WORKSHEET )] = COLOR4D( 0.5, 0.0, 0.0, 1.0 ); // Netnames for copper layers diff --git a/pcbnew/ratsnest_viewitem.cpp b/pcbnew/ratsnest_viewitem.cpp index 0e23b00306..7bf9d79568 100644 --- a/pcbnew/ratsnest_viewitem.cpp +++ b/pcbnew/ratsnest_viewitem.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -57,9 +58,9 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const aGal->SetIsStroke( true ); aGal->SetIsFill( false ); aGal->SetLineWidth( 1.0 ); - aGal->SetStrokeColor( COLOR4D( 0.8, 0.8, 0.8, 0.2 ) ); + RENDER_SETTINGS* rs = m_view->GetPainter()->GetSettings(); + COLOR4D color = rs->GetColor( NULL, ITEM_GAL_LAYER( RATSNEST_VISIBLE ) ); - // Draw the temporary ratsnest (skip the unconnected net [net code == 0]) for( int i = 1; i < m_data->GetNetCount(); ++i ) { const RN_NET& net = m_data->GetNet( i ); @@ -70,6 +71,9 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const // Avoid duplicate destinations for ratsnest lines by storing already used nodes boost::unordered_set usedDestinations; + // Set brighter color for the temporary ratsnest + aGal->SetStrokeColor( color.Brightened( 0.8 ) ); + // Draw the "dynamic" ratsnest (ie. for objects that may be currently being moved) BOOST_FOREACH( const RN_NODE_PTR& node, net.GetSimpleNodes() ) { @@ -86,6 +90,8 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const } // Draw the "static" ratsnest + aGal->SetStrokeColor( color ); // using the default ratsnest color + const std::vector* edges = net.GetUnconnected(); if( edges == NULL ) continue; From 8d37c9122f08b028d593c32bddf543c0f6ede725 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 31 Jan 2014 13:14:18 +0100 Subject: [PATCH 61/95] Ratsnest is updated after backend switch. --- pcbnew/pcbframe.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 72930927ca..15822a9b17 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -742,6 +742,9 @@ void PCB_EDIT_FRAME::UseGalCanvas( bool aEnable ) if( aEnable ) { + // Update potential changes in the ratsnest + m_Pcb->GetRatsnest()->Recalculate(); + m_toolManager->SetEnvironment( m_Pcb, GetGalCanvas()->GetView(), GetGalCanvas()->GetViewControls(), this ); m_toolManager->ResetTools( TOOL_BASE::GAL_SWITCH ); From 63196b5a8a3b276cd2f6c7783ea3930d7b887d97 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 31 Jan 2014 13:19:59 +0100 Subject: [PATCH 62/95] Added missing operators==/!= for RN_NODE_PTR. Moved ClearSimple() functions back to the header file. --- pcbnew/ratsnest_data.cpp | 43 ++++++++++++++++++---------------------- pcbnew/ratsnest_data.h | 20 ++++++++++++++++--- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index 99c84d05eb..95ca62e59b 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -35,7 +35,6 @@ #include #include -#include #include #include #include @@ -75,10 +74,21 @@ bool sortArea( const RN_POLY& aP1, const RN_POLY& aP2 ) } +bool operator==( const RN_NODE_PTR& aFirst, const RN_NODE_PTR& aSecond ) +{ + return aFirst->GetX() == aSecond->GetX() && aFirst->GetY() == aSecond->GetY(); +} + + +bool operator!=( const RN_NODE_PTR& aFirst, const RN_NODE_PTR& aSecond ) +{ + return aFirst->GetX() != aSecond->GetX() || aFirst->GetY() != aSecond->GetY(); +} + + bool isEdgeConnectingNode( const RN_EDGE_PTR& aEdge, const RN_NODE_PTR& aNode ) { - return ( aEdge->getSourceNode().get() == aNode.get() ) || - ( aEdge->getTargetNode().get() == aNode.get() ); + return aEdge->getSourceNode() == aNode || aEdge->getTargetNode() == aNode; } @@ -246,7 +256,7 @@ void RN_NET::compute() return; } - else if( boardNodes.size() == 1 || boardNodes.empty() ) // This case is even simpler + else if( boardNodes.size() <= 1 ) // This case is even simpler { m_rnEdges.reset( new std::vector( 0 ) ); @@ -566,17 +576,18 @@ const RN_NODE_PTR RN_NET::GetClosestNode( const RN_NODE_PTR& aNode, for( it = nodes.begin(), itEnd = nodes.end(); it != itEnd; ++it ) { - RN_NODE_PTR baseNode = *it; + RN_NODE_PTR node = *it; // Obviously the distance between node and itself is the shortest, // that's why we have to skip it - if( *it != aNode && aFilter( baseNode ) ) + if( node != aNode && aFilter( node ) ) { - unsigned int distance = getDistance( *it, aNode ); + unsigned int distance = getDistance( node, aNode ); + if( distance < minDistance ) { minDistance = distance; - closest = *it; + closest = node; } } } @@ -706,15 +717,6 @@ void RN_DATA::AddSimple( const BOARD_ITEM* aItem ) } -void RN_NET::ClearSimple() -{ - BOOST_FOREACH( const RN_NODE_PTR& node, m_simpleNodes ) - node->SetFlag( false ); - - m_simpleNodes.clear(); -} - - void RN_NET::processZones() { BOOST_FOREACH( std::deque& edges, m_zoneConnections | boost::adaptors::map_values ) @@ -935,10 +937,3 @@ void RN_DATA::Recalculate( int aNet ) updateNet( aNet ); } } - - -void RN_DATA::ClearSimple() -{ - BOOST_FOREACH( RN_NET& net, m_nets ) - net.ClearSimple(); -} diff --git a/pcbnew/ratsnest_data.h b/pcbnew/ratsnest_data.h index 4340c74e78..d51c070ee8 100644 --- a/pcbnew/ratsnest_data.h +++ b/pcbnew/ratsnest_data.h @@ -37,6 +37,7 @@ #include #include +#include class BOARD; class BOARD_ITEM; @@ -57,6 +58,9 @@ typedef hed::EdgeMST RN_EDGE_MST; typedef boost::shared_ptr RN_EDGE_MST_PTR; typedef hed::Triangulation TRIANGULATOR; +bool operator==( const RN_NODE_PTR& aFirst, const RN_NODE_PTR& aSecond ); +bool operator!=( const RN_NODE_PTR& aFirst, const RN_NODE_PTR& aSecond ); + ///> General interface for filtering out nodes in search functions. struct RN_NODE_FILTER : public std::unary_function { @@ -83,7 +87,7 @@ struct RN_NODE_COMPARE : std::binary_function { bool operator()( const RN_NODE_PTR& aNode1, const RN_NODE_PTR& aNode2 ) const { - return ( aNode1->GetX() == aNode2->GetX() && aNode1->GetY() == aNode2->GetY() ); + return aNode1 == aNode2; } }; @@ -461,7 +465,13 @@ public: * Function ClearSimple() * Removes all nodes and edges that are used for displaying ratsnest in simple mode. */ - void ClearSimple(); + void ClearSimple() + { + BOOST_FOREACH( const RN_NODE_PTR& node, m_simpleNodes ) + node->SetFlag( false ); + + m_simpleNodes.clear(); + } protected: ///> Validates edge, ie. modifies source and target nodes for an edge @@ -556,7 +566,11 @@ public: * Function ClearSimple() * Clears the list of nodes for which ratsnest is drawn in simple mode (one line per node). */ - void ClearSimple(); + void ClearSimple() + { + BOOST_FOREACH( RN_NET& net, m_nets ) + net.ClearSimple(); + } /** * Function ProcessBoard() From 7faf9fb9a484e8d9f523492e5e578ba051903bdf Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 31 Jan 2014 14:41:15 +0100 Subject: [PATCH 63/95] Safer RN_NET::GetNodes() --- pcbnew/ratsnest_data.cpp | 67 +++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index 95ca62e59b..948362317f 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -548,15 +548,17 @@ const RN_NODE_PTR RN_NET::GetClosestNode( const RN_NODE_PTR& aNode ) const for( it = nodes.begin(), itEnd = nodes.end(); it != itEnd; ++it ) { + RN_NODE_PTR node = *it; + // Obviously the distance between node and itself is the shortest, // that's why we have to skip it - if( *it != aNode ) + if( node != aNode ) { - unsigned int distance = getDistance( *it, aNode ); + unsigned int distance = getDistance( node, aNode ); if( distance < minDistance ) { minDistance = distance; - closest = *it; + closest = node; } } } @@ -650,34 +652,41 @@ std::list RN_NET::GetNodes( const BOARD_CONNECTED_ITEM* aItem ) con { std::list nodes; - switch( aItem->Type() ) + try { - case PCB_PAD_T: - { - const D_PAD* pad = static_cast( aItem ); - nodes.push_back( m_pads.at( pad ) ); - } - break; - - case PCB_VIA_T: - { - const SEGVIA* via = static_cast( aItem ); - nodes.push_back( m_vias.at( via ) ); - } - break; - - case PCB_TRACE_T: - { - const TRACK* track = static_cast( aItem ); - RN_EDGE_PTR edge = m_tracks.at( track ); - - nodes.push_back( edge->getSourceNode() ); - nodes.push_back( edge->getTargetNode() ); - } - break; - - default: + switch( aItem->Type() ) + { + case PCB_PAD_T: + { + const D_PAD* pad = static_cast( aItem ); + nodes.push_back( m_pads.at( pad ) ); + } break; + + case PCB_VIA_T: + { + const SEGVIA* via = static_cast( aItem ); + nodes.push_back( m_vias.at( via ) ); + } + break; + + case PCB_TRACE_T: + { + const TRACK* track = static_cast( aItem ); + RN_EDGE_PTR edge = m_tracks.at( track ); + + nodes.push_back( edge->getSourceNode() ); + nodes.push_back( edge->getTargetNode() ); + } + break; + + default: + break; + } + } + catch ( ... ) + { + return nodes; } return nodes; From 9ba5058e665568cb9191a7ec1dad6d76e3d9da3e Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 31 Jan 2014 14:52:01 +0100 Subject: [PATCH 64/95] Minor change to clearing selection handling. --- pcbnew/tools/selection_tool.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 324bb50032..f226709a86 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -94,8 +94,8 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) if( evt->IsCancel() ) { - if( !m_selection.Empty() ) // Cancel event deselects items... - ClearSelection(); + // Cancel event deselects items... + ClearSelection(); // This tool never exits } @@ -109,7 +109,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) // single click? Select single object else if( evt->IsClick( BUT_LEFT ) ) { - if( !m_additive && m_selection.Size() > 1 ) + if( !m_additive ) ClearSelection(); selectSingle( evt->Position() ); @@ -159,6 +159,9 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) void SELECTION_TOOL::ClearSelection() { + if( m_selection.Empty() ) + return; + KIGFX::VIEW_GROUP::const_iter it, it_end; // Restore the initial properties From 27ecb2c930420cd8a86b749bddef6e06088c8e3b Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 31 Jan 2014 16:08:20 +0100 Subject: [PATCH 65/95] Undo/redo buffer fixed once again.. --- include/tool/tool_event.h | 2 +- pcbnew/board_undo_redo.cpp | 20 ++++++++++---------- pcbnew/router/router_tool.cpp | 15 +++++++++++---- pcbnew/router/router_tool.h | 3 +++ 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/include/tool/tool_event.h b/include/tool/tool_event.h index 9acc1f8f87..46b06e1eed 100644 --- a/include/tool/tool_event.h +++ b/include/tool/tool_event.h @@ -89,7 +89,7 @@ enum TOOL_ACTIONS // closed it without selecting anything. TA_CONTEXT_MENU_CHOICE = 0x10000, - // This event is sent *after* undo/redo command is finished. + // This event is sent *before* undo/redo command is performed. TA_UNDO_REDO = 0x20000, // Tool action (allows to control tools) diff --git a/pcbnew/board_undo_redo.cpp b/pcbnew/board_undo_redo.cpp index 68d008bebb..970ea3167d 100644 --- a/pcbnew/board_undo_redo.cpp +++ b/pcbnew/board_undo_redo.cpp @@ -523,8 +523,8 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed { MODULE* oldModule = static_cast( item ); oldModule->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Remove ), view ) ); - oldModule->RunOnChildren( std::bind1st( std::mem_fun( &RN_DATA::Remove ), ratsnest ) ); } + ratsnest->Remove( item ); item->SwapData( image ); @@ -534,8 +534,8 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed { MODULE* newModule = static_cast( item ); newModule->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), view ) ); - newModule->RunOnChildren( std::bind1st( std::mem_fun( &RN_DATA::Add ), ratsnest ) ); } + ratsnest->Add( item ); item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS ); } @@ -626,6 +626,10 @@ void PCB_EDIT_FRAME::GetBoardFromUndoList( wxCommandEvent& aEvent ) if( GetScreen()->GetUndoCommandCount() <= 0 ) return; + // Inform tools that undo command was issued + TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL ); + m_toolManager->ProcessEvent( event ); + /* Get the old list */ PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList(); /* Undo the command */ @@ -635,10 +639,6 @@ void PCB_EDIT_FRAME::GetBoardFromUndoList( wxCommandEvent& aEvent ) List->ReversePickersListOrder(); GetScreen()->PushCommandToRedoList( List ); - // Inform tools that undo has just occurred - TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL ); - m_toolManager->ProcessEvent( event ); - OnModify(); m_canvas->Refresh(); } @@ -649,6 +649,10 @@ void PCB_EDIT_FRAME::GetBoardFromRedoList( wxCommandEvent& aEvent ) if( GetScreen()->GetRedoCommandCount() == 0 ) return; + // Inform tools that redo command was issued + TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL ); + m_toolManager->ProcessEvent( event ); + /* Get the old list */ PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromRedoList(); @@ -659,10 +663,6 @@ void PCB_EDIT_FRAME::GetBoardFromRedoList( wxCommandEvent& aEvent ) List->ReversePickersListOrder(); GetScreen()->PushCommandToUndoList( List ); - // Inform tools that redo has just occurred - TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL ); - m_toolManager->ProcessEvent( event ); - OnModify(); m_canvas->Refresh(); } diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index d7c29d10ff..94475132e2 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -31,7 +31,6 @@ #include #include -#include #include "router_tool.h" #include "pns_segment.h" @@ -82,6 +81,7 @@ void ROUTER_TOOL::Reset( RESET_REASON aReason ) m_router->ClearWorld(); m_router->SetBoard( getModel( PCB_T ) ); m_router->SyncWorld(); + m_needsSync = false; if( getView() ) m_router->SetView( getView() ); @@ -380,13 +380,14 @@ void ROUTER_TOOL::startRouting() if( saveUndoBuffer ) { // Save the recent changes in the undo buffer - getEditFrame()->SaveCopyInUndoList( m_router->GetLastChanges(), UR_UNSPECIFIED ); + getEditFrame()->SaveCopyInUndoList( m_router->GetLastChanges(), + UR_UNSPECIFIED ); getEditFrame()->OnModify(); } else { // It was interrupted by TA_UNDO_REDO event, so we have to sync the world now - m_router->SyncWorld(); + m_needsSync = true; } ctls->SetAutoPan( false ); @@ -408,10 +409,16 @@ int ROUTER_TOOL::Main( TOOL_EVENT& aEvent ) // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { + if( m_needsSync ) + { + m_router->SyncWorld(); + m_needsSync = false; + } + if( evt->IsCancel() ) break; // Finish else if( evt->Action() == TA_UNDO_REDO ) - m_router->SyncWorld(); + m_needsSync = true; else if( evt->IsMotion() ) updateStartItem( *evt ); else if( evt->IsClick( BUT_LEFT ) ) diff --git a/pcbnew/router/router_tool.h b/pcbnew/router/router_tool.h index c43283a051..42bbceb19c 100644 --- a/pcbnew/router/router_tool.h +++ b/pcbnew/router/router_tool.h @@ -72,6 +72,9 @@ private: PNS_ITEM* m_endItem; VECTOR2I m_endSnapPoint; + ///> Flag marking that the router's world needs syncing. + bool m_needsSync; + /*boost::shared_ptr m_menu;*/ CONTEXT_MENU* m_menu; }; From 2536bae62426d5d08e4237145ace03072510743c Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 31 Jan 2014 18:05:11 +0100 Subject: [PATCH 66/95] Added the dynamic ratsnest for the tracks that are currently routed with the PNS router. --- pcbnew/ratsnest_data.cpp | 71 ++++++++++++++++++++++++++--------- pcbnew/ratsnest_data.h | 51 +++++++++++++++++++++---- pcbnew/ratsnest_viewitem.cpp | 11 +++--- pcbnew/router/pns_router.h | 17 ++++++--- pcbnew/router/router_tool.cpp | 27 +++++++++++++ 5 files changed, 141 insertions(+), 36 deletions(-) diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index 948362317f..bf58ea31b2 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -705,12 +705,9 @@ void RN_DATA::AddSimple( const BOARD_ITEM* aItem ) if( net < 1 ) // do not process unconnected items return; - // Get list of nodes responding to the item - std::list nodes = m_nets[net].GetNodes( item ); - std::list::iterator it, itEnd; - - for( it = nodes.begin(), itEnd = nodes.end(); it != itEnd; ++it ) - m_nets[net].AddSimpleNode( *it ); + // Add all nodes belonging to the item + BOOST_FOREACH( RN_NODE_PTR node, m_nets[net].GetNodes( item ) ) + m_nets[net].AddSimpleNode( node ); } else if( aItem->Type() == PCB_MODULE_T ) { @@ -726,6 +723,46 @@ void RN_DATA::AddSimple( const BOARD_ITEM* aItem ) } +void RN_DATA::AddBlocked( const BOARD_ITEM* aItem ) +{ + int net; + + if( aItem->IsConnected() ) + { + const BOARD_CONNECTED_ITEM* item = static_cast( aItem ); + net = item->GetNet(); + + if( net < 1 ) // do not process unconnected items + return; + + // Block all nodes belonging to the item + BOOST_FOREACH( RN_NODE_PTR node, m_nets[net].GetNodes( item ) ) + m_nets[net].AddBlockedNode( node ); + } + else if( aItem->Type() == PCB_MODULE_T ) + { + const MODULE* module = static_cast( aItem ); + + for( const D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() ) + AddBlocked( pad ); + + return; + } + else + return; +} + + +void RN_DATA::AddSimple( const VECTOR2I& aPosition, int aNetCode ) +{ + assert( aNetCode > 0 ); + + RN_NODE_PTR newNode = boost::make_shared( aPosition.x, aPosition.y ); + + m_nets[aNetCode].AddSimpleNode( newNode ); +} + + void RN_NET::processZones() { BOOST_FOREACH( std::deque& edges, m_zoneConnections | boost::adaptors::map_values ) @@ -773,17 +810,6 @@ void RN_NET::processZones() } -void RN_DATA::updateNet( int aNetCode ) -{ - assert( aNetCode < (int) m_nets.size() ); - if( aNetCode < 1 ) - return; - - m_nets[aNetCode].ClearSimple(); - m_nets[aNetCode].Update(); -} - - void RN_DATA::Add( const BOARD_ITEM* aItem ) { int net; @@ -946,3 +972,14 @@ void RN_DATA::Recalculate( int aNet ) updateNet( aNet ); } } + + +void RN_DATA::updateNet( int aNetCode ) +{ + assert( aNetCode < (int) m_nets.size() ); + if( aNetCode < 1 ) + return; + + m_nets[aNetCode].ClearSimple(); + m_nets[aNetCode].Update(); +} diff --git a/pcbnew/ratsnest_data.h b/pcbnew/ratsnest_data.h index d51c070ee8..712909f2fa 100644 --- a/pcbnew/ratsnest_data.h +++ b/pcbnew/ratsnest_data.h @@ -284,7 +284,7 @@ public: /** * Function MarkDirty() - * Marks ratsnest for given net as 'dirty', ie. requiring recomputation. + * Marks ratsnest for given net as 'dirty', i.e. requiring recomputation. */ void MarkDirty() { @@ -432,7 +432,7 @@ public: /** * Function GetEdges() * Returns pointer to the vector of edges that makes ratsnest for a given net. - * @return Pointer to the vector of edges that makes ratsnest for a given net + * @return Pointer to the vector of edges that makes ratsnest for a given net. */ const std::vector* GetEdges() const { @@ -441,8 +441,8 @@ public: /** * Function AddSimpleNode() - * Changes drawing mode for a node to simple (ie. one ratsnest line per node). - * @param aNode is a node that changes its drawing mode.. + * Changes drawing mode for a node to simple (i.e. one ratsnest line per node). + * @param aNode is a node that changes its drawing mode. */ void AddSimpleNode( RN_NODE_PTR& aNode ) { @@ -450,9 +450,21 @@ public: aNode->SetFlag( true ); } + /** + * Function AddBlockedNode() + * Specifies a node as not suitable as a ratsnest line target (i.e. ratsnest lines will not + * target the node). The status is cleared after calling ClearSimple(). + * @param aNode is the node that is not going to be used as a ratsnest line target. + */ + void AddBlockedNode( RN_NODE_PTR& aNode ) + { + m_blockedNodes.push_back( aNode ); + aNode->SetFlag( true ); + } + /** * Function GetSimpleNodes() - * Returns list of nodes for which ratsnest is drawn in simple mode (ie. one + * Returns list of nodes for which ratsnest is drawn in simple mode (i.e. one * ratsnest line per node). * @return list of nodes for which ratsnest is drawn in simple mode. */ @@ -470,11 +482,15 @@ public: BOOST_FOREACH( const RN_NODE_PTR& node, m_simpleNodes ) node->SetFlag( false ); + BOOST_FOREACH( const RN_NODE_PTR& node, m_blockedNodes ) + node->SetFlag( false ); + m_simpleNodes.clear(); + m_blockedNodes.clear(); } protected: - ///> Validates edge, ie. modifies source and target nodes for an edge + ///> Validates edge, i.e. modifies source and target nodes for an edge ///> to make sure that they are not ones with the flag set. void validateEdge( RN_EDGE_PTR& aEdge ); @@ -496,6 +512,9 @@ protected: ///> List of nodes for which ratsnest is drawn in simple mode. std::deque m_simpleNodes; + ///> List of nodes which should be used as ratsnest target nodes.. + std::deque m_blockedNodes; + ///> Flag indicating necessity of recalculation of ratsnest for a net. bool m_dirty; @@ -556,12 +575,30 @@ public: /** * Function AddSimple() - * Sets an item to be drawn in simple mode (ie. one line per node, instead of full ratsnest). + * Sets an item to be drawn in simple mode (i.e. one line per node, instead of full ratsnest). * It is used for drawing quick, temporary ratsnest, eg. while moving an item. * @param aItem is an item to be drawn in simple node. */ void AddSimple( const BOARD_ITEM* aItem ); + /** + * Function AddSimple() + * Allows to draw a ratsnest line using a position expressed in world coordinates and a + * net code (so there is no need to have a real BOARD_ITEM to draw ratsnest line). + * It is used for drawing quick, temporary ratsnest, eg. while moving an item. + * @param aPosition is the point for which ratsnest line are going to be drawn. + * @param aNetCode determines the net code for which the ratsnest line are going to be drawn. + */ + void AddSimple( const VECTOR2I& aPosition, int aNetCode ); + + /** + * Function AddBlocked() + * Specifies an item as not suitable as a ratsnest line target (i.e. ratsnest lines will not + * target its node(s)). The status is cleared after calling ClearSimple(). + * @param aItem is the item of which node(s) are not going to be used as a ratsnest line target. + */ + void AddBlocked( const BOARD_ITEM* aItem ); + /** * Function ClearSimple() * Clears the list of nodes for which ratsnest is drawn in simple mode (one line per node). diff --git a/pcbnew/ratsnest_viewitem.cpp b/pcbnew/ratsnest_viewitem.cpp index 7bf9d79568..5de2527111 100644 --- a/pcbnew/ratsnest_viewitem.cpp +++ b/pcbnew/ratsnest_viewitem.cpp @@ -63,14 +63,11 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const for( int i = 1; i < m_data->GetNetCount(); ++i ) { - const RN_NET& net = m_data->GetNet( i ); + RN_NET& net = m_data->GetNet( i ); if( !net.IsVisible() ) continue; - // Avoid duplicate destinations for ratsnest lines by storing already used nodes - boost::unordered_set usedDestinations; - // Set brighter color for the temporary ratsnest aGal->SetStrokeColor( color.Brightened( 0.8 ) ); @@ -79,13 +76,15 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const { RN_NODE_PTR dest = net.GetClosestNode( node, WITHOUT_FLAG() ); - if( dest && usedDestinations.find( dest ) == usedDestinations.end() ) + if( dest ) { VECTOR2D origin( node->GetX(), node->GetY() ); VECTOR2D end( dest->GetX(), dest->GetY() ); aGal->DrawLine( origin, end ); - usedDestinations.insert( dest ); + + // Avoid duplicate destinations for ratsnest lines by storing already used nodes + net.AddBlockedNode( dest ); } } diff --git a/pcbnew/router/pns_router.h b/pcbnew/router/pns_router.h index 3ba7be0125..430f950a37 100644 --- a/pcbnew/router/pns_router.h +++ b/pcbnew/router/pns_router.h @@ -139,15 +139,20 @@ public: const VECTOR2I SnapToItem( PNS_ITEM* item, VECTOR2I aP, bool& aSplitsSegment ); /** - * Returns the last changes introduced by the router. After calling the method the list of - * changes is cleared, so only the latest changes are stored. + * Returns the last changes introduced by the router (since the last time ClearLastChanges() + * was called or a new track has been started). */ - PICKED_ITEMS_LIST GetLastChanges() + const PICKED_ITEMS_LIST& GetLastChanges() const { - PICKED_ITEMS_LIST copy = m_undoBuffer; - m_undoBuffer.ClearItemsList(); // TODO and delete? + return m_undoBuffer; + } - return copy; + /** + * Clears the list of recent changes, saved to be stored in the undo buffer. + */ + void ClearLastChanges() + { + m_undoBuffer.ClearItemsList(); } private: diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 94475132e2..9a8528d23a 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -32,6 +32,8 @@ #include +#include + #include "router_tool.h" #include "pns_segment.h" #include "pns_router.h" @@ -282,6 +284,30 @@ void ROUTER_TOOL::updateEndItem( TOOL_EVENT& aEvent ) ctls->ForceCursorPosition( false ); } + // Draw ratsnest for the currently routed track + RN_DATA* ratsnest = getModel( PCB_T )->GetRatsnest(); + ratsnest->ClearSimple(); + + if( ( m_endItem == NULL || m_endItem == m_startItem ) && m_startItem->GetNet() > 0 ) + { + // The ending node has to be first, so the line for the track is drawn first + ratsnest->AddSimple( m_endSnapPoint, m_startItem->GetNet() ); + + // Those nodes are added just to force ratsnest not to drawn + // lines to already routed parts of the track + const PICKED_ITEMS_LIST& changes = m_router->GetLastChanges(); + for( unsigned int i = 0; i < changes.GetCount(); ++i ) + { + // Block the new tracks, do not handle tracks that were moved + // (moved tracks are saved in the undo buffer with UR_DELETED status instead) + if( changes.GetPickedItemStatus( i ) == UR_NEW ) + ratsnest->AddBlocked( static_cast( changes.GetPickedItem( i ) ) ); + } + + // Also the origin of the new track should be skipped in the ratsnest shown for the routed track + ratsnest->AddBlocked( static_cast( m_startItem->GetParent() ) ); + } + if( m_endItem ) TRACE( 0, "%s, layer : %d", m_endItem->GetKindStr().c_str() % m_endItem->GetLayers().Start() ); @@ -382,6 +408,7 @@ void ROUTER_TOOL::startRouting() // Save the recent changes in the undo buffer getEditFrame()->SaveCopyInUndoList( m_router->GetLastChanges(), UR_UNSPECIFIED ); + m_router->ClearLastChanges(); getEditFrame()->OnModify(); } else From 911ee57de68ea6405475f5d872c61e9fe5676bb5 Mon Sep 17 00:00:00 2001 From: Carl Poirier Date: Fri, 31 Jan 2014 18:27:06 +0100 Subject: [PATCH 67/95] Parallelized the RN_DATA::Recalculate() function. --- CMakeLists.txt | 7 +++++++ pcbnew/CMakeLists.txt | 2 ++ pcbnew/ratsnest_data.cpp | 28 +++++++++++++++++++++++----- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d72d54d6de..c3fc56208b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -125,6 +125,13 @@ if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden" ) endif() + find_package( OpenMP QUIET ) + if( OPENMP_FOUND ) + set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}" ) + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}" ) + add_definitions( -DUSE_OPENMP ) + endif() + if( MINGW ) set( CMAKE_EXE_LINKER_FLAGS_RELEASE "-s" ) diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 11663c684f..86e8dd296d 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -1,6 +1,8 @@ set( MAKE_LINK_MAPS false ) +set( CMAKE_CXX_FLAGS "-fopenmp" ) + add_definitions( -DPCBNEW ) add_subdirectory(router) diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index af5f6932fd..977e3bcc9e 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -27,6 +27,10 @@ * @brief Class that computes missing connections on a PCB. */ +#ifdef USE_OPENMP +#include +#endif /* USE_OPENMP */ + #include #include @@ -829,12 +833,25 @@ void RN_DATA::Recalculate( int aNet ) { if( aNet < 0 ) // Recompute everything { - // Start with net number 1, as 0 stand for not connected - for( unsigned int i = 1; i < m_board->GetNetCount(); ++i ) + unsigned int tid, i, chunk, netCount; + netCount = m_board->GetNetCount(); + chunk = 1; + +#ifdef USE_OPENMP + #pragma omp parallel shared(chunk, netCount) private(i, tid) { - if( m_nets[i].IsDirty() ) - updateNet( i ); - } + tid = omp_get_thread_num(); + #pragma omp for schedule(guided, chunk) +#else /* USE_OPENMP */ + { +#endif + // Start with net number 1, as 0 stand for not connected + for( i = 1; i < netCount; ++i ) + { + if( m_nets[i].IsDirty() ) + updateNet( i ); + } + } /* end of parallel section */ } else if( aNet > 0 ) // Recompute only specific net { @@ -848,3 +865,4 @@ void RN_DATA::ClearSimple() BOOST_FOREACH( RN_NET& net, m_nets ) net.ClearSimple(); } + From 7dc9eefc83df3badfa927001f1ccecd484f8385d Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 3 Feb 2014 16:02:54 +0100 Subject: [PATCH 68/95] Minor changes (fix cvpcb build issue, wx2.8 compatibility, some other stuff). --- common/CMakeLists.txt | 1 + pcbnew/CMakeLists.txt | 1 - pcbnew/pcb_painter.cpp | 3 +-- pcbnew/pcb_parser.cpp | 6 +++--- pcbnew/router/pns_router.cpp | 1 - 5 files changed, 5 insertions(+), 7 deletions(-) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 44569f29e2..cd3ae84acc 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -219,6 +219,7 @@ set( PCB_COMMON_SRCS ../pcbnew/class_zone.cpp ../pcbnew/class_zone_settings.cpp ../pcbnew/classpcb.cpp + ../pcbnew/ratsnest_data.cpp ../pcbnew/collectors.cpp ../pcbnew/netlist_reader.cpp ../pcbnew/legacy_netlist_reader.cpp diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 1ff4550e43..7a715d181c 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -221,7 +221,6 @@ set( PCBNEW_CLASS_SRCS print_board_functions.cpp printout_controler.cpp ratsnest.cpp - ratsnest_data.cpp ratsnest_viewitem.cpp # specctra.cpp #moved in pcbcommon lib # specctra_export.cpp diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 4ffdfa4667..b7f9ff0cc3 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -281,7 +280,7 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer ) if( !net ) return; - std::wstring netName = std::wstring( net->GetShortNetname().wc_str() ); + const wxString& netName = aTrack->GetShortNetname(); VECTOR2D textPosition = start + line / 2.0; // center of the track double textOrientation = -atan( line.y / line.x ); double textSize = std::min( static_cast( width ), length / netName.length() ); diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index 1f06ac2ed1..f68743b741 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -2426,9 +2426,9 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR ) NeedSYMBOLorNUMBER(); if( m_board->FindNet( zone->GetNet() )->GetNetname() != FromUTF8() ) { - DisplayError( NULL, wxString::Format( _( "There is a zone that belongs to a not " - "existing net (%s), you should verify it." ), - FromUTF8() ) ); + wxString msg = _( "There is a zone that belongs to a not " + "existing net (" ) + FromUTF8() + _("), you should verify it." ); + DisplayError( NULL, msg ); zone->SetNet( NETINFO_LIST::UNCONNECTED ); } NeedRIGHT(); diff --git a/pcbnew/router/pns_router.cpp b/pcbnew/router/pns_router.cpp index 3046c13f6e..1babefa598 100644 --- a/pcbnew/router/pns_router.cpp +++ b/pcbnew/router/pns_router.cpp @@ -631,7 +631,6 @@ void PNS_ROUTER::commitRouting( PNS_NODE* aNode ) newBI->ClearFlags(); m_view->Add( newBI ); m_board->Add( newBI ); - m_board->GetRatsnest()->Update( newBI ); m_undoBuffer.PushItem( ITEM_PICKER( newBI, UR_NEW ) ); newBI->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } From 8cfc8b0157a0aa9f3ecd579413839f67895d30cd Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 3 Feb 2014 17:40:39 +0100 Subject: [PATCH 69/95] Ratsnest lines for zones are removed when a zone is dragged. --- pcbnew/ratsnest_data.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index bf58ea31b2..4f49e6bed4 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -521,7 +521,12 @@ void RN_NET::RemoveItem( const ZONE_CONTAINER* aZone ) // Remove all subpolygons that make the zone std::deque& polygons = m_zonePolygons.at( aZone ); BOOST_FOREACH( RN_POLY& polygon, polygons ) - m_links.RemoveNode( polygon.GetNode() ); + { + const RN_NODE_PTR node = polygon.GetNode(); + + if( m_links.RemoveNode( node ) ) + clearNode( node ); + } polygons.clear(); // Remove all connections added by the zone From 51bf04932b8ac6914443dc64969ece0b479c672b Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 3 Feb 2014 18:09:17 +0100 Subject: [PATCH 70/95] Enabled PNS for selected items. --- pcbnew/router/router_tool.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 9a8528d23a..558b4dfab6 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -140,7 +140,8 @@ PNS_ITEM* ROUTER_TOOL::pickSingleItem( const VECTOR2I& aWhere, int aNet, int aLa if( !IsCopperLayer( item->GetLayers().Start() ) ) continue; - if( item->GetParent() && !item->GetParent()->ViewIsVisible() ) + if( item->GetParent() && !item->GetParent()->ViewIsVisible() && + !item->GetParent()->IsSelected() ) continue; if( aNet < 0 || item->GetNet() == aNet ) From 221b68d0b8806006ea5cda87a06e967c30daebf4 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 4 Feb 2014 09:44:16 +0100 Subject: [PATCH 71/95] Snapping settings are valid while autopanning. --- common/tool/tool_dispatcher.cpp | 2 +- common/view/wx_view_controls.cpp | 24 ++++++++++++++---------- include/view/wx_view_controls.h | 6 ++++++ 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/common/tool/tool_dispatcher.cpp b/common/tool/tool_dispatcher.cpp index 66efcc2581..f35689c97f 100644 --- a/common/tool/tool_dispatcher.cpp +++ b/common/tool/tool_dispatcher.cpp @@ -224,7 +224,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) VECTOR2D screenPos = m_toolMgr->GetViewControls()->GetMousePosition(); VECTOR2D pos = getView()->ToWorld( screenPos ); - if( pos != m_lastMousePos || type == KIGFX::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE ) + if( pos != m_lastMousePos ) { motion = true; m_lastMousePos = pos; diff --git a/common/view/wx_view_controls.cpp b/common/view/wx_view_controls.cpp index 20778c7d3e..3aeabd6d7d 100644 --- a/common/view/wx_view_controls.cpp +++ b/common/view/wx_view_controls.cpp @@ -73,12 +73,7 @@ void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent ) m_mousePosition.x = aEvent.GetX(); m_mousePosition.y = aEvent.GetY(); - if( m_forceCursorPosition ) - m_cursorPosition = m_view->ToScreen( m_forcedPosition ); - else if( m_snappingEnabled ) - m_cursorPosition = m_view->GetGAL()->GetGridPoint( m_mousePosition ); - else - m_cursorPosition = m_mousePosition; + updateCursor(); bool isAutoPanning = false; @@ -166,17 +161,13 @@ void WX_VIEW_CONTROLS::onButton( wxMouseEvent& aEvent ) } if( aEvent.LeftUp() ) - { m_state = IDLE; // Stop autopanning when user release left mouse button - } break; case DRAG_PANNING: if( aEvent.MiddleUp() ) - { m_state = IDLE; - } break; } @@ -208,6 +199,8 @@ void WX_VIEW_CONTROLS::onTimer( wxTimerEvent& aEvent ) dir = m_view->ToWorld( dir, false ); m_view->SetCenter( m_view->GetCenter() + dir * m_autoPanSpeed ); + updateCursor(); + // Notify tools that the cursor position has changed in the world coordinates wxCommandEvent moveEvent( EVT_REFRESH_MOUSE ); wxPostEvent( m_parentPanel, moveEvent ); @@ -298,3 +291,14 @@ bool WX_VIEW_CONTROLS::handleAutoPanning( const wxMouseEvent& aEvent ) wxASSERT_MSG( false, wxT( "This line should never be reached" ) ); return false; // Should not be reached, just avoid the compiler warnings.. } + + +void WX_VIEW_CONTROLS::updateCursor() +{ + if( m_forceCursorPosition ) + m_cursorPosition = m_view->ToScreen( m_forcedPosition ); + else if( m_snappingEnabled ) + m_cursorPosition = m_view->GetGAL()->GetGridPoint( m_mousePosition ); + else + m_cursorPosition = m_mousePosition; +} diff --git a/include/view/wx_view_controls.h b/include/view/wx_view_controls.h index cfec3eac9b..5df48f3de3 100644 --- a/include/view/wx_view_controls.h +++ b/include/view/wx_view_controls.h @@ -112,6 +112,12 @@ private: */ bool handleAutoPanning( const wxMouseEvent& aEvent ); + /** + * Function updateCursor() + * Recomputes the cursor coordinates basing on the current snapping settings and mouse position. + */ + void updateCursor(); + /// Current state of VIEW_CONTROLS STATE m_state; From 0833cd4b6117e707e1c63348bd24b08a1f1c58ce Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 4 Feb 2014 11:37:54 +0100 Subject: [PATCH 72/95] SELECTION_TOOL::SELECTION::Clear made private, as there was no chance to call it outside the SELECTION_TOOL class. --- pcbnew/tools/selection_tool.cpp | 8 ++++---- pcbnew/tools/selection_tool.h | 5 ++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index f226709a86..9cdd5fc072 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -69,7 +69,7 @@ void SELECTION_TOOL::Reset( RESET_REASON aReason ) if( aReason == TOOL_BASE::MODEL_RELOAD ) // Remove pointers to the selected items from containers // without changing their properties (as they are already deleted) - m_selection.Clear(); + m_selection.clear(); else // Restore previous properties of selected items and remove them from containers ClearSelection(); @@ -172,7 +172,7 @@ void SELECTION_TOOL::ClearSelection() item->ViewSetVisible( true ); item->ClearSelected(); } - m_selection.Clear(); + m_selection.clear(); getEditFrame()->SetCurItem( NULL ); @@ -465,7 +465,7 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const if( aItem->IsOnLayer( LAYER_N_FRONT ) && board->IsElementVisible( MOD_FR_VISIBLE ) ) return true; - if( aItem->IsOnLayer( LAYER_N_BACK ) && board->IsLayerVisible( MOD_BK_VISIBLE ) ) + if( aItem->IsOnLayer( LAYER_N_BACK ) && board->IsElementVisible( MOD_BK_VISIBLE ) ) return true; return false; @@ -590,7 +590,7 @@ bool SELECTION_TOOL::containsSelected( const VECTOR2I& aPoint ) const } -void SELECTION_TOOL::SELECTION::Clear() +void SELECTION_TOOL::SELECTION::clear() { items.ClearItemsList(); group->Clear(); diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h index 168f2288da..93b25083c6 100644 --- a/pcbnew/tools/selection_tool.h +++ b/pcbnew/tools/selection_tool.h @@ -78,9 +78,12 @@ public: return items.GetCount(); } + private: /// Clears both the VIEW_GROUP and set of selected items. Please note that it does not /// change properties of selected items (e.g. selection flag). - void Clear(); + void clear(); + + friend class SELECTION_TOOL; }; /// @copydoc TOOL_INTERACTIVE::Reset() From 6e666b5d624f018fd38989656daaea03692c37be Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 4 Feb 2014 13:38:18 +0100 Subject: [PATCH 73/95] Modifiers (Alt/Shift/Control) are properly set for events when autopanning is active. --- common/view/wx_view_controls.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/common/view/wx_view_controls.cpp b/common/view/wx_view_controls.cpp index 3aeabd6d7d..f9a17fa86a 100644 --- a/common/view/wx_view_controls.cpp +++ b/common/view/wx_view_controls.cpp @@ -202,7 +202,20 @@ void WX_VIEW_CONTROLS::onTimer( wxTimerEvent& aEvent ) updateCursor(); // Notify tools that the cursor position has changed in the world coordinates - wxCommandEvent moveEvent( EVT_REFRESH_MOUSE ); + wxMouseEvent moveEvent( EVT_REFRESH_MOUSE ); + + // Set the modifiers state +#if wxCHECK_VERSION( 3, 0, 0 ) + moveEvent.SetControlDown( wxGetKeyState( WXK_CONTROL ) ); + moveEvent.SetShiftDown( wxGetKeyState( WXK_SHIFT ) ); + moveEvent.SetAltDown( wxGetKeyState( WXK_ALT) ); +#else + // wx <3.0 do not have accessors, but the fields are exposed + moveEvent.m_controlDown = wxGetKeyState( WXK_CONTROL ); + moveEvent.m_shiftDown = wxGetKeyState( WXK_SHIFT ); + moveEvent.m_altDown = wxGetKeyState( WXK_ALT ); +#endif + wxPostEvent( m_parentPanel, moveEvent ); } break; From e954736b5d45aecb309e9b9dd5602e6d5f53f307 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 4 Feb 2014 13:40:39 +0100 Subject: [PATCH 74/95] Protection against non consecutive net codes. --- pcbnew/router/pns_router.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pcbnew/router/pns_router.cpp b/pcbnew/router/pns_router.cpp index 1babefa598..b655ac363f 100644 --- a/pcbnew/router/pns_router.cpp +++ b/pcbnew/router/pns_router.cpp @@ -66,6 +66,9 @@ public: for( unsigned int i = 0; i < aBoard->GetNetCount(); i++ ) { NETINFO_ITEM* ni = aBoard->FindNet( i ); + if( ni == NULL ) + continue; + wxString netClassName = ni->GetClassName(); NETCLASS* nc = aBoard->m_NetClasses.Find( netClassName ); int clearance = nc->GetClearance(); From 980e325ba13750184247ce7606ab9162a1f2363e Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 4 Feb 2014 14:21:29 +0100 Subject: [PATCH 75/95] Edit tool may still be activated if it was invoked with no selected items. --- pcbnew/tools/edit_tool.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 451164bf23..812d7732dd 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -80,7 +80,11 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) m_updateFlag = KIGFX::VIEW_ITEM::GEOMETRY; if( selection.Empty() ) - return 0; // there are no items to operate on + { + setTransitions(); // this is necessary, so later the tool may + // be activated upon reception of the activation event + return 0; // there are no items to operate on, so we can end now + } VECTOR2D dragPosition; // The last position of the cursor while dragging m_dragging = false; From 9ee9c93ef8c2efa4ce086c9666b4424127430ec8 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 4 Feb 2014 16:03:56 +0100 Subject: [PATCH 76/95] Added 2 tool actions: - pcbnew.InteractiveSelection.Single for selecting a single item - pcbnew.InteractiveSelection.Clear for clearing the selection Made SELECTION_TOOL::clearSelection private. --- pcbnew/tools/common_actions.cpp | 6 ++ pcbnew/tools/common_actions.h | 12 ++- pcbnew/tools/edit_tool.cpp | 12 +-- pcbnew/tools/pcb_tools.cpp | 2 + pcbnew/tools/selection_tool.cpp | 147 ++++++++++++++++---------------- pcbnew/tools/selection_tool.h | 12 +-- 6 files changed, 100 insertions(+), 91 deletions(-) diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 6756e10a9d..f1fb3befd6 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -30,6 +30,12 @@ TOOL_ACTION COMMON_ACTIONS::selectionActivate( "pcbnew.InteractiveSelection", AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere +TOOL_ACTION COMMON_ACTIONS::selectionSingle( "pcbnew.InteractiveSelection.Single", + AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere + +TOOL_ACTION COMMON_ACTIONS::selectionClear( "pcbnew.InteractiveSelection.Clear", + AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere + // Edit tool actions TOOL_ACTION COMMON_ACTIONS::editActivate( "pcbnew.InteractiveEdit", AS_GLOBAL, 'M', diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 19b0004182..86aafe5894 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -24,13 +24,11 @@ #include -//class ACTION_MANAGER; - /** * Class COMMON_ACTIONS * - * Gathers all the actions that are shared by tools. The instance of COMMON_ACTIOSN is created - * inside of ACTION_MANAGER object and registers them. + * Gathers all the actions that are shared by tools. The instance of COMMON_ACTION is created + * inside of ACTION_MANAGER object that registers the actions. */ class COMMON_ACTIONS { @@ -38,6 +36,12 @@ public: /// Activation of the selection tool static TOOL_ACTION selectionActivate; + /// Select a single item under the cursor position + static TOOL_ACTION selectionSingle; + + /// Clears the current selection + static TOOL_ACTION selectionClear; + /// Activation of the edit tool static TOOL_ACTION editActivate; diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 812d7732dd..008305193d 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -74,10 +74,6 @@ bool EDIT_TOOL::Init() int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) { const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); - PCB_EDIT_FRAME* editFrame = static_cast( m_toolMgr->GetEditFrame() ); - - // By default, modified items need to update their geometry - m_updateFlag = KIGFX::VIEW_ITEM::GEOMETRY; if( selection.Empty() ) { @@ -90,7 +86,11 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) m_dragging = false; bool restore = false; // Should items' state be restored when finishing the tool? + // By default, modified items need to update their geometry + m_updateFlag = KIGFX::VIEW_ITEM::GEOMETRY; + VIEW_CONTROLS* controls = getViewControls(); + PCB_EDIT_FRAME* editFrame = static_cast( m_toolMgr->GetEditFrame() ); controls->ShowCursor( true ); controls->SetSnapping( true ); controls->SetAutoPan( true ); @@ -163,7 +163,7 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) if( restore ) { - // Modifications has to be rollbacked, so restore the previous state of items + // Modifications have to be rollbacked, so restore the previous state of items wxCommandEvent dummy; editFrame->GetBoardFromUndoList( dummy ); } @@ -290,7 +290,7 @@ int EDIT_TOOL::Remove( TOOL_EVENT& aEvent ) PCB_EDIT_FRAME* editFrame = static_cast( m_toolMgr->GetEditFrame() ); // As we are about to remove items, they have to be removed from the selection first - m_selectionTool->ClearSelection(); + m_toolMgr->RunAction( "pcbnew.InteractiveSelection.Clear" ); // Save them for( unsigned int i = 0; i < selectedItems.GetCount(); ++i ) diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index 9908012f6b..a4b4f21a24 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -47,6 +47,8 @@ void PCB_EDIT_FRAME::setupTools() GetGalCanvas()->SetEventDispatcher( m_toolDispatcher ); // Register tool actions + m_toolManager->RegisterAction( &COMMON_ACTIONS::selectionSingle ); + m_toolManager->RegisterAction( &COMMON_ACTIONS::selectionClear ); m_toolManager->RegisterAction( &COMMON_ACTIONS::editActivate ); m_toolManager->RegisterAction( &COMMON_ACTIONS::rotate ); m_toolManager->RegisterAction( &COMMON_ACTIONS::flip ); diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 9cdd5fc072..ce59adbb1f 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -72,7 +72,7 @@ void SELECTION_TOOL::Reset( RESET_REASON aReason ) m_selection.clear(); else // Restore previous properties of selected items and remove them from containers - ClearSelection(); + clearSelection(); // Reinsert the VIEW_GROUP, in case it was removed from the VIEW getView()->Remove( m_selection.group ); @@ -92,25 +92,22 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) // become the new selection (discarding previously selected items) m_additive = evt->Modifier( MD_SHIFT ); - if( evt->IsCancel() ) + if( evt->IsAction( &COMMON_ACTIONS::selectionSingle ) ) { - // Cancel event deselects items... - ClearSelection(); - - // This tool never exits + selectSingle( getView()->ToWorld( getViewControls()->GetMousePosition() ) ); } - else if( evt->Action() == TA_UNDO_REDO ) + else if( evt->IsCancel() || evt->Action() == TA_UNDO_REDO || + evt->IsAction( &COMMON_ACTIONS::selectionClear ) ) { - // Clear the selection, as it may be altered with undone items - ClearSelection(); + clearSelection(); } // single click? Select single object else if( evt->IsClick( BUT_LEFT ) ) { if( !m_additive ) - ClearSelection(); + clearSelection(); selectSingle( evt->Position() ); } @@ -144,7 +141,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) else { // No -> clear the selection list - ClearSelection(); + clearSelection(); } } } @@ -157,30 +154,6 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) } -void SELECTION_TOOL::ClearSelection() -{ - if( m_selection.Empty() ) - return; - - KIGFX::VIEW_GROUP::const_iter it, it_end; - - // Restore the initial properties - for( it = m_selection.group->Begin(), it_end = m_selection.group->End(); it != it_end; ++it ) - { - BOARD_ITEM* item = static_cast( *it ); - - item->ViewSetVisible( true ); - item->ClearSelected(); - } - m_selection.clear(); - - getEditFrame()->SetCurItem( NULL ); - - // Do not show the context menu when there is nothing selected - SetContextMenu( &m_menu, CMENU_OFF ); -} - - void SELECTION_TOOL::AddMenuItem( const TOOL_ACTION& aAction ) { assert( aAction.GetId() > 0 ); // Check if the action was registered before in ACTION_MANAGER @@ -198,7 +171,7 @@ void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem ) else { if( !m_additive ) - ClearSelection(); + clearSelection(); // Prevent selection of invisible or inactive items if( selectable( aItem ) ) @@ -221,7 +194,7 @@ void SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere ) { case 0: if( !m_additive ) - ClearSelection(); + clearSelection(); break; case 1: @@ -254,43 +227,6 @@ void SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere ) } -BOARD_ITEM* SELECTION_TOOL::pickSmallestComponent( GENERAL_COLLECTOR* aCollector ) -{ - int count = aCollector->GetPrimaryCount(); // try to use preferred layer - - if( 0 == count ) - count = aCollector->GetCount(); - - for( int i = 0; i < count; ++i ) - { - if( ( *aCollector )[i]->Type() != PCB_MODULE_T ) - return NULL; - } - - // All are modules, now find smallest MODULE - int minDim = 0x7FFFFFFF; - int minNdx = 0; - - for( int i = 0; i < count; ++i ) - { - MODULE* module = (MODULE*) ( *aCollector )[i]; - - int lx = module->GetBoundingBox().GetWidth(); - int ly = module->GetBoundingBox().GetHeight(); - - int lmin = std::min( lx, ly ); - - if( lmin < minDim ) - { - minDim = lmin; - minNdx = i; - } - } - - return (*aCollector)[minNdx]; -} - - bool SELECTION_TOOL::selectMultiple() { bool cancelled = false; // Was the tool cancelled while it was running? @@ -311,7 +247,7 @@ bool SELECTION_TOOL::selectMultiple() if( evt->IsDrag( BUT_LEFT ) ) { if( !m_additive ) - ClearSelection(); + clearSelection(); // Start drawing a selection box m_selArea->SetOrigin( evt->DragOrigin() ); @@ -356,6 +292,30 @@ bool SELECTION_TOOL::selectMultiple() } +void SELECTION_TOOL::clearSelection() +{ + if( m_selection.Empty() ) + return; + + KIGFX::VIEW_GROUP::const_iter it, it_end; + + // Restore the initial properties + for( it = m_selection.group->Begin(), it_end = m_selection.group->End(); it != it_end; ++it ) + { + BOARD_ITEM* item = static_cast( *it ); + + item->ViewSetVisible( true ); + item->ClearSelected(); + } + m_selection.clear(); + + getEditFrame()->SetCurItem( NULL ); + + // Do not show the context menu when there is nothing selected + SetContextMenu( &m_menu, CMENU_OFF ); +} + + BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector ) { BOARD_ITEM* current = NULL; @@ -419,6 +379,43 @@ BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector ) } +BOARD_ITEM* SELECTION_TOOL::pickSmallestComponent( GENERAL_COLLECTOR* aCollector ) +{ + int count = aCollector->GetPrimaryCount(); // try to use preferred layer + + if( 0 == count ) + count = aCollector->GetCount(); + + for( int i = 0; i < count; ++i ) + { + if( ( *aCollector )[i]->Type() != PCB_MODULE_T ) + return NULL; + } + + // All are modules, now find smallest MODULE + int minDim = 0x7FFFFFFF; + int minNdx = 0; + + for( int i = 0; i < count; ++i ) + { + MODULE* module = (MODULE*) ( *aCollector )[i]; + + int lx = module->GetBoundingBox().GetWidth(); + int ly = module->GetBoundingBox().GetHeight(); + + int lmin = std::min( lx, ly ); + + if( lmin < minDim ) + { + minDim = lmin; + minNdx = i; + } + } + + return (*aCollector)[minNdx]; +} + + bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const { // Is high contrast mode enabled? diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h index 93b25083c6..4c5e4b2d9a 100644 --- a/pcbnew/tools/selection_tool.h +++ b/pcbnew/tools/selection_tool.h @@ -106,12 +106,6 @@ public: return m_selection; } - /** - * Function ClearSelection() - * Clears the current selection. - */ - void ClearSelection(); - /** * Function AddMenuItem() * @@ -138,6 +132,12 @@ private: */ bool selectMultiple(); + /** + * Function ClearSelection() + * Clears the current selection. + */ + void clearSelection(); + /** * Function disambiguationMenu() * Handles the menu that allows to select one of many items in case there is more than one From 244be39ffa5aaa0d50f295046c8e8b9f5777c5e5 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 4 Feb 2014 17:27:00 +0100 Subject: [PATCH 77/95] Added KiCad-style modification methods (hover over an item and press a hot key, without selecting first). Modification point is selected basing on the number of selected items. Rotation angle setting (Preferences->General) is taken into account while rotating. --- pcbnew/tools/edit_tool.cpp | 122 +++++++++++++++++++++++++------- pcbnew/tools/edit_tool.h | 8 +++ pcbnew/tools/selection_tool.cpp | 2 +- 3 files changed, 105 insertions(+), 27 deletions(-) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 008305193d..9d99f3275c 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -49,10 +49,9 @@ EDIT_TOOL::EDIT_TOOL() : bool EDIT_TOOL::Init() { // Find the selection tool, so they can cooperate - TOOL_BASE* selectionTool = m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ); + m_selectionTool = static_cast( m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ) ); - m_selectionTool = static_cast( selectionTool ); - if( !selectionTool ) + if( !m_selectionTool ) { DisplayError( NULL, wxT( "pcbnew.InteractiveSelection tool is not available" ) ); return false; @@ -75,15 +74,15 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) { const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); - if( selection.Empty() ) - { - setTransitions(); // this is necessary, so later the tool may - // be activated upon reception of the activation event - return 0; // there are no items to operate on, so we can end now - } + // Shall the selection be cleared at the end? + bool unselect = selection.Empty(); + + // Be sure that there is at least one item that we can modify + if( !makeSelection( selection ) ) + return 0; VECTOR2D dragPosition; // The last position of the cursor while dragging - m_dragging = false; + m_dragging = false; // Are selected items being dragged? bool restore = false; // Should items' state be restored when finishing the tool? // By default, modified items need to update their geometry @@ -173,6 +172,9 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) selection.group->ItemsViewUpdate( m_updateFlag ); } + if( unselect ) + m_toolMgr->RunAction( "pcbnew.InteractiveSelection.Clear" ); + RN_DATA* ratsnest = getModel( PCB_T )->GetRatsnest(); ratsnest->ClearSimple(); ratsnest->Recalculate(); @@ -192,26 +194,32 @@ int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); PCB_EDIT_FRAME* editFrame = static_cast( m_toolMgr->GetEditFrame() ); + // Shall the selection be cleared at the end? + bool unselect = selection.Empty(); + + if( !makeSelection( selection ) ) + return 0; + // Properties are displayed when there is only one item selected if( selection.Size() == 1 ) { // Display properties dialog BOARD_ITEM* item = static_cast( selection.items.GetPickedItem( 0 ) ); - if( !m_dragging ) // If it is being dragged, then it is already saved with UR_CHANGED flag - { - editFrame->SaveCopyInUndoList( item, UR_CHANGED ); - editFrame->OnModify(); - } - + editFrame->SaveCopyInUndoList( item, UR_CHANGED ); + editFrame->OnModify(); editFrame->OnEditItemRequest( NULL, item ); item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + + updateRatsnest( true ); + getModel( PCB_T )->GetRatsnest()->Recalculate(); + + if( unselect ) + m_toolMgr->RunAction( "pcbnew.InteractiveSelection.Clear" ); } setTransitions(); - updateRatsnest( true ); - getModel( PCB_T )->GetRatsnest()->Recalculate(); return 0; } @@ -220,20 +228,28 @@ int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) { const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); - VECTOR2D cursor = getView()->ToWorld( getViewControls()->GetCursorPosition() ); PCB_EDIT_FRAME* editFrame = static_cast( m_toolMgr->GetEditFrame() ); + // Shall the selection be cleared at the end? + bool unselect = selection.Empty(); + + if( !makeSelection( selection ) ) + return 0; + + wxPoint rotatePoint = getModificationPoint( selection ); + if( !m_dragging ) // If it is being dragged, then it is already saved with UR_CHANGED flag { editFrame->OnModify(); - editFrame->SaveCopyInUndoList( selection.items, UR_ROTATED, wxPoint( cursor.x, cursor.y ) ); + editFrame->SaveCopyInUndoList( selection.items, UR_ROTATED, rotatePoint ); } for( unsigned int i = 0; i < selection.items.GetCount(); ++i ) { BOARD_ITEM* item = static_cast( selection.items.GetPickedItem( i ) ); - item->Rotate( wxPoint( cursor.x, cursor.y ), 900.0 ); + item->Rotate( rotatePoint, editFrame->GetRotationAngle() ); + if( !m_dragging ) item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } @@ -246,6 +262,9 @@ int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) else getModel( PCB_T )->GetRatsnest()->Recalculate(); + if( unselect ) + m_toolMgr->RunAction( "pcbnew.InteractiveSelection.Clear" ); + return 0; } @@ -253,20 +272,28 @@ int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) int EDIT_TOOL::Flip( TOOL_EVENT& aEvent ) { const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); - VECTOR2D cursor = getView()->ToWorld( getViewControls()->GetCursorPosition() ); PCB_EDIT_FRAME* editFrame = static_cast( m_toolMgr->GetEditFrame() ); + // Shall the selection be cleared at the end? + bool unselect = selection.Empty(); + + if( !makeSelection( selection ) ) + return 0; + + wxPoint flipPoint = getModificationPoint( selection ); + if( !m_dragging ) // If it is being dragged, then it is already saved with UR_CHANGED flag { editFrame->OnModify(); - editFrame->SaveCopyInUndoList( selection.items, UR_FLIPPED, wxPoint( cursor.x, cursor.y ) ); + editFrame->SaveCopyInUndoList( selection.items, UR_FLIPPED, flipPoint ); } for( unsigned int i = 0; i < selection.items.GetCount(); ++i ) { BOARD_ITEM* item = static_cast( selection.items.GetPickedItem( i ) ); - item->Flip( wxPoint( cursor.x, cursor.y ) ); + item->Flip( flipPoint ); + if( !m_dragging ) item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS ); } @@ -279,14 +306,22 @@ int EDIT_TOOL::Flip( TOOL_EVENT& aEvent ) else getModel( PCB_T )->GetRatsnest()->Recalculate(); + if( unselect ) + m_toolMgr->RunAction( "pcbnew.InteractiveSelection.Clear" ); + return 0; } int EDIT_TOOL::Remove( TOOL_EVENT& aEvent ) { + const SELECTION_TOOL::SELECTION selection = m_selectionTool->GetSelection(); + + if( !makeSelection( selection ) ) + return 0; + // Get a copy of the selected items set - PICKED_ITEMS_LIST selectedItems = m_selectionTool->GetSelection().items; + PICKED_ITEMS_LIST selectedItems = selection.items; PCB_EDIT_FRAME* editFrame = static_cast( m_toolMgr->GetEditFrame() ); // As we are about to remove items, they have to be removed from the selection first @@ -385,9 +420,44 @@ void EDIT_TOOL::updateRatsnest( bool aRedraw ) { BOARD_ITEM* item = static_cast( selection.items.GetPickedItem( i ) ); - ratsnest->Update( static_cast( item ) ); + ratsnest->Update( item ); if( aRedraw ) ratsnest->AddSimple( item ); } } + + +wxPoint EDIT_TOOL::getModificationPoint( const SELECTION_TOOL::SELECTION& aSelection ) +{ + if( aSelection.Size() == 1 ) + { + return static_cast( aSelection.items.GetPickedItem( 0 ) )->GetPosition(); + } + else + { + VECTOR2I cursor = getView()->ToWorld( getViewControls()->GetCursorPosition() ); + return wxPoint( cursor.x, cursor.y ); + } +} + + +bool EDIT_TOOL::makeSelection( const SELECTION_TOOL::SELECTION& aSelection ) +{ + if( aSelection.Empty() ) + { + // Try to find an item that could be modified + m_toolMgr->RunAction( "pcbnew.InteractiveSelection.Single" ); + + if( aSelection.Empty() ) + { + // This is necessary, so later the tool may be activated upon + // reception of the activation event + setTransitions(); + + return false; // Still no items to work with + } + } + + return true; +} diff --git a/pcbnew/tools/edit_tool.h b/pcbnew/tools/edit_tool.h index 0079d332b3..d31b159aa5 100644 --- a/pcbnew/tools/edit_tool.h +++ b/pcbnew/tools/edit_tool.h @@ -115,6 +115,14 @@ private: } void updateRatsnest( bool aRedraw ); + + ///> Returns the right modification point (e.g. for rotation), depending on the number of + ///> selected items. + wxPoint getModificationPoint( const SELECTION_TOOL::SELECTION& aSelection ); + + ///> If there are no items currently selected, it tries to choose the item that is under + ///> the cursor or displays a disambiguation menu if there are multpile items. + bool makeSelection( const SELECTION_TOOL::SELECTION& aSelection ); }; #endif diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index ce59adbb1f..17fcd05ee7 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -112,12 +112,12 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) selectSingle( evt->Position() ); } + // double click? Display the properties window else if( evt->IsDblClick( BUT_LEFT ) ) { if( m_selection.Empty() ) selectSingle( evt->Position() ); - // Display properties window m_toolMgr->RunAction( "pcbnew.InteractiveEdit.properties" ); } From cf9e5417d01d4923e528e5f21751d02f0d1cb257 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 5 Feb 2014 09:05:27 +0100 Subject: [PATCH 78/95] Added possibility for editing pads properties. --- pcbnew/tools/edit_tool.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 9d99f3275c..2fa4108047 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -205,6 +205,21 @@ int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) { // Display properties dialog BOARD_ITEM* item = static_cast( selection.items.GetPickedItem( 0 ) ); + VECTOR2I cursor = getView()->ToWorld( getViewControls()->GetCursorPosition() ); + + // Check if user wants to edit pad or module properties + if( item->Type() == PCB_MODULE_T ) + { + for( D_PAD* pad = static_cast( item )->Pads(); pad; pad = pad->Next() ) + { + if( pad->ViewBBox().Contains( cursor ) ) + { + // Turns out that user wants to edit a pad properties + item = pad; + break; + } + } + } editFrame->SaveCopyInUndoList( item, UR_CHANGED ); editFrame->OnModify(); From 7e8b1906b2457dfd2af0d19483f0ca7d3d926e65 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 5 Feb 2014 10:17:14 +0100 Subject: [PATCH 79/95] Grip margin is relative to the world's zoom. --- pcbnew/tools/selection_tool.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 17fcd05ee7..4f2489e81c 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -568,16 +568,15 @@ void SELECTION_TOOL::deselectVisually( BOARD_ITEM* aItem ) const bool SELECTION_TOOL::containsSelected( const VECTOR2I& aPoint ) const { - const unsigned GRIP_MARGIN = 500000; + const unsigned GRIP_MARGIN = 20; + VECTOR2D margin = getView()->ToWorld( VECTOR2D( GRIP_MARGIN, GRIP_MARGIN ), false ); // Check if the point is located within any of the currently selected items bounding boxes - std::set::iterator it, it_end; - for( unsigned int i = 0; i < m_selection.items.GetCount(); ++i ) { BOARD_ITEM* item = static_cast( m_selection.items.GetPickedItem( i ) ); BOX2I itemBox = item->ViewBBox(); - itemBox.Inflate( GRIP_MARGIN ); // Give some margin for gripping an item + itemBox.Inflate( margin.x, margin.y ); // Give some margin for gripping an item if( itemBox.Contains( aPoint ) ) return true; From aff5e66ab8538f55af9868fd2ad29dd382cabd53 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 5 Feb 2014 10:30:50 +0100 Subject: [PATCH 80/95] Some items were still marked as selected after undoing an operation. --- pcbnew/board_undo_redo.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/pcbnew/board_undo_redo.cpp b/pcbnew/board_undo_redo.cpp index 970ea3167d..9931b6c1e6 100644 --- a/pcbnew/board_undo_redo.cpp +++ b/pcbnew/board_undo_redo.cpp @@ -537,6 +537,7 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed } ratsnest->Add( item ); + item->ClearSelected(); // TODO or ClearFlags? item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS ); } break; From cff1ea84ee326e734e37cfa4d82df35e1b2549dc Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 5 Feb 2014 10:47:55 +0100 Subject: [PATCH 81/95] Fixed bug introduced in the last commit. --- pcbnew/board_undo_redo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcbnew/board_undo_redo.cpp b/pcbnew/board_undo_redo.cpp index 9931b6c1e6..a5a3ad314e 100644 --- a/pcbnew/board_undo_redo.cpp +++ b/pcbnew/board_undo_redo.cpp @@ -537,7 +537,7 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed } ratsnest->Add( item ); - item->ClearSelected(); // TODO or ClearFlags? + item->ClearFlags( SELECTED ); item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS ); } break; From de0c4760429477a33a4789a2ac593394ffd3cc3c Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 5 Feb 2014 11:08:34 +0100 Subject: [PATCH 82/95] Fixed removal of items in the KiCad-default style. --- pcbnew/tools/edit_tool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 2fa4108047..f5f1c3b0ff 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -330,7 +330,7 @@ int EDIT_TOOL::Flip( TOOL_EVENT& aEvent ) int EDIT_TOOL::Remove( TOOL_EVENT& aEvent ) { - const SELECTION_TOOL::SELECTION selection = m_selectionTool->GetSelection(); + const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); if( !makeSelection( selection ) ) return 0; From c8c98753b5e19d0ba817ce8e849d4217992b91d7 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 5 Feb 2014 11:33:45 +0100 Subject: [PATCH 83/95] Initialized value to suppress Valgrind warnings. --- pcbnew/tools/selection_tool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 4f2489e81c..366c81659a 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -50,7 +50,7 @@ using boost::optional; SELECTION_TOOL::SELECTION_TOOL() : - TOOL_INTERACTIVE( "pcbnew.InteractiveSelection" ), m_multiple( false ) + TOOL_INTERACTIVE( "pcbnew.InteractiveSelection" ), m_additive( false ), m_multiple( false ) { m_selArea = new SELECTION_AREA; m_selection.group = new KIGFX::VIEW_GROUP; From 6d6181cdfa1c8d86130019f6ddef40fd7f863f45 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 5 Feb 2014 14:51:19 +0100 Subject: [PATCH 84/95] Minor optimizations. --- common/geometry/hetriang.cpp | 74 +++++++++++++++--------------------- 1 file changed, 31 insertions(+), 43 deletions(-) diff --git a/common/geometry/hetriang.cpp b/common/geometry/hetriang.cpp index 175e80dbd5..b69255cdbf 100644 --- a/common/geometry/hetriang.cpp +++ b/common/geometry/hetriang.cpp @@ -223,8 +223,8 @@ void Triangulation::removeTriangle(EdgePtr& edge) { removeLeadingEdgeFromList(e1); // cout << "No leading edges = " << leadingEdges_.size() << endl; // Remove the triangle - EdgePtr e2 = e1->getNextEdgeInFace(); - EdgePtr e3 = e2->getNextEdgeInFace(); + EdgePtr e2(e1->getNextEdgeInFace()); + EdgePtr e3(e2->getNextEdgeInFace()); if (e1->getTwinEdge()) e1->getTwinEdge()->setTwinEdge(EdgePtr()); @@ -240,15 +240,15 @@ void Triangulation::reverse_splitTriangle(EdgePtr& edge) { // Reverse operation of splitTriangle - EdgePtr e1 = edge->getNextEdgeInFace(); - EdgePtr le = getLeadingEdgeInTriangle(e1); + EdgePtr e1(edge->getNextEdgeInFace()); + EdgePtr le(getLeadingEdgeInTriangle(e1)); #ifdef DEBUG_HE if (!le) errorAndExit("Triangulation::removeTriangle: could not find leading edge"); #endif removeLeadingEdgeFromList(le); - EdgePtr e2 = e1->getNextEdgeInFace()->getTwinEdge()->getNextEdgeInFace(); + EdgePtr e2(e1->getNextEdgeInFace()->getTwinEdge()->getNextEdgeInFace()); le = getLeadingEdgeInTriangle(e2); #ifdef DEBUG_HE if (!le) @@ -256,7 +256,7 @@ void Triangulation::reverse_splitTriangle(EdgePtr& edge) { #endif removeLeadingEdgeFromList(le); - EdgePtr e3 = edge->getTwinEdge()->getNextEdgeInFace()->getNextEdgeInFace(); + EdgePtr e3(edge->getTwinEdge()->getNextEdgeInFace()->getNextEdgeInFace()); le = getLeadingEdgeInTriangle(e3); #ifdef DEBUG_HE if (!le) @@ -322,14 +322,11 @@ bool Triangulation::removeLeadingEdgeFromList(EdgePtr& leadingEdge) { edge->setAsLeadingEdge(false); it = leadingEdges_.erase(it); - break; + return true; } } - if (it == leadingEdges_.end()) - return false; - - return true; + return false; } @@ -451,14 +448,14 @@ EdgePtr Triangulation::splitTriangle(EdgePtr& edge, NodePtr& point) { // Add the node to the structure //NodePtr new_node(new Node(x,y,z)); - NodePtr n1 = edge->getSourceNode(); - EdgePtr e1 = edge; + NodePtr n1(edge->getSourceNode()); + EdgePtr e1(edge); - EdgePtr e2 = edge->getNextEdgeInFace(); - NodePtr n2 = e2->getSourceNode(); + EdgePtr e2(edge->getNextEdgeInFace()); + NodePtr n2(e2->getSourceNode()); - EdgePtr e3 = e2->getNextEdgeInFace(); - NodePtr n3 = e3->getSourceNode(); + EdgePtr e3(e2->getNextEdgeInFace()); + NodePtr n3(e3->getSourceNode()); EdgePtr e1_n(new Edge); EdgePtr e11_n(new Edge); @@ -489,7 +486,6 @@ EdgePtr Triangulation::splitTriangle(EdgePtr& edge, NodePtr& point) { e22_n->setNextEdgeInFace(e2); e33_n->setNextEdgeInFace(e3); - // and update old's next edge e1->setNextEdgeInFace(e2_n); e2->setNextEdgeInFace(e3_n); @@ -500,19 +496,15 @@ EdgePtr Triangulation::splitTriangle(EdgePtr& edge, NodePtr& point) { // Use the field telling if an edge is a leading edge // NOTE: Must search in the list!!! - - EdgePtr leadingEdge; if (e1->isLeadingEdge()) - leadingEdge = e1; + removeLeadingEdgeFromList(e1); else if (e2->isLeadingEdge()) - leadingEdge = e2; + removeLeadingEdgeFromList(e2); else if(e3->isLeadingEdge()) - leadingEdge = e3; + removeLeadingEdgeFromList(e3); else return EdgePtr(); - removeLeadingEdgeFromList(leadingEdge); - addLeadingEdge(e1_n); addLeadingEdge(e2_n); addLeadingEdge(e3_n); @@ -532,16 +524,16 @@ void Triangulation::swapEdge(EdgePtr& diagonal) { // Swap by rotating counterclockwise // Use the same objects - no deletion or new objects - EdgePtr eL = diagonal; - EdgePtr eR = eL->getTwinEdge(); - EdgePtr eL_1 = eL->getNextEdgeInFace(); - EdgePtr eL_2 = eL_1->getNextEdgeInFace(); - EdgePtr eR_1 = eR->getNextEdgeInFace(); - EdgePtr eR_2 = eR_1->getNextEdgeInFace(); + EdgePtr eL(diagonal); + EdgePtr eR(eL->getTwinEdge()); + EdgePtr eL_1(eL->getNextEdgeInFace()); + EdgePtr eL_2(eL_1->getNextEdgeInFace()); + EdgePtr eR_1(eR->getNextEdgeInFace()); + EdgePtr eR_2(eR_1->getNextEdgeInFace()); // avoid node to be dereferenced to zero and deleted - NodePtr nR = eR_2->getSourceNode(); - NodePtr nL = eL_2->getSourceNode(); + NodePtr nR(eR_2->getSourceNode()); + NodePtr nL(eL_2->getSourceNode()); eL->setSourceNode(nR); eR->setSourceNode(nL); @@ -555,24 +547,20 @@ void Triangulation::swapEdge(EdgePtr& diagonal) { eR_2->setNextEdgeInFace(eL_1); eL_1->setNextEdgeInFace(eR); - EdgePtr leL; if (eL->isLeadingEdge()) - leL = eL; + removeLeadingEdgeFromList(eL); else if (eL_1->isLeadingEdge()) - leL = eL_1; + removeLeadingEdgeFromList(eL_1); else if (eL_2->isLeadingEdge()) - leL = eL_2; + removeLeadingEdgeFromList(eL_2); - EdgePtr leR; if (eR->isLeadingEdge()) - leR = eR; + removeLeadingEdgeFromList(eR); else if (eR_1->isLeadingEdge()) - leR = eR_1; + removeLeadingEdgeFromList(eR_1); else if (eR_2->isLeadingEdge()) - leR = eR_2; + removeLeadingEdgeFromList(eR_2); - removeLeadingEdgeFromList(leL); - removeLeadingEdgeFromList(leR); addLeadingEdge(eL); addLeadingEdge(eR); } From 9f5d968476fd3c66058e2a9fba2b8af79b061596 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 6 Feb 2014 17:29:13 +0100 Subject: [PATCH 85/95] Fixed snapping item in a wrong spot bug. --- common/view/wx_view_controls.cpp | 2 +- include/view/view_controls.h | 2 +- include/view/wx_view_controls.h | 7 +++++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/common/view/wx_view_controls.cpp b/common/view/wx_view_controls.cpp index f9a17fa86a..48107911d2 100644 --- a/common/view/wx_view_controls.cpp +++ b/common/view/wx_view_controls.cpp @@ -229,7 +229,7 @@ void WX_VIEW_CONTROLS::onTimer( wxTimerEvent& aEvent ) void WX_VIEW_CONTROLS::SetGrabMouse( bool aEnabled ) { - m_grabMouse = aEnabled; + VIEW_CONTROLS::SetGrabMouse( aEnabled ); if( aEnabled ) m_parentPanel->CaptureMouse(); diff --git a/include/view/view_controls.h b/include/view/view_controls.h index a51048dca3..5ec1a037a4 100644 --- a/include/view/view_controls.h +++ b/include/view/view_controls.h @@ -60,7 +60,7 @@ public: * * @param aEnabled says whether the opion should be enabled or disabled. */ - void SetSnapping( bool aEnabled ) + virtual void SetSnapping( bool aEnabled ) { m_snappingEnabled = aEnabled; } diff --git a/include/view/wx_view_controls.h b/include/view/wx_view_controls.h index 5df48f3de3..41540e951b 100644 --- a/include/view/wx_view_controls.h +++ b/include/view/wx_view_controls.h @@ -58,6 +58,13 @@ public: void onEnter( wxMouseEvent& WXUNUSED( aEvent ) ); void onTimer( wxTimerEvent& WXUNUSED( aEvent ) ); + ///> @copydoc VIEW_CONTROLS::SetSnapping() + void SetSnapping( bool aEnabled ) + { + VIEW_CONTROLS::SetSnapping( aEnabled ); + updateCursor(); + } + /** * Function SetGrabMouse() * Enables/disables mouse cursor grabbing (limits the movement field only to the panel area). From 68a1b06674377a488208bedcb2e378cb40bf1c6b Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 7 Feb 2014 19:55:40 +0100 Subject: [PATCH 86/95] Corrected bounding box for arcs (DRAWSEGMENT). --- pcbnew/class_drawsegment.cpp | 56 +++++++++++++++++++++++++++++++++++- pcbnew/class_drawsegment.h | 5 ++-- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/pcbnew/class_drawsegment.cpp b/pcbnew/class_drawsegment.cpp index 4f2376de74..d1e9799258 100644 --- a/pcbnew/class_drawsegment.cpp +++ b/pcbnew/class_drawsegment.cpp @@ -134,7 +134,7 @@ const wxPoint DRAWSEGMENT::GetArcEnd() const return endPoint; // after rotation, the end of the arc. } -const double DRAWSEGMENT::GetArcAngleStart() const +double DRAWSEGMENT::GetArcAngleStart() const { // due to the Y axis orient atan2 needs - y value double angleStart = ArcTangente( GetArcStart().y - GetCenter().y, @@ -148,6 +148,7 @@ const double DRAWSEGMENT::GetArcAngleStart() const return angleStart; } + void DRAWSEGMENT::SetAngle( double aAngle ) { NORMALIZE_ANGLE_360( aAngle ); @@ -379,6 +380,59 @@ const EDA_RECT DRAWSEGMENT::GetBoundingBox() const wxPoint end = m_End; RotatePoint( &end, m_Start, -m_Angle ); bbox.Merge( end ); + + // Determine the starting quarter + // 0 right-bottom + // 1 left-bottom + // 2 left-top + // 3 right-top + unsigned int quarter = 0; // assume right-bottom + + if( m_End.y < m_Start.y ) // change to left-top + quarter |= 3; + + if( m_End.x < m_Start.x ) // for left side, the LSB is 2nd bit negated + quarter ^= 1; + + int radius = GetRadius(); + int angle = (int) GetArcAngleStart() % 900 + m_Angle; + bool directionCW = ( m_Angle > 0 ); // Is the direction of arc clockwise? + + if( !directionCW ) + { + angle = 900 - angle; + quarter = ( quarter + 3 ) % 4; // -1 modulo arithmetic + } + + while( angle > 900 ) + { + switch( quarter ) + { + case 0: + bbox.Merge( wxPoint( m_Start.x, m_Start.y + radius ) ); // down + break; + + case 1: + bbox.Merge( wxPoint( m_Start.x - radius, m_Start.y ) ); // left + break; + + case 2: + bbox.Merge( wxPoint( m_Start.x, m_Start.y - radius ) ); // up + break; + + case 3: + bbox.Merge( wxPoint( m_Start.x + radius, m_Start.y ) ); // right + break; + } + + if( directionCW ) + ++quarter; + else + quarter += 3; // -1 modulo arithmetic + + quarter %= 4; + angle -= 900; + } } break; diff --git a/pcbnew/class_drawsegment.h b/pcbnew/class_drawsegment.h index dacd8061d2..635a3235d7 100644 --- a/pcbnew/class_drawsegment.h +++ b/pcbnew/class_drawsegment.h @@ -30,7 +30,6 @@ #ifndef CLASS_DRAWSEGMENT_H_ #define CLASS_DRAWSEGMENT_H_ - #include #include #include @@ -126,9 +125,9 @@ public: /** * function GetArcAngleStart() - * @return the angle of the stating point of this arc, between 0 and 3600 in 0.1 deg + * @return the angle of the starting point of this arc, between 0 and 3600 in 0.1 deg */ - const double GetArcAngleStart() const; + double GetArcAngleStart() const; /** * Function GetRadius From 90c0e2e8f45237e24011332b3eb5d42e07a48a96 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 7 Feb 2014 20:44:34 +0100 Subject: [PATCH 87/95] Right click on an item when there is nothing selected - enables the context menu. --- pcbnew/tools/selection_tool.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 366c81659a..2a4f167671 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -112,6 +112,16 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) selectSingle( evt->Position() ); } + // right click? if there is any object - show the context menu + else if( evt->IsClick( BUT_RIGHT ) ) + { + if( m_selection.Empty() ) + selectSingle( evt->Position() ); + + if( !m_selection.Empty() ) + SetContextMenu( &m_menu, CMENU_NOW ); + } + // double click? Display the properties window else if( evt->IsDblClick( BUT_LEFT ) ) { @@ -310,9 +320,6 @@ void SELECTION_TOOL::clearSelection() m_selection.clear(); getEditFrame()->SetCurItem( NULL ); - - // Do not show the context menu when there is nothing selected - SetContextMenu( &m_menu, CMENU_OFF ); } @@ -509,9 +516,6 @@ void SELECTION_TOOL::select( BOARD_ITEM* aItem ) { // Set as the current item, so the information about selection is displayed getEditFrame()->SetCurItem( aItem, true ); - - // Now the context menu should be enabled - SetContextMenu( &m_menu, CMENU_BUTTON ); } else if( m_selection.Size() == 2 ) // Check only for 2, so it will not be { // called for every next selected item @@ -539,10 +543,7 @@ void SELECTION_TOOL::deselect( BOARD_ITEM* aItem ) // If there is nothing selected, disable the context menu if( m_selection.Empty() ) - { - SetContextMenu( &m_menu, CMENU_OFF ); getEditFrame()->SetCurItem( NULL ); - } } From 8feab0ad660819fed24b2433d119d82312a0bff9 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 11 Feb 2014 14:26:33 +0100 Subject: [PATCH 88/95] Fixed ratsnest related segfaults on BOARD destruction. --- pcbnew/class_board.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index da3bd81fa9..7f7bbb5a43 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -110,14 +110,14 @@ BOARD::BOARD() : BOARD::~BOARD() { - delete m_ratsnest; - while( m_ZoneDescriptorList.size() ) { ZONE_CONTAINER* area_to_remove = m_ZoneDescriptorList[0]; Delete( area_to_remove ); } + delete m_ratsnest; + m_FullRatsnest.clear(); m_LocalRatsnest.clear(); From ddfdbb6ff070fc6b42522c8d214a50cd78f4ac7b Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 12 Feb 2014 18:01:03 +0100 Subject: [PATCH 89/95] NETINFO_ITEM for orphaned items now have empty netname and net code = 0 (to avoid problems). Fixed case for the footprint legacy plugin when added module's do not have set parent (BOARD). Added copyright notice for pcbnew/class_netinfolist.cpp (feel free to correct, it is just copied from corresponding header file). --- pcbnew/class_netinfolist.cpp | 30 ++++++++++++++++++++++++++++-- pcbnew/legacy_plugin.cpp | 5 ++++- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/pcbnew/class_netinfolist.cpp b/pcbnew/class_netinfolist.cpp index 34b2eded9a..ac8962958e 100644 --- a/pcbnew/class_netinfolist.cpp +++ b/pcbnew/class_netinfolist.cpp @@ -1,3 +1,27 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com + * Copyright (C) 1992-2012 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 class_netinfolist.cpp */ @@ -230,7 +254,8 @@ void NETINFO_MAPPING::Update() // Prepare the new mapping m_netMapping.clear(); - // Now the nets variable stores all the used net codes (not only for pads) + // Now the nets variable stores all the used net codes (not only for pads) and we are ready to + // assign new consecutive net numbers int newNetCode = 0; for( std::set::const_iterator it = nets.begin(), itEnd = nets.end(); it != itEnd; ++it ) m_netMapping[*it] = newNetCode++; @@ -249,5 +274,6 @@ NETINFO_ITEM* NETINFO_MAPPING::iterator::operator->() const } -const NETINFO_ITEM NETINFO_LIST::ORPHANED = NETINFO_ITEM( NULL, wxString::FromUTF8( "orphaned" ), -1 ); const int NETINFO_LIST::UNCONNECTED = 0; +const NETINFO_ITEM NETINFO_LIST::ORPHANED = NETINFO_ITEM( NULL, wxEmptyString, + NETINFO_LIST::UNCONNECTED ); diff --git a/pcbnew/legacy_plugin.cpp b/pcbnew/legacy_plugin.cpp index 0ab7069d3d..727f635dfd 100644 --- a/pcbnew/legacy_plugin.cpp +++ b/pcbnew/legacy_plugin.cpp @@ -1303,7 +1303,10 @@ void LEGACY_PLUGIN::loadPAD( MODULE* aModule ) // read Netname ReadDelimitedText( buf, data, sizeof(buf) ); - assert( m_board->FindNet( netcode )->GetNetname() == FROM_UTF8( StrPurge( buf ) ) ); +#ifndef NDEBUG + if( m_board ) + assert( m_board->FindNet( netcode )->GetNetname() == FROM_UTF8( StrPurge( buf ) ) ); +#endif /* NDEBUG */ } else if( TESTLINE( "Po" ) ) // (Po)sition From ee0b425538c8cd4dbd7a6fa4150dac4e07ed3c84 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 21 Feb 2014 09:53:10 +0100 Subject: [PATCH 90/95] Quick fix for unsupported pad types in PNS router. --- pcbnew/router/pns_router.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pcbnew/router/pns_router.cpp b/pcbnew/router/pns_router.cpp index b655ac363f..b2fed52601 100644 --- a/pcbnew/router/pns_router.cpp +++ b/pcbnew/router/pns_router.cpp @@ -97,12 +97,11 @@ private: PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad ) { - PNS_LAYERSET layers; + PNS_LAYERSET layers( 0, 15 ); switch( aPad->GetAttribute() ) { case PAD_STANDARD: - layers = PNS_LAYERSET( 0, 15 ); break; case PAD_SMD: From c1b7ced4e7d419d28a446e22af5b919252bc1a62 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 25 Feb 2014 11:40:34 +0100 Subject: [PATCH 91/95] Renamed BOARD_CONNECTED_ITEM::GetNet() -> GetNetCode() Renamed BOARD_CONNECTED_ITEM::SetNet() -> SetNetCode() Added BOARD_CONNECTED_ITEM::GetNet() for accessing NETINFO_ITEM* of a given item. Fixed module editor crash when launched to edit a module from a PCB. Replaced some BOARD::FindNet( item->GetNet() ) calls with BOARD_CONNECTED_ITEM::GetNet(). --- pcbnew/attribut.cpp | 4 +- pcbnew/autorouter/auto_place_footprints.cpp | 2 +- pcbnew/autorouter/autorout.cpp | 2 +- pcbnew/autorouter/routing_matrix.cpp | 10 ++--- pcbnew/autorouter/solve.cpp | 6 +-- pcbnew/class_board.cpp | 32 +++++-------- pcbnew/class_board_connected_item.cpp | 19 ++++---- pcbnew/class_board_connected_item.h | 41 ++++++++++------- pcbnew/class_netinfo.h | 2 +- pcbnew/class_netinfo_item.cpp | 9 ++-- pcbnew/class_netinfolist.cpp | 20 +++++---- pcbnew/class_pad.cpp | 4 +- pcbnew/class_pad_draw_functions.cpp | 2 +- pcbnew/class_track.cpp | 45 ++++++++----------- pcbnew/class_zone.cpp | 14 +++--- pcbnew/class_zone_settings.cpp | 4 +- pcbnew/clean.cpp | 22 ++++----- pcbnew/connect.cpp | 24 +++++----- pcbnew/cross-probing.cpp | 2 +- pcbnew/deltrack.cpp | 10 ++--- pcbnew/dialogs/dialog_pad_properties.cpp | 10 ++--- pcbnew/dragsegm.cpp | 2 +- pcbnew/drc.cpp | 4 +- pcbnew/drc_clearance_test_functions.cpp | 8 ++-- pcbnew/eagle_plugin.cpp | 12 ++--- pcbnew/edit.cpp | 18 ++++---- pcbnew/edit_track_width.cpp | 4 +- pcbnew/editrack-part2.cpp | 6 +-- pcbnew/editrack.cpp | 16 +++---- pcbnew/exporters/export_d356.cpp | 2 +- pcbnew/exporters/export_gencad.cpp | 10 ++--- pcbnew/highlight.cpp | 6 +-- pcbnew/kicad_plugin.cpp | 8 ++-- pcbnew/legacy_plugin.cpp | 16 +++---- pcbnew/magnetic_tracks_functions.cpp | 6 +-- pcbnew/move_or_drag_track.cpp | 14 +++--- pcbnew/pad_edition_functions.cpp | 2 +- pcbnew/pcad2kicadpcb_plugin/pcb_line.cpp | 2 +- pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp | 4 +- pcbnew/pcad2kicadpcb_plugin/pcb_polygon.cpp | 2 +- pcbnew/pcb_painter.cpp | 6 +-- pcbnew/pcb_parser.cpp | 18 ++++---- pcbnew/ratsnest.cpp | 34 +++++++------- pcbnew/ratsnest_data.cpp | 20 ++++----- pcbnew/router/pns_router.cpp | 10 ++--- pcbnew/specctra_export.cpp | 6 +-- pcbnew/specctra_import.cpp | 4 +- pcbnew/tr_modif.cpp | 2 +- pcbnew/tracepcb.cpp | 6 +-- pcbnew/xchgmod.cpp | 4 +- pcbnew/zones_by_polygon.cpp | 31 ++++++------- pcbnew/zones_by_polygon_fill_functions.cpp | 2 +- ...nvert_brd_items_to_polygons_with_Boost.cpp | 16 +++---- ...ones_convert_to_polygons_aux_functions.cpp | 2 +- pcbnew/zones_functions_for_undo_redo.cpp | 4 +- ...ones_polygons_insulated_copper_islands.cpp | 4 +- pcbnew/zones_polygons_test_connections.cpp | 22 ++++----- pcbnew/zones_test_and_combine_areas.cpp | 12 ++--- 58 files changed, 310 insertions(+), 319 deletions(-) diff --git a/pcbnew/attribut.cpp b/pcbnew/attribut.cpp index 2bc380abf1..c56f09da24 100644 --- a/pcbnew/attribut.cpp +++ b/pcbnew/attribut.cpp @@ -103,7 +103,7 @@ void PCB_EDIT_FRAME::Attribut_net( wxDC* DC, int net_code, bool Flag_On ) { for( ; Track != NULL; Track = Track->Next() ) { - if( net_code == Track->GetNet() ) + if( net_code == Track->GetNetCode() ) break; } } @@ -112,7 +112,7 @@ void PCB_EDIT_FRAME::Attribut_net( wxDC* DC, int net_code, bool Flag_On ) while( Track ) /* Flag change */ { - if( (net_code >= 0 ) && (net_code != Track->GetNet()) ) + if( ( net_code >= 0 ) && ( net_code != Track->GetNetCode() ) ) break; OnModify(); diff --git a/pcbnew/autorouter/auto_place_footprints.cpp b/pcbnew/autorouter/auto_place_footprints.cpp index 7322f5690b..0351c43bd1 100644 --- a/pcbnew/autorouter/auto_place_footprints.cpp +++ b/pcbnew/autorouter/auto_place_footprints.cpp @@ -499,7 +499,7 @@ int genPlacementRoutingMatrix( BOARD* aBrd, EDA_MSG_PANEL* messagePanel ) TRACK TmpSegm( NULL ); TmpSegm.SetLayer( UNDEFINED_LAYER ); - TmpSegm.SetNet( -1 ); + TmpSegm.SetNetCode( -1 ); TmpSegm.SetWidth( RoutingMatrix.m_GridRouting / 2 ); EDA_ITEM* PtStruct = aBrd->m_Drawings; diff --git a/pcbnew/autorouter/autorout.cpp b/pcbnew/autorouter/autorout.cpp index b0dc59b0b7..88f2e12e6e 100644 --- a/pcbnew/autorouter/autorout.cpp +++ b/pcbnew/autorouter/autorout.cpp @@ -78,7 +78,7 @@ void PCB_EDIT_FRAME::Autoroute( wxDC* DC, int mode ) { case PCB_PAD_T: Pad = (D_PAD*) GetScreen()->GetCurItem(); - autoroute_net_code = Pad->GetNet(); + autoroute_net_code = Pad->GetNetCode(); break; default: diff --git a/pcbnew/autorouter/routing_matrix.cpp b/pcbnew/autorouter/routing_matrix.cpp index 1e57b80293..b5d02e926a 100644 --- a/pcbnew/autorouter/routing_matrix.cpp +++ b/pcbnew/autorouter/routing_matrix.cpp @@ -215,7 +215,7 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag ) { D_PAD* pad = aPcb->GetPad( i ); - if( net_code != pad->GetNet() || (flag & FORCE_PADS) ) + if( net_code != pad->GetNetCode() || (flag & FORCE_PADS) ) { ::PlacePad( pad, HOLE, marge, WRITE_CELL ); } @@ -247,7 +247,7 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag ) tmpSegm.SetShape( edge->GetShape() ); tmpSegm.SetWidth( edge->GetWidth() ); tmpSegm.m_Param = edge->GetAngle(); - tmpSegm.SetNet( -1 ); + tmpSegm.SetNetCode( -1 ); TraceSegmentPcb( &tmpSegm, HOLE, marge, WRITE_CELL ); TraceSegmentPcb( &tmpSegm, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL ); @@ -284,7 +284,7 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag ) tmpSegm.SetShape( DrawSegm->GetShape() ); tmpSegm.SetWidth( DrawSegm->GetWidth() ); tmpSegm.m_Param = DrawSegm->GetAngle(); - tmpSegm.SetNet( -1 ); + tmpSegm.SetNetCode( -1 ); TraceSegmentPcb( &tmpSegm, type_cell, marge, WRITE_CELL ); } @@ -335,7 +335,7 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag ) /* Put tracks and vias on matrix */ for( TRACK* track = aPcb->m_Track; track; track = track->Next() ) { - if( net_code == track->GetNet() ) + if( net_code == track->GetNetCode() ) continue; TraceSegmentPcb( track, HOLE, marge, WRITE_CELL ); @@ -374,7 +374,7 @@ int Build_Work( BOARD* Pcb ) pt_pad = pt_rats->m_PadStart; - current_net_code = pt_pad->GetNet(); + current_net_code = pt_pad->GetNetCode(); pt_ch = pt_rats; r1 = ( pt_pad->GetPosition().y - RoutingMatrix.m_BrdBox.GetY() + demi_pas ) diff --git a/pcbnew/autorouter/solve.cpp b/pcbnew/autorouter/solve.cpp index c06d8545eb..063d56c702 100644 --- a/pcbnew/autorouter/solve.cpp +++ b/pcbnew/autorouter/solve.cpp @@ -1180,7 +1180,7 @@ static void OrCell_Trace( BOARD* pcb, int col, int row, g_CurrentTrackSegment->SetWidth( pcb->GetCurrentViaSize() ); g_CurrentTrackSegment->SetShape( pcb->GetDesignSettings().m_CurrentViaType ); - g_CurrentTrackSegment->SetNet( current_net_code ); + g_CurrentTrackSegment->SetNetCode( current_net_code ); } else // placement of a standard segment { @@ -1198,7 +1198,7 @@ static void OrCell_Trace( BOARD* pcb, int col, int row, ( RoutingMatrix.m_GridRouting * row ), pcb->GetBoundingBox().GetY() + ( RoutingMatrix.m_GridRouting * col ))); - g_CurrentTrackSegment->SetNet( current_net_code ); + g_CurrentTrackSegment->SetNetCode( current_net_code ); if( g_CurrentTrackSegment->Back() == NULL ) /* Start trace. */ { @@ -1319,7 +1319,7 @@ static void AddNewTrace( PCB_EDIT_FRAME* pcbframe, wxDC* DC ) } // Insert new segments in real board - int netcode = g_FirstTrackSegment->GetNet(); + int netcode = g_FirstTrackSegment->GetNetCode(); TRACK* firstTrack = g_FirstTrackSegment; int newCount = g_CurrentTrackList.GetCount(); diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 7f7bbb5a43..ab0272f8b4 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -1345,14 +1345,6 @@ NETINFO_ITEM* BOARD::FindNet( int aNetcode ) const // NULL is returned for non valid netcodes NETINFO_ITEM* net = m_NetInfo.GetNetItem( aNetcode ); -#if defined(DEBUG) - if( net && aNetcode != net->GetNet()) // item can be NULL if anetcode is not valid - { - wxLogError( wxT( "FindNet() anetcode %d != GetNet() %d (net: %s)\n" ), - aNetcode, net->GetNet(), TO_UTF8( net->GetNetname() ) ); - } -#endif - return net; } @@ -1515,7 +1507,7 @@ ZONE_CONTAINER* BOARD::HitTestForAnyFilledArea( const wxPoint& aRefPos, if( area->GetState( BUSY ) ) continue; - if( aNetCode >= 0 && area->GetNet() != aNetCode ) + if( aNetCode >= 0 && area->GetNetCode() != aNetCode ) continue; if( area->HitTestFilledArea( aRefPos ) ) @@ -1534,24 +1526,24 @@ int BOARD::SetAreasNetCodesFromNetNames( void ) { if( !GetArea( ii )->IsOnCopperLayer() ) { - GetArea( ii )->SetNet( NETINFO_LIST::UNCONNECTED ); + GetArea( ii )->SetNetCode( NETINFO_LIST::UNCONNECTED ); continue; } - if( GetArea( ii )->GetNet() != 0 ) // i.e. if this zone is connected to a net + if( GetArea( ii )->GetNetCode() != 0 ) // i.e. if this zone is connected to a net { - const NETINFO_ITEM* net = FindNet( GetArea( ii )->GetNetname() ); + const NETINFO_ITEM* net = GetArea( ii )->GetNet(); if( net ) { - GetArea( ii )->SetNet( net->GetNet() ); + GetArea( ii )->SetNetCode( net->GetNet() ); } else { error_count++; // keep Net Name and set m_NetCode to -1 : error flag. - GetArea( ii )->SetNet( -1 ); + GetArea( ii )->SetNetCode( -1 ); } } } @@ -2271,7 +2263,7 @@ ZONE_CONTAINER* BOARD::InsertArea( int netcode, int iarea, LAYER_NUM layer, int { ZONE_CONTAINER* new_area = new ZONE_CONTAINER( this ); - new_area->SetNet( netcode ); + new_area->SetNetCode( netcode ); new_area->SetLayer( layer ); new_area->SetTimeStamp( GetNewTimeStamp() ); @@ -2310,7 +2302,7 @@ bool BOARD::NormalizeAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList, ZONE_CONTAI { // create new copper area and copy poly into it CPolyLine* new_p = (*pa)[ip - 1]; - NewArea = AddArea( aNewZonesList, aCurrArea->GetNet(), aCurrArea->GetLayer(), + NewArea = AddArea( aNewZonesList, aCurrArea->GetNetCode(), aCurrArea->GetLayer(), wxPoint(0, 0), CPolyLine::NO_HATCH ); // remove the poly that was automatically created for the new area @@ -2551,7 +2543,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, } if( !aNetlist.IsDryRun() ) - pad->SetNet( NETINFO_LIST::UNCONNECTED ); + pad->SetNetCode( NETINFO_LIST::UNCONNECTED ); } } else // Footprint pad has a net. @@ -2580,7 +2572,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, m_NetInfo.AppendNet( netinfo ); } - pad->SetNet( netinfo->GetNet() ); + pad->SetNetCode( netinfo->GetNet() ); } } } @@ -2654,7 +2646,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, aReporter->Report( msg ); } - previouspad->SetNet( NETINFO_LIST::UNCONNECTED ); + previouspad->SetNetCode( NETINFO_LIST::UNCONNECTED ); } netname = pad->GetNetname(); count = 1; @@ -2667,7 +2659,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, // Examine last pad if( pad && count == 1 ) - pad->SetNet( NETINFO_LIST::UNCONNECTED ); + pad->SetNetCode( NETINFO_LIST::UNCONNECTED ); } // Last step: Some tests: diff --git a/pcbnew/class_board_connected_item.cpp b/pcbnew/class_board_connected_item.cpp index 26cca19772..73bdced99a 100644 --- a/pcbnew/class_board_connected_item.cpp +++ b/pcbnew/class_board_connected_item.cpp @@ -35,28 +35,28 @@ #include BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( BOARD_ITEM* aParent, KICAD_T idtype ) : - BOARD_ITEM( aParent, idtype ), m_Subnet( 0 ), m_ZoneSubnet( 0 ), - m_netinfo( &NETINFO_LIST::ORPHANED ) + BOARD_ITEM( aParent, idtype ), m_netinfo( &NETINFO_LIST::ORPHANED ), + m_Subnet( 0 ), m_ZoneSubnet( 0 ) { - // The unconnected is set only in case the item belongs to a BOARD - SetNet( NETINFO_LIST::UNCONNECTED ); + // The unconnected net is set only in case the item belongs to a BOARD + SetNetCode( NETINFO_LIST::UNCONNECTED ); } BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( const BOARD_CONNECTED_ITEM& aItem ) : - BOARD_ITEM( aItem ), m_Subnet( aItem.m_Subnet ), m_ZoneSubnet( aItem.m_ZoneSubnet ), - m_netinfo( aItem.m_netinfo ) + BOARD_ITEM( aItem ), m_netinfo( aItem.m_netinfo ), m_Subnet( aItem.m_Subnet ), + m_ZoneSubnet( aItem.m_ZoneSubnet ) { } -int BOARD_CONNECTED_ITEM::GetNet() const +int BOARD_CONNECTED_ITEM::GetNetCode() const { return m_netinfo->GetNet(); } -void BOARD_CONNECTED_ITEM::SetNet( int aNetCode ) +void BOARD_CONNECTED_ITEM::SetNetCode( int aNetCode ) { BOARD* board = GetBoard(); if( board ) @@ -136,8 +136,7 @@ NETCLASS* BOARD_CONNECTED_ITEM::GetNetClass() const } NETCLASS* netclass = NULL; - int netcode = GetNet(); - NETINFO_ITEM* net = board->FindNet( netcode ); + NETINFO_ITEM* net = board->FindNet( GetNetCode() ); if( net ) { diff --git a/pcbnew/class_board_connected_item.h b/pcbnew/class_board_connected_item.h index eab6d310fd..2742fa3106 100644 --- a/pcbnew/class_board_connected_item.h +++ b/pcbnew/class_board_connected_item.h @@ -54,18 +54,6 @@ public: std::vector m_TracksConnected; // list of other tracks connected to me std::vector m_PadsConnected; // list of other pads connected to me -private: - int m_Subnet; /* In rastnest routines : for the current net, block number - * (number common to the current connected items found) - */ - - int m_ZoneSubnet; // used in rastnest computations : for the current net, - // handle cluster number in zone connection - - /// Stores all informations about the net that item belongs to - const NETINFO_ITEM* m_netinfo; - -public: BOARD_CONNECTED_ITEM( BOARD_ITEM* aParent, KICAD_T idtype ); BOARD_CONNECTED_ITEM( const BOARD_CONNECTED_ITEM& aItem ); @@ -78,17 +66,26 @@ public: /** * Function GetNet - * @return int - the net code. + * Returns NET_INFO object for a given item. */ - int GetNet() const; + NETINFO_ITEM* GetNet() const + { + return m_netinfo; + } /** - * Function SetNet + * Function GetNetCode + * @return int - the net code. + */ + int GetNetCode() const; + + /** + * Function SetNetCode * sets net using a net code. * @param aNetCode is a net code for the new net. It has to exist in NETINFO_LIST held by BOARD. * Otherwise, item is assigned to the unconnected net. */ - void SetNet( int aNetCode ); + void SetNetCode( int aNetCode ); /** * Function GetSubNet @@ -156,6 +153,18 @@ public: * @return the Net Class name of this item */ wxString GetNetClassName() const; + +protected: + /// Stores all informations about the net that item belongs to + NETINFO_ITEM* m_netinfo; + +private: + int m_Subnet; /* In rastnest routines : for the current net, block number + * (number common to the current connected items found) + */ + + int m_ZoneSubnet; // used in rastnest computations : for the current net, + // handle cluster number in zone connection }; diff --git a/pcbnew/class_netinfo.h b/pcbnew/class_netinfo.h index 50bb30457d..f566926fcc 100644 --- a/pcbnew/class_netinfo.h +++ b/pcbnew/class_netinfo.h @@ -320,7 +320,7 @@ public: ///> NETINFO_ITEM meaning that there was no net assigned for an item, as there was no ///> board storing net list available. - static const NETINFO_ITEM ORPHANED; + static NETINFO_ITEM ORPHANED; #if defined(DEBUG) void Show() const; diff --git a/pcbnew/class_netinfo_item.cpp b/pcbnew/class_netinfo_item.cpp index 1ca37ec3a1..f61705385f 100644 --- a/pcbnew/class_netinfo_item.cpp +++ b/pcbnew/class_netinfo_item.cpp @@ -58,8 +58,7 @@ NETINFO_ITEM::NETINFO_ITEM( BOARD_ITEM* aParent, const wxString& aNetName, int a m_RatsnestEndIdx = 0; // Ending point of ratsnests of this net m_NetClassName = NETCLASS::Default; - - m_NetClass = 0; + m_NetClass = NULL; } @@ -102,7 +101,7 @@ void NETINFO_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) { for( pad = module->Pads(); pad != 0; pad = pad->Next() ) { - if( pad->GetNet() == GetNet() ) + if( pad->GetNetCode() == GetNet() ) { count++; lengthPadToDie += pad->GetPadToDieLength(); @@ -120,13 +119,13 @@ void NETINFO_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) { if( Struct->Type() == PCB_VIA_T ) { - if( ( (SEGVIA*) Struct )->GetNet() == GetNet() ) + if( ( (SEGVIA*) Struct )->GetNetCode() == GetNet() ) count++; } if( Struct->Type() == PCB_TRACE_T ) { - if( ( (TRACK*) Struct )->GetNet() == GetNet() ) + if( ( (TRACK*) Struct )->GetNetCode() == GetNet() ) lengthnet += ( (TRACK*) Struct )->GetLength(); } } diff --git a/pcbnew/class_netinfolist.cpp b/pcbnew/class_netinfolist.cpp index ac8962958e..da3bd875d1 100644 --- a/pcbnew/class_netinfolist.cpp +++ b/pcbnew/class_netinfolist.cpp @@ -125,11 +125,16 @@ void NETINFO_LIST::buildListOfNets() { pad = m_PadsFullList[ii]; - if( pad->GetNet() == NETINFO_LIST::UNCONNECTED ) // pad not connected + if( pad->GetNetCode() == NETINFO_LIST::UNCONNECTED ) // pad not connected continue; // Add pad to the appropriate list of pads - GetNetItem( pad->GetNet() )->m_PadInNetList.push_back( pad ); + NETINFO_ITEM* net = pad->GetNet(); + // it should not be possible for BOARD_CONNECTED_ITEM to return NULL as a result of GetNet() + wxASSERT( net ); + + if( net ) + net->m_PadInNetList.push_back( pad ); ++nodes_count; } @@ -232,24 +237,24 @@ void NETINFO_MAPPING::Update() // Zones for( int i = 0; i < m_board->GetAreaCount(); ++i ) - nets.insert( m_board->GetArea( i )->GetNet() ); + nets.insert( m_board->GetArea( i )->GetNetCode() ); // Tracks for( TRACK* track = m_board->m_Track; track; track = track->Next() ) - nets.insert( track->GetNet() ); + nets.insert( track->GetNetCode() ); // Modules/pads for( MODULE* module = m_board->m_Modules; module; module = module->Next() ) { for( D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() ) { - nets.insert( pad->GetNet() ); + nets.insert( pad->GetNetCode() ); } } // Segzones for( SEGZONE* zone = m_board->m_Zone; zone; zone = zone->Next() ) - nets.insert( zone->GetNet() ); + nets.insert( zone->GetNetCode() ); // Prepare the new mapping m_netMapping.clear(); @@ -275,5 +280,4 @@ NETINFO_ITEM* NETINFO_MAPPING::iterator::operator->() const const int NETINFO_LIST::UNCONNECTED = 0; -const NETINFO_ITEM NETINFO_LIST::ORPHANED = NETINFO_ITEM( NULL, wxEmptyString, - NETINFO_LIST::UNCONNECTED ); +NETINFO_ITEM NETINFO_LIST::ORPHANED = NETINFO_ITEM( NULL, wxEmptyString, NETINFO_LIST::UNCONNECTED ); diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index a3b87e06c6..c4a83d2441 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -373,7 +373,7 @@ void D_PAD::Copy( D_PAD* source ) m_layerMask = source->m_layerMask; m_NumPadName = source->m_NumPadName; - SetNet( source->GetNet() ); + m_netinfo = source->m_netinfo; m_Drill = source->m_Drill; m_drillShape = source->m_drillShape; m_Offset = source->m_Offset; @@ -403,7 +403,7 @@ void D_PAD::CopyNetlistSettings( D_PAD* aPad ) // Don't do anything foolish like trying to copy to yourself. wxCHECK_RET( aPad != NULL && aPad != this, wxT( "Cannot copy to NULL or yourself." ) ); - aPad->SetNet( GetNet() ); + aPad->SetNetCode( GetNetCode() ); aPad->SetLocalClearance( m_LocalClearance ); aPad->SetLocalSolderMaskMargin( m_LocalSolderMaskMargin ); diff --git a/pcbnew/class_pad_draw_functions.cpp b/pcbnew/class_pad_draw_functions.cpp index b61fc4de32..7c21d9c4b2 100644 --- a/pcbnew/class_pad_draw_functions.cpp +++ b/pcbnew/class_pad_draw_functions.cpp @@ -473,7 +473,7 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo ) GRSetDrawMode( aDC, aDrawInfo.m_DrawMode ); // Draw "No connect" ( / or \ or cross X ) if necessary - if( GetNet() == 0 && aDrawInfo.m_ShowNCMark ) + if( GetNetCode() == 0 && aDrawInfo.m_ShowNCMark ) { int dx0 = std::min( halfsize.x, halfsize.y ); EDA_COLOR_T nc_color = BLUE; diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index 0e554a2a4e..6221756253 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -160,15 +160,11 @@ EDA_ITEM* SEGZONE::Clone() const wxString SEGZONE::GetSelectMenuText() const { wxString text, nettxt; - NETINFO_ITEM* net; BOARD* board = GetBoard(); if( board ) { - net = board->FindNet( GetNet() ); - - if( net ) - nettxt = net->GetNetname(); + nettxt = GetNetname(); } else { @@ -201,7 +197,6 @@ wxString SEGVIA::GetSelectMenuText() const { wxString text; wxString format; - NETINFO_ITEM* net; BOARD* board = GetBoard(); int shape = GetShape(); @@ -215,18 +210,14 @@ wxString SEGVIA::GetSelectMenuText() const if( board ) { - net = board->FindNet( GetNet() ); - wxString netname; - - if( net ) - netname = net->GetNetname(); + wxString netname = GetNetname(); // say which layers, only two for now LAYER_NUM topLayer; LAYER_NUM botLayer; ReturnLayerPair( &topLayer, &botLayer ); text.Printf( format.GetData(), GetChars( ShowWidth() ), - GetChars( netname ), GetNet(), + GetChars( netname ), GetNetCode(), GetChars( board->GetLayerName( topLayer ) ), GetChars( board->GetLayerName( botLayer ) ) ); @@ -496,7 +487,7 @@ TRACK* TRACK::GetBestInsertPoint( BOARD* aPcb ) for( ; track; track = track->Next() ) { - if( GetNet() <= track->GetNet() ) + if( GetNetCode() <= track->GetNetCode() ) return track; } @@ -510,14 +501,14 @@ TRACK* TRACK::GetStartNetCode( int NetCode ) int ii = 0; if( NetCode == -1 ) - NetCode = GetNet(); + NetCode = GetNetCode(); while( Track != NULL ) { - if( Track->GetNet() > NetCode ) + if( Track->GetNetCode() > NetCode ) break; - if( Track->GetNet() == NetCode ) + if( Track->GetNetCode() == NetCode ) { ii++; break; @@ -542,19 +533,19 @@ TRACK* TRACK::GetEndNetCode( int NetCode ) return NULL; if( NetCode == -1 ) - NetCode = GetNet(); + NetCode = GetNetCode(); while( Track != NULL ) { NextS = (TRACK*) Track->Pnext; - if( Track->GetNet() == NetCode ) + if( Track->GetNetCode() == NetCode ) ii++; if( NextS == NULL ) break; - if( NextS->GetNet() > NetCode ) + if( NextS->GetNetCode() > NetCode ) break; Track = NextS; @@ -690,10 +681,10 @@ void TRACK::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, if( aDC->LogicalToDeviceXRel( m_Width ) < MIN_TEXT_SIZE ) return; - if( GetNet() == NETINFO_LIST::UNCONNECTED ) + if( GetNetCode() == NETINFO_LIST::UNCONNECTED ) return; - NETINFO_ITEM* net = ( (BOARD*) GetParent() )->FindNet( GetNet() ); + NETINFO_ITEM* net = GetNet(); if( net == NULL ) return; @@ -952,13 +943,13 @@ void SEGVIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, } // Display the short netname: - if( GetNet() == NETINFO_LIST::UNCONNECTED ) + if( GetNetCode() == NETINFO_LIST::UNCONNECTED ) return; if( DisplayOpt.DisplayNetNamesMode == 0 || DisplayOpt.DisplayNetNamesMode == 1 ) return; - NETINFO_ITEM* net = ( (BOARD*) GetParent() )->FindNet( GetNet() ); + NETINFO_ITEM* net = GetNet(); if( net == NULL ) return; @@ -1095,7 +1086,7 @@ void TRACK::GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ) // Display Net Name (in Pcbnew) if( board ) { - NETINFO_ITEM* net = board->FindNet( GetNet() ); + NETINFO_ITEM* net = GetNet(); if( net ) msg = net->GetNetname(); @@ -1105,7 +1096,7 @@ void TRACK::GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ) aList.push_back( MSG_PANEL_ITEM( _( "NetName" ), msg, RED ) ); /* Display net code : (useful in test or debug) */ - msg.Printf( wxT( "%d.%d" ), GetNet(), GetSubNet() ); + msg.Printf( wxT( "%d.%d" ), GetNetCode(), GetSubNet() ); aList.push_back( MSG_PANEL_ITEM( _( "NetCode" ), msg, RED ) ); } @@ -1576,7 +1567,7 @@ wxString TRACK::GetSelectMenuText() const // disambiguate all the choices under the cursor! if( board ) { - net = board->FindNet( GetNet() ); + net = GetNet(); if( net ) netname = net->GetNetname(); @@ -1591,7 +1582,7 @@ wxString TRACK::GetSelectMenuText() const text.Printf( _("Track %s, net [%s] (%d) on layer %s, length: %s" ), GetChars( ShowWidth() ), GetChars( netname ), - GetNet(), GetChars( GetLayerName() ), + GetNetCode(), GetChars( GetLayerName() ), GetChars( ::LengthDoubleToString( GetLength() ) ) ); return text; diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index cf5ab48ff7..627d98ac87 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -74,7 +74,7 @@ ZONE_CONTAINER::ZONE_CONTAINER( const ZONE_CONTAINER& aZone ) : BOARD_CONNECTED_ITEM( aZone ) { // Should the copy be on the same net? - SetNet( aZone.GetNet() ); + SetNetCode( aZone.GetNetCode() ); m_Poly = new CPolyLine( *aZone.m_Poly ); // For corner moving, corner index to drag, or -1 if no selection @@ -620,9 +620,9 @@ void ZONE_CONTAINER::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) } else if( IsOnCopperLayer() ) { - if( GetNet() >= 0 ) + if( GetNetCode() >= 0 ) { - NETINFO_ITEM* equipot = board->FindNet( GetNet() ); + NETINFO_ITEM* equipot = GetNet(); if( equipot ) msg = equipot->GetNetname(); @@ -640,7 +640,7 @@ void ZONE_CONTAINER::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) #if 1 // Display net code : (useful in test or debug) - msg.Printf( wxT( "%d" ), GetNet() ); + msg.Printf( wxT( "%d" ), GetNetCode() ); aList.push_back( MSG_PANEL_ITEM( _( "NetCode" ), msg, RED ) ); #endif @@ -801,7 +801,7 @@ void ZONE_CONTAINER::Copy( ZONE_CONTAINER* src ) { m_Parent = src->m_Parent; m_Layer = src->m_Layer; - SetNet( src->GetNet() ); + SetNetCode( src->GetNetCode() ); SetTimeStamp( src->m_TimeStamp ); m_Poly->RemoveAllContours(); m_Poly->Copy( src->m_Poly ); // copy outlines @@ -869,11 +869,11 @@ wxString ZONE_CONTAINER::GetSelectMenuText() const // Display net name for copper zones if( !GetIsKeepout() ) { - if( GetNet() >= 0 ) + if( GetNetCode() >= 0 ) { if( board ) { - net = board->FindNet( GetNet() ); + net = GetNet(); if( net ) { diff --git a/pcbnew/class_zone_settings.cpp b/pcbnew/class_zone_settings.cpp index bdf85dbbd6..b17968123f 100644 --- a/pcbnew/class_zone_settings.cpp +++ b/pcbnew/class_zone_settings.cpp @@ -76,7 +76,7 @@ ZONE_SETTINGS& ZONE_SETTINGS::operator << ( const ZONE_CONTAINER& aSource ) m_FillMode = aSource.GetFillMode(); m_ZoneClearance = aSource.GetClearance(); m_ZoneMinThickness = aSource.GetMinThickness(); - m_NetcodeSelection = aSource.GetNet(); + m_NetcodeSelection = aSource.GetNetCode(); m_CurrentZone_Layer = aSource.GetLayer(); m_Zone_HatchingStyle = aSource.GetHatchStyle(); m_ArcToSegmentsCount = aSource.GetArcSegmentCount(); @@ -113,7 +113,7 @@ void ZONE_SETTINGS::ExportSetting( ZONE_CONTAINER& aTarget, bool aFullExport ) c if( aFullExport ) { aTarget.SetPriority( m_ZonePriority ); - aTarget.SetNet( m_NetcodeSelection ); + aTarget.SetNetCode( m_NetcodeSelection ); aTarget.SetLayer( m_CurrentZone_Layer ); aTarget.Outline()->SetLayer( m_CurrentZone_Layer ); } diff --git a/pcbnew/clean.cpp b/pcbnew/clean.cpp index 2fdd6e9975..8e2f77d506 100644 --- a/pcbnew/clean.cpp +++ b/pcbnew/clean.cpp @@ -323,14 +323,14 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() zone = m_Brd->HitTestForAnyFilledArea( track->GetStart(), track->GetLayer(), track->GetLayer(), - track->GetNet() ); + track->GetNetCode() ); } else { ((SEGVIA*)track)->ReturnLayerPair( &top_layer, &bottom_layer ); zone = m_Brd->HitTestForAnyFilledArea( track->GetStart(), top_layer, bottom_layer, - track->GetNet() ); + track->GetNetCode() ); } } @@ -359,7 +359,7 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() zone = m_Brd->HitTestForAnyFilledArea( via->GetStart(), bottom_layer, top_layer, - via->GetNet() ); + via->GetNetCode() ); } if( (other == NULL) && (zone == NULL) ) @@ -383,14 +383,14 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() zone = m_Brd->HitTestForAnyFilledArea( track->GetEnd(), track->GetLayer(), track->GetLayer(), - track->GetNet() ); + track->GetNetCode() ); } else { ((SEGVIA*)track)->ReturnLayerPair( &top_layer, &bottom_layer ); zone = m_Brd->HitTestForAnyFilledArea( track->GetEnd(), top_layer, bottom_layer, - track->GetNet() ); + track->GetNetCode() ); } } @@ -419,7 +419,7 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() via->ReturnLayerPair( &top_layer, &bottom_layer ); zone = m_Brd->HitTestForAnyFilledArea( via->GetEnd(), bottom_layer, top_layer, - via->GetNet() ); + via->GetNetCode() ); } if( (other == NULL) && (zone == NULL) ) @@ -479,7 +479,7 @@ bool TRACKS_CLEANER::clean_segments() if( segment->GetLayer() != other->GetLayer() ) continue; - if( segment->GetNet() != other->GetNet() ) + if( segment->GetNetCode() != other->GetNetCode() ) break; if( ( segment->GetStart() == other->GetStart() ) && @@ -748,14 +748,14 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks() if( segment->start && segment->start->Type()==PCB_PAD_T ) { // get the netcode of the pad to propagate. - net_code_s = ((D_PAD*)(segment->start))->GetNet(); + net_code_s = ((D_PAD*)(segment->start))->GetNetCode(); } else { other = segment->GetTrace( GetBoard()->m_Track, NULL, FLG_START ); if( other ) - net_code_s = other->GetNet(); + net_code_s = other->GetNetCode(); } if( net_code_s < 0 ) @@ -766,14 +766,14 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks() if( segment->end && segment->end->Type()==PCB_PAD_T ) { - net_code_e = ((D_PAD*)(segment->end))->GetNet(); + net_code_e = ((D_PAD*)(segment->end))->GetNetCode(); } else { other = segment->GetTrace( GetBoard()->m_Track, NULL, FLG_END ); if( other ) - net_code_e = other->GetNet(); + net_code_e = other->GetNetCode(); } if( net_code_e < 0 ) diff --git a/pcbnew/connect.cpp b/pcbnew/connect.cpp index 1833bd0d65..9fd2c7ad47 100644 --- a/pcbnew/connect.cpp +++ b/pcbnew/connect.cpp @@ -718,7 +718,7 @@ void PCB_BASE_FRAME::TestConnections() for( TRACK* track = m_Pcb->m_Track; track; ) { // At this point, track is the first track of a given net - current_net_code = track->GetNet(); + current_net_code = track->GetNetCode(); // Get last track of the current net TRACK* lastTrack = track->GetEndNetCode( current_net_code ); @@ -760,7 +760,7 @@ void PCB_BASE_FRAME::TestNetConnection( wxDC* aDC, int aNetCode ) for( unsigned i = 0; i < m_Pcb->GetPadCount(); ++i ) { D_PAD* pad = m_Pcb->GetPad(i); - int pad_net_code = pad->GetNet(); + int pad_net_code = pad->GetNetCode(); if( pad_net_code < aNetCode ) continue; @@ -786,7 +786,7 @@ void PCB_BASE_FRAME::TestNetConnection( wxDC* aDC, int aNetCode ) if( firstTrack && lastTrack ) // i.e. if there are segments { - connections.Build_CurrNet_SubNets_Connections( firstTrack, lastTrack, firstTrack->GetNet() ); + connections.Build_CurrNet_SubNets_Connections( firstTrack, lastTrack, firstTrack->GetNetCode() ); } } @@ -842,7 +842,7 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode() curr_track->end = NULL; curr_track->SetState( BUSY | IN_EDIT | BEGIN_ONPAD | END_ONPAD, false ); curr_track->SetZoneSubNet( 0 ); - curr_track->SetNet( NETINFO_LIST::UNCONNECTED ); + curr_track->SetNetCode( NETINFO_LIST::UNCONNECTED ); } // If no pad, reset pointers and netcode, and do nothing else @@ -863,7 +863,7 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode() for( ; curr_track != NULL; curr_track = curr_track->Next() ) { if( curr_track->m_PadsConnected.size() ) - curr_track->SetNet( curr_track->m_PadsConnected[0]->GetNet() ); + curr_track->SetNetCode( curr_track->m_PadsConnected[0]->GetNetCode() ); } // Pass 2: build connections between track ends @@ -883,17 +883,17 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode() for( curr_track = m_Pcb->m_Track; curr_track; curr_track = curr_track->Next() ) { - int netcode = curr_track->GetNet(); + int netcode = curr_track->GetNetCode(); if( netcode == 0 ) { // try to find a connected item having a netcode for( unsigned kk = 0; kk < curr_track->m_TracksConnected.size(); kk++ ) { - int altnetcode = curr_track->m_TracksConnected[kk]->GetNet(); + int altnetcode = curr_track->m_TracksConnected[kk]->GetNetCode(); if( altnetcode ) { new_pass_request = true; netcode = altnetcode; - curr_track->SetNet(netcode); + curr_track->SetNetCode(netcode); break; } } @@ -902,10 +902,10 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode() { // propagate this netcode to connected tracks having no netcode for( unsigned kk = 0; kk < curr_track->m_TracksConnected.size(); kk++ ) { - int altnetcode = curr_track->m_TracksConnected[kk]->GetNet(); + int altnetcode = curr_track->m_TracksConnected[kk]->GetNetCode(); if( altnetcode == 0 ) { - curr_track->m_TracksConnected[kk]->SetNet(netcode); + curr_track->m_TracksConnected[kk]->SetNetCode(netcode); new_pass_request = true; } } @@ -926,10 +926,10 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode() static bool SortTracksByNetCode( const TRACK* const & ref, const TRACK* const & compare ) { // For items having the same Net, keep the order in list - if( ref->GetNet() == compare->GetNet()) + if( ref->GetNetCode() == compare->GetNetCode()) return ref->m_Param < compare->m_Param; - return ref->GetNet() < compare->GetNet(); + return ref->GetNetCode() < compare->GetNetCode(); } /** diff --git a/pcbnew/cross-probing.cpp b/pcbnew/cross-probing.cpp index d1f41b791f..8042a892a0 100644 --- a/pcbnew/cross-probing.cpp +++ b/pcbnew/cross-probing.cpp @@ -87,7 +87,7 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline ) if( pad ) { - netcode = pad->GetNet(); + netcode = pad->GetNetCode(); // put cursor on the pad: pos = pad->GetPosition(); diff --git a/pcbnew/deltrack.cpp b/pcbnew/deltrack.cpp index 2a77f9faec..331fbd22ab 100644 --- a/pcbnew/deltrack.cpp +++ b/pcbnew/deltrack.cpp @@ -120,7 +120,7 @@ TRACK* PCB_EDIT_FRAME::Delete_Segment( wxDC* DC, TRACK* aTrack ) return NULL; } - current_net_code = aTrack->GetNet(); + current_net_code = aTrack->GetNetCode(); DLIST* container = (DLIST*)aTrack->GetList(); wxASSERT( container ); @@ -142,7 +142,7 @@ void PCB_EDIT_FRAME::Delete_Track( wxDC* DC, TRACK* aTrack ) { if( aTrack != NULL ) { - int current_net_code = aTrack->GetNet(); + int current_net_code = aTrack->GetNetCode(); Remove_One_Track( DC, aTrack ); OnModify(); TestNetConnection( DC, current_net_code ); @@ -160,7 +160,7 @@ void PCB_EDIT_FRAME::Delete_net( wxDC* DC, TRACK* aTrack ) PICKED_ITEMS_LIST itemsList; ITEM_PICKER picker( NULL, UR_DELETED ); - int net_code_delete = aTrack->GetNet(); + int net_code_delete = aTrack->GetNetCode(); /* Search the first item for the given net code */ TRACK* trackList = GetBoard()->m_Track->GetStartNetCode( net_code_delete ); @@ -171,7 +171,7 @@ void PCB_EDIT_FRAME::Delete_net( wxDC* DC, TRACK* aTrack ) for( TRACK* segm = trackList; segm; segm = next_track, ++ii ) { next_track = segm->Next(); - if( segm->GetNet() != net_code_delete ) + if( segm->GetNetCode() != net_code_delete ) break; GetBoard()->m_Track.Remove( segm ); @@ -202,7 +202,7 @@ void PCB_EDIT_FRAME::Remove_One_Track( wxDC* DC, TRACK* pt_segm ) if( segments_to_delete_count == 0 ) return; - int net_code = pt_segm->GetNet(); + int net_code = pt_segm->GetNetCode(); PICKED_ITEMS_LIST itemsList; ITEM_PICKER picker( NULL, UR_DELETED ); diff --git a/pcbnew/dialogs/dialog_pad_properties.cpp b/pcbnew/dialogs/dialog_pad_properties.cpp index b280eaf099..73cbbd446b 100644 --- a/pcbnew/dialogs/dialog_pad_properties.cpp +++ b/pcbnew/dialogs/dialog_pad_properties.cpp @@ -812,14 +812,14 @@ void DIALOG_PAD_PROPERTIES::PadPropertiesAccept( wxCommandEvent& event ) if( m_currentPad->GetNetname() != m_PadNetNameCtrl->GetValue() ) { - if( !m_PadNetNameCtrl->GetValue().IsEmpty() && m_padMaster.GetNet() == 0 ) + if( !m_PadNetNameCtrl->GetValue().IsEmpty() && m_padMaster.GetNetCode() == 0 ) { DisplayError( NULL, _( "Unknown netname, netname not changed" ) ); } else { rastnestIsChanged = true; - m_currentPad->SetNet( m_padMaster.GetNet() ); + m_currentPad->SetNetCode( m_padMaster.GetNetCode() ); } } @@ -982,9 +982,9 @@ bool DIALOG_PAD_PROPERTIES::transferDataToPad( D_PAD* aPad ) // Check if user has set an existing net name const NETINFO_ITEM* netinfo = m_board->FindNet( m_PadNetNameCtrl->GetValue() ); if( netinfo != NULL ) - aPad->SetNet( netinfo->GetNet() ); + aPad->SetNetCode( netinfo->GetNet() ); else - aPad->SetNet( 0 ); + aPad->SetNetCode( NETINFO_LIST::UNCONNECTED ); // Clear some values, according to the pad type and shape switch( aPad->GetShape() ) @@ -1032,7 +1032,7 @@ bool DIALOG_PAD_PROPERTIES::transferDataToPad( D_PAD* aPad ) // no offset, no net name, no pad name allowed aPad->SetOffset( wxPoint( 0, 0 ) ); aPad->SetPadName( wxEmptyString ); - aPad->SetNet( 0 ); + aPad->SetNetCode( NETINFO_LIST::UNCONNECTED ); break; default: diff --git a/pcbnew/dragsegm.cpp b/pcbnew/dragsegm.cpp index 0e0303f860..122d1ea110 100644 --- a/pcbnew/dragsegm.cpp +++ b/pcbnew/dragsegm.cpp @@ -342,7 +342,7 @@ void Collect_TrackSegmentsToDrag( BOARD* aPcb, const wxPoint& aRefPos, LAYER_MSK for( ; track; track = track->Next() ) { - if( track->GetNet() != aNetCode ) // not the same netcodenet code: all candidates tested + if( track->GetNetCode() != aNetCode ) // not the same netcode: all candidates tested break; if( ( aLayerMask & track->GetLayerMask() ) == 0 ) diff --git a/pcbnew/drc.cpp b/pcbnew/drc.cpp index bad9f65fd7..c10f0537b0 100644 --- a/pcbnew/drc.cpp +++ b/pcbnew/drc.cpp @@ -549,7 +549,7 @@ void DRC::testZones() if( !test_area->IsOnCopperLayer() ) continue; - if( test_area->GetNet() < 0 ) + if( test_area->GetNetCode() < 0 ) { m_currentMarker = fillMarker( test_area, DRCE_NON_EXISTANT_NET_FOR_ZONE_OUTLINE, m_currentMarker ); @@ -756,7 +756,7 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_li // The pad must be in a net (i.e pt_pad->GetNet() != 0 ), // But no problem if pads have the same netcode (same net) - if( pad->GetNet() && ( aRefPad->GetNet() == pad->GetNet() ) ) + if( pad->GetNetCode() && ( aRefPad->GetNetCode() == pad->GetNetCode() ) ) continue; // if pads are from the same footprint diff --git a/pcbnew/drc_clearance_test_functions.cpp b/pcbnew/drc_clearance_test_functions.cpp index 1fd8a94ccd..06bc935cd1 100644 --- a/pcbnew/drc_clearance_test_functions.cpp +++ b/pcbnew/drc_clearance_test_functions.cpp @@ -164,7 +164,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) m_segmAngle = 0; layerMask = aRefSeg->GetLayerMask(); - net_code_ref = aRefSeg->GetNet(); + net_code_ref = aRefSeg->GetNetCode(); // Phase 0 : Test vias if( aRefSeg->Type() == PCB_VIA_T ) @@ -310,8 +310,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) // The pad must be in a net (i.e pt_pad->GetNet() != 0 ) // but no problem if the pad netcode is the current netcode (same net) - if( pad->GetNet() // the pad must be connected - && net_code_ref == pad->GetNet() ) // the pad net is the same as current net -> Ok + if( pad->GetNetCode() // the pad must be connected + && net_code_ref == pad->GetNetCode() ) // the pad net is the same as current net -> Ok continue; // DRC for the pad @@ -339,7 +339,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) for( track = aStart; track; track = track->Next() ) { // No problem if segments have the same net code: - if( net_code_ref == track->GetNet() ) + if( net_code_ref == track->GetNetCode() ) continue; // No problem if segment are on different layers : diff --git a/pcbnew/eagle_plugin.cpp b/pcbnew/eagle_plugin.cpp index 078600f081..f8e31fddec 100644 --- a/pcbnew/eagle_plugin.cpp +++ b/pcbnew/eagle_plugin.cpp @@ -1493,7 +1493,7 @@ void EAGLE_PLUGIN::loadPlain( CPTREE& aGraphics ) zone->SetTimeStamp( timeStamp( gr->second ) ); zone->SetLayer( layer ); - zone->SetNet( NETINFO_LIST::UNCONNECTED ); + zone->SetNetCode( NETINFO_LIST::UNCONNECTED ); CPolyLine::HATCH_STYLE outline_hatch = CPolyLine::DIAGONAL_EDGE; @@ -1696,7 +1696,7 @@ void EAGLE_PLUGIN::loadElements( CPTREE& aElements ) if( ni != m_pads_to_nets.end() ) { const ENET* enet = &ni->second; - pad->SetNet( enet->netcode ); + pad->SetNetCode( enet->netcode ); } } @@ -2387,7 +2387,7 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals ) t->SetWidth( width ); t->SetLayer( layer ); - t->SetNet( netCode ); + t->SetNetCode( netCode ); m_board->m_Track.Insert( t, NULL ); } @@ -2452,7 +2452,7 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals ) via->SetPosition( pos ); via->SetEnd( pos ); - via->SetNet( netCode ); + via->SetNetCode( netCode ); via->SetShape( S_CIRCLE ); // @todo should be in SEGVIA constructor } @@ -2495,7 +2495,7 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals ) zone->SetTimeStamp( timeStamp( it->second ) ); zone->SetLayer( layer ); - zone->SetNet( netCode ); + zone->SetNetCode( netCode ); CPolyLine::HATCH_STYLE outline_hatch = CPolyLine::DIAGONAL_EDGE; @@ -2551,7 +2551,7 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals ) // KiCad does not support an unconnected zone with its own non-zero netcode, // but only when assigned netcode = 0 w/o a name... for( ZONES::iterator it = zones.begin(); it != zones.end(); ++it ) - (*it)->SetNet( NETINFO_LIST::UNCONNECTED ); + (*it)->SetNetCode( NETINFO_LIST::UNCONNECTED ); // therefore omit this signal/net. } diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index e2ccdd8a8f..9356d9787a 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -328,7 +328,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) if( type == PCB_TRACE_T || type == PCB_VIA_T ) { BOARD_CONNECTED_ITEM*item = (BOARD_CONNECTED_ITEM*) GetCurItem(); - DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS dlg( this, item->GetNet() ); + DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS dlg( this, item->GetNetCode() ); dlg.ShowModal(); } @@ -468,11 +468,11 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) break; case ID_POPUP_PCB_LOCK_ON_NET: - Attribut_net( &dc, ( (TRACK*) GetCurItem() )->GetNet(), true ); + Attribut_net( &dc, ( (TRACK*) GetCurItem() )->GetNetCode(), true ); break; case ID_POPUP_PCB_LOCK_OFF_NET: - Attribut_net( &dc, ( (TRACK*) GetCurItem() )->GetNet(), false ); + Attribut_net( &dc, ( (TRACK*) GetCurItem() )->GetNetCode(), false ); break; case ID_POPUP_PCB_SETFLAGS_TRACK_MNU: @@ -486,7 +486,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) { SEGZONE* zsegm = (SEGZONE*) GetCurItem(); - int netcode = zsegm->GetNet(); + int netcode = zsegm->GetNetCode(); Delete_OldZone_Fill( zsegm ); SetCurItem( NULL ); TestNetConnection( NULL, netcode ); @@ -523,7 +523,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) case ID_POPUP_PCB_DELETE_ZONE_CUTOUT: m_canvas->MoveCursorToCrossHair(); { - int netcode = ( (ZONE_CONTAINER*) GetCurItem() )->GetNet(); + int netcode = ( (ZONE_CONTAINER*) GetCurItem() )->GetNetCode(); Delete_Zone_Contour( &dc, (ZONE_CONTAINER*) GetCurItem() ); SetCurItem( NULL ); TestNetConnection( NULL, netcode ); @@ -604,7 +604,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) { ZONE_CONTAINER* zone_container = (ZONE_CONTAINER*) GetCurItem(); zone_container->UnFill(); - TestNetConnection( NULL, zone_container->GetNet() ); + TestNetConnection( NULL, zone_container->GetNetCode() ); OnModify(); SetMsgPanel( GetBoard() ); m_canvas->Refresh(); @@ -633,7 +633,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) case ID_POPUP_PCB_FILL_ZONE: m_canvas->MoveCursorToCrossHair(); Fill_Zone( (ZONE_CONTAINER*) GetCurItem() ); - TestNetConnection( NULL, ( (ZONE_CONTAINER*) GetCurItem() )->GetNet() ); + TestNetConnection( NULL, ( (ZONE_CONTAINER*) GetCurItem() )->GetNetCode() ); SetMsgPanel( GetBoard() ); m_canvas->Refresh(); break; @@ -1156,7 +1156,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) newtrack->Draw( m_canvas, &dc, GR_XOR ); // compute the new ratsnest, because connectivity could change - TestNetConnection( &dc, track->GetNet() ); + TestNetConnection( &dc, track->GetNetCode() ); } break; @@ -1248,7 +1248,7 @@ void PCB_EDIT_FRAME::RemoveStruct( BOARD_ITEM* Item, wxDC* DC ) case PCB_ZONE_AREA_T: { SetCurItem( NULL ); - int netcode = ( (ZONE_CONTAINER*) Item )->GetNet(); + int netcode = ( (ZONE_CONTAINER*) Item )->GetNetCode(); Delete_Zone_Contour( DC, (ZONE_CONTAINER*) Item ); TestNetConnection( NULL, netcode ); SetMsgPanel( GetBoard() ); diff --git a/pcbnew/edit_track_width.cpp b/pcbnew/edit_track_width.cpp index 6698f2be1a..4c2d5e8327 100644 --- a/pcbnew/edit_track_width.cpp +++ b/pcbnew/edit_track_width.cpp @@ -36,7 +36,7 @@ bool PCB_EDIT_FRAME::SetTrackSegmentWidth( TRACK* aTrackItem, NETINFO_ITEM* net = NULL; if( aUseNetclassValue ) - net = GetBoard()->FindNet( aTrackItem->GetNet() ); + net = aTrackItem->GetNet(); initial_width = aTrackItem->GetWidth(); @@ -224,7 +224,7 @@ bool PCB_EDIT_FRAME::Change_Net_Tracks_And_Vias_Sizes( int aNetcode, bool aUseNe for( pt_segm = GetBoard()->m_Track; pt_segm != NULL; pt_segm = pt_segm->Next() ) { - if( aNetcode != pt_segm->GetNet() ) // not in net + if( aNetcode != pt_segm->GetNetCode() ) // not in net continue; // we have found a item member of the net diff --git a/pcbnew/editrack-part2.cpp b/pcbnew/editrack-part2.cpp index 81ba0cbd8b..e394ad1ca3 100644 --- a/pcbnew/editrack-part2.cpp +++ b/pcbnew/editrack-part2.cpp @@ -99,7 +99,7 @@ bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC ) via->SetFlags( IS_NEW ); via->SetShape( GetDesignSettings().m_CurrentViaType ); via->SetWidth( GetBoard()->GetCurrentViaSize()); - via->SetNet( GetBoard()->GetHighLightNetCode() ); + via->SetNetCode( GetBoard()->GetHighLightNetCode() ); via->SetEnd( g_CurrentTrackSegment->GetEnd() ); via->SetStart( g_CurrentTrackSegment->GetEnd() ); @@ -139,7 +139,7 @@ bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC ) // else error: will be removed later via->SetLayerPair( first_layer, last_layer ); { - NETINFO_ITEM* net = GetBoard()->FindNet( via->GetNet() ); + NETINFO_ITEM* net = via->GetNet(); via->SetWidth( net->GetMicroViaSize() ); } } @@ -244,7 +244,7 @@ void PCB_EDIT_FRAME::Show_1_Ratsnest( EDA_ITEM* item, wxDC* DC ) { RATSNEST_ITEM* net = &GetBoard()->m_FullRatsnest[ii]; - if( net->GetNet() == pt_pad->GetNet() ) + if( net->GetNet() == pt_pad->GetNetCode() ) { if( ( net->m_Status & CH_VISIBLE ) != 0 ) continue; diff --git a/pcbnew/editrack.cpp b/pcbnew/editrack.cpp index 24223bc8f4..41cc2d7e30 100644 --- a/pcbnew/editrack.cpp +++ b/pcbnew/editrack.cpp @@ -133,12 +133,12 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC ) // A pad is found: put the starting point on pad center pos = pad->GetPosition(); - GetBoard()->SetHighLightNet( pad->GetNet() ); + GetBoard()->SetHighLightNet( pad->GetNetCode() ); } else // A track segment is found { TrackOnStartPoint = (TRACK*) LockPoint; - GetBoard()->SetHighLightNet( TrackOnStartPoint->GetNet() ); + GetBoard()->SetHighLightNet( TrackOnStartPoint->GetNetCode() ); GetBoard()->CreateLockPoint( pos, TrackOnStartPoint, &s_ItemsListPicker ); } } @@ -153,7 +153,7 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC ) -1 ); if( zone ) - GetBoard()->SetHighLightNet( zone->GetNet() ); + GetBoard()->SetHighLightNet( zone->GetNetCode() ); } DBG( g_CurrentTrackList.VerifyListIntegrity() ); @@ -166,7 +166,7 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC ) GetBoard()->DrawHighLight( m_canvas, aDC, GetBoard()->GetHighLightNetCode() ); // Display info about track Net class, and init track and vias sizes: - g_CurrentTrackSegment->SetNet( GetBoard()->GetHighLightNetCode() ); + g_CurrentTrackSegment->SetNetCode( GetBoard()->GetHighLightNetCode() ); GetBoard()->SetCurrentNetClass( g_CurrentTrackSegment->GetNetClassName() ); g_CurrentTrackSegment->SetLayer( GetScreen()->m_Active_Layer ); @@ -476,7 +476,7 @@ bool PCB_EDIT_FRAME::End_Route( TRACK* aTrack, wxDC* aDC ) // g_FirstTrackSegment can be NULL on a double click on the starting point if( g_FirstTrackSegment != NULL ) { - int netcode = g_FirstTrackSegment->GetNet(); + int netcode = g_FirstTrackSegment->GetNetCode(); TRACK* firstTrack = g_FirstTrackSegment; int newCount = g_CurrentTrackList.GetCount(); @@ -540,7 +540,7 @@ bool PCB_EDIT_FRAME::End_Route( TRACK* aTrack, wxDC* aDC ) TRACK* LocateIntrusion( TRACK* listStart, TRACK* aTrack, LAYER_NUM aLayer, const wxPoint& aRef ) { - int net = aTrack->GetNet(); + int net = aTrack->GetNetCode(); int width = aTrack->GetWidth(); TRACK* found = NULL; @@ -555,7 +555,7 @@ TRACK* LocateIntrusion( TRACK* listStart, TRACK* aTrack, LAYER_NUM aLayer, const if( aLayer != track->GetLayer() ) continue; - if( track->GetNet() == net ) + if( track->GetNetCode() == net ) continue; // TRACK::HitTest @@ -614,7 +614,7 @@ static void PushTrack( EDA_DRAW_PANEL* panel ) if( !other ) return; - if( other->GetNet() == track->GetNet() ) + if( other->GetNetCode() == track->GetNetCode() ) return; cv = cursor - other->GetStart(); diff --git a/pcbnew/exporters/export_d356.cpp b/pcbnew/exporters/export_d356.cpp index e8ef8f3fbf..1c64ff64bd 100644 --- a/pcbnew/exporters/export_d356.cpp +++ b/pcbnew/exporters/export_d356.cpp @@ -199,7 +199,7 @@ static void build_via_testpoints( BOARD *aPcb, if( track->Type() == PCB_VIA_T ) { SEGVIA *via = (SEGVIA*) track; - NETINFO_ITEM *net = aPcb->FindNet( track->GetNet() ); + NETINFO_ITEM *net = track->GetNet(); D356_RECORD rk; rk.smd = false; diff --git a/pcbnew/exporters/export_gencad.cpp b/pcbnew/exporters/export_gencad.cpp index 394a39f808..638d22f55d 100644 --- a/pcbnew/exporters/export_gencad.cpp +++ b/pcbnew/exporters/export_gencad.cpp @@ -663,7 +663,7 @@ static void CreateSignalsSection( FILE* aFile, BOARD* aPcb ) { wxString padname; - if( pad->GetNet() != net->GetNet() ) + if( pad->GetNetCode() != net->GetNet() ) continue; pad->ReturnStringPadName( padname ); @@ -730,7 +730,7 @@ static int TrackListSortByNetcode( const void* refptr, const void* objptr ) ref = *( (TRACK**) refptr ); cmp = *( (TRACK**) objptr ); - if( ( diff = ref->GetNet() - cmp->GetNet() ) ) + if( ( diff = ref->GetNetCode() - cmp->GetNetCode() ) ) return diff; if( ( diff = ref->GetWidth() - cmp->GetWidth() ) ) @@ -797,10 +797,10 @@ static void CreateRoutesSection( FILE* aFile, BOARD* aPcb ) { track = tracklist[ii]; - if( old_netcode != track->GetNet() ) + if( old_netcode != track->GetNetCode() ) { - old_netcode = track->GetNet(); - NETINFO_ITEM* net = aPcb->FindNet( track->GetNet() ); + old_netcode = track->GetNetCode(); + NETINFO_ITEM* net = track->GetNet(); wxString netname; if( net && (net->GetNetname() != wxEmptyString) ) diff --git a/pcbnew/highlight.cpp b/pcbnew/highlight.cpp index fc8e805ed1..d4188bdb4d 100644 --- a/pcbnew/highlight.cpp +++ b/pcbnew/highlight.cpp @@ -142,7 +142,7 @@ int PCB_EDIT_FRAME::SelectHighLight( wxDC* DC ) switch( item->Type() ) { case PCB_PAD_T: - netcode = ( (D_PAD*) item )->GetNet(); + netcode = ( (D_PAD*) item )->GetNetCode(); SendMessageToEESCHEMA( item ); break; @@ -151,11 +151,11 @@ int PCB_EDIT_FRAME::SelectHighLight( wxDC* DC ) case PCB_ZONE_T: // since these classes are all derived from TRACK, use a common // GetNet() function: - netcode = ( (TRACK*) item )->GetNet(); + netcode = ( (TRACK*) item )->GetNetCode(); break; case PCB_ZONE_AREA_T: - netcode = ( (ZONE_CONTAINER*) item )->GetNet(); + netcode = ( (ZONE_CONTAINER*) item )->GetNetCode(); break; default: diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index 981b4644db..f8ef4c8d13 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -1230,8 +1230,8 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const std::string output; // Unconnected pad is default net so don't save it. - if( !(m_ctl & CTL_OMIT_NETS) && aPad->GetNet() != 0 ) - StrPrintf( &output, " (net %d %s)", m_mapping->Translate( aPad->GetNet() ), + if( !(m_ctl & CTL_OMIT_NETS) && aPad->GetNetCode() != 0 ) + StrPrintf( &output, " (net %d %s)", m_mapping->Translate( aPad->GetNetCode() ), m_out->Quotew( aPad->GetNetname() ).c_str() ); if( aPad->GetPadToDieLength() != 0 ) @@ -1389,7 +1389,7 @@ void PCB_IO::format( TRACK* aTrack, int aNestLevel ) const m_out->Print( 0, " (layer %s)", m_out->Quotew( aTrack->GetLayerName() ).c_str() ); } - m_out->Print( 0, " (net %d)", m_mapping->Translate( aTrack->GetNet() ) ); + m_out->Print( 0, " (net %d)", m_mapping->Translate( aTrack->GetNetCode() ) ); if( aTrack->GetTimeStamp() != 0 ) m_out->Print( 0, " (tstamp %lX)", aTrack->GetTimeStamp() ); @@ -1408,7 +1408,7 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const // so be sure a dummy value is stored, just for ZONE_CONTAINER compatibility // (perhaps netcode and netname should be not stored) m_out->Print( aNestLevel, "(zone (net %d) (net_name %s)", - aZone->GetIsKeepout() ? 0 : m_mapping->Translate( aZone->GetNet() ), + aZone->GetIsKeepout() ? 0 : m_mapping->Translate( aZone->GetNetCode() ), m_out->Quotew( aZone->GetIsKeepout() ? wxT("") : aZone->GetNetname() ).c_str() ); formatLayer( aZone ); diff --git a/pcbnew/legacy_plugin.cpp b/pcbnew/legacy_plugin.cpp index 727f635dfd..96c7a75a8f 100644 --- a/pcbnew/legacy_plugin.cpp +++ b/pcbnew/legacy_plugin.cpp @@ -1299,7 +1299,7 @@ void LEGACY_PLUGIN::loadPAD( MODULE* aModule ) char buf[1024]; // can be fairly long int netcode = intParse( line + SZ( "Ne" ), &data ); - pad->SetNet( netcode ); + pad->SetNetCode( netcode ); // read Netname ReadDelimitedText( buf, data, sizeof(buf) ); @@ -2090,7 +2090,7 @@ void LEGACY_PLUGIN::loadTrackList( int aStructType ) ( (SEGVIA*) newTrack )->SetLayerPair( LAYER_N_FRONT, LAYER_N_BACK ); } - newTrack->SetNet( net_code ); + newTrack->SetNetCode( net_code ); newTrack->SetState( flags, true ); } @@ -2240,7 +2240,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER() // Init the net code only, not the netname, to be sure // the zone net name is the name read in file. // (When mismatch, the user will be prompted in DRC, to fix the actual name) - zc->BOARD_CONNECTED_ITEM::SetNet( netcode ); + zc->BOARD_CONNECTED_ITEM::SetNetCode( netcode ); } else if( TESTLINE( "ZLayer" ) ) // layer found @@ -2424,7 +2424,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER() // Ensure keepout does not have a net // (which have no sense for a keepout zone) if( zc->GetIsKeepout() ) - zc->SetNet( NETINFO_LIST::UNCONNECTED ); + zc->SetNetCode( NETINFO_LIST::UNCONNECTED ); // should always occur, but who knows, a zone without two corners // is no zone at all, it's a spot? @@ -2434,7 +2434,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER() if( !zc->IsOnCopperLayer() ) { zc->SetFillMode( 0 ); - zc->SetNet( NETINFO_LIST::UNCONNECTED ); + zc->SetNetCode( NETINFO_LIST::UNCONNECTED ); } // Hatch here, after outlines corners are read @@ -3373,7 +3373,7 @@ void LEGACY_PLUGIN::savePAD( const D_PAD* me ) const fprintf( m_fp, "At %s N %08X\n", texttype, me->GetLayerMask() ); - fprintf( m_fp, "Ne %d %s\n", me->GetNet(), EscapedUTF8( me->GetNetname() ).c_str() ); + fprintf( m_fp, "Ne %d %s\n", me->GetNetCode(), EscapedUTF8( me->GetNetname() ).c_str() ); fprintf( m_fp, "Po %s\n", fmtBIUPoint( me->GetPos0() ).c_str() ); @@ -3633,7 +3633,7 @@ void LEGACY_PLUGIN::saveTRACK( const TRACK* me ) const "-1" : fmtBIU( me->GetDrill() ).c_str() ); fprintf(m_fp, "De %d %d %d %lX %X\n", - me->GetLayer(), type, me->GetNet(), + me->GetLayer(), type, me->GetNetCode(), me->GetTimeStamp(), me->GetStatus() ); } @@ -3647,7 +3647,7 @@ void LEGACY_PLUGIN::saveZONE_CONTAINER( const ZONE_CONTAINER* me ) const // just for ZONE_CONTAINER compatibility fprintf( m_fp, "ZInfo %lX %d %s\n", me->GetTimeStamp(), - me->GetIsKeepout() ? 0 : me->GetNet(), + me->GetIsKeepout() ? 0 : me->GetNetCode(), EscapedUTF8( me->GetIsKeepout() ? wxT("") : me->GetNetname() ).c_str() ); // Save the outline layer info diff --git a/pcbnew/magnetic_tracks_functions.cpp b/pcbnew/magnetic_tracks_functions.cpp index 8f7a8e5064..5c84d0d6d8 100644 --- a/pcbnew/magnetic_tracks_functions.cpp +++ b/pcbnew/magnetic_tracks_functions.cpp @@ -161,7 +161,7 @@ bool Magnetize( PCB_EDIT_FRAME* frame, int aCurrentTool, wxSize aGridSize, if( pad ) { - if( doCheckNet && currTrack && currTrack->GetNet() != pad->GetNet() ) + if( doCheckNet && currTrack && currTrack->GetNetCode() != pad->GetNetCode() ) return false; *curpos = pad->GetPosition(); @@ -180,7 +180,7 @@ bool Magnetize( PCB_EDIT_FRAME* frame, int aCurrentTool, wxSize aGridSize, { if( via != currTrack ) // a via cannot influence itself { - if( !doCheckNet || !currTrack || currTrack->GetNet() == via->GetNet() ) + if( !doCheckNet || !currTrack || currTrack->GetNetCode() == via->GetNetCode() ) { *curpos = via->GetStart(); // D(printf("via hit\n");) @@ -223,7 +223,7 @@ bool Magnetize( PCB_EDIT_FRAME* frame, int aCurrentTool, wxSize aGridSize, if( track->Type() != PCB_TRACE_T ) continue; - if( doCheckNet && currTrack && currTrack->GetNet() != track->GetNet() ) + if( doCheckNet && currTrack && currTrack->GetNetCode() != track->GetNetCode() ) continue; if( m_Pcb->IsLayerVisible( track->GetLayer() ) == false ) diff --git a/pcbnew/move_or_drag_track.cpp b/pcbnew/move_or_drag_track.cpp index 968ea993ec..6525d7abd7 100644 --- a/pcbnew/move_or_drag_track.cpp +++ b/pcbnew/move_or_drag_track.cpp @@ -627,7 +627,7 @@ void PCB_EDIT_FRAME::StartMoveOneNodeOrSegment( TRACK* aTrack, wxDC* aDC, int aC { Collect_TrackSegmentsToDrag( GetBoard(), aTrack->GetStart(), aTrack->GetLayerMask(), - aTrack->GetNet(), aTrack->GetWidth() / 2 ); + aTrack->GetNetCode(), aTrack->GetWidth() / 2 ); } PosInit = aTrack->GetStart(); @@ -647,17 +647,17 @@ void PCB_EDIT_FRAME::StartMoveOneNodeOrSegment( TRACK* aTrack, wxDC* aDC, int aC case ID_POPUP_PCB_DRAG_TRACK_SEGMENT: // drag a segment pos = aTrack->GetStart(); Collect_TrackSegmentsToDrag( GetBoard(), pos, aTrack->GetLayerMask(), - aTrack->GetNet(), aTrack->GetWidth() / 2 ); + aTrack->GetNetCode(), aTrack->GetWidth() / 2 ); pos = aTrack->GetEnd(); aTrack->SetFlags( IS_DRAGGED | ENDPOINT | STARTPOINT ); Collect_TrackSegmentsToDrag( GetBoard(), pos, aTrack->GetLayerMask(), - aTrack->GetNet(), aTrack->GetWidth() / 2 ); + aTrack->GetNetCode(), aTrack->GetWidth() / 2 ); break; case ID_POPUP_PCB_MOVE_TRACK_NODE: // Drag via or move node pos = (diag & STARTPOINT) ? aTrack->GetStart() : aTrack->GetEnd(); Collect_TrackSegmentsToDrag( GetBoard(), pos, aTrack->GetLayerMask(), - aTrack->GetNet(), aTrack->GetWidth() / 2 ); + aTrack->GetNetCode(), aTrack->GetWidth() / 2 ); PosInit = pos; break; } @@ -684,7 +684,7 @@ void PCB_EDIT_FRAME::StartMoveOneNodeOrSegment( TRACK* aTrack, wxDC* aDC, int aC s_LastPos = PosInit; m_canvas->SetMouseCapture( Show_MoveNode, Abort_MoveTrack ); - GetBoard()->SetHighLightNet( aTrack->GetNet() ); + GetBoard()->SetHighLightNet( aTrack->GetNetCode() ); GetBoard()->HighLightON(); GetBoard()->DrawHighLight( m_canvas, aDC, GetBoard()->GetHighLightNetCode() ); @@ -792,7 +792,7 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC s_LastPos = GetCrossHairPosition(); m_canvas->SetMouseCapture( Show_Drag_Track_Segment_With_Cte_Slope, Abort_MoveTrack ); - GetBoard()->SetHighLightNet( track->GetNet() ); + GetBoard()->SetHighLightNet( track->GetNetCode() ); GetBoard()->HighLightON(); GetBoard()->DrawHighLight( m_canvas, DC, GetBoard()->GetHighLightNetCode() ); @@ -828,7 +828,7 @@ bool PCB_EDIT_FRAME::PlaceDraggedOrMovedTrackSegment( TRACK* Track, wxDC* DC ) if( Track == NULL ) return false; - int current_net_code = Track->GetNet(); + int current_net_code = Track->GetNetCode(); // DRC control: if( g_Drc_On ) diff --git a/pcbnew/pad_edition_functions.cpp b/pcbnew/pad_edition_functions.cpp index 3295312f29..50fae272bf 100644 --- a/pcbnew/pad_edition_functions.cpp +++ b/pcbnew/pad_edition_functions.cpp @@ -161,7 +161,7 @@ void PCB_BASE_FRAME::AddPad( MODULE* aModule, bool draw ) // Update the pad properties. Import_Pad_Settings( pad, false ); - pad->SetNet( NETINFO_LIST::UNCONNECTED ); + pad->SetNetCode( NETINFO_LIST::UNCONNECTED ); pad->SetPosition( GetCrossHairPosition() ); diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_line.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_line.cpp index ad18b26748..28112177f9 100644 --- a/pcbnew/pcad2kicadpcb_plugin/pcb_line.cpp +++ b/pcbnew/pcad2kicadpcb_plugin/pcb_line.cpp @@ -147,7 +147,7 @@ void PCB_LINE::AddToBoard() track->SetWidth( m_width ); track->SetLayer( m_KiCadLayer ); - track->SetNet( m_netCode ); + track->SetNetCode( m_netCode ); } else { diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp index 55b50c49a5..4985958fc9 100644 --- a/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp +++ b/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp @@ -282,7 +282,7 @@ void PCB_PAD::AddToModule( MODULE* aModule, int aRotation, bool aEncapsulatedPad m_board->AppendNet( netinfo ); } - pad->SetNet( netinfo->GetNet() ); + pad->SetNetCode( netinfo->GetNet() ); } if( !aEncapsulatedPad ) @@ -343,7 +343,7 @@ void PCB_PAD::AddToBoard() via->SetDrill( m_hole ); via->SetLayer( m_KiCadLayer ); - via->SetNet( m_netCode ); + via->SetNetCode( m_netCode ); } } else // pad diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_polygon.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_polygon.cpp index 5fab0055e8..6d7045fb94 100644 --- a/pcbnew/pcad2kicadpcb_plugin/pcb_polygon.cpp +++ b/pcbnew/pcad2kicadpcb_plugin/pcb_polygon.cpp @@ -171,7 +171,7 @@ void PCB_POLYGON::AddToBoard() zone->SetTimeStamp( m_timestamp ); zone->SetLayer( m_KiCadLayer ); - zone->SetNet( m_netCode ); + zone->SetNetCode( m_netCode ); // add outline int outline_hatch = CPolyLine::DIAGONAL_EDGE; diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index ce9a2cb18b..e3f7c7f7c3 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -152,7 +152,7 @@ const COLOR4D& PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer // Try to obtain the netcode for the item const BOARD_CONNECTED_ITEM* item = dynamic_cast( aItem ); if( item ) - netCode = item->GetNet(); + netCode = item->GetNetCode(); } // Return grayish color for non-highlighted layers in the high contrast mode @@ -265,7 +265,7 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer ) if( m_pcbSettings->m_netNamesOnTracks && IsNetnameLayer( aLayer ) ) { - int netCode = aTrack->GetNet(); + int netCode = aTrack->GetNetCode(); // If there is a net name - display it on the track if( netCode > 0 ) @@ -277,7 +277,7 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer ) if( length < 10 * width ) return; - NETINFO_ITEM* net = ( (BOARD*) aTrack->GetParent() )->FindNet( netCode ); + NETINFO_ITEM* net = aTrack->GetNet(); if( !net ) return; diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index f68743b741..8ca4bd4cdc 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -2190,9 +2190,9 @@ D_PAD* PCB_PARSER::parseD_PAD( MODULE* aParent ) throw( IO_ERROR, PARSE_ERROR ) break; case T_net: - pad->SetNet( parseInt( "net number" ) ); + pad->SetNetCode( parseInt( "net number" ) ); NeedSYMBOLorNUMBER(); - assert( FromUTF8() == m_board->FindNet( pad->GetNet() )->GetNetname() ); + assert( FromUTF8() == m_board->FindNet( pad->GetNetCode() )->GetNetname() ); NeedRIGHT(); break; @@ -2288,7 +2288,7 @@ TRACK* PCB_PARSER::parseTRACK() throw( IO_ERROR, PARSE_ERROR ) break; case T_net: - track->SetNet( parseInt( "net number" ) ); + track->SetNetCode( parseInt( "net number" ) ); break; case T_tstamp: @@ -2366,7 +2366,7 @@ SEGVIA* PCB_PARSER::parseSEGVIA() throw( IO_ERROR, PARSE_ERROR ) break; case T_net: - via->SetNet( parseInt( "net number" ) ); + via->SetNetCode( parseInt( "net number" ) ); NeedRIGHT(); break; @@ -2418,18 +2418,18 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR ) // Init the net code only, not the netname, to be sure // the zone net name is the name read in file. // (When mismatch, the user will be prompted in DRC, to fix the actual name) - zone->SetNet( parseInt( "net number" ) ); + zone->SetNetCode( parseInt( "net number" ) ); NeedRIGHT(); break; case T_net_name: NeedSYMBOLorNUMBER(); - if( m_board->FindNet( zone->GetNet() )->GetNetname() != FromUTF8() ) + if( zone->GetNet()->GetNetname() != FromUTF8() ) { wxString msg = _( "There is a zone that belongs to a not " "existing net (" ) + FromUTF8() + _("), you should verify it." ); DisplayError( NULL, msg ); - zone->SetNet( NETINFO_LIST::UNCONNECTED ); + zone->SetNetCode( NETINFO_LIST::UNCONNECTED ); } NeedRIGHT(); break; @@ -2694,7 +2694,7 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR ) if( !zone->IsOnCopperLayer() ) { zone->SetFillMode( 0 ); - zone->SetNet( NETINFO_LIST::UNCONNECTED ); + zone->SetNetCode( NETINFO_LIST::UNCONNECTED ); } // Set hatch here, after outlines corners are read @@ -2706,7 +2706,7 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR ) // Ensure keepout does not have a net (which have no sense for a keepout zone) if( zone->GetIsKeepout() ) - zone->SetNet( NETINFO_LIST::UNCONNECTED ); + zone->SetNetCode( NETINFO_LIST::UNCONNECTED ); return zone.release(); } diff --git a/pcbnew/ratsnest.cpp b/pcbnew/ratsnest.cpp index 32dba7213d..028c632568 100644 --- a/pcbnew/ratsnest.cpp +++ b/pcbnew/ratsnest.cpp @@ -74,7 +74,7 @@ void MIN_SPAN_TREE_PADS::AddTreeToRatsnest( std::vector &aRatsnes if( padsBuffer.empty() ) return; - int netcode = padsBuffer[0]->GetNet(); + int netcode = padsBuffer[0]->GetNetCode(); // Note: to get edges in minimum spanning tree, // the index value 0 is not used: it is just // the entry point of the minimum spanning tree. @@ -182,7 +182,7 @@ void PCB_BASE_FRAME::Compile_Ratsnest( wxDC* aDC, bool aDisplayStatus ) */ static bool sortByNetcode( const D_PAD* const & ref, const D_PAD* const & item ) { - return ref->GetNet() < item->GetNet(); + return ref->GetNetCode() < item->GetNetCode(); } @@ -540,7 +540,7 @@ void PCB_BASE_FRAME::build_ratsnest_module( MODULE* aModule ) // collect active pads of the module: for( pad_ref = aModule->Pads(); pad_ref != NULL; pad_ref = pad_ref->Next() ) { - if( pad_ref->GetNet() == NETINFO_LIST::UNCONNECTED ) + if( pad_ref->GetNetCode() == NETINFO_LIST::UNCONNECTED ) continue; localPadList.push_back( pad_ref ); @@ -562,11 +562,11 @@ void PCB_BASE_FRAME::build_ratsnest_module( MODULE* aModule ) { pad_ref = localPadList[ii]; - if( pad_ref->GetNet() == current_net_code ) + if( pad_ref->GetNetCode() == current_net_code ) continue; // A new net was found, load all pads of others modules members of this net: - NETINFO_ITEM* net = m_Pcb->FindNet( pad_ref->GetNet() ); + NETINFO_ITEM* net = pad_ref->GetNet(); if( net == NULL ) //Should not occur { @@ -597,7 +597,7 @@ void PCB_BASE_FRAME::build_ratsnest_module( MODULE* aModule ) * footprint pads it is therefore not time consuming, and it is made only * once */ - current_net_code = localPadList[0]->GetNet(); + current_net_code = localPadList[0]->GetNetCode(); MIN_SPAN_TREE_PADS min_spanning_tree; std::vector padsBuffer; // contains pads of only one net @@ -611,7 +611,7 @@ void PCB_BASE_FRAME::build_ratsnest_module( MODULE* aModule ) if( jj >= pads_module_count ) break; - if( localPadList[jj]->GetNet() != current_net_code ) + if( localPadList[jj]->GetNetCode() != current_net_code ) break; } @@ -623,7 +623,7 @@ void PCB_BASE_FRAME::build_ratsnest_module( MODULE* aModule ) padsBuffer.clear(); ii = jj; if( ii < localPadList.size() ) - current_net_code = localPadList[ii]->GetNet(); + current_net_code = localPadList[ii]->GetNetCode(); } internalRatsCount = m_Pcb->m_LocalRatsnest.size(); @@ -655,13 +655,13 @@ void PCB_BASE_FRAME::build_ratsnest_module( MODULE* aModule ) m_Pcb->m_LocalRatsnest.erase( m_Pcb->m_LocalRatsnest.begin() + internalRatsCount, m_Pcb->m_LocalRatsnest.end() ); - current_net_code = localPadList[0]->GetNet(); + current_net_code = localPadList[0]->GetNetCode(); for( unsigned ii = 0; ii < pads_module_count; ii++ ) { pad_ref = localPadList[ii]; - if( pad_ref->GetNet() != current_net_code ) + if( pad_ref->GetNetCode() != current_net_code ) { // if needed, creates a new ratsnest for the old net if( addRats ) @@ -670,7 +670,7 @@ void PCB_BASE_FRAME::build_ratsnest_module( MODULE* aModule ) } addRats = false; - current_net_code = pad_ref->GetNet(); + current_net_code = pad_ref->GetNetCode(); local_rats.m_Lenght = INT_MAX; } @@ -682,10 +682,10 @@ void PCB_BASE_FRAME::build_ratsnest_module( MODULE* aModule ) pad_externe = localPadList[jj]; // we search pads having the same net code - if( pad_externe->GetNet() < pad_ref->GetNet() ) + if( pad_externe->GetNetCode() < pad_ref->GetNetCode() ) continue; - if( pad_externe->GetNet() > pad_ref->GetNet() ) // pads are sorted by net code + if( pad_externe->GetNetCode() > pad_ref->GetNetCode() ) // pads are sorted by net code break; distance = abs( pad_externe->GetPosition().x - pad_pos.x ) + @@ -695,7 +695,7 @@ void PCB_BASE_FRAME::build_ratsnest_module( MODULE* aModule ) { local_rats.m_PadStart = pad_ref; local_rats.m_PadEnd = pad_externe; - local_rats.SetNet( pad_ref->GetNet() ); + local_rats.SetNet( pad_ref->GetNetCode() ); local_rats.m_Lenght = distance; local_rats.m_Status = 0; @@ -813,7 +813,7 @@ void PCB_BASE_FRAME::BuildAirWiresTargetsList( BOARD_CONNECTED_ITEM* aItemRef, if( aItemRef == NULL ) return; - int net_code = aItemRef->GetNet(); + int net_code = aItemRef->GetNetCode(); int subnet = aItemRef->GetSubNet(); if( net_code <= 0 ) @@ -844,9 +844,9 @@ void PCB_BASE_FRAME::BuildAirWiresTargetsList( BOARD_CONNECTED_ITEM* aItemRef, // current track: for( TRACK* track = m_Pcb->m_Track; track; track = track->Next() ) { - if( track->GetNet() < net_code ) + if( track->GetNetCode() < net_code ) continue; - if( track->GetNet() > net_code ) + if( track->GetNetCode() > net_code ) break;; if( !track->GetSubNet() || (track->GetSubNet() != subnet) ) diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index 430674887c..201f6b6041 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -709,7 +709,7 @@ void RN_DATA::AddSimple( const BOARD_ITEM* aItem ) if( aItem->IsConnected() ) { const BOARD_CONNECTED_ITEM* item = static_cast( aItem ); - net = item->GetNet(); + net = item->GetNetCode(); if( net < 1 ) // do not process unconnected items return; @@ -739,7 +739,7 @@ void RN_DATA::AddBlocked( const BOARD_ITEM* aItem ) if( aItem->IsConnected() ) { const BOARD_CONNECTED_ITEM* item = static_cast( aItem ); - net = item->GetNet(); + net = item->GetNetCode(); if( net < 1 ) // do not process unconnected items return; @@ -825,7 +825,7 @@ void RN_DATA::Add( const BOARD_ITEM* aItem ) if( aItem->IsConnected() ) { - net = static_cast( aItem )->GetNet(); + net = static_cast( aItem )->GetNetCode(); if( net < 1 ) // do not process unconnected items return; @@ -838,7 +838,7 @@ void RN_DATA::Add( const BOARD_ITEM* aItem ) const MODULE* module = static_cast( aItem ); for( const D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() ) { - net = pad->GetNet(); + net = pad->GetNetCode(); if( net < 1 ) // do not process unconnected items continue; @@ -884,7 +884,7 @@ void RN_DATA::Remove( const BOARD_ITEM* aItem ) if( aItem->IsConnected() ) { - net = static_cast( aItem )->GetNet(); + net = static_cast( aItem )->GetNetCode(); if( net < 1 ) // do not process unconnected items return; } @@ -893,7 +893,7 @@ void RN_DATA::Remove( const BOARD_ITEM* aItem ) const MODULE* module = static_cast( aItem ); for( const D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() ) { - net = pad->GetNet(); + net = pad->GetNetCode(); if( net < 1 ) // do not process unconnected items continue; @@ -945,21 +945,21 @@ void RN_DATA::ProcessBoard() for( MODULE* module = m_board->m_Modules; module; module = module->Next() ) { for( D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() ) - m_nets[pad->GetNet()].AddItem( pad ); + m_nets[pad->GetNetCode()].AddItem( pad ); } for( TRACK* track = m_board->m_Track; track; track = track->Next() ) { if( track->Type() == PCB_VIA_T ) - m_nets[track->GetNet()].AddItem( static_cast( track ) ); + m_nets[track->GetNetCode()].AddItem( static_cast( track ) ); else if( track->Type() == PCB_TRACE_T ) - m_nets[track->GetNet()].AddItem( track ); + m_nets[track->GetNetCode()].AddItem( track ); } for( int i = 0; i < m_board->GetAreaCount(); ++i ) { ZONE_CONTAINER* zone = m_board->GetArea( i ); - m_nets[zone->GetNet()].AddItem( zone ); + m_nets[zone->GetNetCode()].AddItem( zone ); } } diff --git a/pcbnew/router/pns_router.cpp b/pcbnew/router/pns_router.cpp index b2fed52601..0aef34f903 100644 --- a/pcbnew/router/pns_router.cpp +++ b/pcbnew/router/pns_router.cpp @@ -129,7 +129,7 @@ PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad ) PNS_SOLID* solid = new PNS_SOLID; solid->SetLayers( layers ); - solid->SetNet( aPad->GetNet() ); + solid->SetNet( aPad->GetNetCode() ); wxPoint wx_c = aPad->GetPosition(); wxSize wx_sz = aPad->GetSize(); @@ -180,7 +180,7 @@ PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad ) PNS_ITEM* PNS_ROUTER::syncTrack( TRACK* aTrack ) { PNS_SEGMENT* s = - new PNS_SEGMENT( SEG( aTrack->GetStart(), aTrack->GetEnd() ), aTrack->GetNet() ); + new PNS_SEGMENT( SEG( aTrack->GetStart(), aTrack->GetEnd() ), aTrack->GetNetCode() ); s->SetWidth( aTrack->GetWidth() ); s->SetLayers( PNS_LAYERSET( aTrack->GetLayer() ) ); @@ -195,7 +195,7 @@ PNS_ITEM* PNS_ROUTER::syncVia( SEGVIA* aVia ) aVia->GetPosition(), PNS_LAYERSET( 0, 15 ), aVia->GetWidth(), - aVia->GetNet() ); + aVia->GetNetCode() ); v->SetParent( aVia ); return v; @@ -607,7 +607,7 @@ void PNS_ROUTER::commitRouting( PNS_NODE* aNode ) track->SetEnd( wxPoint( s.B.x, s.B.y ) ); track->SetWidth( seg->GetWidth() ); track->SetLayer( seg->GetLayers().Start() ); - track->SetNet( seg->GetNet() ); + track->SetNetCode( seg->GetNet() ); newBI = track; break; } @@ -618,7 +618,7 @@ void PNS_ROUTER::commitRouting( PNS_NODE* aNode ) PNS_VIA* via = static_cast( item ); via_board->SetPosition( wxPoint( via->GetPos().x, via->GetPos().y ) ); via_board->SetWidth( via->GetDiameter() ); - via_board->SetNet( via->GetNet() ); + via_board->SetNetCode( via->GetNet() ); newBI = via_board; break; } diff --git a/pcbnew/specctra_export.cpp b/pcbnew/specctra_export.cpp index 5d1140a181..2ac40ef5af 100644 --- a/pcbnew/specctra_export.cpp +++ b/pcbnew/specctra_export.cpp @@ -692,7 +692,7 @@ IMAGE* SPECCTRA_DB::makeIMAGE( BOARD* aBoard, MODULE* aModule ) pin->pin_id += buf; // append "@1" or "@2", etc. to pin name } - pin->kiNetCode = pad->GetNet(); + pin->kiNetCode = pad->GetNetCode(); image->pins.push_back( pin ); @@ -1922,7 +1922,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) { TRACK* track = (TRACK*) items[i]; - int netcode = track->GetNet(); + int netcode = track->GetNetCode(); if( netcode == 0 ) continue; @@ -1981,7 +1981,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) SEGVIA* via = (SEGVIA*) items[i]; wxASSERT( via->Type() == PCB_VIA_T ); - int netcode = via->GetNet(); + int netcode = via->GetNetCode(); if( netcode == 0 ) continue; diff --git a/pcbnew/specctra_import.cpp b/pcbnew/specctra_import.cpp index 9b541d1ed8..06d9a61843 100644 --- a/pcbnew/specctra_import.cpp +++ b/pcbnew/specctra_import.cpp @@ -207,7 +207,7 @@ TRACK* SPECCTRA_DB::makeTRACK( PATH* aPath, int aPointIndex, int aNetcode ) thro track->SetEnd( mapPt( aPath->points[aPointIndex+1], routeResolution ) ); track->SetLayer( pcbLayer2kicad[layerNdx] ); track->SetWidth( scale( aPath->aperture_width, routeResolution ) ); - track->SetNet( aNetcode ); + track->SetNetCode( aNetcode ); return track; } @@ -339,7 +339,7 @@ SEGVIA* SPECCTRA_DB::makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNet } if( via ) - via->SetNet( aNetCode ); + via->SetNetCode( aNetCode ); return via; } diff --git a/pcbnew/tr_modif.cpp b/pcbnew/tr_modif.cpp index d4aa7eb5a6..59c0f042fb 100644 --- a/pcbnew/tr_modif.cpp +++ b/pcbnew/tr_modif.cpp @@ -72,7 +72,7 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC, wxPoint end; LAYER_MSK startmasklayer, endmasklayer; - int netcode = aNewTrack->GetNet(); + int netcode = aNewTrack->GetNetCode(); /* Reconstruct the complete track (the new track has to start on a segment of track). */ diff --git a/pcbnew/tracepcb.cpp b/pcbnew/tracepcb.cpp index ccd092fcca..06ffe75859 100644 --- a/pcbnew/tracepcb.cpp +++ b/pcbnew/tracepcb.cpp @@ -250,7 +250,7 @@ void BOARD::DrawHighLight( EDA_DRAW_PANEL* am_canvas, wxDC* DC, int aNetCode ) for( BOARD::ZONE_CONTAINERS::iterator zc = zones.begin(); zc!=zones.end(); ++zc ) { - if( (*zc)->GetNet() == aNetCode ) + if( (*zc)->GetNetCode() == aNetCode ) { (*zc)->Draw( am_canvas, DC, draw_mode ); } @@ -261,7 +261,7 @@ void BOARD::DrawHighLight( EDA_DRAW_PANEL* am_canvas, wxDC* DC, int aNetCode ) { for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() ) { - if( pad->GetNet() == aNetCode ) + if( pad->GetNetCode() == aNetCode ) { pad->Draw( am_canvas, DC, draw_mode ); } @@ -271,7 +271,7 @@ void BOARD::DrawHighLight( EDA_DRAW_PANEL* am_canvas, wxDC* DC, int aNetCode ) // Redraw track and vias that have aNetCode for( TRACK* seg = m_Track; seg; seg = seg->Next() ) { - if( seg->GetNet() == aNetCode ) + if( seg->GetNetCode() == aNetCode ) { seg->Draw( am_canvas, DC, draw_mode ); } diff --git a/pcbnew/xchgmod.cpp b/pcbnew/xchgmod.cpp index 40fde81e06..74b5a58e0c 100644 --- a/pcbnew/xchgmod.cpp +++ b/pcbnew/xchgmod.cpp @@ -455,13 +455,13 @@ void PCB_EDIT_FRAME::Exchange_Module( MODULE* aOldModule, // Update pad netnames ( when possible) for( D_PAD* pad = aNewModule->Pads(); pad != NULL; pad = pad->Next() ) { - pad->SetNet( NETINFO_LIST::UNCONNECTED ); + pad->SetNetCode( NETINFO_LIST::UNCONNECTED ); D_PAD* old_pad = aOldModule->Pads(); for( ; old_pad != NULL; old_pad = old_pad->Next() ) { if( pad->PadNameEqual( old_pad ) ) - pad->SetNet( old_pad->GetNet() ); + pad->SetNetCode( old_pad->GetNetCode() ); } } diff --git a/pcbnew/zones_by_polygon.cpp b/pcbnew/zones_by_polygon.cpp index 9eddd5f7bb..838bf67bb7 100644 --- a/pcbnew/zones_by_polygon.cpp +++ b/pcbnew/zones_by_polygon.cpp @@ -130,7 +130,7 @@ void PCB_EDIT_FRAME::duplicateZone( wxDC* aDC, ZONE_CONTAINER* aZone ) s_AuxiliaryList.ClearListAndDeleteItems(); s_PickedList.ClearListAndDeleteItems(); - SaveCopyOfZones( s_PickedList, GetBoard(), newZone->GetNet(), newZone->GetLayer() ); + SaveCopyOfZones( s_PickedList, GetBoard(), newZone->GetNetCode(), newZone->GetLayer() ); GetBoard()->Add( newZone ); ITEM_PICKER picker( newZone, UR_NEW ); @@ -227,10 +227,10 @@ void PCB_EDIT_FRAME::Start_Move_Zone_Corner( wxDC* DC, ZONE_CONTAINER* aZone, } ZONE_SETTINGS zoneInfo = GetZoneSettings(); - zoneInfo.m_NetcodeSelection = aZone->GetNet(); + zoneInfo.m_NetcodeSelection = aZone->GetNetCode(); SetZoneSettings( zoneInfo ); - GetBoard()->SetHighLightNet( aZone->GetNet() ); + GetBoard()->SetHighLightNet( aZone->GetNetCode() ); if( DC ) HighLight( DC ); @@ -248,8 +248,7 @@ void PCB_EDIT_FRAME::Start_Move_Zone_Corner( wxDC* DC, ZONE_CONTAINER* aZone, s_AuxiliaryList.ClearListAndDeleteItems(); s_PickedList.ClearListAndDeleteItems(); - SaveCopyOfZones( s_PickedList, GetBoard(), aZone->GetNet(), - aZone->GetLayer() ); + SaveCopyOfZones( s_PickedList, GetBoard(), aZone->GetNetCode(), aZone->GetLayer() ); if ( IsNewCorner ) aZone->Outline()->InsertCorner(corner_id-1, cx, cy ); @@ -278,8 +277,7 @@ void PCB_EDIT_FRAME::Start_Move_Zone_Drag_Outline_Edge( wxDC* DC, s_PickedList.ClearListAndDeleteItems(); s_AuxiliaryList.ClearListAndDeleteItems(); - SaveCopyOfZones( s_PickedList, GetBoard(), aZone->GetNet(), - aZone->GetLayer() ); + SaveCopyOfZones( s_PickedList, GetBoard(), aZone->GetNetCode(), aZone->GetLayer() ); } @@ -294,17 +292,16 @@ void PCB_EDIT_FRAME::Start_Move_Zone_Outlines( wxDC* DC, ZONE_CONTAINER* aZone ) } ZONE_SETTINGS zoneInfo = GetZoneSettings(); - zoneInfo.m_NetcodeSelection = aZone->GetNet(); + zoneInfo.m_NetcodeSelection = aZone->GetNetCode(); SetZoneSettings( zoneInfo ); - GetBoard()->SetHighLightNet( aZone->GetNet() ); + GetBoard()->SetHighLightNet( aZone->GetNetCode() ); HighLight( DC ); } s_PickedList.ClearListAndDeleteItems(); s_AuxiliaryList.ClearListAndDeleteItems(); - SaveCopyOfZones( s_PickedList, GetBoard(), aZone->GetNet(), - aZone->GetLayer() ); + SaveCopyOfZones( s_PickedList, GetBoard(), aZone->GetNetCode(), aZone->GetLayer() ); aZone->SetFlags( IS_MOVED ); m_canvas->SetMouseCapture( Show_Zone_Corner_Or_Outline_While_Move_Mouse, @@ -382,7 +379,7 @@ void PCB_EDIT_FRAME::Remove_Zone_Corner( wxDC* DC, ZONE_CONTAINER* aZone ) s_AuxiliaryList.ClearListAndDeleteItems(); s_PickedList. ClearListAndDeleteItems(); - SaveCopyOfZones( s_PickedList, GetBoard(), aZone->GetNet(), aZone->GetLayer() ); + SaveCopyOfZones( s_PickedList, GetBoard(), aZone->GetNetCode(), aZone->GetLayer() ); aZone->Outline()->DeleteCorner( aZone->GetSelectedCorner() ); // modify zones outlines according to the new aZone shape @@ -549,7 +546,7 @@ int PCB_EDIT_FRAME::Begin_Zone( wxDC* DC ) { zoneInfo.m_NetcodeSelection = GetBoard()->GetHighLightNetCode(); - zone->SetNet( zoneInfo.m_NetcodeSelection ); + zone->SetNetCode( zoneInfo.m_NetcodeSelection ); } double tmp = ZONE_THERMAL_RELIEF_GAP_MIL; wxGetApp().GetSettings()->Read( ZONE_THERMAL_RELIEF_GAP_STRING_KEY, &tmp ); @@ -577,7 +574,7 @@ int PCB_EDIT_FRAME::Begin_Zone( wxDC* DC ) zoneInfo.SetIsKeepout( true ); // Netcode and netname are irrelevant, // so ensure they are cleared - zone->SetNet( NETINFO_LIST::UNCONNECTED ); + zone->SetNetCode( NETINFO_LIST::UNCONNECTED ); edited = InvokeKeepoutAreaEditor( this, &zoneInfo ); } else @@ -623,7 +620,7 @@ int PCB_EDIT_FRAME::Begin_Zone( wxDC* DC ) { if( s_CurrentZone ) { - zoneInfo.m_NetcodeSelection = s_CurrentZone->GetNet(); + zoneInfo.m_NetcodeSelection = s_CurrentZone->GetNetCode(); GetBoard()->SetZoneSettings( zoneInfo ); } @@ -744,7 +741,7 @@ bool PCB_EDIT_FRAME::End_Zone( wxDC* DC ) // Save initial zones configuration, for undo/redo, before adding new zone s_AuxiliaryList.ClearListAndDeleteItems(); s_PickedList.ClearListAndDeleteItems(); - SaveCopyOfZones(s_PickedList, GetBoard(), zone->GetNet(), zone->GetLayer() ); + SaveCopyOfZones(s_PickedList, GetBoard(), zone->GetNetCode(), zone->GetLayer() ); // Put new zone in list if( !s_CurrentZone ) @@ -902,7 +899,7 @@ void PCB_EDIT_FRAME::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* aZone ) NETINFO_ITEM* net = GetBoard()->FindNet( zoneInfo.m_NetcodeSelection ); if( net ) // net == NULL should not occur - aZone->SetNet( net->GetNet() ); + aZone->SetNetCode( net->GetNet() ); // Combine zones if possible GetBoard()->OnAreaPolygonModified( &s_AuxiliaryList, aZone ); diff --git a/pcbnew/zones_by_polygon_fill_functions.cpp b/pcbnew/zones_by_polygon_fill_functions.cpp index 73ca2a8217..3146786a6b 100644 --- a/pcbnew/zones_by_polygon_fill_functions.cpp +++ b/pcbnew/zones_by_polygon_fill_functions.cpp @@ -100,7 +100,7 @@ int PCB_EDIT_FRAME::Fill_Zone( ZONE_CONTAINER* aZone ) // Shows the net ZONE_SETTINGS zoneInfo = GetZoneSettings(); - zoneInfo.m_NetcodeSelection = aZone->GetNet(); + zoneInfo.m_NetcodeSelection = aZone->GetNetCode(); SetZoneSettings( zoneInfo ); msg = aZone->GetNetname(); diff --git a/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp b/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp index eaef234893..c51da1fc1c 100644 --- a/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp +++ b/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp @@ -228,7 +228,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) pad = &dummypad; } - if( pad->GetNet() != GetNet() ) + if( pad->GetNetCode() != GetNetCode() ) { item_clearance = pad->GetClearance() + margin; item_boundingbox = pad->GetBoundingBox(); @@ -249,7 +249,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) int gap = zone_clearance; if( ( GetPadConnection( pad ) == PAD_NOT_IN_ZONE ) - || ( GetNet() == 0 ) || ( pad->GetShape() == PAD_TRAPEZOID ) ) + || ( GetNetCode() == 0 ) || ( pad->GetShape() == PAD_TRAPEZOID ) ) // PAD_TRAPEZOID shapes are not in zones because they are used in microwave apps // and i think it is good that shapes are not changed by thermal pads or others @@ -275,7 +275,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) if( !track->IsOnLayer( GetLayer() ) ) continue; - if( track->GetNet() == GetNet() && (GetNet() != 0) ) + if( track->GetNetCode() == GetNetCode() && (GetNetCode() != 0) ) continue; item_clearance = track->GetClearance() + margin; @@ -363,7 +363,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) // do not add clearance. // the zone will be connected to the current zone, but filled areas // will use different parameters (clearance, thermal shapes ) - bool addclearance = GetNet() != zone->GetNet(); + bool addclearance = GetNetCode() != zone->GetNetCode(); int clearance = zone_clearance; if( zone->GetIsKeepout() ) @@ -394,7 +394,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) if( !pad->IsOnLayer( GetLayer() ) ) continue; - if( pad->GetNet() != GetNet() ) + if( pad->GetNetCode() != GetNetCode() ) continue; item_boundingbox = pad->GetBoundingBox(); int thermalGap = GetThermalReliefGap( pad ); @@ -428,7 +428,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) CopyPolygonsFromKiPolygonListToFilledPolysList( polyset_zone_solid_areas ); // Remove insulated islands: - if( GetNet() > 0 ) + if( GetNetCode() > 0 ) TestForCopperIslandAndRemoveInsulatedIslands( aPcb ); // Now we remove all unused thermal stubs. @@ -436,7 +436,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) // Test thermal stubs connections and add polygons to remove unconnected stubs. // (this is a refinement for thermal relief shapes) - if( GetNet() > 0 ) + if( GetNetCode() > 0 ) BuildUnconnectedThermalStubsPolygonList( cornerBufferPolysToSubstract, aPcb, this, s_Correction, s_thermalRot ); @@ -453,7 +453,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) m_FilledPolysList.RemoveAllContours(); CopyPolygonsFromKiPolygonListToFilledPolysList( polyset_zone_solid_areas ); - if( GetNet() > 0 ) + if( GetNetCode() > 0 ) TestForCopperIslandAndRemoveInsulatedIslands( aPcb ); } diff --git a/pcbnew/zones_convert_to_polygons_aux_functions.cpp b/pcbnew/zones_convert_to_polygons_aux_functions.cpp index f570ebdd4b..16549b2ed4 100644 --- a/pcbnew/zones_convert_to_polygons_aux_functions.cpp +++ b/pcbnew/zones_convert_to_polygons_aux_functions.cpp @@ -162,7 +162,7 @@ void BuildUnconnectedThermalStubsPolygonList( CPOLYGONS_LIST& aCornerBuffer, if( !pad->IsOnLayer( aZone->GetLayer() ) ) continue; - if( pad->GetNet() != aZone->GetNet() ) + if( pad->GetNetCode() != aZone->GetNetCode() ) continue; // Calculate thermal bridge half width diff --git a/pcbnew/zones_functions_for_undo_redo.cpp b/pcbnew/zones_functions_for_undo_redo.cpp index 8abd5b6306..5710937208 100644 --- a/pcbnew/zones_functions_for_undo_redo.cpp +++ b/pcbnew/zones_functions_for_undo_redo.cpp @@ -67,7 +67,7 @@ bool ZONE_CONTAINER::IsSame( const ZONE_CONTAINER& aZoneToCompare ) if( GetLayer() != aZoneToCompare.GetLayer() ) return false; - if( GetNet() != aZoneToCompare.GetNet() ) + if( GetNetCode() != aZoneToCompare.GetNetCode() ) return false; if( GetPriority() != aZoneToCompare.GetPriority() ) @@ -146,7 +146,7 @@ int SaveCopyOfZones( PICKED_ITEMS_LIST& aPickList, BOARD* aPcb, int aNetCode, LA if( zone == NULL ) // End of list break; - if( aNetCode >= 0 && aNetCode != zone->GetNet() ) + if( aNetCode >= 0 && aNetCode != zone->GetNetCode() ) continue; if( aLayer >= 0 && aLayer != zone->GetLayer() ) diff --git a/pcbnew/zones_polygons_insulated_copper_islands.cpp b/pcbnew/zones_polygons_insulated_copper_islands.cpp index c2154ae5dc..5e72a64497 100644 --- a/pcbnew/zones_polygons_insulated_copper_islands.cpp +++ b/pcbnew/zones_polygons_insulated_copper_islands.cpp @@ -54,7 +54,7 @@ void ZONE_CONTAINER::TestForCopperIslandAndRemoveInsulatedIslands( BOARD* aPcb ) if( !pad->IsOnLayer( GetLayer() ) ) continue; - if( pad->GetNet() != GetNet() ) + if( pad->GetNetCode() != GetNetCode() ) continue; listPointsCandidates.push_back( pad->GetPosition() ); @@ -66,7 +66,7 @@ void ZONE_CONTAINER::TestForCopperIslandAndRemoveInsulatedIslands( BOARD* aPcb ) if( !track->IsOnLayer( GetLayer() ) ) continue; - if( track->GetNet() != GetNet() ) + if( track->GetNetCode() != GetNetCode() ) continue; listPointsCandidates.push_back( track->GetStart() ); diff --git a/pcbnew/zones_polygons_test_connections.cpp b/pcbnew/zones_polygons_test_connections.cpp index ccc91634e2..fd277f2a63 100644 --- a/pcbnew/zones_polygons_test_connections.cpp +++ b/pcbnew/zones_polygons_test_connections.cpp @@ -50,11 +50,11 @@ void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb, int aNetcode ); // zone size = size of the m_FilledPolysList buffer bool sort_areas( const ZONE_CONTAINER* ref, const ZONE_CONTAINER* tst ) { - if( ref->GetNet() == tst->GetNet() ) + if( ref->GetNetCode() == tst->GetNetCode() ) return ref->GetFilledPolysList().GetCornersCount() < tst->GetFilledPolysList().GetCornersCount(); else - return ref->GetNet() < tst->GetNet(); + return ref->GetNetCode() < tst->GetNetCode(); } /** @@ -72,14 +72,14 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode ) for( MODULE* module = m_Modules; module; module = module->Next() ) { for( D_PAD* pad = module->Pads(); pad != NULL; pad = pad->Next() ) - if( (aNetcode < 0) || ( aNetcode == pad->GetNet() ) ) + if( (aNetcode < 0) || ( aNetcode == pad->GetNetCode() ) ) pad->SetZoneSubNet( 0 ); } // clear .m_ZoneSubnet parameter for tracks and vias for( TRACK* track = m_Track; track; track = track->Next() ) { - if( (aNetcode < 0) || ( aNetcode == track->GetNet() ) ) + if( (aNetcode < 0) || ( aNetcode == track->GetNetCode() ) ) track->SetZoneSubNet( 0 ); } @@ -93,7 +93,7 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode ) ZONE_CONTAINER* curr_zone = GetArea( index ); if( !curr_zone->IsOnCopperLayer() ) continue; - if( (aNetcode >= 0) && ( aNetcode != curr_zone->GetNet() ) ) + if( (aNetcode >= 0) && ( aNetcode != curr_zone->GetNetCode() ) ) continue; if( curr_zone->GetFilledPolysList().GetCornersCount() == 0 ) continue; @@ -112,7 +112,7 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode ) { ZONE_CONTAINER* curr_zone = zones_candidates[idx]; - int netcode = curr_zone->GetNet(); + int netcode = curr_zone->GetNetCode(); // Build a list of candidates connected to the net: // At this point, layers are not considered, because areas on different layers can @@ -136,7 +136,7 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode ) TRACK* track = m_Track.GetFirst()->GetStartNetCode( netcode ); for( ; track; track = track->Next() ) { - if( track->GetNet() != netcode ) + if( track->GetNetCode() != netcode ) break; candidates.push_back( track ); } @@ -255,10 +255,10 @@ void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb ) if ( ! curr_zone->IsOnCopperLayer() ) continue; - if ( curr_zone->GetNet() <= 0 ) + if ( curr_zone->GetNetCode() <= 0 ) continue; - Merge_SubNets_Connected_By_CopperAreas( aPcb, curr_zone->GetNet() ); + Merge_SubNets_Connected_By_CopperAreas( aPcb, curr_zone->GetNetCode() ); } } @@ -284,7 +284,7 @@ void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb, int aNetcode ) { ZONE_CONTAINER* curr_zone = aPcb->GetArea( index ); - if( aNetcode == curr_zone->GetNet() ) + if( aNetcode == curr_zone->GetNetCode() ) { found = true; break; @@ -311,7 +311,7 @@ void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb, int aNetcode ) track = aPcb->m_Track.GetFirst()->GetStartNetCode( aNetcode ); for( ; track; track = track->Next() ) { - if( track->GetNet() != aNetcode ) + if( track->GetNetCode() != aNetcode ) break; Candidates.push_back( track ); } diff --git a/pcbnew/zones_test_and_combine_areas.cpp b/pcbnew/zones_test_and_combine_areas.cpp index 362d469daa..b35c1be122 100644 --- a/pcbnew/zones_test_and_combine_areas.cpp +++ b/pcbnew/zones_test_and_combine_areas.cpp @@ -59,7 +59,7 @@ bool BOARD::OnAreaPolygonModified( PICKED_ITEMS_LIST* aModifiedZonesList, if( bCheckAllAreas ) { modified = true; - CombineAllAreasInNet( aModifiedZonesList, modified_area->GetNet(), true ); + CombineAllAreasInNet( aModifiedZonesList, modified_area->GetNetCode(), true ); } if( !IsCopperLayer( layer ) ) // Refill non copper zones on this layer @@ -98,7 +98,7 @@ bool BOARD::CombineAllAreasInNet( PICKED_ITEMS_LIST* aDeletedList, int aNetCode, { ZONE_CONTAINER* curr_area = m_ZoneDescriptorList[ia1]; - if( curr_area->GetNet() != aNetCode ) + if( curr_area->GetNetCode() != aNetCode ) continue; // legal polygon @@ -109,7 +109,7 @@ bool BOARD::CombineAllAreasInNet( PICKED_ITEMS_LIST* aDeletedList, int aNetCode, { ZONE_CONTAINER* area2 = m_ZoneDescriptorList[ia2]; - if( area2->GetNet() != aNetCode ) + if( area2->GetNetCode() != aNetCode ) continue; if( curr_area->GetPriority() != area2->GetPriority() ) @@ -158,7 +158,7 @@ bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test ) { ZONE_CONTAINER* area2 = m_ZoneDescriptorList[ia2]; - if( area_to_test->GetNet() != area2->GetNet() ) + if( area_to_test->GetNetCode() != area2->GetNetCode() ) continue; if( area_to_test == area2 ) @@ -390,7 +390,7 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E continue; // Test for same net - if( Area_Ref->GetNet() == area_to_test->GetNet() && Area_Ref->GetNet() >= 0 ) + if( Area_Ref->GetNetCode() == area_to_test->GetNetCode() && Area_Ref->GetNetCode() >= 0 ) continue; // test for different priorities @@ -586,7 +586,7 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex ) continue; // Test for same net - if( ( aArea->GetNet() == area_to_test->GetNet() ) && (aArea->GetNet() >= 0) ) + if( ( aArea->GetNetCode() == area_to_test->GetNetCode() ) && (aArea->GetNetCode() >= 0) ) continue; // test for same priority From c66a3232ac30987f2eafa613a504932b67364e83 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 3 Mar 2014 17:15:41 +0100 Subject: [PATCH 92/95] Removed a few memory leaks. --- common/CMakeLists.txt | 1 + common/worksheet_viewitem.cpp | 4 +--- include/math/vector2d.h | 1 + include/worksheet_viewitem.h | 3 +-- pcbnew/class_board.cpp | 11 ++++++++++- pcbnew/class_board.h | 26 ++++++++++++++++++++++++++ pcbnew/pcbframe.cpp | 22 +++++++++------------- pcbnew/router/pns_router.cpp | 4 ++++ pcbnew/router/pns_solid.h | 8 ++++++-- 9 files changed, 59 insertions(+), 21 deletions(-) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 7bc4b9ed88..ea5c2b3144 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -220,6 +220,7 @@ set( PCB_COMMON_SRCS ../pcbnew/class_zone_settings.cpp ../pcbnew/classpcb.cpp ../pcbnew/ratsnest_data.cpp + ../pcbnew/ratsnest_viewitem.cpp ../pcbnew/collectors.cpp ../pcbnew/netlist_reader.cpp ../pcbnew/legacy_netlist_reader.cpp diff --git a/common/worksheet_viewitem.cpp b/common/worksheet_viewitem.cpp index 7ecf6de8d7..ba4185f8af 100644 --- a/common/worksheet_viewitem.cpp +++ b/common/worksheet_viewitem.cpp @@ -36,10 +36,8 @@ using namespace KIGFX; -WORKSHEET_VIEWITEM::WORKSHEET_VIEWITEM( const std::string& aFileName, const std::string& aSheetName, - const PAGE_INFO* aPageInfo, const TITLE_BLOCK* aTitleBlock ) : +WORKSHEET_VIEWITEM::WORKSHEET_VIEWITEM( const PAGE_INFO* aPageInfo, const TITLE_BLOCK* aTitleBlock ) : EDA_ITEM( NOT_USED ), // this item is never added to a BOARD so it needs no type - m_fileName( aFileName ), m_sheetName( aSheetName ), m_titleBlock( aTitleBlock ), m_pageInfo( aPageInfo ), m_sheetNumber( 1 ), m_sheetCount( 1 ) {} diff --git a/include/math/vector2d.h b/include/math/vector2d.h index 09cae7b31f..feee5ff060 100644 --- a/include/math/vector2d.h +++ b/include/math/vector2d.h @@ -31,6 +31,7 @@ #include #include #include +#include #include diff --git a/include/worksheet_viewitem.h b/include/worksheet_viewitem.h index 6380af9fd8..ca506c8577 100644 --- a/include/worksheet_viewitem.h +++ b/include/worksheet_viewitem.h @@ -47,8 +47,7 @@ class GAL; class WORKSHEET_VIEWITEM : public EDA_ITEM { public: - WORKSHEET_VIEWITEM( const std::string& aFileName, const std::string& aSheetName, - const PAGE_INFO* aPageInfo, const TITLE_BLOCK* aTitleBlock ); + WORKSHEET_VIEWITEM( const PAGE_INFO* aPageInfo, const TITLE_BLOCK* aTitleBlock ); /** * Function SetFileName() diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index ab0272f8b4..ff2a89a0d5 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -43,6 +43,8 @@ #include #include #include +#include +#include #include #include @@ -104,7 +106,13 @@ BOARD::BOARD() : SetCurrentNetClass( m_NetClasses.GetDefault()->GetName() ); + // Initialize ratsnest m_ratsnest = new RN_DATA( this ); + m_ratsnestViewItem = new KIGFX::RATSNEST_VIEWITEM( m_ratsnest ); + + // Initialize view item for displaying worksheet frame + m_worksheetViewItem = new KIGFX::WORKSHEET_VIEWITEM( &m_paper, &m_titles ); + m_worksheetViewItem->SetFileName( std::string( m_fileName.mb_str() ) ); } @@ -116,10 +124,11 @@ BOARD::~BOARD() Delete( area_to_remove ); } + delete m_worksheetViewItem; + delete m_ratsnestViewItem; delete m_ratsnest; m_FullRatsnest.clear(); - m_LocalRatsnest.clear(); DeleteMARKERs(); diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h index c32d1d90e7..cac0f66ffd 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -58,6 +58,12 @@ class NETLIST; class REPORTER; class RN_DATA; +namespace KIGFX +{ + class RATSNEST_VIEWITEM; + class WORKSHEET_VIEWITEM; +} + // non-owning container of item candidates when searching for items on the same track. typedef std::vector< TRACK* > TRACK_PTRS; @@ -227,6 +233,8 @@ private: EDA_RECT m_BoundingBox; NETINFO_LIST m_NetInfo; ///< net info list (name, design constraints .. RN_DATA* m_ratsnest; + KIGFX::RATSNEST_VIEWITEM* m_ratsnestViewItem; ///< VIEW_ITEM that draws ratsnest + KIGFX::WORKSHEET_VIEWITEM* m_worksheetViewItem; ///< VIEW_ITEM that draws worksheet frame BOARD_DESIGN_SETTINGS m_designSettings; ZONE_SETTINGS m_zoneSettings; @@ -367,6 +375,24 @@ public: return m_ratsnest; } + /** + * Function GetRatsnestViewItem() + * returns VIEW_ITEM responsible for drawing the ratsnest for the board. + */ + KIGFX::RATSNEST_VIEWITEM* GetRatsnestViewItem() const + { + return m_ratsnestViewItem; + } + + /** + * Function GetWorksheetViewItem() + * returns VIEW_ITEM responsible for drawing the worksheet frame. + */ + KIGFX::WORKSHEET_VIEWITEM* GetWorksheetViewItem() const + { + return m_worksheetViewItem; + } + /** * Function DeleteMARKERs * deletes ALL MARKERS from the board. diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index ac4debcc70..64abab4807 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -596,26 +596,22 @@ void PCB_EDIT_FRAME::ViewReloadBoard( const BOARD* aBoard ) const view->Add( zone ); } - // Add an entry for the worksheet layout - KIGFX::WORKSHEET_VIEWITEM* worksheet = new KIGFX::WORKSHEET_VIEWITEM( - std::string( aBoard->GetFileName().mb_str() ), - std::string( GetScreenDesc().mb_str() ), - &GetPageSettings(), &GetTitleBlock() ); + KIGFX::WORKSHEET_VIEWITEM* worksheet = aBoard->GetWorksheetViewItem(); + worksheet->SetSheetName( std::string( GetScreenDesc().mb_str() ) ); + BASE_SCREEN* screen = GetScreen(); + if( screen != NULL ) { - worksheet->SetSheetNumber( GetScreen()->m_ScreenNumber ); - worksheet->SetSheetCount( GetScreen()->m_NumberOfScreens ); + worksheet->SetSheetNumber( screen->m_ScreenNumber ); + worksheet->SetSheetCount( screen->m_NumberOfScreens ); } view->Add( worksheet ); + view->Add( aBoard->GetRatsnestViewItem() ); - // Add an entry for the ratsnest - RN_DATA* ratsnest = aBoard->GetRatsnest(); - ratsnest->Recalculate(); - view->Add( new KIGFX::RATSNEST_VIEWITEM( ratsnest ) ); - - view->SetPanBoundary( worksheet->ViewBBox() ); + // Limit panning to the size of worksheet frame + view->SetPanBoundary( aBoard->GetWorksheetViewItem()->ViewBBox() ); view->RecacheAllItems( true ); if( IsGalCanvasActive() ) diff --git a/pcbnew/router/pns_router.cpp b/pcbnew/router/pns_router.cpp index 0aef34f903..646d011404 100644 --- a/pcbnew/router/pns_router.cpp +++ b/pcbnew/router/pns_router.cpp @@ -338,9 +338,13 @@ void PNS_ROUTER::ClearWorld() if( m_placer ) delete m_placer; + if( m_previewItems ) + delete m_previewItems; + m_clearanceFunc = NULL; m_world = NULL; m_placer = NULL; + m_previewItems = NULL; } diff --git a/pcbnew/router/pns_solid.h b/pcbnew/router/pns_solid.h index db52c808c4..b6f38a2851 100644 --- a/pcbnew/router/pns_solid.h +++ b/pcbnew/router/pns_solid.h @@ -32,10 +32,14 @@ class PNS_SOLID : public PNS_ITEM { public: - PNS_SOLID() : PNS_ITEM( SOLID ) + PNS_SOLID() : PNS_ITEM( SOLID ), m_shape( NULL ) { m_movable = false; - m_shape = NULL; + } + + ~PNS_SOLID() + { + delete m_shape; } PNS_ITEM* Clone() const; From 1d6357a76a6aa2b27b2b9be5d97ee6b402ba4e5b Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 5 Mar 2014 14:57:14 +0100 Subject: [PATCH 93/95] Squashed memory leaks. --- common/geometry/hetriang.cpp | 92 +++++++++++++++------------------ include/ttl/halfedge/hetriang.h | 61 +++++++++++++--------- pcbnew/ratsnest_data.cpp | 37 ++++++++----- 3 files changed, 102 insertions(+), 88 deletions(-) diff --git a/common/geometry/hetriang.cpp b/common/geometry/hetriang.cpp index b69255cdbf..eb5e59ecf7 100644 --- a/common/geometry/hetriang.cpp +++ b/common/geometry/hetriang.cpp @@ -45,6 +45,8 @@ #include #include #include +#include +#include using namespace hed; @@ -115,28 +117,27 @@ EdgePtr Triangulation::initTwoEnclosingTriangles(NodesContainer::iterator first, double dx = (xmax-xmin)/fac; double dy = (ymax-ymin)/fac; - NodePtr n1(new Node(xmin-dx,ymin-dy)); - NodePtr n2(new Node(xmax+dx,ymin-dy)); - NodePtr n3(new Node(xmax+dx,ymax+dy)); - NodePtr n4(new Node(xmin-dx,ymax+dy)); + NodePtr n1 = boost::make_shared(xmin-dx, ymin-dy); + NodePtr n2 = boost::make_shared(xmax+dx, ymin-dy); + NodePtr n3 = boost::make_shared(xmax+dx, ymax+dy); + NodePtr n4 = boost::make_shared(xmin-dx, ymax+dy); // diagonal - EdgePtr e1d(new Edge); // lower - EdgePtr e2d(new Edge); // upper, the twin edge + EdgePtr e1d = boost::make_shared(); + EdgePtr e2d = boost::make_shared(); // lower triangle - EdgePtr e11(new Edge); - EdgePtr e12(new Edge); + EdgePtr e11 = boost::make_shared(); + EdgePtr e12 = boost::make_shared(); // upper triangle - EdgePtr e21(new Edge); // upper upper - EdgePtr e22(new Edge); + EdgePtr e21 = boost::make_shared(); + EdgePtr e22 = boost::make_shared(); // lower triangle e1d->setSourceNode(n3); e1d->setNextEdgeInFace(e11); e1d->setTwinEdge(e2d); - e1d->setAsLeadingEdge(); addLeadingEdge(e1d); e11->setSourceNode(n1); @@ -149,7 +150,6 @@ EdgePtr Triangulation::initTwoEnclosingTriangles(NodesContainer::iterator first, e2d->setSourceNode(n1); e2d->setNextEdgeInFace(e21); e2d->setTwinEdge(e1d); - e2d->setAsLeadingEdge(); addLeadingEdge(e2d); e21->setSourceNode(n3); @@ -225,13 +225,10 @@ void Triangulation::removeTriangle(EdgePtr& edge) { // Remove the triangle EdgePtr e2(e1->getNextEdgeInFace()); EdgePtr e3(e2->getNextEdgeInFace()); - - if (e1->getTwinEdge()) - e1->getTwinEdge()->setTwinEdge(EdgePtr()); - if (e2->getTwinEdge()) - e2->getTwinEdge()->setTwinEdge(EdgePtr()); - if (e3->getTwinEdge()) - e3->getTwinEdge()->setTwinEdge(EdgePtr()); + + e1->clear(); + e2->clear(); + e3->clear(); } @@ -268,6 +265,19 @@ void Triangulation::reverse_splitTriangle(EdgePtr& edge) { // from the triangulation, but the arcs have not been deleted. // Next delete the 6 half edges radiating from the node // The node is maintained by handle and need not be deleted explicitly + EdgePtr estar = edge; + EdgePtr enext = estar->getTwinEdge()->getNextEdgeInFace(); + estar->getTwinEdge()->clear(); + estar->clear(); + + estar = enext; + enext = estar->getTwinEdge()->getNextEdgeInFace(); + estar->getTwinEdge()->clear(); + estar->clear(); + + enext->getTwinEdge()->clear(); + enext->clear(); + // Create the new triangle e1->setNextEdgeInFace(e2); @@ -277,25 +287,6 @@ void Triangulation::reverse_splitTriangle(EdgePtr& edge) { } -//-------------------------------------------------------------------------------------------------- -// This is a "template" for iterating the boundary -/* -static void iterateBoundary(const Dart& dart) { -cout << "Iterate boundary 2" << endl; -// input is a dart at the boundary - - Dart dart_iter = dart; - do { - if (helper->isBoundaryEdge(dart_iter)) - dart_iter.alpha0().alpha1(); - else - dart_iter.alpha2().alpha1(); - - } while(dart_iter != dart); -} -*/ - - //-------------------------------------------------------------------------------------------------- Dart Triangulation::createDart() { @@ -332,18 +323,19 @@ bool Triangulation::removeLeadingEdgeFromList(EdgePtr& leadingEdge) { //-------------------------------------------------------------------------------------------------- void Triangulation::cleanAll() { - leadingEdges_.clear(); + BOOST_FOREACH(EdgePtr& edge, leadingEdges_) + edge->setNextEdgeInFace(EdgePtr()); } //-------------------------------------------------------------------------------------------------- void Triangulation::swapEdge(Dart& dart) { - if (!dart.getEdge()->isConstrained()) swapEdge(dart.getEdge()); + swapEdge(dart.getEdge()); } //-------------------------------------------------------------------------------------------------- -void Triangulation::splitTriangle(Dart& dart, NodePtr point) { +void Triangulation::splitTriangle(Dart& dart, const NodePtr& point) { EdgePtr edge = splitTriangle(dart.getEdge(), point); dart.init(edge); } @@ -429,7 +421,7 @@ list* Triangulation::getEdges(bool skip_boundary_edges) const { //-------------------------------------------------------------------------------------------------- -EdgePtr Triangulation::splitTriangle(EdgePtr& edge, NodePtr& point) { +EdgePtr Triangulation::splitTriangle(EdgePtr& edge, const NodePtr& point) { // Add a node by just splitting a triangle into three triangles // Assumes the half edge is located in the triangle @@ -457,12 +449,12 @@ EdgePtr Triangulation::splitTriangle(EdgePtr& edge, NodePtr& point) { EdgePtr e3(e2->getNextEdgeInFace()); NodePtr n3(e3->getSourceNode()); - EdgePtr e1_n(new Edge); - EdgePtr e11_n(new Edge); - EdgePtr e2_n(new Edge); - EdgePtr e22_n(new Edge); - EdgePtr e3_n(new Edge); - EdgePtr e33_n(new Edge); + EdgePtr e1_n = boost::make_shared(); + EdgePtr e11_n = boost::make_shared(); + EdgePtr e2_n = boost::make_shared(); + EdgePtr e22_n = boost::make_shared(); + EdgePtr e3_n = boost::make_shared(); + EdgePtr e33_n = boost::make_shared(); e1_n->setSourceNode(n1); e11_n->setSourceNode(point); @@ -503,7 +495,7 @@ EdgePtr Triangulation::splitTriangle(EdgePtr& edge, NodePtr& point) { else if(e3->isLeadingEdge()) removeLeadingEdgeFromList(e3); else - return EdgePtr(); + assert( false ); // one of the edges should be leading addLeadingEdge(e1_n); addLeadingEdge(e2_n); @@ -640,7 +632,7 @@ void Triangulation::optimizeDelaunay() { Dart dart(edge); // Constrained edges should not be swapped - if (!edge->isConstrained() && helper->swapTestDelaunay(dart, cycling_check)) { + if (helper->swapTestDelaunay(dart, cycling_check)) { optimal = false; swapEdge(edge); } diff --git a/include/ttl/halfedge/hetriang.h b/include/ttl/halfedge/hetriang.h index c8326a417d..2c5380864e 100644 --- a/include/ttl/halfedge/hetriang.h +++ b/include/ttl/halfedge/hetriang.h @@ -53,6 +53,7 @@ #include #include #include +#include namespace ttl { class TriangulationHelper; @@ -68,6 +69,7 @@ namespace hed { class Edge; typedef boost::shared_ptr NodePtr; typedef boost::shared_ptr EdgePtr; + typedef boost::weak_ptr EdgeWeakPtr; typedef std::vector NodesContainer; //------------------------------------------------------------------------------------------------ @@ -154,8 +156,7 @@ public: class Edge { public: /// Constructor - Edge() : weight_(0) - { flags_.isLeadingEdge_ = false; flags_.isConstrained_ = false; } + Edge() : weight_(0), isLeadingEdge_(false) {} /// Destructor virtual ~Edge() {} @@ -170,49 +171,52 @@ public: void setTwinEdge(const EdgePtr& edge) { twinEdge_ = edge; } /// Sets the edge as a leading edge - void setAsLeadingEdge(bool val=true) { flags_.isLeadingEdge_ = val; } + void setAsLeadingEdge(bool val=true) { isLeadingEdge_ = val; } /// Checks if an edge is a leading edge - bool isLeadingEdge() const { return flags_.isLeadingEdge_; } - - /// Sets the edge as a constrained edge - void setConstrained(bool val=true) { flags_.isConstrained_ = val; - if (twinEdge_) twinEdge_->flags_.isConstrained_ = val; } - - /// Checks if an edge is constrained - bool isConstrained() const { return flags_.isConstrained_; } + bool isLeadingEdge() const { return isLeadingEdge_; } /// Returns the twin edge - const EdgePtr& getTwinEdge() const { return twinEdge_; }; + EdgePtr getTwinEdge() const { return twinEdge_.lock(); }; + + void clearTwinEdge() { twinEdge_.reset(); } /// Returns the next edge in face const EdgePtr& getNextEdgeInFace() const { return nextEdgeInFace_; } /// Retuns the source node - virtual const NodePtr& getSourceNode() const { return sourceNode_; } + const NodePtr& getSourceNode() const { return sourceNode_; } /// Returns the target node - virtual const NodePtr& getTargetNode() const { return getNextEdgeInFace()->getSourceNode(); } + virtual const NodePtr& getTargetNode() const { return nextEdgeInFace_->getSourceNode(); } void setWeight( unsigned int weight ) { weight_ = weight; } unsigned int getWeight() const { return weight_; } + void clear() + { + sourceNode_.reset(); + nextEdgeInFace_.reset(); + + if( !twinEdge_.expired() ) + { + twinEdge_.lock()->clearTwinEdge(); + twinEdge_.reset(); + } + } + protected: NodePtr sourceNode_; - EdgePtr twinEdge_; + EdgeWeakPtr twinEdge_; EdgePtr nextEdgeInFace_; unsigned int weight_; - - struct { - bool isLeadingEdge_; - bool isConstrained_; - } flags_; + bool isLeadingEdge_; }; // End of class Edge /** \class EdgeMST - * \brief \b %Specialization of Edge class to be used for Minimum Spanning Tree algorithm. + * \brief \b Specialization of %Edge class to be used for Minimum Spanning Tree algorithm. */ class EdgeMST : public Edge { @@ -224,10 +228,17 @@ public: target_(target) { sourceNode_ = source; weight_ = weight; } + EdgeMST( const Edge& edge ) + { + sourceNode_ = edge.getSourceNode(); + target_ = edge.getTargetNode(); + weight_ = edge.getWeight(); + } + ~EdgeMST() {}; /// @copydoc Edge::setSourceNode() - const NodePtr& getTargetNode() const { return target_; } + virtual const NodePtr& getTargetNode() const { return target_; } }; @@ -288,7 +299,7 @@ public: * \param dart * Output: A CCW dart incident with the new node; see the figure. */ - void splitTriangle(Dart& dart, NodePtr point); + void splitTriangle(Dart& dart, const NodePtr& point); /** The reverse operation of TTLtraits::splitTriangle. * This function is only required for functions that involve @@ -332,7 +343,7 @@ public: void swapEdge(EdgePtr& diagonal); /// Splits the triangle associated with edge into three new triangles joining at point - EdgePtr splitTriangle(EdgePtr& edge, NodePtr& point); + EdgePtr splitTriangle(EdgePtr& edge, const NodePtr& point); // Functions required by TTL for removing nodes in a Delaunay triangulation @@ -350,7 +361,7 @@ public: const std::list& getLeadingEdges() const { return leadingEdges_; } /// Returns the number of triangles - int noTriangles() const { return (int)leadingEdges_.size(); } + int noTriangles() const { return (int)leadingEdges_.size(); } /// Returns a list of half-edges (one half-edge for each arc) std::list* getEdges(bool skip_boundary_edges = false) const; diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index 201f6b6041..234326c132 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -40,6 +40,7 @@ #include #include +#include #include #include #include @@ -140,10 +141,18 @@ std::vector* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges, cycles[srcTag].splice( cycles[srcTag].end(), cycles[trgTag] ); if( dt->getWeight() == 0 ) // Skip already existing connections (weight == 0) + { mstExpectedSize--; + } else { - mst->push_back( dt ); + // Do a copy of edge, but make it RN_EDGE_MST. In contrary to RN_EDGE, + // RN_EDGE_MST saves both source and target node and does not require any other + // edges to exist for getting source/target nodes + RN_EDGE_MST_PTR newEdge = boost::make_shared( dt->getSourceNode(), + dt->getTargetNode(), + dt->getWeight() ); + mst->push_back( newEdge ); ++mstSize; } } @@ -414,7 +423,7 @@ void RN_NET::AddItem( const ZONE_CONTAINER* aZone ) // Origin and end of bounding box for a polygon VECTOR2I origin( polyPoints[0].x, polyPoints[0].y ); VECTOR2I end( polyPoints[0].x, polyPoints[0].y ); - int idxStart = 0; + unsigned int idxStart = 0; // Extract polygons from zones for( unsigned int i = 0; i < polyPoints.size(); ++i ) @@ -440,10 +449,14 @@ void RN_NET::AddItem( const ZONE_CONTAINER* aZone ) m_links, BOX2I( origin, end - origin ) ) ); idxStart = i + 1; - origin.x = polyPoints[idxStart].x; - origin.y = polyPoints[idxStart].y; - end.x = polyPoints[idxStart].x; - end.y = polyPoints[idxStart].y; + + if( idxStart < polyPoints.size() ) + { + origin.x = polyPoints[idxStart].x; + origin.y = polyPoints[idxStart].y; + end.x = polyPoints[idxStart].x; + end.y = polyPoints[idxStart].y; + } } } @@ -968,25 +981,23 @@ void RN_DATA::Recalculate( int aNet ) { if( aNet < 0 ) // Recompute everything { - unsigned int tid, i, chunk, netCount; + unsigned int i, netCount; netCount = m_board->GetNetCount(); - chunk = 1; #ifdef USE_OPENMP - #pragma omp parallel shared(chunk, netCount) private(i, tid) + #pragma omp parallel shared(netCount) private(i) { - tid = omp_get_thread_num(); - #pragma omp for schedule(guided, chunk) + #pragma omp for schedule(guided, 1) #else /* USE_OPENMP */ { #endif - // Start with net number 1, as 0 stand for not connected + // Start with net number 1, as 0 stands for not connected for( i = 1; i < netCount; ++i ) { if( m_nets[i].IsDirty() ) updateNet( i ); } - } /* end of parallel section */ + } /* end of parallel section */ } else if( aNet > 0 ) // Recompute only specific net { From aa54a3e5a1b804af6c6697e1af18004eef95d94c Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 5 Mar 2014 16:44:08 +0100 Subject: [PATCH 94/95] Fixed undo while PNS is active. --- pcbnew/router/pns_router.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pcbnew/router/pns_router.cpp b/pcbnew/router/pns_router.cpp index 646d011404..e3cf287596 100644 --- a/pcbnew/router/pns_router.cpp +++ b/pcbnew/router/pns_router.cpp @@ -324,6 +324,9 @@ PNS_ROUTER::~PNS_ROUTER() { ClearWorld(); theRouter = NULL; + + if( m_previewItems ) + delete m_previewItems; } @@ -338,13 +341,9 @@ void PNS_ROUTER::ClearWorld() if( m_placer ) delete m_placer; - if( m_previewItems ) - delete m_previewItems; - m_clearanceFunc = NULL; m_world = NULL; m_placer = NULL; - m_previewItems = NULL; } @@ -468,9 +467,10 @@ void PNS_ROUTER::EraseView() } if( m_previewItems ) + { m_previewItems->FreeItems(); - - m_previewItems->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + m_previewItems->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } } From 8461fc2f3b6f7b3083a664f978b160e5af9592cf Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 6 Mar 2014 09:14:06 +0100 Subject: [PATCH 95/95] Removed warnings. --- pcbnew/class_zone.cpp | 4 ---- pcbnew/legacy_plugin.cpp | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index 627d98ac87..6679fee49a 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -588,10 +588,6 @@ void ZONE_CONTAINER::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) { wxString msg; - BOARD* board = (BOARD*) m_Parent; - - wxASSERT( board ); - msg = _( "Zone Outline" ); // Display Cutout instead of Outline for holes inside a zone diff --git a/pcbnew/legacy_plugin.cpp b/pcbnew/legacy_plugin.cpp index 96c7a75a8f..f548c2b997 100644 --- a/pcbnew/legacy_plugin.cpp +++ b/pcbnew/legacy_plugin.cpp @@ -1814,7 +1814,7 @@ void LEGACY_PLUGIN::loadNETINFO_ITEM() { char buf[1024]; - NETINFO_ITEM* net; + NETINFO_ITEM* net = NULL; char* line; while( ( line = READLINE( m_reader ) ) != NULL ) @@ -1835,7 +1835,7 @@ void LEGACY_PLUGIN::loadNETINFO_ITEM() { // net 0 should be already in list, so store this net // if it is not the net 0, or if the net 0 does not exists. - if( net->GetNet() > 0 || m_board->FindNet( 0 ) == NULL ) + if( net != NULL && ( net->GetNet() > 0 || m_board->FindNet( 0 ) == NULL ) ) m_board->AppendNet( net ); else delete net;