From 81f84748b3c79d7e6fc21b6aa9e9e1ea5fc102d8 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 6 Feb 2014 10:43:19 +0100 Subject: [PATCH 001/134] Modifiers (Shift/Ctrl/Alt) are set also while moving the mouse cursor. --- common/tool/tool_dispatcher.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/common/tool/tool_dispatcher.cpp b/common/tool/tool_dispatcher.cpp index 49ab4382ac..916730d042 100644 --- a/common/tool/tool_dispatcher.cpp +++ b/common/tool/tool_dispatcher.cpp @@ -208,6 +208,9 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) // but changes in world coordinates (eg. autopanning) type == KIGFX::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE ) { + wxMouseEvent* me = static_cast( &aEvent ); + int mods = decodeModifiers( me ); + VECTOR2D screenPos = m_toolMgr->GetViewControls()->GetCursorPosition(); VECTOR2D pos = getView()->ToWorld( screenPos ); @@ -222,7 +225,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) if( !buttonEvents && motion ) { - evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_MOTION ); + evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_MOTION, mods ); evt->SetMousePosition( pos ); } } From b9df36eca58331ca17fda2c0389716f6026bf457 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 6 Feb 2014 12:38:06 +0100 Subject: [PATCH 002/134] GAL::GetGridPoint() takes a const reference. --- common/gal/graphics_abstraction_layer.cpp | 2 +- include/gal/graphics_abstraction_layer.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/gal/graphics_abstraction_layer.cpp b/common/gal/graphics_abstraction_layer.cpp index 6fa929b062..2a3d9a089c 100644 --- a/common/gal/graphics_abstraction_layer.cpp +++ b/common/gal/graphics_abstraction_layer.cpp @@ -232,7 +232,7 @@ void GAL::DrawGrid() } -VECTOR2D GAL::GetGridPoint( VECTOR2D aPoint ) const +VECTOR2D GAL::GetGridPoint( const VECTOR2D& aPoint ) const { VECTOR2D pointWorld = ToWorld( aPoint ); diff --git a/include/gal/graphics_abstraction_layer.h b/include/gal/graphics_abstraction_layer.h index 7745dfa172..118faf38ac 100644 --- a/include/gal/graphics_abstraction_layer.h +++ b/include/gal/graphics_abstraction_layer.h @@ -720,7 +720,7 @@ public: * @param aPoint is the point for which the grid point is searched. * @return The nearest grid point. */ - VECTOR2D GetGridPoint( VECTOR2D aPoint ) const; + VECTOR2D GetGridPoint( const VECTOR2D& aPoint ) const; /** From 8944e924560d2e3882f7909cc93b1d038208bc0d Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 6 Feb 2014 12:38:47 +0100 Subject: [PATCH 003/134] Fixed included headers. --- include/class_board_item.h | 1 - pcbnew/class_drawsegment.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/include/class_board_item.h b/include/class_board_item.h index 6f6bf201d6..a2f032b877 100644 --- a/include/class_board_item.h +++ b/include/class_board_item.h @@ -34,7 +34,6 @@ #include #include #include -#include #include /// Abbrevation for fomatting internal units to a string. diff --git a/pcbnew/class_drawsegment.h b/pcbnew/class_drawsegment.h index dacd8061d2..cc8f5ff80e 100644 --- a/pcbnew/class_drawsegment.h +++ b/pcbnew/class_drawsegment.h @@ -30,7 +30,7 @@ #ifndef CLASS_DRAWSEGMENT_H_ #define CLASS_DRAWSEGMENT_H_ - +#include #include #include #include From 363709e7a930ba925df26964da5a50586e3de6b2 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 6 Feb 2014 14:45:33 +0100 Subject: [PATCH 004/134] Added TOOL_INTERACTIVE::Activate(). Removed an unnecessary header from class_board_item.h. --- common/tool/tool_interactive.cpp | 6 ++++++ include/class_board_item.h | 1 - include/tool/tool_interactive.h | 6 ++++++ pcbnew/ratsnest_data.cpp | 4 ++-- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/common/tool/tool_interactive.cpp b/common/tool/tool_interactive.cpp index 33756cf3d8..14ea61a86a 100644 --- a/common/tool/tool_interactive.cpp +++ b/common/tool/tool_interactive.cpp @@ -46,6 +46,12 @@ TOOL_INTERACTIVE::~TOOL_INTERACTIVE() } +void TOOL_INTERACTIVE::Activate() +{ + m_toolMgr->InvokeTool( m_toolId ); +} + + OPT_TOOL_EVENT TOOL_INTERACTIVE::Wait( const TOOL_EVENT_LIST& aEventList ) { return m_toolMgr->ScheduleWait( this, aEventList ); diff --git a/include/class_board_item.h b/include/class_board_item.h index 8a49d87b0c..d438483502 100644 --- a/include/class_board_item.h +++ b/include/class_board_item.h @@ -33,7 +33,6 @@ #include #include -#include #include /// Abbrevation for fomatting internal units to a string. diff --git a/include/tool/tool_interactive.h b/include/tool/tool_interactive.h index 7e816bd3a4..1888011b5f 100644 --- a/include/tool/tool_interactive.h +++ b/include/tool/tool_interactive.h @@ -48,6 +48,12 @@ public: TOOL_INTERACTIVE( const std::string& aName ); virtual ~TOOL_INTERACTIVE(); + /** + * Function Activate() + * Runs the tool. After activation, the tool starts receiving events until it is finished. + */ + void Activate(); + /** * Function SetContextMenu() * diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index 430674887c..80d082a9b3 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -968,11 +968,11 @@ 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 + unsigned int chunk = 1, tid; #pragma omp parallel shared(chunk, netCount) private(i, tid) { tid = omp_get_thread_num(); From b21ce73c371d1e61e1817a1962e56ef530c824f5 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 6 Feb 2014 15:09:38 +0100 Subject: [PATCH 005/134] Initial version of the drawing tool. --- pcbnew/CMakeLists.txt | 1 + pcbnew/tools/common_actions.cpp | 4 ++++ pcbnew/tools/common_actions.h | 3 +++ pcbnew/tools/edit_tool.h | 3 +++ pcbnew/tools/pcb_tools.cpp | 3 +++ 5 files changed, 14 insertions(+) diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 8d7a842f55..e697375ec2 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -251,6 +251,7 @@ set( PCBNEW_CLASS_SRCS tools/selection_tool.cpp tools/selection_area.cpp tools/bright_box.cpp + tools/drawing_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 f1fb3befd6..464a8ab505 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -56,3 +56,7 @@ TOOL_ACTION COMMON_ACTIONS::remove( "pcbnew.InteractiveEdit.remove", TOOL_ACTION COMMON_ACTIONS::properties( "pcbnew.InteractiveEdit.properties", AS_GLOBAL, 'E', "Properties...", "Displays properties window" ); + +TOOL_ACTION COMMON_ACTIONS::drawingLine( "pcbnew.InteractiveDrawing.line", + AS_GLOBAL, 'D', + "Draw a line", "Draw a line" ); diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 86aafe5894..42a03b3cb3 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -56,4 +56,7 @@ public: /// Deleting a BOARD_ITEM static TOOL_ACTION remove; + + /// Activation of the drawing tool (line) + static TOOL_ACTION drawingLine; }; diff --git a/pcbnew/tools/edit_tool.h b/pcbnew/tools/edit_tool.h index d31b159aa5..49fbe48450 100644 --- a/pcbnew/tools/edit_tool.h +++ b/pcbnew/tools/edit_tool.h @@ -114,6 +114,9 @@ private: m_updateFlag = aFlag; } + ///> Updates ratsnest for selected items. + ///> @param aRedraw says if selected items should be drawn using the simple mode (e.g. one line + ///> per item). void updateRatsnest( bool aRedraw ); ///> Returns the right modification point (e.g. for rotation), depending on the number of diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index a4b4f21a24..63c98d5009 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -36,6 +36,7 @@ #include "selection_tool.h" #include "edit_tool.h" +#include "drawing_tool.h" #include "common_actions.h" #include @@ -54,11 +55,13 @@ void PCB_EDIT_FRAME::setupTools() m_toolManager->RegisterAction( &COMMON_ACTIONS::flip ); m_toolManager->RegisterAction( &COMMON_ACTIONS::remove ); m_toolManager->RegisterAction( &COMMON_ACTIONS::properties ); + m_toolManager->RegisterAction( &COMMON_ACTIONS::drawingLine ); // Register tools m_toolManager->RegisterTool( new SELECTION_TOOL ); m_toolManager->RegisterTool( new ROUTER_TOOL ); m_toolManager->RegisterTool( new EDIT_TOOL ); + m_toolManager->RegisterTool( new DRAWING_TOOL ); m_toolManager->SetEnvironment( NULL, GetGalCanvas()->GetView(), GetGalCanvas()->GetViewControls(), this ); From 45f55fb8c5b7fa592327ab9b1d8b8fa05c24889e Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 6 Feb 2014 17:12:37 +0100 Subject: [PATCH 006/134] Actually added files for drawing tools. Added possibility of drawing circles. --- pcbnew/tools/common_actions.cpp | 6 +- pcbnew/tools/common_actions.h | 5 +- pcbnew/tools/drawing_tool.cpp | 196 ++++++++++++++++++++++++++++++++ pcbnew/tools/drawing_tool.h | 72 ++++++++++++ pcbnew/tools/pcb_tools.cpp | 3 +- 5 files changed, 279 insertions(+), 3 deletions(-) create mode 100644 pcbnew/tools/drawing_tool.cpp create mode 100644 pcbnew/tools/drawing_tool.h diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 464a8ab505..22b0c10e2f 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -57,6 +57,10 @@ TOOL_ACTION COMMON_ACTIONS::properties( "pcbnew.InteractiveEdit.properties", AS_GLOBAL, 'E', "Properties...", "Displays properties window" ); -TOOL_ACTION COMMON_ACTIONS::drawingLine( "pcbnew.InteractiveDrawing.line", +TOOL_ACTION COMMON_ACTIONS::drawLine( "pcbnew.InteractiveDrawing.line", AS_GLOBAL, 'D', "Draw a line", "Draw a line" ); + +TOOL_ACTION COMMON_ACTIONS::drawCircle( "pcbnew.InteractiveDrawing.circle", + AS_GLOBAL, 'S', + "Draw a circle", "Draw a circle" ); diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 42a03b3cb3..d573a8a96c 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -58,5 +58,8 @@ public: static TOOL_ACTION remove; /// Activation of the drawing tool (line) - static TOOL_ACTION drawingLine; + static TOOL_ACTION drawLine; + + /// Activation of the drawing tool (circle) + static TOOL_ACTION drawCircle; }; diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp new file mode 100644 index 0000000000..8f03336bdc --- /dev/null +++ b/pcbnew/tools/drawing_tool.cpp @@ -0,0 +1,196 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 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 "drawing_tool.h" +#include "common_actions.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +DRAWING_TOOL::DRAWING_TOOL() : + TOOL_INTERACTIVE( "pcbnew.InteractiveDrawing" ) +{ +} + + +DRAWING_TOOL::~DRAWING_TOOL() +{ +} + + +void DRAWING_TOOL::Reset( RESET_REASON aReason ) +{ + setTransitions(); +} + + +int DRAWING_TOOL::DrawLine( TOOL_EVENT& aEvent ) +{ + m_continous = true; + + return draw( S_SEGMENT ); +} + + +int DRAWING_TOOL::DrawCircle( TOOL_EVENT& aEvent ) +{ + m_continous = false; + + return draw( S_CIRCLE ); +} + + +int DRAWING_TOOL::draw( STROKE_T aShape ) +{ + bool started = false; + KIGFX::VIEW* view = getView(); + KIGFX::VIEW_CONTROLS* controls = getViewControls(); + BOARD* board = getModel( PCB_T ); + DRAWSEGMENT graphic; + + // Init the new item attributes + graphic.SetShape( aShape ); + graphic.SetWidth( board->GetDesignSettings().m_DrawSegmentWidth ); + + // Add a VIEW_GROUP that serves as a preview for the new item + KIGFX::VIEW_GROUP preview( view ); + view->Add( &preview ); + + controls->ShowCursor( true ); + controls->SetSnapping( true ); + + Activate(); + + // Main loop: keep receiving events + while( OPT_TOOL_EVENT evt = Wait() ) + { + // Enable 45 degrees lines only mode by holding shift + bool linesAngle45 = evt->Modifier( MD_SHIFT ); + VECTOR2D cursorPos = view->ToWorld( controls->GetCursorPosition() ); + + if( evt->IsCancel() ) + break; + + else if( evt->IsKeyUp() ) + { + int width = graphic.GetWidth(); + + // Modify the new item width + if( evt->KeyCode() == '-' && width > WIDTH_STEP ) + graphic.SetWidth( width - WIDTH_STEP ); + else if( evt->KeyCode() == '=' ) + graphic.SetWidth( width + WIDTH_STEP ); + + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + + else if( evt->IsClick( BUT_LEFT ) ) + { + if( !started ) + { + LAYER_NUM layer = getEditFrame()->GetScreen()->m_Active_Layer; + + if( IsCopperLayer( layer ) ) + { + DisplayInfoMessage( NULL, _( "Graphic not allowed on Copper layers" ) ); + } + else + { + controls->SetAutoPan( true ); + + graphic.SetStart( wxPoint( cursorPos.x, cursorPos.y ) ); + graphic.SetLayer( layer ); + preview.Add( &graphic ); + + started = true; + } + } + else + { + if( wxPoint( cursorPos.x, cursorPos.y ) != graphic.GetStart() ) + { + DRAWSEGMENT* newItem = new DRAWSEGMENT( graphic ); + view->Add( newItem ); + getModel( PCB_T )->Add( newItem ); + newItem->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + + if( m_continous ) + graphic.SetStart( graphic.GetEnd() ); // This is the origin point for a new item + else + break; + } + else // User has clicked twice in the same spot + break; // seems like a clear sign that the drawing is finished + } + } + + else if( evt->IsMotion() && started ) + { + // 45 degree lines + if( linesAngle45 && aShape == S_SEGMENT ) + { + VECTOR2D lineVector( wxPoint( cursorPos.x, cursorPos.y ) - graphic.GetStart() ); + double angle = atan2( lineVector.y, lineVector.x ); + + double newAngle = round( angle / ( M_PI / 4.0 ) ) * M_PI / 4.0; + VECTOR2D newLineVector = lineVector.Rotate( newAngle - angle ); + + // Snap the new line to the grid // TODO fix it, does not work good.. + VECTOR2D newLineEnd = VECTOR2D( graphic.GetStart() ) + newLineVector; + VECTOR2D snapped = view->GetGAL()->GetGridPoint( newLineEnd ); + + graphic.SetEnd( wxPoint( snapped.x, snapped.y ) ); + } + else + { + graphic.SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); + } + + // Show a preview of the item + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + } + + controls->ShowCursor( false ); + controls->SetSnapping( false ); + controls->SetAutoPan( false ); + view->Remove( &preview ); + + setTransitions(); + + return 0; +} + + +void DRAWING_TOOL::setTransitions() +{ + Go( &DRAWING_TOOL::DrawLine, COMMON_ACTIONS::drawLine.MakeEvent() ); + Go( &DRAWING_TOOL::DrawCircle, COMMON_ACTIONS::drawCircle.MakeEvent() ); +} diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h new file mode 100644 index 0000000000..4cef5744cd --- /dev/null +++ b/pcbnew/tools/drawing_tool.h @@ -0,0 +1,72 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 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 __DRAWING_TOOL_H +#define __DRAWING_TOOL_H + +#include +#include + +/** + * Class DRAWING_TOOL + * + * Tool responsible for drawing graphical elements like lines, arcs, circles, etc. + */ + +class DRAWING_TOOL : public TOOL_INTERACTIVE +{ +public: + DRAWING_TOOL(); + ~DRAWING_TOOL(); + + /// @copydoc TOOL_INTERACTIVE::Reset() + void Reset( RESET_REASON aReason ); + + /** + * Function DrawLine() + * Starts interactively drawing a line. After invoking the function it expects the user + * to click at least twice to determine the origin and the end for a line. If there are + * more clicks, the line is drawn as a continous polyline. + */ + int DrawLine( TOOL_EVENT& aEvent ); + + int DrawCircle( TOOL_EVENT& aEvent ); + + int DrawArc( TOOL_EVENT& aEvent ); + +private: + ///> Starts drawing a selected shape. + int draw( STROKE_T aShape ); + + ///> Sets up handlers for various events. + void setTransitions(); + + ///> Should drawing be stopped after drawing one object or should it continue with another one. + bool m_continous; + + // How does line width change after one -/+ key press. + static const int WIDTH_STEP = 100000; +}; + +#endif /* __DRAWING_TOOL_H */ diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index 63c98d5009..5dff5788a9 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -55,7 +55,8 @@ void PCB_EDIT_FRAME::setupTools() m_toolManager->RegisterAction( &COMMON_ACTIONS::flip ); m_toolManager->RegisterAction( &COMMON_ACTIONS::remove ); m_toolManager->RegisterAction( &COMMON_ACTIONS::properties ); - m_toolManager->RegisterAction( &COMMON_ACTIONS::drawingLine ); + m_toolManager->RegisterAction( &COMMON_ACTIONS::drawLine ); + m_toolManager->RegisterAction( &COMMON_ACTIONS::drawCircle ); // Register tools m_toolManager->RegisterTool( new SELECTION_TOOL ); From 0dadf3bc7c2be8cc4c77b88be7ba79dbfc64e603 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 7 Feb 2014 19:51:04 +0100 Subject: [PATCH 007/134] 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 cc8f5ff80e..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 #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 02316e02c312d9316fa0964e8dca40a06caf3d3b Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 10 Feb 2014 10:58:58 +0100 Subject: [PATCH 008/134] Drawing arcs - version 1 --- pcbnew/tools/common_actions.cpp | 4 + pcbnew/tools/common_actions.h | 3 + pcbnew/tools/drawing_tool.cpp | 156 +++++++++++++++++++++++++++++++- pcbnew/tools/pcb_tools.cpp | 1 + 4 files changed, 163 insertions(+), 1 deletion(-) diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 22b0c10e2f..d7368b96c6 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -64,3 +64,7 @@ TOOL_ACTION COMMON_ACTIONS::drawLine( "pcbnew.InteractiveDrawing.line", TOOL_ACTION COMMON_ACTIONS::drawCircle( "pcbnew.InteractiveDrawing.circle", AS_GLOBAL, 'S', "Draw a circle", "Draw a circle" ); + +TOOL_ACTION COMMON_ACTIONS::drawArc( "pcbnew.InteractiveDrawing.arc", + AS_GLOBAL, 'A', + "Draw an arc", "Draw an arc" ); diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index d573a8a96c..3542490c24 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -62,4 +62,7 @@ public: /// Activation of the drawing tool (circle) static TOOL_ACTION drawCircle; + + /// Activation of the drawing tool (arc) + static TOOL_ACTION drawArc; }; diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 8f03336bdc..1f2a64ec1a 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -67,6 +67,159 @@ int DRAWING_TOOL::DrawCircle( TOOL_EVENT& aEvent ) } +int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) +{ + m_continous = false; + + int step = 0; + + KIGFX::VIEW* view = getView(); + KIGFX::VIEW_CONTROLS* controls = getViewControls(); + BOARD* board = getModel( PCB_T ); + DRAWSEGMENT graphic; + DRAWSEGMENT helperLine; + bool positive = true; + + // Init the new item attributes + graphic.SetShape( S_ARC ); + graphic.SetAngle( 0.0 ); + graphic.SetWidth( board->GetDesignSettings().m_DrawSegmentWidth ); + + helperLine.SetShape( S_SEGMENT ); + helperLine.SetLayer( DRAW_N ); + helperLine.SetWidth( 1 ); + + // Add a VIEW_GROUP that serves as a preview for the new item + KIGFX::VIEW_GROUP preview( view ); + view->Add( &preview ); + + controls->ShowCursor( true ); + controls->SetSnapping( true ); + + Activate(); + + // Main loop: keep receiving events + while( OPT_TOOL_EVENT evt = Wait() ) + { + VECTOR2D cursorPos = view->ToWorld( controls->GetCursorPosition() ); + + if( evt->IsCancel() ) + break; + + else if( evt->IsKeyUp() ) + { + int width = graphic.GetWidth(); + + // Modify the new item width + if( evt->KeyCode() == '-' && width > WIDTH_STEP ) + graphic.SetWidth( width - WIDTH_STEP ); + else if( evt->KeyCode() == '=' ) + graphic.SetWidth( width + WIDTH_STEP ); + else if( evt->KeyCode() == ' ' ) + { + if( positive ) + graphic.SetAngle( graphic.GetAngle() - 3600.0 ); + else + graphic.SetAngle( graphic.GetAngle() + 3600.0 ); + + positive = !positive; + } + + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + + else if( evt->IsClick( BUT_LEFT ) ) + { + switch( step ) + { + case 0: + { + LAYER_NUM layer = getEditFrame()->GetScreen()->m_Active_Layer; + + if( IsCopperLayer( layer ) ) + { + DisplayInfoMessage( NULL, _( "Graphic not allowed on Copper layers" ) ); + --step; + } + else + { + controls->SetAutoPan( true ); + + helperLine.SetStart( graphic.GetCenter() ); + graphic.SetLayer( layer ); + preview.Add( &graphic ); + preview.Add( &helperLine ); + } + } + break; + + case 2: + { + if( wxPoint( cursorPos.x, cursorPos.y ) != graphic.GetCenter() ) + { + DRAWSEGMENT* newItem = new DRAWSEGMENT( graphic ); + view->Add( newItem ); + getModel( PCB_T )->Add( newItem ); + newItem->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + } + break; + + } + + if( ++step == 3 ) + break; + } + + else if( evt->IsMotion() ) + { + switch( step ) + { + case 0: + graphic.SetCenter( wxPoint( cursorPos.x, cursorPos.y ) ); + break; + + case 1: + helperLine.SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); + graphic.SetArcStart( wxPoint( cursorPos.x, cursorPos.y ) ); + break; + + case 2: + { + VECTOR2D firstLine( graphic.GetArcStart() - graphic.GetCenter() ); + double firstAngle = firstLine.Angle(); + + VECTOR2D secondLine( wxPoint( cursorPos.x, cursorPos.y ) - graphic.GetCenter() ); + double secondAngle = secondLine.Angle(); + + double angle = RAD2DECIDEG( secondAngle - firstAngle ); + + if( positive && angle < 0.0 ) + angle += 3600.0; + else if( !positive && angle > 0.0 ) + angle -= 3600.0; + + graphic.SetAngle( angle ); + } + break; + } + + // Show a preview of the item + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + } + + controls->ShowCursor( false ); + controls->SetSnapping( false ); + controls->SetAutoPan( false ); + view->Remove( &preview ); + + setTransitions(); + + return 0; +} + + int DRAWING_TOOL::draw( STROKE_T aShape ) { bool started = false; @@ -157,7 +310,7 @@ int DRAWING_TOOL::draw( STROKE_T aShape ) if( linesAngle45 && aShape == S_SEGMENT ) { VECTOR2D lineVector( wxPoint( cursorPos.x, cursorPos.y ) - graphic.GetStart() ); - double angle = atan2( lineVector.y, lineVector.x ); + double angle = lineVector.Angle(); double newAngle = round( angle / ( M_PI / 4.0 ) ) * M_PI / 4.0; VECTOR2D newLineVector = lineVector.Rotate( newAngle - angle ); @@ -193,4 +346,5 @@ void DRAWING_TOOL::setTransitions() { Go( &DRAWING_TOOL::DrawLine, COMMON_ACTIONS::drawLine.MakeEvent() ); Go( &DRAWING_TOOL::DrawCircle, COMMON_ACTIONS::drawCircle.MakeEvent() ); + Go( &DRAWING_TOOL::DrawArc, COMMON_ACTIONS::drawArc.MakeEvent() ); } diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index 5dff5788a9..2f893cf509 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -57,6 +57,7 @@ void PCB_EDIT_FRAME::setupTools() m_toolManager->RegisterAction( &COMMON_ACTIONS::properties ); m_toolManager->RegisterAction( &COMMON_ACTIONS::drawLine ); m_toolManager->RegisterAction( &COMMON_ACTIONS::drawCircle ); + m_toolManager->RegisterAction( &COMMON_ACTIONS::drawArc ); // Register tools m_toolManager->RegisterTool( new SELECTION_TOOL ); From 4b277784515652f42dd0440649489e34789086b5 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 10 Feb 2014 15:40:25 +0100 Subject: [PATCH 009/134] Basic text placing tool. --- pcbnew/edit_pcb_text.cpp | 5 ++- pcbnew/tools/common_actions.cpp | 4 ++ pcbnew/tools/common_actions.h | 3 ++ pcbnew/tools/drawing_tool.cpp | 66 ++++++++++++++++++++++++++++++++- pcbnew/tools/drawing_tool.h | 2 + pcbnew/tools/pcb_tools.cpp | 1 + 6 files changed, 77 insertions(+), 4 deletions(-) diff --git a/pcbnew/edit_pcb_text.cpp b/pcbnew/edit_pcb_text.cpp index e4ecfcb5a2..277159a5ee 100644 --- a/pcbnew/edit_pcb_text.cpp +++ b/pcbnew/edit_pcb_text.cpp @@ -195,7 +195,8 @@ TEXTE_PCB* PCB_EDIT_FRAME::CreateTextePcb( wxDC* aDC, TEXTE_PCB* aText ) textePcb->Copy( aText ); GetBoard()->Add( textePcb ); textePcb->SetFlags( IS_NEW ); - StartMoveTextePcb( textePcb, aDC, false ); // Don't erase aText when copying + if( aDC ) + StartMoveTextePcb( textePcb, aDC, false ); // Don't erase aText when copying } else { @@ -222,7 +223,7 @@ TEXTE_PCB* PCB_EDIT_FRAME::CreateTextePcb( wxDC* aDC, TEXTE_PCB* aText ) textePcb->DeleteStructure(); textePcb = NULL; } - else + else if( aDC ) { StartMoveTextePcb( textePcb, aDC ); } diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index d7368b96c6..44217508bc 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -68,3 +68,7 @@ TOOL_ACTION COMMON_ACTIONS::drawCircle( "pcbnew.InteractiveDrawing.circle", TOOL_ACTION COMMON_ACTIONS::drawArc( "pcbnew.InteractiveDrawing.arc", AS_GLOBAL, 'A', "Draw an arc", "Draw an arc" ); + +TOOL_ACTION COMMON_ACTIONS::drawText( "pcbnew.InteractiveDrawing.text", + AS_GLOBAL, 'T', + "Add a text", "Add a text" ); diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 3542490c24..992d9cbdf8 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -65,4 +65,7 @@ public: /// Activation of the drawing tool (arc) static TOOL_ACTION drawArc; + + /// Activation of the drawing tool (text) + static TOOL_ACTION drawText; }; diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 1f2a64ec1a..d658f3c23d 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -159,7 +160,7 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) { DRAWSEGMENT* newItem = new DRAWSEGMENT( graphic ); view->Add( newItem ); - getModel( PCB_T )->Add( newItem ); + board->Add( newItem ); newItem->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } } @@ -291,7 +292,7 @@ int DRAWING_TOOL::draw( STROKE_T aShape ) { DRAWSEGMENT* newItem = new DRAWSEGMENT( graphic ); view->Add( newItem ); - getModel( PCB_T )->Add( newItem ); + board->Add( newItem ); newItem->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); if( m_continous ) @@ -342,9 +343,70 @@ int DRAWING_TOOL::draw( STROKE_T aShape ) } +int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) +{ + KIGFX::VIEW* view = getView(); + KIGFX::VIEW_CONTROLS* controls = getViewControls(); + + // Init the new item attributes + TEXTE_PCB* newText = getEditFrame()->CreateTextePcb( NULL ); + + // Add a VIEW_GROUP that serves as a preview for the new item + KIGFX::VIEW_GROUP preview( view ); + preview.Add( newText ); + view->Add( &preview ); + + controls->ShowCursor( true ); + controls->SetSnapping( true ); + controls->SetAutoPan( true ); + + Activate(); + + // Main loop: keep receiving events + while( OPT_TOOL_EVENT evt = Wait() ) + { + VECTOR2D cursorPos = view->ToWorld( controls->GetCursorPosition() ); + + if( evt->IsCancel() ) + { + // it was already added by CreateTextPcb() + getModel( PCB_T )->Delete( newText ); + break; + } + + else if( evt->IsClick( BUT_LEFT ) ) + { + newText->ClearFlags(); + view->Add( newText ); + // board->Add( newText ); // it is already added by CreateTextePcb() + newText->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + break; + } + + else if( evt->IsMotion() ) + { + newText->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) ); + + // Show a preview of the item + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + } + + controls->ShowCursor( false ); + controls->SetSnapping( false ); + controls->SetAutoPan( false ); + view->Remove( &preview ); + + setTransitions(); + + return 0; +} + + void DRAWING_TOOL::setTransitions() { Go( &DRAWING_TOOL::DrawLine, COMMON_ACTIONS::drawLine.MakeEvent() ); Go( &DRAWING_TOOL::DrawCircle, COMMON_ACTIONS::drawCircle.MakeEvent() ); Go( &DRAWING_TOOL::DrawArc, COMMON_ACTIONS::drawArc.MakeEvent() ); + Go( &DRAWING_TOOL::DrawText, COMMON_ACTIONS::drawText.MakeEvent() ); } diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index 4cef5744cd..4e969860db 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -55,6 +55,8 @@ public: int DrawArc( TOOL_EVENT& aEvent ); + int DrawText( TOOL_EVENT& aEvent ); + private: ///> Starts drawing a selected shape. int draw( STROKE_T aShape ); diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index 2f893cf509..73f9f14a5f 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -58,6 +58,7 @@ void PCB_EDIT_FRAME::setupTools() m_toolManager->RegisterAction( &COMMON_ACTIONS::drawLine ); m_toolManager->RegisterAction( &COMMON_ACTIONS::drawCircle ); m_toolManager->RegisterAction( &COMMON_ACTIONS::drawArc ); + m_toolManager->RegisterAction( &COMMON_ACTIONS::drawText ); // Register tools m_toolManager->RegisterTool( new SELECTION_TOOL ); From 2aef11a5fc8716d5dd6dd4418e0ce702cd71f686 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 10 Feb 2014 17:08:55 +0100 Subject: [PATCH 010/134] Made rotate & flip tool actions generic. Drawing tool reacts to rotate & flip events while placing a text. --- pcbnew/tools/common_actions.cpp | 4 ++-- pcbnew/tools/drawing_tool.cpp | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 44217508bc..0878657b1f 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -41,11 +41,11 @@ TOOL_ACTION COMMON_ACTIONS::editActivate( "pcbnew.InteractiveEdit", AS_GLOBAL, 'M', "Move", "Moves the selected item(s)" ); -TOOL_ACTION COMMON_ACTIONS::rotate( "pcbnew.InteractiveEdit.rotate", +TOOL_ACTION COMMON_ACTIONS::rotate( "pcbnew.rotate", AS_CONTEXT, 'R', "Rotate", "Rotates selected item(s)" ); -TOOL_ACTION COMMON_ACTIONS::flip( "pcbnew.InteractiveEdit.flip", +TOOL_ACTION COMMON_ACTIONS::flip( "pcbnew.flip", AS_CONTEXT, 'F', "Flip", "Flips selected item(s)" ); diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index d658f3c23d..9950ea65e9 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -374,6 +374,20 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) break; } + else if( evt->Category() == TC_COMMAND ) + { + if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) + { + newText->Rotate( newText->GetPosition(), getEditFrame()->GetRotationAngle() ); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) + { + newText->Flip( newText->GetPosition() ); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + } + else if( evt->IsClick( BUT_LEFT ) ) { newText->ClearFlags(); From 46db6ac182d52e7ef322b8637da1c8e67cfcf20f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 11 Feb 2014 13:22:30 +0100 Subject: [PATCH 011/134] Removed redundant fields DIMENSION::m_arrowD1O, m_arrowD2O, m_arrowG1O, m_arrowG2O (==m_crossBarO/F). Added DIMENSION::SetOrigin(), DIMENSION::SetEnd(), DIMENSION::GetOrigin(), DIMENSION::GetEnd(), DIMENSION::GetHeight(). Fixed flipping for DIMENSION class. Added an information that helps to understand roles of the points in the DIMENSION class. Some minor changes to PCB_PAINTER (mainly using const COLOR4D& for taking the result of GetColor() function). --- pcbnew/class_dimension.cpp | 93 ++++++++++++++++---------------- pcbnew/class_dimension.h | 77 ++++++++++++++++++++++++-- pcbnew/dimension.cpp | 31 +++-------- pcbnew/kicad_plugin.cpp | 16 +++--- pcbnew/legacy_plugin.cpp | 24 ++++----- pcbnew/pcb_painter.cpp | 45 +++++++--------- pcbnew/pcb_parser.cpp | 8 +-- pcbnew/plot_brditems_plotter.cpp | 8 +-- 8 files changed, 172 insertions(+), 130 deletions(-) diff --git a/pcbnew/class_dimension.cpp b/pcbnew/class_dimension.cpp index e49ca7e5dd..3a56797468 100644 --- a/pcbnew/class_dimension.cpp +++ b/pcbnew/class_dimension.cpp @@ -109,13 +109,9 @@ void DIMENSION::Copy( DIMENSION* source ) m_featureLineGF = source->m_featureLineGF; m_featureLineDO = source->m_featureLineDO; m_featureLineDF = source->m_featureLineDF; - m_arrowD1O = source->m_arrowD1O; m_arrowD1F = source->m_arrowD1F; - m_arrowD2O = source->m_arrowD2O; m_arrowD2F = source->m_arrowD2F; - m_arrowG1O = source->m_arrowG1O; m_arrowG1F = source->m_arrowG1F; - m_arrowG2O = source->m_arrowG2O; m_arrowG2F = source->m_arrowG2F; } @@ -129,13 +125,9 @@ void DIMENSION::Move( const wxPoint& offset ) m_featureLineGF += offset; m_featureLineDO += offset; m_featureLineDF += offset; - m_arrowG1O += offset; m_arrowG1F += offset; - m_arrowG2O += offset; m_arrowG2F += offset; - m_arrowD1O += offset; m_arrowD1F += offset; - m_arrowD2O += offset; m_arrowD2F += offset; } @@ -162,13 +154,9 @@ void DIMENSION::Rotate( const wxPoint& aRotCentre, double aAngle ) RotatePoint( &m_featureLineGF, aRotCentre, aAngle ); RotatePoint( &m_featureLineDO, aRotCentre, aAngle ); RotatePoint( &m_featureLineDF, aRotCentre, aAngle ); - RotatePoint( &m_arrowG1O, aRotCentre, aAngle ); RotatePoint( &m_arrowG1F, aRotCentre, aAngle ); - RotatePoint( &m_arrowG2O, aRotCentre, aAngle ); RotatePoint( &m_arrowG2F, aRotCentre, aAngle ); - RotatePoint( &m_arrowD1O, aRotCentre, aAngle ); RotatePoint( &m_arrowD1F, aRotCentre, aAngle ); - RotatePoint( &m_arrowD2O, aRotCentre, aAngle ); RotatePoint( &m_arrowD2F, aRotCentre, aAngle ); } @@ -190,15 +178,7 @@ void DIMENSION::Mirror( const wxPoint& axis_pos ) m_Text.SetTextPosition( newPos ); // invert angle - double newAngle = m_Text.GetOrientation(); - - if( newAngle >= 3600 ) - newAngle -= 3600; - - if( newAngle > 900 && newAngle < 2700 ) - newAngle -= 1800; - - m_Text.SetOrientation( newAngle ); + m_Text.SetOrientation( -m_Text.GetOrientation() ); INVERT( m_crossBarO.y ); INVERT( m_crossBarF.y ); @@ -206,17 +186,47 @@ void DIMENSION::Mirror( const wxPoint& axis_pos ) INVERT( m_featureLineGF.y ); INVERT( m_featureLineDO.y ); INVERT( m_featureLineDF.y ); - INVERT( m_arrowG1O.y ); INVERT( m_arrowG1F.y ); - INVERT( m_arrowG2O.y ); INVERT( m_arrowG2F.y ); - INVERT( m_arrowD1O.y ); INVERT( m_arrowD1F.y ); - INVERT( m_arrowD2O.y ); INVERT( m_arrowD2F.y ); } +void DIMENSION::SetOrigin( const wxPoint& aOrigin ) +{ + m_crossBarO = aOrigin; + m_featureLineGO = aOrigin; + + AdjustDimensionDetails(); +} + + +void DIMENSION::SetEnd( const wxPoint& aEnd ) +{ + m_crossBarF = aEnd; + m_featureLineDO = aEnd; + + AdjustDimensionDetails(); +} + + +void DIMENSION::SetHeight( double aHeight ) +{ + /* Calculating the direction of travel perpendicular to the selected axis. */ + double angle = GetAngle() + ( M_PI / 2 ); + + int dx = KiROUND( aHeight * cos( angle ) ); + int dy = KiROUND( aHeight * sin( angle ) ); + m_crossBarO.x = m_featureLineGO.x + dx; + m_crossBarO.y = m_featureLineGO.y + dy; + m_crossBarF.x = m_featureLineDO.x + dx; + m_crossBarF.y = m_featureLineDO.y + dy; + + AdjustDimensionDetails(); +} + + void DIMENSION::AdjustDimensionDetails( bool aDoNotChangeText ) { const int arrowz = DMils2iu( 500 ); // size of arrows @@ -271,30 +281,21 @@ void DIMENSION::AdjustDimensionDetails( bool aDoNotChangeText ) arrow_dw_Y = wxRound( arrowz * sin( angle_f ) ); } - m_arrowG1O.x = m_crossBarO.x; - m_arrowG1O.y = m_crossBarO.y; m_arrowG1F.x = m_crossBarO.x + arrow_up_X; m_arrowG1F.y = m_crossBarO.y + arrow_up_Y; - m_arrowG2O.x = m_crossBarO.x; - m_arrowG2O.y = m_crossBarO.y; m_arrowG2F.x = m_crossBarO.x + arrow_dw_X; m_arrowG2F.y = m_crossBarO.y + arrow_dw_Y; /* The right arrow is symmetrical to the left. * / = -\ and \ = -/ */ - m_arrowD1O.x = m_crossBarF.x; - m_arrowD1O.y = m_crossBarF.y; m_arrowD1F.x = m_crossBarF.x - arrow_dw_X; m_arrowD1F.y = m_crossBarF.y - arrow_dw_Y; - m_arrowD2O.x = m_crossBarF.x; - m_arrowD2O.y = m_crossBarF.y; m_arrowD2F.x = m_crossBarF.x - arrow_up_X; m_arrowD2F.y = m_crossBarF.y - arrow_up_Y; - m_featureLineGF.x = m_crossBarO.x + hx; m_featureLineGF.y = m_crossBarO.y + hy; @@ -358,13 +359,13 @@ void DIMENSION::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE mode_color, m_featureLineGF + offset, width, gcolor ); GRLine( panel->GetClipBox(), DC, m_featureLineDO + offset, m_featureLineDF + offset, width, gcolor ); - GRLine( panel->GetClipBox(), DC, m_arrowD1O + offset, + GRLine( panel->GetClipBox(), DC, m_crossBarF + offset, m_arrowD1F + offset, width, gcolor ); - GRLine( panel->GetClipBox(), DC, m_arrowD2O + offset, + GRLine( panel->GetClipBox(), DC, m_crossBarF + offset, m_arrowD2F + offset, width, gcolor ); - GRLine( panel->GetClipBox(), DC, m_arrowG1O + offset, + GRLine( panel->GetClipBox(), DC, m_crossBarO + offset, m_arrowG1F + offset, width, gcolor ); - GRLine( panel->GetClipBox(), DC, m_arrowG2O + offset, + GRLine( panel->GetClipBox(), DC, m_crossBarO + offset, m_arrowG2F + offset, width, gcolor ); break; @@ -375,13 +376,13 @@ void DIMENSION::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE mode_color, m_featureLineGF + offset, width, gcolor ); GRCSegm( panel->GetClipBox(), DC, m_featureLineDO + offset, m_featureLineDF + offset, width, gcolor ); - GRCSegm( panel->GetClipBox(), DC, m_arrowD1O + offset, + GRCSegm( panel->GetClipBox(), DC, m_crossBarF + offset, m_arrowD1F + offset, width, gcolor ); - GRCSegm( panel->GetClipBox(), DC, m_arrowD2O + offset, + GRCSegm( panel->GetClipBox(), DC, m_crossBarF + offset, m_arrowD2F + offset, width, gcolor ); - GRCSegm( panel->GetClipBox(), DC, m_arrowG1O + offset, + GRCSegm( panel->GetClipBox(), DC, m_crossBarO + offset, m_arrowG1F + offset, width, gcolor ); - GRCSegm( panel->GetClipBox(), DC, m_arrowG2O + offset, + GRCSegm( panel->GetClipBox(), DC, m_crossBarO + offset, m_arrowG2F + offset, width, gcolor ); break; } @@ -414,16 +415,16 @@ bool DIMENSION::HitTest( const wxPoint& aPosition ) if( TestSegmentHit( aPosition, m_featureLineDO, m_featureLineDF, dist_max ) ) return true; - if( TestSegmentHit( aPosition, m_arrowD1O, m_arrowD1F, dist_max ) ) + if( TestSegmentHit( aPosition, m_crossBarF, m_arrowD1F, dist_max ) ) return true; - if( TestSegmentHit( aPosition, m_arrowD2O, m_arrowD2F, dist_max ) ) + if( TestSegmentHit( aPosition, m_crossBarF, m_arrowD2F, dist_max ) ) return true; - if( TestSegmentHit( aPosition, m_arrowG1O, m_arrowG1F, dist_max ) ) + if( TestSegmentHit( aPosition, m_crossBarO, m_arrowG1F, dist_max ) ) return true; - if( TestSegmentHit( aPosition, m_arrowG2O, m_arrowG2F, dist_max ) ) + if( TestSegmentHit( aPosition, m_crossBarO, m_arrowG2F, dist_max ) ) return true; return false; diff --git a/pcbnew/class_dimension.h b/pcbnew/class_dimension.h index 1ea29bd8dc..2992991505 100644 --- a/pcbnew/class_dimension.h +++ b/pcbnew/class_dimension.h @@ -41,6 +41,24 @@ class TEXTE_PCB; class MSG_PANEL_ITEM; +/** + * Class DIMENSION + * + * For better understanding of the points that make a dimension: + * + * m_featureLineGO m_featureLineDO + * | | + * | | + * | | + * | m_arrowG2F m_arrowD2F | + * | / \ | + * m_crossBarO|/____________________________\|m_crossBarF + * |\ m_Text /| + * | \ / | + * | m_arrowG1F m_arrowD1F | + * | | + * m_featureLineGF m_featureLineDF + */ class DIMENSION : public BOARD_ITEM { int m_Width; @@ -52,14 +70,12 @@ class DIMENSION : public BOARD_ITEM public: -// private: These member should be private. they are public only due to legacy code +// TODO private: These member should be private. they are public only due to legacy code wxPoint m_crossBarO, m_crossBarF; wxPoint m_featureLineGO, m_featureLineGF; wxPoint m_featureLineDO, m_featureLineDF; - wxPoint m_arrowD1O, m_arrowD1F; - wxPoint m_arrowD2O, m_arrowD2F; - wxPoint m_arrowG1O, m_arrowG1F; - wxPoint m_arrowG2O, m_arrowG2F; + wxPoint m_arrowD1F, m_arrowD2F; + wxPoint m_arrowG1F, m_arrowG2F; DIMENSION( BOARD_ITEM* aParent ); @@ -88,6 +104,57 @@ public: int GetWidth() const { return m_Width; } void SetWidth( int aWidth ) { m_Width = aWidth; } + /** + * Function SetOrigin + * Sets a new origin of the crossbar line. All remaining lines are adjusted after that. + * @param aOrigin is the new point to be used as the new origin of the crossbar line. + */ + void SetOrigin( const wxPoint& aOrigin ); + + /** + * Function GetOrigin + * @return Origin of the crossbar line. + */ + const wxPoint& GetOrigin() const + { + return m_crossBarO; + } + + /** + * Function SetEnd + * Sets a new end of the crossbar line. All remaining lines are adjusted after that. + * @param aEnd is the new point to be used as the new end of the crossbar line. + */ + void SetEnd( const wxPoint& aEnd ); + + /** + * Function GetEnd + * @return End of the crossbar line. + */ + const wxPoint& GetEnd() + { + return m_crossBarF; + } + + /** + * Function SetHeight + * Sets the length of feature lines. + * @param aHeight is the new height. + */ + void SetHeight( double aHeight ); + + /** + * Function GetAngle + * Returns angle of the crossbar. + * @return Angle of the crossbar line. + */ + double GetAngle() const + { + wxPoint delta( m_featureLineDO - m_featureLineGO ); + + return atan2( delta.y, delta.x ); + } + /** * Function AdjustDimensionDetails * Calculate coordinates of segments used to draw the dimension. diff --git a/pcbnew/dimension.cpp b/pcbnew/dimension.cpp index 819c1a3110..71c1a14393 100644 --- a/pcbnew/dimension.cpp +++ b/pcbnew/dimension.cpp @@ -251,16 +251,9 @@ DIMENSION* PCB_EDIT_FRAME::EditDimension( DIMENSION* aDimension, wxDC* aDC ) aDimension = new DIMENSION( GetBoard() ); aDimension->SetFlags( IS_NEW ); - aDimension->SetLayer( getActiveLayer() ); - - aDimension->m_crossBarO = aDimension->m_crossBarF = pos; - aDimension->m_featureLineDO = aDimension->m_featureLineDF = pos; - aDimension->m_featureLineGO = aDimension->m_featureLineGF = pos; - aDimension->m_arrowG1O = aDimension->m_arrowG1F = pos; - aDimension->m_arrowG2O = aDimension->m_arrowG2F = pos; - aDimension->m_arrowD1O = aDimension->m_arrowD1F = pos; - aDimension->m_arrowD2O = aDimension->m_arrowD2F = pos; + aDimension->SetOrigin( pos ); + aDimension->SetEnd( pos ); aDimension->Text().SetSize( GetBoard()->GetDesignSettings().m_PcbTextSize ); int width = GetBoard()->GetDesignSettings().m_PcbTextWidth; @@ -330,24 +323,12 @@ static void BuildDimension( EDA_DRAW_PANEL* aPanel, wxDC* aDC, } else { - wxPoint delta; - int dx, dy; - double angle, depl; - delta = Dimension->m_featureLineDO - Dimension->m_featureLineGO; - /* Calculating the direction of travel perpendicular to the selected axis. */ - angle = atan2( delta.y, delta.x ) + (M_PI / 2); + double angle = Dimension->GetAngle() + (M_PI / 2); - delta = pos - Dimension->m_featureLineDO; - depl = ( delta.x * cos( angle ) ) + ( delta.y * sin( angle ) ); - dx = KiROUND( depl * cos( angle ) ); - dy = KiROUND( depl * sin( angle ) ); - Dimension->m_crossBarO.x = Dimension->m_featureLineGO.x + dx; - Dimension->m_crossBarO.y = Dimension->m_featureLineGO.y + dy; - Dimension->m_crossBarF.x = Dimension->m_featureLineDO.x + dx; - Dimension->m_crossBarF.y = Dimension->m_featureLineDO.y + dy; - - Dimension->AdjustDimensionDetails( ); + wxPoint delta = pos - Dimension->m_featureLineDO; + double depl = ( delta.x * cos( angle ) ) + ( delta.y * sin( angle ) ); + Dimension->SetHeight( depl ); } Dimension->Draw( aPanel, aDC, GR_XOR ); diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index 981b4644db..36342dcd47 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -747,26 +747,26 @@ void PCB_IO::format( DIMENSION* aDimension, int aNestLevel ) const FMT_IU( aDimension->m_crossBarF.y ).c_str() ); m_out->Print( aNestLevel+1, "(arrow1a (pts (xy %s %s) (xy %s %s)))\n", - FMT_IU( aDimension->m_arrowD1O.x ).c_str(), - FMT_IU( aDimension->m_arrowD1O.y ).c_str(), + FMT_IU( aDimension->m_crossBarF.x ).c_str(), + FMT_IU( aDimension->m_crossBarF.y ).c_str(), FMT_IU( aDimension->m_arrowD1F.x ).c_str(), FMT_IU( aDimension->m_arrowD1F.y ).c_str() ); m_out->Print( aNestLevel+1, "(arrow1b (pts (xy %s %s) (xy %s %s)))\n", - FMT_IU( aDimension->m_arrowD2O.x ).c_str(), - FMT_IU( aDimension->m_arrowD2O.y ).c_str(), + FMT_IU( aDimension->m_crossBarF.x ).c_str(), + FMT_IU( aDimension->m_crossBarF.y ).c_str(), FMT_IU( aDimension->m_arrowD2F.x ).c_str(), FMT_IU( aDimension->m_arrowD2F.y ).c_str() ); m_out->Print( aNestLevel+1, "(arrow2a (pts (xy %s %s) (xy %s %s)))\n", - FMT_IU( aDimension->m_arrowG1O.x ).c_str(), - FMT_IU( aDimension->m_arrowG1O.y ).c_str(), + FMT_IU( aDimension->m_crossBarO.x ).c_str(), + FMT_IU( aDimension->m_crossBarO.y ).c_str(), FMT_IU( aDimension->m_arrowG1F.x ).c_str(), FMT_IU( aDimension->m_arrowG1F.y ).c_str() ); m_out->Print( aNestLevel+1, "(arrow2b (pts (xy %s %s) (xy %s %s)))\n", - FMT_IU( aDimension->m_arrowG2O.x ).c_str(), - FMT_IU( aDimension->m_arrowG2O.y ).c_str(), + FMT_IU( aDimension->m_crossBarO.x ).c_str(), + FMT_IU( aDimension->m_crossBarO.y ).c_str(), FMT_IU( aDimension->m_arrowG2F.x ).c_str(), FMT_IU( aDimension->m_arrowG2F.y ).c_str() ); diff --git a/pcbnew/legacy_plugin.cpp b/pcbnew/legacy_plugin.cpp index 0ab7069d3d..cdb598ad27 100644 --- a/pcbnew/legacy_plugin.cpp +++ b/pcbnew/legacy_plugin.cpp @@ -2588,8 +2588,8 @@ void LEGACY_PLUGIN::loadDIMENSION() BIU arrowD1Fx = biuParse( data, &data ); BIU arrowD1Fy = biuParse( data ); - dim->m_arrowD1O.x = arrowD10x; - dim->m_arrowD1O.y = arrowD10y; + dim->m_crossBarF.x = arrowD10x; + dim->m_crossBarF.y = arrowD10y; dim->m_arrowD1F.x = arrowD1Fx; dim->m_arrowD1F.y = arrowD1Fy; (void) ignore; @@ -2605,8 +2605,8 @@ void LEGACY_PLUGIN::loadDIMENSION() BIU arrowD2Fx = biuParse( data, &data ); BIU arrowD2Fy = biuParse( data, &data ); - dim->m_arrowD2O.x = arrowD2Ox; - dim->m_arrowD2O.y = arrowD2Oy; + dim->m_crossBarF.x = arrowD2Ox; + dim->m_crossBarF.y = arrowD2Oy; dim->m_arrowD2F.x = arrowD2Fx; dim->m_arrowD2F.y = arrowD2Fy; (void) ignore; @@ -2621,8 +2621,8 @@ void LEGACY_PLUGIN::loadDIMENSION() BIU arrowG1Fx = biuParse( data, &data ); BIU arrowG1Fy = biuParse( data, &data ); - dim->m_arrowG1O.x = arrowG1Ox; - dim->m_arrowG1O.y = arrowG1Oy; + dim->m_crossBarO.x = arrowG1Ox; + dim->m_crossBarO.y = arrowG1Oy; dim->m_arrowG1F.x = arrowG1Fx; dim->m_arrowG1F.y = arrowG1Fy; (void) ignore; @@ -2637,8 +2637,8 @@ void LEGACY_PLUGIN::loadDIMENSION() BIU arrowG2Fx = biuParse( data, &data ); BIU arrowG2Fy = biuParse( data, &data ); - dim->m_arrowG2O.x = arrowG2Ox; - dim->m_arrowG2O.y = arrowG2Oy; + dim->m_crossBarO.x = arrowG2Ox; + dim->m_crossBarO.y = arrowG2Oy; dim->m_arrowG2F.x = arrowG2Fx; dim->m_arrowG2F.y = arrowG2Fy; (void) ignore; @@ -3794,22 +3794,22 @@ void LEGACY_PLUGIN::saveDIMENTION( const DIMENSION* me ) const fmtBIU( me->GetWidth() ).c_str() ); fprintf( m_fp, "S1 %d %s %s %s\n", S_SEGMENT, - fmtBIUPair( me->m_arrowD1O.x, me->m_arrowD1O.y ).c_str(), + fmtBIUPair( me->m_crossBarF.x, me->m_crossBarF.y ).c_str(), fmtBIUPair( me->m_arrowD1F.x, me->m_arrowD1F.y ).c_str(), fmtBIU( me->GetWidth() ).c_str() ); fprintf( m_fp, "S2 %d %s %s %s\n", S_SEGMENT, - fmtBIUPair( me->m_arrowD2O.x, me->m_arrowD2O.y ).c_str(), + fmtBIUPair( me->m_crossBarF.x, me->m_crossBarF.y ).c_str(), fmtBIUPair( me->m_arrowD2F.x, me->m_arrowD2F.y ).c_str(), fmtBIU( me->GetWidth() ).c_str() ); fprintf( m_fp, "S3 %d %s %s %s\n", S_SEGMENT, - fmtBIUPair( me->m_arrowG1O.x, me->m_arrowG1O.y ).c_str(), + fmtBIUPair( me->m_crossBarO.x, me->m_crossBarO.y ).c_str(), fmtBIUPair( me->m_arrowG1F.x, me->m_arrowG1F.y ).c_str(), fmtBIU( me->GetWidth() ).c_str() ); fprintf( m_fp, "S4 %d %s %s %s\n", S_SEGMENT, - fmtBIUPair( me->m_arrowG2O.x, me->m_arrowG2O.y ).c_str(), + fmtBIUPair( me->m_crossBarO.x, me->m_crossBarO.y ).c_str(), fmtBIUPair( me->m_arrowG2F.x, me->m_arrowG2F.y ).c_str(), fmtBIU( me->GetWidth() ).c_str() ); diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index b7f9ff0cc3..93414fc3e0 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -262,7 +262,6 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer ) VECTOR2D end( aTrack->GetEnd() ); int width = aTrack->GetWidth(); int netNumber = aTrack->GetNet(); - COLOR4D color; if( m_pcbSettings->m_netNamesOnTracks && IsNetnameLayer( aLayer ) ) { @@ -286,7 +285,7 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer ) double textSize = std::min( static_cast( width ), length / netName.length() ); // Set a proper color for the label - color = m_pcbSettings->GetColor( aTrack, aTrack->GetLayer() ); + const COLOR4D& color = m_pcbSettings->GetColor( aTrack, aTrack->GetLayer() ); COLOR4D labelColor = m_pcbSettings->GetColor( NULL, aLayer ); if( color.GetBrightness() > 0.5 ) @@ -307,7 +306,7 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer ) else if( IsCopperLayer( aLayer )) { // Draw a regular track - color = m_pcbSettings->GetColor( aTrack, aLayer ); + const COLOR4D& color = m_pcbSettings->GetColor( aTrack, aLayer ); m_gal->SetStrokeColor( color ); m_gal->SetIsStroke( true ); @@ -332,7 +331,6 @@ void PCB_PAINTER::draw( const SEGVIA* aVia, int aLayer ) { VECTOR2D center( aVia->GetStart() ); double radius; - COLOR4D color; // Choose drawing settings depending on if we are drawing via's pad or hole if( aLayer == ITEM_GAL_LAYER( VIAS_VISIBLE ) ) @@ -346,7 +344,7 @@ void PCB_PAINTER::draw( const SEGVIA* aVia, int aLayer ) else return; - color = m_pcbSettings->GetColor( aVia, aLayer ); + const COLOR4D& color = m_pcbSettings->GetColor( aVia, aLayer ); if( m_pcbSettings->m_sketchModeSelect[VIAS_VISIBLE] ) { @@ -370,7 +368,6 @@ void PCB_PAINTER::draw( const SEGVIA* aVia, int aLayer ) void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer ) { - COLOR4D color; VECTOR2D size; VECTOR2D position( aPad->GetPosition() ); PAD_SHAPE_T shape; @@ -385,7 +382,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer ) if( m_pcbSettings->m_netNamesOnPads || m_pcbSettings->m_padNumbers ) { // Min char count to calculate string size - #define MIN_CHAR_COUNT 3 + const int MIN_CHAR_COUNT = 3; bool displayNetname = ( m_pcbSettings->m_netNamesOnPads && !aPad->GetNetname().empty() ); @@ -405,9 +402,6 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer ) // If the text is displayed on a symmetrical pad, do not rotate it orientation = 0.0; } - else - { - } // Font size limits if( size > maxSize ) @@ -428,7 +422,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer ) m_gal->SetMirrored( false ); // Set a proper color for the label - color = m_pcbSettings->GetColor( aPad, aPad->GetLayer() ); + const COLOR4D& color = m_pcbSettings->GetColor( aPad, aPad->GetLayer() ); COLOR4D labelColor = m_pcbSettings->GetColor( NULL, aLayer ); if( color.GetBrightness() > 0.5 ) @@ -456,8 +450,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer ) VECTOR2D namesize( tsize, tsize ); m_gal->SetGlyphSize( namesize ); m_gal->SetLineWidth( namesize.x / 12.0 ); - m_gal->StrokeText( std::wstring( aPad->GetShortNetname().wc_str() ), - textpos, 0.0 ); + m_gal->StrokeText( aPad->GetShortNetname(), textpos, 0.0 ); } if( m_pcbSettings->m_padNumbers ) @@ -474,7 +467,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer ) m_gal->SetGlyphSize( numsize ); m_gal->SetLineWidth( numsize.x / 12.0 ); - m_gal->StrokeText( std::wstring( aPad->GetPadName().wc_str() ), textpos, 0.0 ); + m_gal->StrokeText( aPad->GetPadName(), textpos, 0.0 ); } m_gal->Restore(); @@ -483,7 +476,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer ) } // Pad drawing - color = m_pcbSettings->GetColor( aPad, aLayer ); + const COLOR4D& color = m_pcbSettings->GetColor( aPad, aLayer ); if( m_pcbSettings->m_sketchModeSelect[PADS_VISIBLE] ) { // Outline mode @@ -628,7 +621,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer ) void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment ) { - COLOR4D color = m_pcbSettings->GetColor( aSegment, aSegment->GetLayer() ); + const COLOR4D& color = m_pcbSettings->GetColor( aSegment, aSegment->GetLayer() ); m_gal->SetIsFill( false ); m_gal->SetIsStroke( true ); @@ -708,7 +701,7 @@ void PCB_PAINTER::draw( const TEXTE_PCB* aText, int aLayer ) if( aText->GetText().Length() == 0 ) return; - COLOR4D strokeColor = m_pcbSettings->GetColor( aText, aText->GetLayer() ); + const COLOR4D& strokeColor = m_pcbSettings->GetColor( aText, aText->GetLayer() ); VECTOR2D position( aText->GetTextPosition().x, aText->GetTextPosition().y ); double orientation = aText->GetOrientation() * M_PI / 1800.0; @@ -724,7 +717,7 @@ void PCB_PAINTER::draw( const TEXTE_MODULE* aText, int aLayer ) if( aText->GetLength() == 0 ) return; - COLOR4D strokeColor = m_pcbSettings->GetColor( aText, aLayer ); + const COLOR4D& strokeColor = m_pcbSettings->GetColor( aText, aLayer ); VECTOR2D position( aText->GetTextPosition().x, aText->GetTextPosition().y ); double orientation = aText->GetDrawRotation() * M_PI / 1800.0; @@ -737,7 +730,7 @@ void PCB_PAINTER::draw( const TEXTE_MODULE* aText, int aLayer ) void PCB_PAINTER::draw( const ZONE_CONTAINER* aZone ) { - COLOR4D color = m_pcbSettings->GetColor( aZone, aZone->GetLayer() ); + const COLOR4D& color = m_pcbSettings->GetColor( aZone, aZone->GetLayer() ); std::deque corners; PCB_RENDER_SETTINGS::DisplayZonesMode displayMode = m_pcbSettings->m_displayZoneMode; @@ -810,7 +803,7 @@ void PCB_PAINTER::draw( const ZONE_CONTAINER* aZone ) void PCB_PAINTER::draw( const DIMENSION* aDimension, int aLayer ) { - COLOR4D strokeColor = m_pcbSettings->GetColor( aDimension, aLayer ); + const COLOR4D& strokeColor = m_pcbSettings->GetColor( aDimension, aLayer ); m_gal->SetStrokeColor( strokeColor ); m_gal->SetIsFill( false ); @@ -823,10 +816,10 @@ void PCB_PAINTER::draw( const DIMENSION* aDimension, int aLayer ) VECTOR2D( aDimension->m_featureLineGF ) ); m_gal->DrawLine( VECTOR2D( aDimension->m_featureLineDO ), VECTOR2D( aDimension->m_featureLineDF ) ); - m_gal->DrawLine( VECTOR2D( aDimension->m_arrowD1O ), VECTOR2D( aDimension->m_arrowD1F ) ); - m_gal->DrawLine( VECTOR2D( aDimension->m_arrowD2O ), VECTOR2D( aDimension->m_arrowD2F ) ); - m_gal->DrawLine( VECTOR2D( aDimension->m_arrowG1O ), VECTOR2D( aDimension->m_arrowG1F ) ); - m_gal->DrawLine( VECTOR2D( aDimension->m_arrowG2O ), VECTOR2D( aDimension->m_arrowG2F ) ); + m_gal->DrawLine( VECTOR2D( aDimension->m_crossBarF ), VECTOR2D( aDimension->m_arrowD1F ) ); + m_gal->DrawLine( VECTOR2D( aDimension->m_crossBarF ), VECTOR2D( aDimension->m_arrowD2F ) ); + m_gal->DrawLine( VECTOR2D( aDimension->m_crossBarO ), VECTOR2D( aDimension->m_arrowG1F ) ); + m_gal->DrawLine( VECTOR2D( aDimension->m_crossBarO ), VECTOR2D( aDimension->m_arrowG2F ) ); // Draw text TEXTE_PCB& text = aDimension->Text(); @@ -835,13 +828,13 @@ void PCB_PAINTER::draw( const DIMENSION* aDimension, int aLayer ) m_gal->SetLineWidth( text.GetThickness() ); m_gal->SetTextAttributes( &text ); - m_gal->StrokeText( std::wstring( text.GetText().wc_str() ), position, orientation ); + m_gal->StrokeText( text.GetText(), position, orientation ); } void PCB_PAINTER::draw( const PCB_TARGET* aTarget ) { - COLOR4D strokeColor = m_pcbSettings->GetColor( aTarget, aTarget->GetLayer() ); + const COLOR4D& strokeColor = m_pcbSettings->GetColor( aTarget, aTarget->GetLayer() ); VECTOR2D position( aTarget->GetPosition() ); double size, radius; diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index f68743b741..33bfd5e587 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -1476,7 +1476,7 @@ DIMENSION* PCB_PARSER::parseDIMENSION() throw( IO_ERROR, PARSE_ERROR ) if( token != T_pts ) Expecting( T_pts ); - parseXY( &dimension->m_arrowD1O.x, &dimension->m_arrowD1O.y ); + parseXY( &dimension->m_crossBarF.x, &dimension->m_crossBarF.y ); parseXY( &dimension->m_arrowD1F.x, &dimension->m_arrowD1F.y ); NeedRIGHT(); NeedRIGHT(); @@ -1489,7 +1489,7 @@ DIMENSION* PCB_PARSER::parseDIMENSION() throw( IO_ERROR, PARSE_ERROR ) if( token != T_pts ) Expecting( T_pts ); - parseXY( &dimension->m_arrowD2O.x, &dimension->m_arrowD2O.y ); + parseXY( &dimension->m_crossBarF.x, &dimension->m_crossBarF.y ); parseXY( &dimension->m_arrowD2F.x, &dimension->m_arrowD2F.y ); NeedRIGHT(); NeedRIGHT(); @@ -1502,7 +1502,7 @@ DIMENSION* PCB_PARSER::parseDIMENSION() throw( IO_ERROR, PARSE_ERROR ) if( token != T_pts ) Expecting( T_pts ); - parseXY( &dimension->m_arrowG1O.x, &dimension->m_arrowG1O.y ); + parseXY( &dimension->m_crossBarO.x, &dimension->m_crossBarO.y ); parseXY( &dimension->m_arrowG1F.x, &dimension->m_arrowG1F.y ); NeedRIGHT(); NeedRIGHT(); @@ -1515,7 +1515,7 @@ DIMENSION* PCB_PARSER::parseDIMENSION() throw( IO_ERROR, PARSE_ERROR ) if( token != T_pts ) Expecting( T_pts ); - parseXY( &dimension->m_arrowG2O.x, &dimension->m_arrowG2O.y ); + parseXY( &dimension->m_crossBarO.x, &dimension->m_crossBarO.y ); parseXY( &dimension->m_arrowG2F.x, &dimension->m_arrowG2F.y ); NeedRIGHT(); NeedRIGHT(); diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp index 5cc2e4fd5c..8e891fbe8e 100644 --- a/pcbnew/plot_brditems_plotter.cpp +++ b/pcbnew/plot_brditems_plotter.cpp @@ -274,19 +274,19 @@ void BRDITEMS_PLOTTER::PlotDimension( DIMENSION* aDim ) draw.SetEnd( aDim->m_featureLineDF ); PlotDrawSegment( &draw ); - draw.SetStart( aDim->m_arrowD1O ); + draw.SetStart( aDim->m_crossBarF ); draw.SetEnd( aDim->m_arrowD1F ); PlotDrawSegment( &draw ); - draw.SetStart( aDim->m_arrowD2O ); + draw.SetStart( aDim->m_crossBarF ); draw.SetEnd( aDim->m_arrowD2F ); PlotDrawSegment( &draw ); - draw.SetStart( aDim->m_arrowG1O ); + draw.SetStart( aDim->m_crossBarO ); draw.SetEnd( aDim->m_arrowG1F ); PlotDrawSegment( &draw ); - draw.SetStart( aDim->m_arrowG2O ); + draw.SetStart( aDim->m_crossBarO ); draw.SetEnd( aDim->m_arrowG2F ); PlotDrawSegment( &draw ); } From ae5fa232853145599fe69296a7730bc0bc3f5d3f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 11 Feb 2014 14:38:44 +0100 Subject: [PATCH 012/134] Added DIMENSION drawing tool. --- pcbnew/tools/common_actions.cpp | 4 + pcbnew/tools/common_actions.h | 3 + pcbnew/tools/drawing_tool.cpp | 142 ++++++++++++++++++++++++++++++++ pcbnew/tools/drawing_tool.h | 2 + pcbnew/tools/pcb_tools.cpp | 1 + 5 files changed, 152 insertions(+) diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 0878657b1f..4649123d24 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -72,3 +72,7 @@ TOOL_ACTION COMMON_ACTIONS::drawArc( "pcbnew.InteractiveDrawing.arc", TOOL_ACTION COMMON_ACTIONS::drawText( "pcbnew.InteractiveDrawing.text", AS_GLOBAL, 'T', "Add a text", "Add a text" ); + +TOOL_ACTION COMMON_ACTIONS::drawDimension( "pcbnew.InteractiveDrawing.dimension", + AS_GLOBAL, 'X', + "Add a dimension", "Add a dimension" ); diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 992d9cbdf8..c2e350a67d 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -68,4 +68,7 @@ public: /// Activation of the drawing tool (text) static TOOL_ACTION drawText; + + /// Activation of the drawing tool (dimension) + static TOOL_ACTION drawDimension; }; diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 9950ea65e9..bfe59af214 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -350,6 +351,11 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) // Init the new item attributes TEXTE_PCB* newText = getEditFrame()->CreateTextePcb( NULL ); + if( newText == NULL ) + { + setTransitions(); + return 0; + } // Add a VIEW_GROUP that serves as a preview for the new item KIGFX::VIEW_GROUP preview( view ); @@ -417,10 +423,146 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) } +int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) +{ + m_continous = false; + + int step = 0; + + KIGFX::VIEW* view = getView(); + KIGFX::VIEW_CONTROLS* controls = getViewControls(); + BOARD* board = getModel( PCB_T ); + DIMENSION* dimension = new DIMENSION( board ); + + // Init the new item attributes + dimension->Text().SetSize( board->GetDesignSettings().m_PcbTextSize ); + int width = board->GetDesignSettings().m_PcbTextWidth; + int maxthickness = Clamp_Text_PenSize( width, dimension->Text().GetSize() ); + + if( width > maxthickness ) + width = maxthickness; + + dimension->Text().SetThickness( width ); + dimension->SetWidth( width ); + dimension->SetFlags( IS_NEW ); + dimension->AdjustDimensionDetails(); + + // Add a VIEW_GROUP that serves as a preview for the new item + KIGFX::VIEW_GROUP preview( view ); + view->Add( &preview ); + + controls->ShowCursor( true ); + controls->SetSnapping( true ); + + Activate(); + + // Main loop: keep receiving events + while( OPT_TOOL_EVENT evt = Wait() ) + { + VECTOR2D cursorPos = view->ToWorld( controls->GetCursorPosition() ); + + if( evt->IsCancel() ) + { + delete dimension; + break; + } + + else if( evt->IsKeyUp() ) + { + int width = dimension->GetWidth(); + + // Modify the new item width + if( evt->KeyCode() == '-' && width > WIDTH_STEP ) + dimension->SetWidth( width - WIDTH_STEP ); + else if( evt->KeyCode() == '=' ) + dimension->SetWidth( width + WIDTH_STEP ); + + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + + else if( evt->IsClick( BUT_LEFT ) ) + { + switch( step ) + { + case 0: + { + LAYER_NUM layer = getEditFrame()->GetScreen()->m_Active_Layer; + + if( IsCopperLayer( layer ) ) + { + DisplayInfoMessage( NULL, _( "Graphic not allowed on Copper layers" ) ); + --step; + } + else + { + controls->SetAutoPan( true ); + + dimension->SetLayer( layer ); + dimension->SetOrigin( wxPoint( cursorPos.x, cursorPos.y ) ); + + preview.Add( dimension ); + } + } + break; + + case 2: + { + if( wxPoint( cursorPos.x, cursorPos.y ) != dimension->GetPosition() ) + { + view->Add( dimension ); + board->Add( dimension ); + dimension->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + } + break; + } + + if( ++step == 3 ) + break; + } + + else if( evt->IsMotion() ) + { + switch( step ) + { + case 1: + dimension->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); + break; + + case 2: + { + /* Calculating the direction of travel perpendicular to the selected axis. */ + double angle = dimension->GetAngle() + ( M_PI / 2 ); + + wxPoint pos( cursorPos.x, cursorPos.y ); + wxPoint delta( pos - dimension->m_featureLineDO ); + double height = ( delta.x * cos( angle ) ) + ( delta.y * sin( angle ) ); + dimension->SetHeight( height ); + } + break; + } + + // Show a preview of the item + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + } + + controls->ShowCursor( false ); + controls->SetSnapping( false ); + controls->SetAutoPan( false ); + view->Remove( &preview ); + + setTransitions(); + + return 0; +} + + void DRAWING_TOOL::setTransitions() { Go( &DRAWING_TOOL::DrawLine, COMMON_ACTIONS::drawLine.MakeEvent() ); Go( &DRAWING_TOOL::DrawCircle, COMMON_ACTIONS::drawCircle.MakeEvent() ); Go( &DRAWING_TOOL::DrawArc, COMMON_ACTIONS::drawArc.MakeEvent() ); Go( &DRAWING_TOOL::DrawText, COMMON_ACTIONS::drawText.MakeEvent() ); + Go( &DRAWING_TOOL::DrawDimension, COMMON_ACTIONS::drawDimension.MakeEvent() ); } diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index 4e969860db..3af4c4fee7 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -57,6 +57,8 @@ public: int DrawText( TOOL_EVENT& aEvent ); + int DrawDimension( TOOL_EVENT& aEvent ); + private: ///> Starts drawing a selected shape. int draw( STROKE_T aShape ); diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index 73f9f14a5f..e05d294a11 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -59,6 +59,7 @@ void PCB_EDIT_FRAME::setupTools() m_toolManager->RegisterAction( &COMMON_ACTIONS::drawCircle ); m_toolManager->RegisterAction( &COMMON_ACTIONS::drawArc ); m_toolManager->RegisterAction( &COMMON_ACTIONS::drawText ); + m_toolManager->RegisterAction( &COMMON_ACTIONS::drawDimension ); // Register tools m_toolManager->RegisterTool( new SELECTION_TOOL ); From c09e8ade2a729ec43f845da015c65f08f2058b9f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 11 Feb 2014 14:39:14 +0100 Subject: [PATCH 013/134] 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 e43b5f7c0fb78c1d3a8b64442bbc38694eb29d03 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 11 Feb 2014 15:01:49 +0100 Subject: [PATCH 014/134] Small fix for crippled polylines containing 0 points. --- common/gal/opengl/opengl_gal.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index f9cccbd365..a665377e73 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -466,10 +466,13 @@ void OPENGL_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEn void OPENGL_GAL::DrawPolyline( std::deque& aPointList ) { + if( aPointList.empty() ) + return; + std::deque::const_iterator it = aPointList.begin(); // Start from the second point - for( it++; it != aPointList.end(); it++ ) + for( ++it; it != aPointList.end(); ++it ) { const VECTOR2D startEndVector = ( *it - *( it - 1 ) ); double lineAngle = startEndVector.Angle(); From 87d3458ea9c6bf8d5807b4b6276faced82c4f382 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 11 Feb 2014 17:15:33 +0100 Subject: [PATCH 015/134] Added PCB_TARGET placing tool. --- pcbnew/target_edit.cpp | 6 ++- pcbnew/tools/common_actions.cpp | 4 ++ pcbnew/tools/common_actions.h | 3 ++ pcbnew/tools/drawing_tool.cpp | 73 +++++++++++++++++++++++++++++++++ pcbnew/tools/drawing_tool.h | 2 + pcbnew/tools/pcb_tools.cpp | 1 + 6 files changed, 87 insertions(+), 2 deletions(-) diff --git a/pcbnew/target_edit.cpp b/pcbnew/target_edit.cpp index dba25a86d2..75989719c9 100644 --- a/pcbnew/target_edit.cpp +++ b/pcbnew/target_edit.cpp @@ -127,7 +127,8 @@ void TARGET_PROPERTIES_DIALOG_EDITOR::OnCancelClick( wxCommandEvent& event ) */ void TARGET_PROPERTIES_DIALOG_EDITOR::OnOkClick( wxCommandEvent& event ) { - m_Target->Draw( m_Parent->GetCanvas(), m_DC, GR_XOR ); + if( m_DC ) + m_Target->Draw( m_Parent->GetCanvas(), m_DC, GR_XOR ); // Save old item in undo list, if is is not currently edited (will be later if so) if( m_Target->GetFlags() == 0 ) @@ -145,7 +146,8 @@ void TARGET_PROPERTIES_DIALOG_EDITOR::OnOkClick( wxCommandEvent& event ) m_Target->SetShape( m_TargetShape->GetSelection() ? 1 : 0 ); - m_Target->Draw( m_Parent->GetCanvas(), m_DC, ( m_Target->IsMoving() ) ? GR_XOR : GR_OR ); + if( m_DC ) + m_Target->Draw( m_Parent->GetCanvas(), m_DC, ( m_Target->IsMoving() ) ? GR_XOR : GR_OR ); m_Parent->OnModify(); EndModal( 1 ); diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 4649123d24..de860ccc06 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -76,3 +76,7 @@ TOOL_ACTION COMMON_ACTIONS::drawText( "pcbnew.InteractiveDrawing.text", TOOL_ACTION COMMON_ACTIONS::drawDimension( "pcbnew.InteractiveDrawing.dimension", AS_GLOBAL, 'X', "Add a dimension", "Add a dimension" ); + +TOOL_ACTION COMMON_ACTIONS::placeTarget( "pcbnew.InteractiveDrawing.placeTarget", + AS_GLOBAL, 'C', + "Add layer alignment target", "Add layer alignment target" ); diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index c2e350a67d..732aa22e7d 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -71,4 +71,7 @@ public: /// Activation of the drawing tool (dimension) static TOOL_ACTION drawDimension; + + /// Activation of the drawing tool (placing a TARGET) + static TOOL_ACTION placeTarget; }; diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index bfe59af214..28c287ea7a 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -558,6 +559,77 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) } +int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) +{ + KIGFX::VIEW* view = getView(); + KIGFX::VIEW_CONTROLS* controls = getViewControls(); + BOARD* board = getModel( PCB_T ); + PCB_TARGET* target = new PCB_TARGET( board ); + + // Init the new item attributes + target->SetLayer( EDGE_N ); + target->SetWidth( board->GetDesignSettings().m_EdgeSegmentWidth ); + target->SetSize( Millimeter2iu( 5 ) ); + + // Add a VIEW_GROUP that serves as a preview for the new item + KIGFX::VIEW_GROUP preview( view ); + preview.Add( target ); + view->Add( &preview ); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + + controls->SetSnapping( true ); + + Activate(); + + // Main loop: keep receiving events + while( OPT_TOOL_EVENT evt = Wait() ) + { + VECTOR2D cursorPos = view->ToWorld( controls->GetCursorPosition() ); + + if( evt->IsCancel() ) + { + delete target; + break; + } + + else if( evt->IsKeyUp() ) + { + int width = target->GetWidth(); + + // Modify the new item width + if( evt->KeyCode() == '-' && width > WIDTH_STEP ) + target->SetWidth( width - WIDTH_STEP ); + else if( evt->KeyCode() == '=' ) + target->SetWidth( width + WIDTH_STEP ); + + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + + else if( evt->IsClick( BUT_LEFT ) ) + { + view->Add( target ); + board->Add( target ); + target->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + break; + } + + else if( evt->IsMotion() ) + { + target->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + } + + controls->SetSnapping( false ); + controls->SetAutoPan( false ); + view->Remove( &preview ); + + setTransitions(); + + return 0; +} + + void DRAWING_TOOL::setTransitions() { Go( &DRAWING_TOOL::DrawLine, COMMON_ACTIONS::drawLine.MakeEvent() ); @@ -565,4 +637,5 @@ void DRAWING_TOOL::setTransitions() Go( &DRAWING_TOOL::DrawArc, COMMON_ACTIONS::drawArc.MakeEvent() ); Go( &DRAWING_TOOL::DrawText, COMMON_ACTIONS::drawText.MakeEvent() ); Go( &DRAWING_TOOL::DrawDimension, COMMON_ACTIONS::drawDimension.MakeEvent() ); + Go( &DRAWING_TOOL::PlaceTarget, COMMON_ACTIONS::placeTarget.MakeEvent() ); } diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index 3af4c4fee7..c34109a2cf 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -59,6 +59,8 @@ public: int DrawDimension( TOOL_EVENT& aEvent ); + int PlaceTarget( TOOL_EVENT& aEvent ); + private: ///> Starts drawing a selected shape. int draw( STROKE_T aShape ); diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index e05d294a11..9202ddb4b5 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -60,6 +60,7 @@ void PCB_EDIT_FRAME::setupTools() m_toolManager->RegisterAction( &COMMON_ACTIONS::drawArc ); m_toolManager->RegisterAction( &COMMON_ACTIONS::drawText ); m_toolManager->RegisterAction( &COMMON_ACTIONS::drawDimension ); + m_toolManager->RegisterAction( &COMMON_ACTIONS::placeTarget ); // Register tools m_toolManager->RegisterTool( new SELECTION_TOOL ); From ba1867fe0e96be4c380c30f214399ca7c32a640d Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 12 Feb 2014 18:04:27 +0100 Subject: [PATCH 016/134] Merged fix from the selection_tool branch. --- 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 cdb598ad27..97777200ea 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 45c5a3de7feb9e64659baff0884c35df16d92e2d Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 13 Feb 2014 12:46:39 +0100 Subject: [PATCH 017/134] Placing modules with a minor bug. --- pcbnew/pcbframe.cpp | 19 +------ pcbnew/tools/common_actions.cpp | 4 ++ pcbnew/tools/common_actions.h | 3 ++ pcbnew/tools/drawing_tool.cpp | 92 +++++++++++++++++++++++++++++++-- pcbnew/tools/drawing_tool.h | 2 + pcbnew/tools/pcb_tools.cpp | 1 + 6 files changed, 100 insertions(+), 21 deletions(-) diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 15822a9b17..0331d6b326 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -569,24 +569,7 @@ void PCB_EDIT_FRAME::ViewReloadBoard( const BOARD* aBoard ) const // 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() ); - - // Add the module itself + module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), view ) ); view->Add( module ); } diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index de860ccc06..f3ea912d31 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -80,3 +80,7 @@ TOOL_ACTION COMMON_ACTIONS::drawDimension( "pcbnew.InteractiveDrawing.dimension" TOOL_ACTION COMMON_ACTIONS::placeTarget( "pcbnew.InteractiveDrawing.placeTarget", AS_GLOBAL, 'C', "Add layer alignment target", "Add layer alignment target" ); + +TOOL_ACTION COMMON_ACTIONS::placeModule( "pcbnew.InteractiveDrawing.placeModule", + AS_GLOBAL, 'V', + "Add modules", "Add modules" ); diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 732aa22e7d..fa07c45ce4 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -74,4 +74,7 @@ public: /// Activation of the drawing tool (placing a TARGET) static TOOL_ACTION placeTarget; + + /// Activation of the drawing tool (placing a MODULE) + static TOOL_ACTION placeModule; }; diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 28c287ea7a..b9433db085 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -26,16 +26,20 @@ #include "common_actions.h" #include +#include + #include #include +#include +#include + #include #include #include #include #include -#include -#include -#include +#include +#include // TODO to be removed if we do not need the flags DRAWING_TOOL::DRAWING_TOOL() : TOOL_INTERACTIVE( "pcbnew.InteractiveDrawing" ) @@ -570,6 +574,8 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) target->SetLayer( EDGE_N ); target->SetWidth( board->GetDesignSettings().m_EdgeSegmentWidth ); target->SetSize( Millimeter2iu( 5 ) ); + VECTOR2D cursorPos = view->ToWorld( controls->GetCursorPosition() ); + target->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); // Add a VIEW_GROUP that serves as a preview for the new item KIGFX::VIEW_GROUP preview( view ); @@ -630,6 +636,85 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) } +int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) +{ + KIGFX::VIEW* view = getView(); + KIGFX::VIEW_CONTROLS* controls = getViewControls(); + BOARD* board = getModel( PCB_T ); + PCB_EDIT_FRAME* editFrame = getEditFrame(); + MODULE* module = editFrame->LoadModuleFromLibrary( wxEmptyString, + editFrame->GetFootprintLibraryTable(), true, NULL ); + if( module == NULL ) + { + setTransitions(); + return 0; + } + + // Init the new item attributes + VECTOR2D cursorPos = view->ToWorld( controls->GetCursorPosition() ); + module->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); + + // Add a VIEW_GROUP that serves as a preview for the new item + KIGFX::VIEW_GROUP preview( view ); + preview.Add( module ); + module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW_GROUP::Add ), &preview ) ); + view->Add( &preview ); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + + controls->SetSnapping( true ); + + Activate(); + + // Main loop: keep receiving events + while( OPT_TOOL_EVENT evt = Wait() ) + { + cursorPos = view->ToWorld( controls->GetCursorPosition() ); + + if( evt->IsCancel() ) + { + board->Delete( module ); + break; + } + + else if( evt->Category() == TC_COMMAND ) + { + if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) + { + module->Rotate( module->GetPosition(), getEditFrame()->GetRotationAngle() ); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) + { + module->Flip( module->GetPosition() ); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + } + + else if( evt->IsClick( BUT_LEFT ) ) + { + module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), view ) ); + view->Add( module ); + module->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + break; + } + + else if( evt->IsMotion() ) + { + module->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + } + + controls->SetSnapping( false ); + controls->SetAutoPan( false ); + view->Remove( &preview ); + + setTransitions(); + + return 0; +} + + void DRAWING_TOOL::setTransitions() { Go( &DRAWING_TOOL::DrawLine, COMMON_ACTIONS::drawLine.MakeEvent() ); @@ -638,4 +723,5 @@ void DRAWING_TOOL::setTransitions() Go( &DRAWING_TOOL::DrawText, COMMON_ACTIONS::drawText.MakeEvent() ); Go( &DRAWING_TOOL::DrawDimension, COMMON_ACTIONS::drawDimension.MakeEvent() ); Go( &DRAWING_TOOL::PlaceTarget, COMMON_ACTIONS::placeTarget.MakeEvent() ); + Go( &DRAWING_TOOL::PlaceModule, COMMON_ACTIONS::placeModule.MakeEvent() ); } diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index c34109a2cf..1a33d4f7f8 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -61,6 +61,8 @@ public: int PlaceTarget( TOOL_EVENT& aEvent ); + int PlaceModule( TOOL_EVENT& aEvent ); + private: ///> Starts drawing a selected shape. int draw( STROKE_T aShape ); diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index 9202ddb4b5..7d2ed216be 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -61,6 +61,7 @@ void PCB_EDIT_FRAME::setupTools() m_toolManager->RegisterAction( &COMMON_ACTIONS::drawText ); m_toolManager->RegisterAction( &COMMON_ACTIONS::drawDimension ); m_toolManager->RegisterAction( &COMMON_ACTIONS::placeTarget ); + m_toolManager->RegisterAction( &COMMON_ACTIONS::placeModule ); // Register tools m_toolManager->RegisterTool( new SELECTION_TOOL ); From 042b6a100293e4ef88468d36f5da8faa43b91c5a Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 13 Feb 2014 15:57:57 +0100 Subject: [PATCH 018/134] Changed PCB_EDIT_FRAME::setTopLayer() to PCB_EDIT_FRAME::SetTopLayer() and changed to public (as it had exactly the same functionality). --- include/wxPcbStruct.h | 18 ++++++------------ pcbnew/pcbframe.cpp | 4 ++-- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index 1b5bc4b299..18f208b04f 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -156,12 +156,6 @@ protected: */ void setHighContrastLayer( LAYER_NUM aLayer ); - /** - * Function setTopLayer - * moves the selected layer to the top, so it is displayed above all others. - */ - void setTopLayer( LAYER_NUM aLayer ); - /** * Function syncLayerWidgetLayer * updates the currently layer "selection" within the PCB_LAYER_WIDGET. @@ -578,6 +572,12 @@ public: */ virtual void OnModify(); + /** + * Function SetTopLayer + * moves the selected layer to the top, so it is displayed above all others. + */ + void SetTopLayer( LAYER_NUM aLayer ); + /** * Function IsElementVisible * tests whether a given element category is visible. Keep this as an @@ -1694,12 +1694,6 @@ public: */ void UpdateTitle(); - void SetTopLayer( LAYER_NUM aLayer ) - { - setTopLayer( aLayer ); - } - - DECLARE_EVENT_TABLE() }; diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 0331d6b326..967f8dde9c 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -883,7 +883,7 @@ void PCB_EDIT_FRAME::setHighContrastLayer( LAYER_NUM aLayer ) KIGFX::VIEW* view = GetGalCanvas()->GetView(); KIGFX::RENDER_SETTINGS* rSettings = view->GetPainter()->GetSettings(); - setTopLayer( aLayer ); + SetTopLayer( aLayer ); rSettings->ClearActiveLayers(); rSettings->SetActiveLayer( aLayer ); @@ -920,7 +920,7 @@ void PCB_EDIT_FRAME::setHighContrastLayer( LAYER_NUM aLayer ) } -void PCB_EDIT_FRAME::setTopLayer( LAYER_NUM aLayer ) +void PCB_EDIT_FRAME::SetTopLayer( LAYER_NUM aLayer ) { // Set display settings for high contrast mode KIGFX::VIEW* view = GetGalCanvas()->GetView(); From fce753ba24ddccd6a474d83549491382cb2de7f4 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 13 Feb 2014 16:10:32 +0100 Subject: [PATCH 019/134] Added zone drawing tool. --- pcbnew/tools/common_actions.cpp | 4 + pcbnew/tools/common_actions.h | 3 + pcbnew/tools/drawing_tool.cpp | 153 ++++++++++++++++++++++++++++++++ pcbnew/tools/drawing_tool.h | 2 + pcbnew/tools/pcb_tools.cpp | 1 + 5 files changed, 163 insertions(+) diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index f3ea912d31..0a6cceaa7b 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -77,6 +77,10 @@ TOOL_ACTION COMMON_ACTIONS::drawDimension( "pcbnew.InteractiveDrawing.dimension" AS_GLOBAL, 'X', "Add a dimension", "Add a dimension" ); +TOOL_ACTION COMMON_ACTIONS::drawZone( "pcbnew.InteractiveDrawing.zone", + AS_GLOBAL, 'B', + "Add a filled zone", "Add a filled zone" ); + TOOL_ACTION COMMON_ACTIONS::placeTarget( "pcbnew.InteractiveDrawing.placeTarget", AS_GLOBAL, 'C', "Add layer alignment target", "Add layer alignment target" ); diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index fa07c45ce4..76f3d9f2f7 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -72,6 +72,9 @@ public: /// Activation of the drawing tool (dimension) static TOOL_ACTION drawDimension; + /// Activation of the drawing tool (drawing a ZONE) + static TOOL_ACTION drawZone; + /// Activation of the drawing tool (placing a TARGET) static TOOL_ACTION placeTarget; diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index b9433db085..4100be4e3a 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include // TODO to be removed if we do not need the flags @@ -563,6 +564,157 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) } +int DRAWING_TOOL::DrawZone( TOOL_EVENT& aEvent ) +{ + KIGFX::VIEW* view = getView(); + KIGFX::VIEW_CONTROLS* controls = getViewControls(); + BOARD* board = getModel( PCB_T ); + ZONE_CONTAINER* zone = new ZONE_CONTAINER( board ); + PCB_EDIT_FRAME* editFrame = getEditFrame(); + + // Get the current, default settings for zones + ZONE_SETTINGS zoneInfo = editFrame->GetZoneSettings(); + + ZONE_EDIT_T dialogResult; + if( IsCopperLayer( editFrame->GetScreen()->m_Active_Layer ) ) + dialogResult = InvokeCopperZonesEditor( editFrame, &zoneInfo ); + else + dialogResult = InvokeNonCopperZonesEditor( editFrame, zone, &zoneInfo ); + + if( dialogResult == ZONE_ABORT ) + { + delete zone; + setTransitions(); + return 0; + } + + zoneInfo.ExportSetting( *zone ); + editFrame->SetTopLayer( zoneInfo.m_CurrentZone_Layer ); + + DRAWSEGMENT* helperLine = new DRAWSEGMENT; + helperLine->SetShape( S_SEGMENT ); + helperLine->SetLayer( zoneInfo.m_CurrentZone_Layer ); + helperLine->SetWidth( 1 ); + + // Add a VIEW_GROUP that serves as a preview for the new item + KIGFX::VIEW_GROUP preview( view ); +// preview.Add( zone ); + view->Add( &preview ); + + controls->ShowCursor( true ); + controls->SetSnapping( true ); + controls->SetAutoPan( true ); + + Activate(); + + VECTOR2D lastCursorPos = view->ToWorld( controls->GetCursorPosition() ); + + // Main loop: keep receiving events + while( OPT_TOOL_EVENT evt = Wait() ) + { + // Enable 45 degrees lines only mode by holding shift + bool linesAngle45 = evt->Modifier( MD_SHIFT ); + VECTOR2D cursorPos = view->ToWorld( controls->GetCursorPosition() ); + + if( evt->IsCancel() ) + { + delete zone; + break; + } + + else if( evt->IsClick( BUT_LEFT ) ) + { + if( lastCursorPos == cursorPos || + ( zone->GetNumCorners() > 0 && wxPoint( cursorPos.x, cursorPos.y ) == zone->Outline()->GetPos( 0 ) ) ) // TODO better conditions + { + if( zone->GetNumCorners() > 2 ) + { + // Finish the zone + zone->Outline()->CloseLastContour(); + zone->Outline()->RemoveNullSegments(); + + board->Add( zone ); + view->Add( zone ); + + editFrame->Fill_Zone( zone ); + zone->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + else + { + // That is not a valid zone + delete zone; + } + + break; + } + else + { + if( zone->GetNumCorners() == 0 ) + { + zone->Outline()->Start( zoneInfo.m_CurrentZone_Layer, + cursorPos.x, + cursorPos.y, + zone->GetHatchStyle() ); + helperLine->SetStart( wxPoint( cursorPos.x, cursorPos.y ) ); + preview.Add( helperLine ); + } + else + { + zone->AppendCorner( helperLine->GetEnd() ); + helperLine = new DRAWSEGMENT( *helperLine ); + preview.Add( helperLine ); + helperLine->SetStart( helperLine->GetEnd() ); + } + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + + lastCursorPos = cursorPos; + } + + else if( evt->IsMotion() ) + { + helperLine->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); + + // 45 degree lines + if( linesAngle45 ) + { + VECTOR2D lineVector( wxPoint( cursorPos.x, cursorPos.y ) - helperLine->GetStart() ); + double angle = lineVector.Angle(); + + double newAngle = round( angle / ( M_PI / 4.0 ) ) * M_PI / 4.0; + VECTOR2D newLineVector = lineVector.Rotate( newAngle - angle ); + + // Snap the new line to the grid // TODO fix it, does not work good.. + VECTOR2D newLineEnd = VECTOR2D( helperLine->GetStart() ) + newLineVector; + VECTOR2D snapped = view->GetGAL()->GetGridPoint( newLineEnd ); + + helperLine->SetEnd( wxPoint( snapped.x, snapped.y ) ); + } + else + { + helperLine->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); + } + + // Show a preview of the item + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + } + + controls->ShowCursor( false ); + controls->SetSnapping( false ); + controls->SetAutoPan( false ); + view->Remove( &preview ); + + // remove helper lines only +// preview.Remove( zone ); + preview.FreeItems(); + + setTransitions(); + + return 0; +} + + int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) { KIGFX::VIEW* view = getView(); @@ -722,6 +874,7 @@ void DRAWING_TOOL::setTransitions() Go( &DRAWING_TOOL::DrawArc, COMMON_ACTIONS::drawArc.MakeEvent() ); Go( &DRAWING_TOOL::DrawText, COMMON_ACTIONS::drawText.MakeEvent() ); Go( &DRAWING_TOOL::DrawDimension, COMMON_ACTIONS::drawDimension.MakeEvent() ); + Go( &DRAWING_TOOL::DrawZone, COMMON_ACTIONS::drawZone.MakeEvent() ); Go( &DRAWING_TOOL::PlaceTarget, COMMON_ACTIONS::placeTarget.MakeEvent() ); Go( &DRAWING_TOOL::PlaceModule, COMMON_ACTIONS::placeModule.MakeEvent() ); } diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index 1a33d4f7f8..419604345f 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -59,6 +59,8 @@ public: int DrawDimension( TOOL_EVENT& aEvent ); + int DrawZone( TOOL_EVENT& aEvent ); + int PlaceTarget( TOOL_EVENT& aEvent ); int PlaceModule( TOOL_EVENT& aEvent ); diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index 7d2ed216be..bceee5f8d7 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -60,6 +60,7 @@ void PCB_EDIT_FRAME::setupTools() m_toolManager->RegisterAction( &COMMON_ACTIONS::drawArc ); m_toolManager->RegisterAction( &COMMON_ACTIONS::drawText ); m_toolManager->RegisterAction( &COMMON_ACTIONS::drawDimension ); + m_toolManager->RegisterAction( &COMMON_ACTIONS::drawZone ); m_toolManager->RegisterAction( &COMMON_ACTIONS::placeTarget ); m_toolManager->RegisterAction( &COMMON_ACTIONS::placeModule ); From 3106d25361204cbddfcf27195ce3bb6f771cd593 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 13 Feb 2014 16:24:33 +0100 Subject: [PATCH 020/134] Added keepout areas drawing tool. --- pcbnew/tools/common_actions.cpp | 4 + pcbnew/tools/common_actions.h | 3 + pcbnew/tools/drawing_tool.cpp | 148 +++++++++++++++++++++++++++++++- pcbnew/tools/drawing_tool.h | 2 + pcbnew/tools/pcb_tools.cpp | 1 + 5 files changed, 155 insertions(+), 3 deletions(-) diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 0a6cceaa7b..339087bdb8 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -81,6 +81,10 @@ TOOL_ACTION COMMON_ACTIONS::drawZone( "pcbnew.InteractiveDrawing.zone", AS_GLOBAL, 'B', "Add a filled zone", "Add a filled zone" ); +TOOL_ACTION COMMON_ACTIONS::drawKeepout( "pcbnew.InteractiveDrawing.keepout", + AS_GLOBAL, 'N', + "Add a keepout area", "Add a keepout area" ); + TOOL_ACTION COMMON_ACTIONS::placeTarget( "pcbnew.InteractiveDrawing.placeTarget", AS_GLOBAL, 'C', "Add layer alignment target", "Add layer alignment target" ); diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 76f3d9f2f7..fc66573988 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -75,6 +75,9 @@ public: /// Activation of the drawing tool (drawing a ZONE) static TOOL_ACTION drawZone; + /// Activation of the drawing tool (drawing a keepout area) + static TOOL_ACTION drawKeepout; + /// Activation of the drawing tool (placing a TARGET) static TOOL_ACTION placeTarget; diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 4100be4e3a..2c08379718 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -598,7 +598,6 @@ int DRAWING_TOOL::DrawZone( TOOL_EVENT& aEvent ) // Add a VIEW_GROUP that serves as a preview for the new item KIGFX::VIEW_GROUP preview( view ); -// preview.Add( zone ); view->Add( &preview ); controls->ShowCursor( true ); @@ -705,8 +704,150 @@ int DRAWING_TOOL::DrawZone( TOOL_EVENT& aEvent ) controls->SetAutoPan( false ); view->Remove( &preview ); - // remove helper lines only -// preview.Remove( zone ); + // delete helper lines + preview.FreeItems(); + + setTransitions(); + + return 0; +} + + +int DRAWING_TOOL::DrawKeepout( TOOL_EVENT& aEvent ) +{ + KIGFX::VIEW* view = getView(); + KIGFX::VIEW_CONTROLS* controls = getViewControls(); + BOARD* board = getModel( PCB_T ); + ZONE_CONTAINER* keepout = new ZONE_CONTAINER( board ); + PCB_EDIT_FRAME* editFrame = getEditFrame(); + + // Get the current, default settings for zones + ZONE_SETTINGS zoneInfo = editFrame->GetZoneSettings(); + + ZONE_EDIT_T dialogResult = InvokeKeepoutAreaEditor( editFrame, &zoneInfo ); + if( dialogResult == ZONE_ABORT ) + { + delete keepout; + setTransitions(); + return 0; + } + + zoneInfo.ExportSetting( *keepout ); + editFrame->SetTopLayer( zoneInfo.m_CurrentZone_Layer ); + + DRAWSEGMENT* helperLine = new DRAWSEGMENT; + helperLine->SetShape( S_SEGMENT ); + helperLine->SetLayer( zoneInfo.m_CurrentZone_Layer ); + helperLine->SetWidth( 1 ); + + // Add a VIEW_GROUP that serves as a preview for the new item + KIGFX::VIEW_GROUP preview( view ); + view->Add( &preview ); + + controls->ShowCursor( true ); + controls->SetSnapping( true ); + controls->SetAutoPan( true ); + + Activate(); + + VECTOR2D lastCursorPos = view->ToWorld( controls->GetCursorPosition() ); + + // Main loop: keep receiving events + while( OPT_TOOL_EVENT evt = Wait() ) + { + // Enable 45 degrees lines only mode by holding shift + bool linesAngle45 = evt->Modifier( MD_SHIFT ); + VECTOR2D cursorPos = view->ToWorld( controls->GetCursorPosition() ); + + if( evt->IsCancel() ) + { + delete keepout; + break; + } + + else if( evt->IsClick( BUT_LEFT ) ) + { + if( lastCursorPos == cursorPos || + ( keepout->GetNumCorners() > 0 && wxPoint( cursorPos.x, cursorPos.y ) == keepout->Outline()->GetPos( 0 ) ) ) // TODO better conditions + { + if( keepout->GetNumCorners() > 2 ) + { + // Finish the zone + keepout->Outline()->CloseLastContour(); + keepout->Outline()->RemoveNullSegments(); + + board->Add( keepout ); + view->Add( keepout ); + + keepout->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + else + { + // That is not a valid zone + delete keepout; + } + + break; + } + else + { + if( keepout->GetNumCorners() == 0 ) + { + keepout->Outline()->Start( zoneInfo.m_CurrentZone_Layer, + cursorPos.x, + cursorPos.y, + keepout->GetHatchStyle() ); + helperLine->SetStart( wxPoint( cursorPos.x, cursorPos.y ) ); + preview.Add( helperLine ); + } + else + { + keepout->AppendCorner( helperLine->GetEnd() ); + helperLine = new DRAWSEGMENT( *helperLine ); + preview.Add( helperLine ); + helperLine->SetStart( helperLine->GetEnd() ); + } + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + + lastCursorPos = cursorPos; + } + + else if( evt->IsMotion() ) + { + helperLine->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); + + // 45 degree lines + if( linesAngle45 ) + { + VECTOR2D lineVector( wxPoint( cursorPos.x, cursorPos.y ) - helperLine->GetStart() ); + double angle = lineVector.Angle(); + + double newAngle = round( angle / ( M_PI / 4.0 ) ) * M_PI / 4.0; + VECTOR2D newLineVector = lineVector.Rotate( newAngle - angle ); + + // Snap the new line to the grid // TODO fix it, does not work good.. + VECTOR2D newLineEnd = VECTOR2D( helperLine->GetStart() ) + newLineVector; + VECTOR2D snapped = view->GetGAL()->GetGridPoint( newLineEnd ); + + helperLine->SetEnd( wxPoint( snapped.x, snapped.y ) ); + } + else + { + helperLine->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); + } + + // Show a preview of the item + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + } + + controls->ShowCursor( false ); + controls->SetSnapping( false ); + controls->SetAutoPan( false ); + view->Remove( &preview ); + + // delete helper lines preview.FreeItems(); setTransitions(); @@ -875,6 +1016,7 @@ void DRAWING_TOOL::setTransitions() Go( &DRAWING_TOOL::DrawText, COMMON_ACTIONS::drawText.MakeEvent() ); Go( &DRAWING_TOOL::DrawDimension, COMMON_ACTIONS::drawDimension.MakeEvent() ); Go( &DRAWING_TOOL::DrawZone, COMMON_ACTIONS::drawZone.MakeEvent() ); + Go( &DRAWING_TOOL::DrawKeepout, COMMON_ACTIONS::drawKeepout.MakeEvent() ); Go( &DRAWING_TOOL::PlaceTarget, COMMON_ACTIONS::placeTarget.MakeEvent() ); Go( &DRAWING_TOOL::PlaceModule, COMMON_ACTIONS::placeModule.MakeEvent() ); } diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index 419604345f..149eccda6a 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -61,6 +61,8 @@ public: int DrawZone( TOOL_EVENT& aEvent ); + int DrawKeepout( TOOL_EVENT& aEvent ); + int PlaceTarget( TOOL_EVENT& aEvent ); int PlaceModule( TOOL_EVENT& aEvent ); diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index bceee5f8d7..23c899b2fa 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -61,6 +61,7 @@ void PCB_EDIT_FRAME::setupTools() m_toolManager->RegisterAction( &COMMON_ACTIONS::drawText ); m_toolManager->RegisterAction( &COMMON_ACTIONS::drawDimension ); m_toolManager->RegisterAction( &COMMON_ACTIONS::drawZone ); + m_toolManager->RegisterAction( &COMMON_ACTIONS::drawKeepout ); m_toolManager->RegisterAction( &COMMON_ACTIONS::placeTarget ); m_toolManager->RegisterAction( &COMMON_ACTIONS::placeModule ); From f9f0b46b63e3d0589aaa144cc784d7e2dd0345ab Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 13 Feb 2014 19:31:27 +0100 Subject: [PATCH 021/134] Small GAL refactorization, mostly correcting constness. --- common/gal/cairo/cairo_gal.cpp | 5 +-- common/gal/graphics_abstraction_layer.cpp | 12 +++---- common/gal/opengl/opengl_gal.cpp | 2 +- common/view/view.cpp | 4 +-- common/view/wx_view_controls.cpp | 4 +-- include/gal/cairo/cairo_gal.h | 5 ++- include/gal/graphics_abstraction_layer.h | 42 ++++++++++++++--------- include/gal/opengl/opengl_gal.h | 2 +- 8 files changed, 41 insertions(+), 35 deletions(-) diff --git a/common/gal/cairo/cairo_gal.cpp b/common/gal/cairo/cairo_gal.cpp index 5f180d7338..2c172d0400 100644 --- a/common/gal/cairo/cairo_gal.cpp +++ b/common/gal/cairo/cairo_gal.cpp @@ -35,9 +35,6 @@ using namespace KIGFX; -///> Opacity of a single layer -const float LAYER_ALPHA = 0.8; - CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, wxEvtHandler* aPaintListener, const wxString& aName ) : wxWindow( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxEXPAND, aName ) @@ -430,7 +427,7 @@ void CAIRO_GAL::SetLayerDepth( double aLayerDepth ) } -void CAIRO_GAL::Transform( MATRIX3x3D aTransformation ) +void CAIRO_GAL::Transform( const MATRIX3x3D& aTransformation ) { cairo_matrix_t cairoTransformation; diff --git a/common/gal/graphics_abstraction_layer.cpp b/common/gal/graphics_abstraction_layer.cpp index 2a3d9a089c..67794a89c1 100644 --- a/common/gal/graphics_abstraction_layer.cpp +++ b/common/gal/graphics_abstraction_layer.cpp @@ -112,17 +112,17 @@ void GAL::DrawGrid() SetTarget( TARGET_NONCACHED ); // Draw the origin marker - double origSize = static_cast( gridOriginMarkerSize ) / worldScale; + double originSize = gridOriginMarkerSize / worldScale; SetLayerDepth( GAL::GRID_DEPTH ); SetIsFill( false ); SetIsStroke( true ); SetStrokeColor( COLOR4D( 1.0, 1.0, 1.0, 1.0 ) ); SetLineWidth( gridLineWidth / worldScale ); - DrawLine( gridOrigin + VECTOR2D( -origSize, -origSize ), - gridOrigin + VECTOR2D( origSize, origSize ) ); - DrawLine( gridOrigin + VECTOR2D( -origSize, origSize ), - gridOrigin + VECTOR2D( origSize, -origSize ) ); - DrawCircle( gridOrigin, origSize * 0.7 ); + DrawLine( gridOrigin + VECTOR2D( -originSize, -originSize ), + gridOrigin + VECTOR2D( originSize, originSize ) ); + DrawLine( gridOrigin + VECTOR2D( -originSize, originSize ), + gridOrigin + VECTOR2D( originSize, -originSize ) ); + DrawCircle( gridOrigin, originSize * 0.7 ); // Draw the grid // For the drawing the start points, end points and increments have diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index a665377e73..873fff51fd 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -600,7 +600,7 @@ void OPENGL_GAL::SetStrokeColor( const COLOR4D& aColor ) } -void OPENGL_GAL::Transform( MATRIX3x3D aTransformation ) +void OPENGL_GAL::Transform( const MATRIX3x3D& aTransformation ) { GLdouble matrixData[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }; diff --git a/common/view/view.cpp b/common/view/view.cpp index e27751bb76..e9c6324012 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -197,7 +197,7 @@ int VIEW::Query( const BOX2I& aRect, std::vector& aResult ) VECTOR2D VIEW::ToWorld( const VECTOR2D& aCoord, bool aAbsolute ) const { - MATRIX3x3D matrix = m_gal->GetWorldScreenMatrix().Inverse(); + const MATRIX3x3D& matrix = m_gal->GetScreenWorldMatrix(); if( aAbsolute ) { @@ -212,7 +212,7 @@ VECTOR2D VIEW::ToWorld( const VECTOR2D& aCoord, bool aAbsolute ) const VECTOR2D VIEW::ToScreen( const VECTOR2D& aCoord, bool aAbsolute ) const { - MATRIX3x3D matrix = m_gal->GetWorldScreenMatrix(); + const MATRIX3x3D& matrix = m_gal->GetWorldScreenMatrix(); if( aAbsolute ) { diff --git a/common/view/wx_view_controls.cpp b/common/view/wx_view_controls.cpp index 48107911d2..ef919c68e6 100644 --- a/common/view/wx_view_controls.cpp +++ b/common/view/wx_view_controls.cpp @@ -35,9 +35,7 @@ using namespace KIGFX; const wxEventType WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE = wxNewEventType(); WX_VIEW_CONTROLS::WX_VIEW_CONTROLS( VIEW* aView, wxWindow* aParentPanel ) : - VIEW_CONTROLS( aView ), - m_state( IDLE ), - m_parentPanel( aParentPanel ) + VIEW_CONTROLS( aView ), m_state( IDLE ), m_parentPanel( aParentPanel ) { m_parentPanel->Connect( wxEVT_MOTION, wxMouseEventHandler( WX_VIEW_CONTROLS::onMotion ), NULL, this ); diff --git a/include/gal/cairo/cairo_gal.h b/include/gal/cairo/cairo_gal.h index 20477db08a..8da314560e 100644 --- a/include/gal/cairo/cairo_gal.h +++ b/include/gal/cairo/cairo_gal.h @@ -164,7 +164,7 @@ public: // -------------- /// @copydoc GAL::Transform() - virtual void Transform( MATRIX3x3D aTransformation ); + virtual void Transform( const MATRIX3x3D& aTransformation ); /// @copydoc GAL::Rotate() virtual void Rotate( double aAngle ); @@ -386,6 +386,9 @@ private: /// Format used to store pixels static const cairo_format_t GAL_FORMAT = CAIRO_FORMAT_RGB24; + + ///> Opacity of a single layer + static const float LAYER_ALPHA = 0.8; }; } // namespace KIGFX diff --git a/include/gal/graphics_abstraction_layer.h b/include/gal/graphics_abstraction_layer.h index 118faf38ac..a6fad9b6fc 100644 --- a/include/gal/graphics_abstraction_layer.h +++ b/include/gal/graphics_abstraction_layer.h @@ -31,8 +31,6 @@ #include #include -#include - #include #include @@ -162,7 +160,7 @@ public: virtual bool Show( bool aShow ) = 0; /// @brief Returns GAL canvas size in pixels - VECTOR2D GetScreenPixelSize() const + const VECTOR2D& GetScreenPixelSize() const { return screenSize; } @@ -222,7 +220,7 @@ public: * * @return the color for stroking the outline. */ - inline COLOR4D GetStrokeColor() + inline const COLOR4D& GetStrokeColor() const { return strokeColor; } @@ -252,7 +250,7 @@ public: * * @return the actual line width. */ - inline double GetLineWidth() + inline double GetLineWidth() const { return lineWidth; } @@ -335,7 +333,7 @@ public: * * @param aTransformation is the ransformation matrix. */ - virtual void Transform( MATRIX3x3D aTransformation ) = 0; + virtual void Transform( const MATRIX3x3D& aTransformation ) = 0; /** * @brief Rotate the context. @@ -428,11 +426,21 @@ public: * * @return the transformation matrix. */ - MATRIX3x3D GetWorldScreenMatrix() + const MATRIX3x3D& GetWorldScreenMatrix() const { return worldScreenMatrix; } + /** + * @brief Get the screen <-> world transformation matrix. + * + * @return the transformation matrix. + */ + const MATRIX3x3D& GetScreenWorldMatrix() const + { + return screenWorldMatrix; + } + /** * @brief Set the world <-> screen transformation matrix. * @@ -487,7 +495,7 @@ public: * * @return the look at point. */ - inline VECTOR2D GetLookAtPoint() + inline const VECTOR2D& GetLookAtPoint() const { return lookAtPoint; } @@ -507,7 +515,7 @@ public: * * @return the zoom factor. */ - inline double GetZoomFactor() + inline double GetZoomFactor() const { return zoomFactor; } @@ -528,7 +536,7 @@ public: /** * @brief Returns the minimum depth in the currently used range (the top). */ - inline double GetMinDepth() + inline double GetMinDepth() const { return depthRange.x; } @@ -536,7 +544,7 @@ public: /** * @brief Returns the maximum depth in the currently used range (the bottom). */ - inline double GetMaxDepth() + inline double GetMaxDepth() const { return depthRange.y; } @@ -546,7 +554,7 @@ public: * * @return the actual world scale factor. */ - inline double GetWorldScale() + inline double GetWorldScale() const { return worldScale; } @@ -694,7 +702,7 @@ public: * * @return the grid line width */ - inline double GetGridLineWidth() + inline double GetGridLineWidth() const { return gridLineWidth; } @@ -739,7 +747,7 @@ public: * @param aPoint the pointposition in screen coordinates. * @return the point position in world coordinates. */ - inline virtual VECTOR2D ToWorld( const VECTOR2D& aPoint ) const + inline VECTOR2D ToWorld( const VECTOR2D& aPoint ) const { return VECTOR2D( screenWorldMatrix * aPoint ); } @@ -750,15 +758,15 @@ public: * @param aPoint the pointposition in world coordinates. * @return the point position in screen coordinates. */ - inline virtual VECTOR2D ToScreen( const VECTOR2D& aPoint ) const + inline VECTOR2D ToScreen( const VECTOR2D& aPoint ) const { return VECTOR2D( worldScreenMatrix * aPoint ); } /** - * @brief Enable/Disable cursor. + * @brief Enable/disable cursor. * - * @param aIsCursorEnabled is true if the cursor should be enabled, else false. + * @param aCursorEnabled is true if the cursor should be drawn, else false. */ inline void SetCursorEnabled( bool aCursorEnabled ) { diff --git a/include/gal/opengl/opengl_gal.h b/include/gal/opengl/opengl_gal.h index 401f0a4411..792205c91d 100644 --- a/include/gal/opengl/opengl_gal.h +++ b/include/gal/opengl/opengl_gal.h @@ -157,7 +157,7 @@ public: // -------------- /// @copydoc GAL::Transform() - virtual void Transform( MATRIX3x3D aTransformation ); + virtual void Transform( const MATRIX3x3D& aTransformation ); /// @copydoc GAL::Rotate() virtual void Rotate( double aAngle ); From 597e98dbf476c9dc0ca0ed3e6aa61082d4668b8c Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 13 Feb 2014 20:23:28 +0100 Subject: [PATCH 022/134] Cursor is in world coordinates. --- common/drawpanel_gal.cpp | 11 ------ common/gal/cairo/cairo_gal.cpp | 22 ++++++------ common/gal/graphics_abstraction_layer.cpp | 3 ++ common/gal/opengl/opengl_gal.cpp | 23 +++--------- common/view/wx_view_controls.cpp | 44 +++++++++++------------ include/gal/cairo/cairo_gal.h | 8 ++--- include/gal/graphics_abstraction_layer.h | 20 ++++------- include/gal/opengl/opengl_gal.h | 5 --- include/view/view_controls.h | 17 ++++----- include/view/wx_view_controls.h | 20 ++--------- pcbnew/router/router_tool.cpp | 2 +- pcbnew/tools/drawing_tool.cpp | 25 +++++++------ pcbnew/tools/edit_tool.cpp | 11 +++--- 13 files changed, 81 insertions(+), 130 deletions(-) diff --git a/common/drawpanel_gal.cpp b/common/drawpanel_gal.cpp index e0d9dcdf89..2a03dcc571 100644 --- a/common/drawpanel_gal.cpp +++ b/common/drawpanel_gal.cpp @@ -45,8 +45,6 @@ #include #endif /* __WXDEBUG__ */ -#define METRIC_UNIT_LENGTH (1e9) - EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWindowId, const wxPoint& aPosition, const wxSize& aSize, GalType aGalType ) : @@ -61,11 +59,6 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin SwitchBackend( aGalType ); SetBackgroundStyle( wxBG_STYLE_CUSTOM ); - // Initial display settings - m_gal->SetLookAtPoint( VECTOR2D( 0, 0 ) ); - m_gal->SetZoomFactor( 1.0 ); - m_gal->ComputeWorldScreenMatrix(); - m_painter = new KIGFX::PCB_PAINTER( m_gal ); m_view = new KIGFX::VIEW( true ); @@ -220,10 +213,6 @@ void EDA_DRAW_PANEL_GAL::SwitchBackend( GalType aGalType ) return; } - m_gal->SetWorldUnitLength( 1.0 / METRIC_UNIT_LENGTH * 2.54 ); // 1 inch in nanometers - m_gal->SetScreenDPI( 106 ); // Display resolution setting - m_gal->ComputeWorldScreenMatrix(); - wxSize size = GetClientSize(); m_gal->ResizeScreen( size.GetX(), size.GetY() ); diff --git a/common/gal/cairo/cairo_gal.cpp b/common/gal/cairo/cairo_gal.cpp index 2c172d0400..5d1d4f6cd7 100644 --- a/common/gal/cairo/cairo_gal.cpp +++ b/common/gal/cairo/cairo_gal.cpp @@ -70,7 +70,7 @@ CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, SetSize( aParent->GetSize() ); screenSize = VECTOR2D( aParent->GetSize() ); - initCursor( 20 ); + initCursor(); // Grid color settings are different in Cairo and OpenGL SetGridColor( COLOR4D( 0.1, 0.1, 0.1, 0.8 ) ); @@ -881,11 +881,10 @@ void CAIRO_GAL::skipMouseEvent( wxMouseEvent& aEvent ) } -void CAIRO_GAL::initCursor( int aCursorSize ) +void CAIRO_GAL::initCursor() { - cursorPixels = new wxBitmap( aCursorSize, aCursorSize ); - cursorPixelsSaved = new wxBitmap( aCursorSize, aCursorSize ); - cursorSize = aCursorSize; + cursorPixels = new wxBitmap( cursorSize, cursorSize ); + cursorPixelsSaved = new wxBitmap( cursorSize, cursorSize ); wxMemoryDC cursorShape( *cursorPixels ); @@ -896,8 +895,8 @@ void CAIRO_GAL::initCursor( int aCursorSize ) cursorShape.SetPen( pen ); cursorShape.Clear(); - cursorShape.DrawLine( 0, aCursorSize / 2, aCursorSize, aCursorSize / 2 ); - cursorShape.DrawLine( aCursorSize / 2, 0, aCursorSize / 2, aCursorSize ); + cursorShape.DrawLine( 0, cursorSize / 2, cursorSize, cursorSize / 2 ); + cursorShape.DrawLine( cursorSize / 2, 0, cursorSize / 2, cursorSize ); } @@ -921,14 +920,15 @@ void CAIRO_GAL::blitCursor( wxBufferedDC& clientDC ) } // Store pixels that are going to be overpainted - cursorSave.Blit( 0, 0, cursorSize, cursorSize, &clientDC, cursorPosition.x, cursorPosition.y ); + VECTOR2D cursorScreen = ToScreen( cursorPosition ) - cursorSize / 2; + cursorSave.Blit( 0, 0, cursorSize, cursorSize, &clientDC, cursorScreen.x, cursorScreen.y ); // Draw the cursor - clientDC.Blit( cursorPosition.x, cursorPosition.y, cursorSize, cursorSize, + clientDC.Blit( cursorScreen.x, cursorScreen.y, cursorSize, cursorSize, &cursorShape, 0, 0, wxOR ); - savedCursorPosition.x = (wxCoord) cursorPosition.x; - savedCursorPosition.y = (wxCoord) cursorPosition.y; + savedCursorPosition.x = (wxCoord) cursorScreen.x; + savedCursorPosition.y = (wxCoord) cursorScreen.y; } diff --git a/common/gal/graphics_abstraction_layer.cpp b/common/gal/graphics_abstraction_layer.cpp index 67794a89c1..9bc79b5ab7 100644 --- a/common/gal/graphics_abstraction_layer.cpp +++ b/common/gal/graphics_abstraction_layer.cpp @@ -39,7 +39,10 @@ GAL::GAL() : SetIsStroke( true ); SetFillColor( COLOR4D( 0.0, 0.0, 0.0, 0.0 ) ); SetStrokeColor( COLOR4D( 1.0, 1.0, 1.0, 1.0 ) ); + SetLookAtPoint( VECTOR2D( 0, 0 ) ); SetZoomFactor( 1.0 ); + SetWorldUnitLength( 1.0 / METRIC_UNIT_LENGTH * 2.54 ); // 1 inch in nanometers + SetScreenDPI( 106 ); // Display resolution setting SetDepthRange( VECTOR2D( GAL::MIN_DEPTH, GAL::MAX_DEPTH ) ); SetFlip( false, false ); SetLineWidth( 1.0 ); diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index 873fff51fd..84b8225ac3 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -86,7 +86,6 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, SetSize( aParent->GetSize() ); screenSize = VECTOR2D( aParent->GetSize() ); - initCursor( 80 ); // Grid color settings are different in Cairo and OpenGL SetGridColor( COLOR4D( 0.8, 0.8, 0.8, 0.1 ) ); @@ -769,8 +768,8 @@ void OPENGL_GAL::DrawCursor( const VECTOR2D& aCursorPosition ) { // Now we should only store the position of the mouse cursor // The real drawing routines are in blitCursor() - cursorPosition = VECTOR2D( aCursorPosition.x, - screenSize.y - aCursorPosition.y ); // invert Y axis + VECTOR2D screenCursor = worldScreenMatrix * aCursorPosition; + cursorPosition = screenWorldMatrix * VECTOR2D( screenCursor.x, screenSize.y - screenCursor.y ); } @@ -780,13 +779,9 @@ void OPENGL_GAL::drawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEnd // We do not need a very precise comparison here (the lineWidth is set by GAL::DrawGrid()) if( fabs( lineWidth - 2.0 * gridLineWidth / worldScale ) < 0.1 ) - { glLineWidth( 1.0 ); - } else - { glLineWidth( 2.0 ); - } glColor4d( gridColor.r, gridColor.g, gridColor.b, gridColor.a ); @@ -970,12 +965,6 @@ void OPENGL_GAL::initGlew() } -void OPENGL_GAL::initCursor( int aCursorSize ) -{ - cursorSize = aCursorSize; -} - - void OPENGL_GAL::blitCursor() { if( !isCursorEnabled ) @@ -983,11 +972,9 @@ void OPENGL_GAL::blitCursor() compositor.SetBuffer( OPENGL_COMPOSITOR::DIRECT_RENDERING ); - VECTOR2D cursorBegin = ToWorld( cursorPosition - - VECTOR2D( cursorSize / 2, cursorSize / 2 ) ); - VECTOR2D cursorEnd = ToWorld( cursorPosition + - VECTOR2D( cursorSize / 2, cursorSize / 2 ) ); - VECTOR2D cursorCenter = ( cursorBegin + cursorEnd ) / 2.0; + VECTOR2D cursorBegin = cursorPosition - cursorSize / ( 2 * worldScale ); + VECTOR2D cursorEnd = cursorPosition + cursorSize / ( 2 * worldScale ); + VECTOR2D cursorCenter = ( cursorBegin + cursorEnd ) / 2; glDisable( GL_TEXTURE_2D ); glLineWidth( 1.0 ); diff --git a/common/view/wx_view_controls.cpp b/common/view/wx_view_controls.cpp index ef919c68e6..df8b9849c3 100644 --- a/common/view/wx_view_controls.cpp +++ b/common/view/wx_view_controls.cpp @@ -68,11 +68,6 @@ void VIEW_CONTROLS::ShowCursor( bool aEnabled ) void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent ) { - m_mousePosition.x = aEvent.GetX(); - m_mousePosition.y = aEvent.GetY(); - - updateCursor(); - bool isAutoPanning = false; if( m_autoPanEnabled ) @@ -82,7 +77,7 @@ void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent ) { if( m_state == DRAG_PANNING ) { - VECTOR2D d = m_dragStartPoint - m_mousePosition; + VECTOR2D d = m_dragStartPoint - VECTOR2D( aEvent.GetX(), aEvent.GetY() ); VECTOR2D delta = m_view->ToWorld( d, false ); m_view->SetCenter( m_lookStartPoint + delta ); @@ -197,8 +192,6 @@ 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 wxMouseEvent moveEvent( EVT_REFRESH_MOUSE ); @@ -236,7 +229,7 @@ void WX_VIEW_CONTROLS::SetGrabMouse( bool aEnabled ) } -const VECTOR2D WX_VIEW_CONTROLS::GetMousePosition() const +VECTOR2D WX_VIEW_CONTROLS::GetMousePosition() const { wxPoint msp = wxGetMousePosition(); wxPoint winp = m_parentPanel->GetScreenPosition(); @@ -245,6 +238,22 @@ const VECTOR2D WX_VIEW_CONTROLS::GetMousePosition() const } +VECTOR2D WX_VIEW_CONTROLS::GetCursorPosition() const +{ + if( m_forceCursorPosition ) + return m_forcedPosition; + else + { + VECTOR2D mousePosition = GetMousePosition(); + + if( m_snappingEnabled ) + return m_view->ToWorld( m_view->GetGAL()->GetGridPoint( mousePosition ) ); + else + return m_view->ToWorld( mousePosition ); + } +} + + bool WX_VIEW_CONTROLS::handleAutoPanning( const wxMouseEvent& aEvent ) { VECTOR2D p( aEvent.GetX(), aEvent.GetY() ); @@ -255,17 +264,19 @@ bool WX_VIEW_CONTROLS::handleAutoPanning( const wxMouseEvent& aEvent ) double borderEndX = m_view->GetScreenPixelSize().x - borderStart; double borderEndY = m_view->GetScreenPixelSize().y - borderStart; - m_panDirection = VECTOR2D(); - if( p.x < borderStart ) m_panDirection.x = -( borderStart - p.x ); else if( p.x > borderEndX ) m_panDirection.x = ( p.x - borderEndX ); + else + m_panDirection.x = 0; if( p.y < borderStart ) m_panDirection.y = -( borderStart - p.y ); else if( p.y > borderEndY ) m_panDirection.y = ( p.y - borderEndY ); + else + m_panDirection.y = 0; bool borderHit = ( m_panDirection.x != 0 || m_panDirection.y != 0 ); @@ -302,14 +313,3 @@ 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/gal/cairo/cairo_gal.h b/include/gal/cairo/cairo_gal.h index 8da314560e..352e262931 100644 --- a/include/gal/cairo/cairo_gal.h +++ b/include/gal/cairo/cairo_gal.h @@ -283,8 +283,6 @@ private: wxPoint savedCursorPosition; ///< The last cursor position wxBitmap* cursorPixels; ///< Cursor pixels wxBitmap* cursorPixelsSaved; ///< Saved cursor pixels - int cursorSize; ///< Cursor size - VECTOR2D cursorPosition; ///< Current cursor position /// Maximum number of arguments for one command static const int MAX_CAIRO_ARGUMENTS = 6; @@ -354,8 +352,10 @@ private: */ void skipMouseEvent( wxMouseEvent& aEvent ); - /// @copydoc GAL::initCursor() - virtual void initCursor( int aCursorSize ); + /** + * @brief Prepares cursor bitmap. + */ + virtual void initCursor(); /** * @brief Blits cursor into the current screen. diff --git a/include/gal/graphics_abstraction_layer.h b/include/gal/graphics_abstraction_layer.h index a6fad9b6fc..5b6c656e32 100644 --- a/include/gal/graphics_abstraction_layer.h +++ b/include/gal/graphics_abstraction_layer.h @@ -720,17 +720,15 @@ public: /// @brief Draw the grid void DrawGrid(); - /** * Function GetGridPoint() - * For a given point it returns the nearest point belonging to the grid. + * For a given point it returns the nearest point belonging to the grid in screen coordinates. * * @param aPoint is the point for which the grid point is searched. - * @return The nearest grid point. + * @return The nearest grid point in screen coordinates. */ VECTOR2D GetGridPoint( const VECTOR2D& aPoint ) const; - /** * @brief Change the grid display style. * @@ -786,7 +784,7 @@ public: /** * @brief Set the cursor size. * - * @param aCursorSize is the size of the cursor. + * @param aCursorSize is the size of the cursor expressed in pixels. */ inline void SetCursorSize( unsigned int aCursorSize ) { @@ -829,6 +827,8 @@ public: /// Depth level on which the grid is drawn static const int GRID_DEPTH = 1024; + static const double METRIC_UNIT_LENGTH = 1e9; + protected: std::stack depthStack; ///< Stored depth values VECTOR2D screenSize; ///< Screen size in screen coordinates @@ -870,7 +870,8 @@ protected: bool isCursorEnabled; ///< Is the cursor enabled? COLOR4D cursorColor; ///< Cursor color - int cursorSize; ///< Size of the cursor in pixels + unsigned int cursorSize; ///< Size of the cursor in pixels + VECTOR2D cursorPosition; ///< Current cursor position (world coordinates) /// Instance of object that stores information about how to draw texts STROKE_FONT strokeFont; @@ -889,13 +890,6 @@ protected: */ virtual void drawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) = 0; - /** - * @brief Initialize the cursor. - * - * @param aCursorSize is the size of the cursor. - */ - virtual void initCursor( int aCursorSize ) = 0; - static const int MIN_DEPTH = -2048; static const int MAX_DEPTH = 2047; }; diff --git a/include/gal/opengl/opengl_gal.h b/include/gal/opengl/opengl_gal.h index 792205c91d..7a1879d085 100644 --- a/include/gal/opengl/opengl_gal.h +++ b/include/gal/opengl/opengl_gal.h @@ -299,8 +299,6 @@ private: bool isShaderInitialized; ///< Was the shader initialized? bool isGrouping; ///< Was a group started? - VECTOR2D cursorPosition; ///< Current cursor position - // Polygon tesselation /// The tessellator GLUtesselator* tesselator; @@ -364,9 +362,6 @@ private: /// Initialize GLEW void initGlew(); - /// @copydoc GAL::initCursor() - virtual void initCursor( int aCursorSize ); - /** * @brief Blits cursor into the current screen. */ diff --git a/include/view/view_controls.h b/include/view/view_controls.h index 5ec1a037a4..35e6709f18 100644 --- a/include/view/view_controls.h +++ b/include/view/view_controls.h @@ -108,21 +108,22 @@ public: /** * Function GetMousePosition() - * Returns the current mouse pointer position in the screen coordinates. Note, that it may be + * Returns the current mouse pointer position in screen coordinates. Note, that it may be * different from the cursor position if snapping is enabled (@see GetCursorPosition()). * - * @return The current mouse pointer position. + * @return The current mouse pointer position in screen coordinates. */ - virtual const VECTOR2D GetMousePosition() const = 0; + virtual VECTOR2D GetMousePosition() const = 0; /** * Function GetCursorPosition() - * Returns the current cursor position in the screen coordinates. Note, that it may be - * different from the mouse pointer position if snapping is enabled (@see GetMousePosition()). + * Returns the current cursor position in world coordinates. Note, that it may be + * different from the mouse pointer position if snapping is enabled or cursor position + * is forced to specific point. * - * @return The current cursor position in screen coordinates. + * @return The current cursor position in world coordinates. */ - virtual const VECTOR2D GetCursorPosition() const = 0; + virtual VECTOR2D GetCursorPosition() const = 0; /** @@ -131,7 +132,7 @@ public: * @param aEnabled enable forced cursor position * @param aPosition the position */ - virtual void ForceCursorPosition( bool aEnabled, const VECTOR2D& aPosition = VECTOR2D(0, 0) ) + virtual void ForceCursorPosition( bool aEnabled, const VECTOR2D& aPosition = VECTOR2D( 0, 0 ) ) { m_forcedPosition = aPosition; m_forceCursorPosition = aEnabled; diff --git a/include/view/wx_view_controls.h b/include/view/wx_view_controls.h index 41540e951b..d8722d5b78 100644 --- a/include/view/wx_view_controls.h +++ b/include/view/wx_view_controls.h @@ -58,13 +58,6 @@ 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). @@ -88,13 +81,10 @@ public: } /// @copydoc VIEW_CONTROLS::GetMousePosition() - const VECTOR2D GetMousePosition() const; + VECTOR2D GetMousePosition() const; /// @copydoc VIEW_CONTROLS::GetCursorPosition() - const VECTOR2D GetCursorPosition() const - { - return m_cursorPosition; - } + VECTOR2D GetCursorPosition() const; /// 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) @@ -119,12 +109,6 @@ 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; diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 558b4dfab6..6896bb5a15 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -281,7 +281,7 @@ void ROUTER_TOOL::updateEndItem( TOOL_EVENT& aEvent ) else { m_endItem = NULL; - m_endSnapPoint = getView()->ToWorld( ctls->GetCursorPosition() ); + m_endSnapPoint = ctls->GetCursorPosition(); ctls->ForceCursorPosition( false ); } diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 2c08379718..0e4ea58424 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -109,7 +109,7 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { - VECTOR2D cursorPos = view->ToWorld( controls->GetCursorPosition() ); + VECTOR2I cursorPos = controls->GetCursorPosition(); if( evt->IsCancel() ) break; @@ -254,7 +254,7 @@ int DRAWING_TOOL::draw( STROKE_T aShape ) { // Enable 45 degrees lines only mode by holding shift bool linesAngle45 = evt->Modifier( MD_SHIFT ); - VECTOR2D cursorPos = view->ToWorld( controls->GetCursorPosition() ); + VECTOR2I cursorPos = controls->GetCursorPosition(); if( evt->IsCancel() ) break; @@ -343,7 +343,6 @@ int DRAWING_TOOL::draw( STROKE_T aShape ) controls->SetSnapping( false ); controls->SetAutoPan( false ); view->Remove( &preview ); - setTransitions(); return 0; @@ -377,7 +376,7 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { - VECTOR2D cursorPos = view->ToWorld( controls->GetCursorPosition() ); + VECTOR2I cursorPos = controls->GetCursorPosition(); if( evt->IsCancel() ) { @@ -465,7 +464,7 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { - VECTOR2D cursorPos = view->ToWorld( controls->GetCursorPosition() ); + VECTOR2I cursorPos = controls->GetCursorPosition(); if( evt->IsCancel() ) { @@ -606,14 +605,14 @@ int DRAWING_TOOL::DrawZone( TOOL_EVENT& aEvent ) Activate(); - VECTOR2D lastCursorPos = view->ToWorld( controls->GetCursorPosition() ); + VECTOR2I lastCursorPos = controls->GetCursorPosition(); // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { // Enable 45 degrees lines only mode by holding shift bool linesAngle45 = evt->Modifier( MD_SHIFT ); - VECTOR2D cursorPos = view->ToWorld( controls->GetCursorPosition() ); + VECTOR2I cursorPos = controls->GetCursorPosition(); if( evt->IsCancel() ) { @@ -750,14 +749,14 @@ int DRAWING_TOOL::DrawKeepout( TOOL_EVENT& aEvent ) Activate(); - VECTOR2D lastCursorPos = view->ToWorld( controls->GetCursorPosition() ); + VECTOR2I lastCursorPos = controls->GetCursorPosition(); // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { // Enable 45 degrees lines only mode by holding shift bool linesAngle45 = evt->Modifier( MD_SHIFT ); - VECTOR2D cursorPos = view->ToWorld( controls->GetCursorPosition() ); + VECTOR2I cursorPos = controls->GetCursorPosition(); if( evt->IsCancel() ) { @@ -867,7 +866,7 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) target->SetLayer( EDGE_N ); target->SetWidth( board->GetDesignSettings().m_EdgeSegmentWidth ); target->SetSize( Millimeter2iu( 5 ) ); - VECTOR2D cursorPos = view->ToWorld( controls->GetCursorPosition() ); + VECTOR2I cursorPos = controls->GetCursorPosition(); target->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); // Add a VIEW_GROUP that serves as a preview for the new item @@ -883,7 +882,7 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { - VECTOR2D cursorPos = view->ToWorld( controls->GetCursorPosition() ); + VECTOR2I cursorPos = controls->GetCursorPosition(); if( evt->IsCancel() ) { @@ -944,7 +943,7 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) } // Init the new item attributes - VECTOR2D cursorPos = view->ToWorld( controls->GetCursorPosition() ); + VECTOR2I cursorPos = controls->GetCursorPosition(); module->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); // Add a VIEW_GROUP that serves as a preview for the new item @@ -961,7 +960,7 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { - cursorPos = view->ToWorld( controls->GetCursorPosition() ); + cursorPos = controls->GetCursorPosition(); if( evt->IsCancel() ) { diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index f5f1c3b0ff..ab79ba8e84 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -81,7 +81,7 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) if( !makeSelection( selection ) ) return 0; - VECTOR2D dragPosition; // The last position of the cursor while dragging + VECTOR2I dragPosition; // The last position of the cursor while dragging m_dragging = false; // Are selected items being dragged? bool restore = false; // Should items' state be restored when finishing the tool? @@ -131,8 +131,7 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) if( m_dragging ) { // Drag items to the current cursor position - VECTOR2D movement = ( getView()->ToWorld( controls->GetCursorPosition() ) - - dragPosition ); + VECTOR2I movement = ( controls->GetCursorPosition() - dragPosition ); for( unsigned int i = 0; i < selection.items.GetCount(); ++i ) { BOARD_ITEM* item = static_cast( selection.items.GetPickedItem( i ) ); @@ -151,7 +150,7 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) } selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); - dragPosition = getView()->ToWorld( controls->GetCursorPosition() ); + dragPosition = controls->GetCursorPosition(); } else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) @@ -205,7 +204,7 @@ 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() ); + VECTOR2I cursor = getViewControls()->GetCursorPosition(); // Check if user wants to edit pad or module properties if( item->Type() == PCB_MODULE_T ) @@ -451,7 +450,7 @@ wxPoint EDIT_TOOL::getModificationPoint( const SELECTION_TOOL::SELECTION& aSelec } else { - VECTOR2I cursor = getView()->ToWorld( getViewControls()->GetCursorPosition() ); + VECTOR2I cursor = getViewControls()->GetCursorPosition(); return wxPoint( cursor.x, cursor.y ); } } From 2b62a85263d8461ee832249392a5a23b69908efe Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 14 Feb 2014 09:49:49 +0100 Subject: [PATCH 023/134] Refactoring: made VIEW, VIEW_CONTROLS, BOARD and PCB_EDIT_FRAME fields in DRAWING_TOOL. --- pcbnew/tools/drawing_tool.cpp | 285 ++++++++++++++++------------------ pcbnew/tools/drawing_tool.h | 16 +- 2 files changed, 146 insertions(+), 155 deletions(-) diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 0e4ea58424..f98372d8fa 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -55,6 +55,12 @@ DRAWING_TOOL::~DRAWING_TOOL() void DRAWING_TOOL::Reset( RESET_REASON aReason ) { + // Init variables used by every drawing tool + m_view = getView(); + m_controls = getViewControls(); + m_board = getModel( PCB_T ); + m_frame = getEditFrame(); + setTransitions(); } @@ -81,9 +87,6 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) int step = 0; - KIGFX::VIEW* view = getView(); - KIGFX::VIEW_CONTROLS* controls = getViewControls(); - BOARD* board = getModel( PCB_T ); DRAWSEGMENT graphic; DRAWSEGMENT helperLine; bool positive = true; @@ -91,25 +94,25 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) // Init the new item attributes graphic.SetShape( S_ARC ); graphic.SetAngle( 0.0 ); - graphic.SetWidth( board->GetDesignSettings().m_DrawSegmentWidth ); + graphic.SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth ); helperLine.SetShape( S_SEGMENT ); helperLine.SetLayer( DRAW_N ); helperLine.SetWidth( 1 ); // Add a VIEW_GROUP that serves as a preview for the new item - KIGFX::VIEW_GROUP preview( view ); - view->Add( &preview ); + KIGFX::VIEW_GROUP preview( m_view ); + m_view->Add( &preview ); - controls->ShowCursor( true ); - controls->SetSnapping( true ); + m_controls->ShowCursor( true ); + m_controls->SetSnapping( true ); Activate(); // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { - VECTOR2I cursorPos = controls->GetCursorPosition(); + VECTOR2I cursorPos = m_controls->GetCursorPosition(); if( evt->IsCancel() ) break; @@ -151,7 +154,7 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) } else { - controls->SetAutoPan( true ); + m_controls->SetAutoPan( true ); helperLine.SetStart( graphic.GetCenter() ); graphic.SetLayer( layer ); @@ -166,8 +169,8 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) if( wxPoint( cursorPos.x, cursorPos.y ) != graphic.GetCenter() ) { DRAWSEGMENT* newItem = new DRAWSEGMENT( graphic ); - view->Add( newItem ); - board->Add( newItem ); + m_view->Add( newItem ); + m_board->Add( newItem ); newItem->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } } @@ -217,10 +220,10 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) } } - controls->ShowCursor( false ); - controls->SetSnapping( false ); - controls->SetAutoPan( false ); - view->Remove( &preview ); + m_controls->ShowCursor( false ); + m_controls->SetSnapping( false ); + m_controls->SetAutoPan( false ); + m_view->Remove( &preview ); setTransitions(); @@ -228,24 +231,21 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) } -int DRAWING_TOOL::draw( STROKE_T aShape ) +int DRAWING_TOOL::draw( int aShape ) { bool started = false; - KIGFX::VIEW* view = getView(); - KIGFX::VIEW_CONTROLS* controls = getViewControls(); - BOARD* board = getModel( PCB_T ); DRAWSEGMENT graphic; // Init the new item attributes - graphic.SetShape( aShape ); - graphic.SetWidth( board->GetDesignSettings().m_DrawSegmentWidth ); + graphic.SetShape( (STROKE_T) aShape ); + graphic.SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth ); // Add a VIEW_GROUP that serves as a preview for the new item - KIGFX::VIEW_GROUP preview( view ); - view->Add( &preview ); + KIGFX::VIEW_GROUP preview( m_view ); + m_view->Add( &preview ); - controls->ShowCursor( true ); - controls->SetSnapping( true ); + m_controls->ShowCursor( true ); + m_controls->SetSnapping( true ); Activate(); @@ -254,7 +254,7 @@ int DRAWING_TOOL::draw( STROKE_T aShape ) { // Enable 45 degrees lines only mode by holding shift bool linesAngle45 = evt->Modifier( MD_SHIFT ); - VECTOR2I cursorPos = controls->GetCursorPosition(); + VECTOR2I cursorPos = m_controls->GetCursorPosition(); if( evt->IsCancel() ) break; @@ -276,7 +276,7 @@ int DRAWING_TOOL::draw( STROKE_T aShape ) { if( !started ) { - LAYER_NUM layer = getEditFrame()->GetScreen()->m_Active_Layer; + LAYER_NUM layer = m_frame->GetScreen()->m_Active_Layer; if( IsCopperLayer( layer ) ) { @@ -284,7 +284,7 @@ int DRAWING_TOOL::draw( STROKE_T aShape ) } else { - controls->SetAutoPan( true ); + m_controls->SetAutoPan( true ); graphic.SetStart( wxPoint( cursorPos.x, cursorPos.y ) ); graphic.SetLayer( layer ); @@ -298,8 +298,8 @@ int DRAWING_TOOL::draw( STROKE_T aShape ) if( wxPoint( cursorPos.x, cursorPos.y ) != graphic.GetStart() ) { DRAWSEGMENT* newItem = new DRAWSEGMENT( graphic ); - view->Add( newItem ); - board->Add( newItem ); + m_view->Add( newItem ); + m_board->Add( newItem ); newItem->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); if( m_continous ) @@ -325,7 +325,7 @@ int DRAWING_TOOL::draw( STROKE_T aShape ) // Snap the new line to the grid // TODO fix it, does not work good.. VECTOR2D newLineEnd = VECTOR2D( graphic.GetStart() ) + newLineVector; - VECTOR2D snapped = view->GetGAL()->GetGridPoint( newLineEnd ); + VECTOR2D snapped = m_view->GetGAL()->GetGridPoint( newLineEnd ); graphic.SetEnd( wxPoint( snapped.x, snapped.y ) ); } @@ -339,10 +339,10 @@ int DRAWING_TOOL::draw( STROKE_T aShape ) } } - controls->ShowCursor( false ); - controls->SetSnapping( false ); - controls->SetAutoPan( false ); - view->Remove( &preview ); + m_controls->ShowCursor( false ); + m_controls->SetSnapping( false ); + m_controls->SetAutoPan( false ); + m_view->Remove( &preview ); setTransitions(); return 0; @@ -351,11 +351,8 @@ int DRAWING_TOOL::draw( STROKE_T aShape ) int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) { - KIGFX::VIEW* view = getView(); - KIGFX::VIEW_CONTROLS* controls = getViewControls(); - // Init the new item attributes - TEXTE_PCB* newText = getEditFrame()->CreateTextePcb( NULL ); + TEXTE_PCB* newText = m_frame->CreateTextePcb( NULL ); if( newText == NULL ) { setTransitions(); @@ -363,25 +360,25 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) } // Add a VIEW_GROUP that serves as a preview for the new item - KIGFX::VIEW_GROUP preview( view ); + KIGFX::VIEW_GROUP preview( m_view ); preview.Add( newText ); - view->Add( &preview ); + m_view->Add( &preview ); - controls->ShowCursor( true ); - controls->SetSnapping( true ); - controls->SetAutoPan( true ); + m_controls->ShowCursor( true ); + m_controls->SetSnapping( true ); + m_controls->SetAutoPan( true ); Activate(); // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { - VECTOR2I cursorPos = controls->GetCursorPosition(); + VECTOR2I cursorPos = m_controls->GetCursorPosition(); if( evt->IsCancel() ) { // it was already added by CreateTextPcb() - getModel( PCB_T )->Delete( newText ); + m_board->Delete( newText ); break; } @@ -389,7 +386,7 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) { if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) { - newText->Rotate( newText->GetPosition(), getEditFrame()->GetRotationAngle() ); + newText->Rotate( newText->GetPosition(), m_frame->GetRotationAngle() ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) @@ -402,8 +399,8 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) else if( evt->IsClick( BUT_LEFT ) ) { newText->ClearFlags(); - view->Add( newText ); - // board->Add( newText ); // it is already added by CreateTextePcb() + m_view->Add( newText ); + // m_board->Add( newText ); // it is already added by CreateTextePcb() newText->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); break; } @@ -417,10 +414,10 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) } } - controls->ShowCursor( false ); - controls->SetSnapping( false ); - controls->SetAutoPan( false ); - view->Remove( &preview ); + m_controls->ShowCursor( false ); + m_controls->SetSnapping( false ); + m_controls->SetAutoPan( false ); + m_view->Remove( &preview ); setTransitions(); @@ -434,14 +431,11 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) int step = 0; - KIGFX::VIEW* view = getView(); - KIGFX::VIEW_CONTROLS* controls = getViewControls(); - BOARD* board = getModel( PCB_T ); - DIMENSION* dimension = new DIMENSION( board ); + DIMENSION* dimension = new DIMENSION( m_board ); // Init the new item attributes - dimension->Text().SetSize( board->GetDesignSettings().m_PcbTextSize ); - int width = board->GetDesignSettings().m_PcbTextWidth; + dimension->Text().SetSize( m_board->GetDesignSettings().m_PcbTextSize ); + int width = m_board->GetDesignSettings().m_PcbTextWidth; int maxthickness = Clamp_Text_PenSize( width, dimension->Text().GetSize() ); if( width > maxthickness ) @@ -453,18 +447,18 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) dimension->AdjustDimensionDetails(); // Add a VIEW_GROUP that serves as a preview for the new item - KIGFX::VIEW_GROUP preview( view ); - view->Add( &preview ); + KIGFX::VIEW_GROUP preview( m_view ); + m_view->Add( &preview ); - controls->ShowCursor( true ); - controls->SetSnapping( true ); + m_controls->ShowCursor( true ); + m_controls->SetSnapping( true ); Activate(); // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { - VECTOR2I cursorPos = controls->GetCursorPosition(); + VECTOR2I cursorPos = m_controls->GetCursorPosition(); if( evt->IsCancel() ) { @@ -491,7 +485,7 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) { case 0: { - LAYER_NUM layer = getEditFrame()->GetScreen()->m_Active_Layer; + LAYER_NUM layer = m_frame->GetScreen()->m_Active_Layer; if( IsCopperLayer( layer ) ) { @@ -500,7 +494,7 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) } else { - controls->SetAutoPan( true ); + m_controls->SetAutoPan( true ); dimension->SetLayer( layer ); dimension->SetOrigin( wxPoint( cursorPos.x, cursorPos.y ) ); @@ -514,8 +508,8 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) { if( wxPoint( cursorPos.x, cursorPos.y ) != dimension->GetPosition() ) { - view->Add( dimension ); - board->Add( dimension ); + m_view->Add( dimension ); + m_board->Add( dimension ); dimension->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } } @@ -552,10 +546,10 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) } } - controls->ShowCursor( false ); - controls->SetSnapping( false ); - controls->SetAutoPan( false ); - view->Remove( &preview ); + m_controls->ShowCursor( false ); + m_controls->SetSnapping( false ); + m_controls->SetAutoPan( false ); + m_view->Remove( &preview ); setTransitions(); @@ -565,20 +559,16 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) int DRAWING_TOOL::DrawZone( TOOL_EVENT& aEvent ) { - KIGFX::VIEW* view = getView(); - KIGFX::VIEW_CONTROLS* controls = getViewControls(); - BOARD* board = getModel( PCB_T ); - ZONE_CONTAINER* zone = new ZONE_CONTAINER( board ); - PCB_EDIT_FRAME* editFrame = getEditFrame(); + ZONE_CONTAINER* zone = new ZONE_CONTAINER( m_board ); // Get the current, default settings for zones - ZONE_SETTINGS zoneInfo = editFrame->GetZoneSettings(); + ZONE_SETTINGS zoneInfo = m_frame->GetZoneSettings(); ZONE_EDIT_T dialogResult; - if( IsCopperLayer( editFrame->GetScreen()->m_Active_Layer ) ) - dialogResult = InvokeCopperZonesEditor( editFrame, &zoneInfo ); + if( IsCopperLayer( m_frame->GetScreen()->m_Active_Layer ) ) + dialogResult = InvokeCopperZonesEditor( m_frame, &zoneInfo ); else - dialogResult = InvokeNonCopperZonesEditor( editFrame, zone, &zoneInfo ); + dialogResult = InvokeNonCopperZonesEditor( m_frame, zone, &zoneInfo ); if( dialogResult == ZONE_ABORT ) { @@ -588,7 +578,7 @@ int DRAWING_TOOL::DrawZone( TOOL_EVENT& aEvent ) } zoneInfo.ExportSetting( *zone ); - editFrame->SetTopLayer( zoneInfo.m_CurrentZone_Layer ); + m_frame->SetTopLayer( zoneInfo.m_CurrentZone_Layer ); DRAWSEGMENT* helperLine = new DRAWSEGMENT; helperLine->SetShape( S_SEGMENT ); @@ -596,23 +586,23 @@ int DRAWING_TOOL::DrawZone( TOOL_EVENT& aEvent ) helperLine->SetWidth( 1 ); // Add a VIEW_GROUP that serves as a preview for the new item - KIGFX::VIEW_GROUP preview( view ); - view->Add( &preview ); + KIGFX::VIEW_GROUP preview( m_view ); + m_view->Add( &preview ); - controls->ShowCursor( true ); - controls->SetSnapping( true ); - controls->SetAutoPan( true ); + m_controls->ShowCursor( true ); + m_controls->SetSnapping( true ); + m_controls->SetAutoPan( true ); Activate(); - VECTOR2I lastCursorPos = controls->GetCursorPosition(); + VECTOR2I lastCursorPos = m_controls->GetCursorPosition(); // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { // Enable 45 degrees lines only mode by holding shift bool linesAngle45 = evt->Modifier( MD_SHIFT ); - VECTOR2I cursorPos = controls->GetCursorPosition(); + VECTOR2I cursorPos = m_controls->GetCursorPosition(); if( evt->IsCancel() ) { @@ -631,10 +621,10 @@ int DRAWING_TOOL::DrawZone( TOOL_EVENT& aEvent ) zone->Outline()->CloseLastContour(); zone->Outline()->RemoveNullSegments(); - board->Add( zone ); - view->Add( zone ); + m_board->Add( zone ); + m_view->Add( zone ); - editFrame->Fill_Zone( zone ); + m_frame->Fill_Zone( zone ); zone->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } else @@ -684,7 +674,7 @@ int DRAWING_TOOL::DrawZone( TOOL_EVENT& aEvent ) // Snap the new line to the grid // TODO fix it, does not work good.. VECTOR2D newLineEnd = VECTOR2D( helperLine->GetStart() ) + newLineVector; - VECTOR2D snapped = view->GetGAL()->GetGridPoint( newLineEnd ); + VECTOR2D snapped = m_view->GetGAL()->GetGridPoint( newLineEnd ); helperLine->SetEnd( wxPoint( snapped.x, snapped.y ) ); } @@ -698,10 +688,10 @@ int DRAWING_TOOL::DrawZone( TOOL_EVENT& aEvent ) } } - controls->ShowCursor( false ); - controls->SetSnapping( false ); - controls->SetAutoPan( false ); - view->Remove( &preview ); + m_controls->ShowCursor( false ); + m_controls->SetSnapping( false ); + m_controls->SetAutoPan( false ); + m_view->Remove( &preview ); // delete helper lines preview.FreeItems(); @@ -714,16 +704,12 @@ int DRAWING_TOOL::DrawZone( TOOL_EVENT& aEvent ) int DRAWING_TOOL::DrawKeepout( TOOL_EVENT& aEvent ) { - KIGFX::VIEW* view = getView(); - KIGFX::VIEW_CONTROLS* controls = getViewControls(); - BOARD* board = getModel( PCB_T ); - ZONE_CONTAINER* keepout = new ZONE_CONTAINER( board ); - PCB_EDIT_FRAME* editFrame = getEditFrame(); + ZONE_CONTAINER* keepout = new ZONE_CONTAINER( m_board ); // Get the current, default settings for zones - ZONE_SETTINGS zoneInfo = editFrame->GetZoneSettings(); + ZONE_SETTINGS zoneInfo = m_frame->GetZoneSettings(); - ZONE_EDIT_T dialogResult = InvokeKeepoutAreaEditor( editFrame, &zoneInfo ); + ZONE_EDIT_T dialogResult = InvokeKeepoutAreaEditor( m_frame, &zoneInfo ); if( dialogResult == ZONE_ABORT ) { delete keepout; @@ -732,7 +718,7 @@ int DRAWING_TOOL::DrawKeepout( TOOL_EVENT& aEvent ) } zoneInfo.ExportSetting( *keepout ); - editFrame->SetTopLayer( zoneInfo.m_CurrentZone_Layer ); + m_frame->SetTopLayer( zoneInfo.m_CurrentZone_Layer ); DRAWSEGMENT* helperLine = new DRAWSEGMENT; helperLine->SetShape( S_SEGMENT ); @@ -740,23 +726,23 @@ int DRAWING_TOOL::DrawKeepout( TOOL_EVENT& aEvent ) helperLine->SetWidth( 1 ); // Add a VIEW_GROUP that serves as a preview for the new item - KIGFX::VIEW_GROUP preview( view ); - view->Add( &preview ); + KIGFX::VIEW_GROUP preview( m_view ); + m_view->Add( &preview ); - controls->ShowCursor( true ); - controls->SetSnapping( true ); - controls->SetAutoPan( true ); + m_controls->ShowCursor( true ); + m_controls->SetSnapping( true ); + m_controls->SetAutoPan( true ); Activate(); - VECTOR2I lastCursorPos = controls->GetCursorPosition(); + VECTOR2I lastCursorPos = m_controls->GetCursorPosition(); // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { // Enable 45 degrees lines only mode by holding shift bool linesAngle45 = evt->Modifier( MD_SHIFT ); - VECTOR2I cursorPos = controls->GetCursorPosition(); + VECTOR2I cursorPos = m_controls->GetCursorPosition(); if( evt->IsCancel() ) { @@ -775,8 +761,8 @@ int DRAWING_TOOL::DrawKeepout( TOOL_EVENT& aEvent ) keepout->Outline()->CloseLastContour(); keepout->Outline()->RemoveNullSegments(); - board->Add( keepout ); - view->Add( keepout ); + m_board->Add( keepout ); + m_view->Add( keepout ); keepout->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } @@ -827,7 +813,7 @@ int DRAWING_TOOL::DrawKeepout( TOOL_EVENT& aEvent ) // Snap the new line to the grid // TODO fix it, does not work good.. VECTOR2D newLineEnd = VECTOR2D( helperLine->GetStart() ) + newLineVector; - VECTOR2D snapped = view->GetGAL()->GetGridPoint( newLineEnd ); + VECTOR2D snapped = m_view->GetGAL()->GetGridPoint( newLineEnd ); helperLine->SetEnd( wxPoint( snapped.x, snapped.y ) ); } @@ -841,10 +827,10 @@ int DRAWING_TOOL::DrawKeepout( TOOL_EVENT& aEvent ) } } - controls->ShowCursor( false ); - controls->SetSnapping( false ); - controls->SetAutoPan( false ); - view->Remove( &preview ); + m_controls->ShowCursor( false ); + m_controls->SetSnapping( false ); + m_controls->SetAutoPan( false ); + m_view->Remove( &preview ); // delete helper lines preview.FreeItems(); @@ -857,32 +843,29 @@ int DRAWING_TOOL::DrawKeepout( TOOL_EVENT& aEvent ) int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) { - KIGFX::VIEW* view = getView(); - KIGFX::VIEW_CONTROLS* controls = getViewControls(); - BOARD* board = getModel( PCB_T ); - PCB_TARGET* target = new PCB_TARGET( board ); + PCB_TARGET* target = new PCB_TARGET( m_board ); // Init the new item attributes target->SetLayer( EDGE_N ); - target->SetWidth( board->GetDesignSettings().m_EdgeSegmentWidth ); + target->SetWidth( m_board->GetDesignSettings().m_EdgeSegmentWidth ); target->SetSize( Millimeter2iu( 5 ) ); - VECTOR2I cursorPos = controls->GetCursorPosition(); + VECTOR2I cursorPos = m_controls->GetCursorPosition(); target->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); // Add a VIEW_GROUP that serves as a preview for the new item - KIGFX::VIEW_GROUP preview( view ); + KIGFX::VIEW_GROUP preview( m_view ); preview.Add( target ); - view->Add( &preview ); + m_view->Add( &preview ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - controls->SetSnapping( true ); + m_controls->SetSnapping( true ); Activate(); // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { - VECTOR2I cursorPos = controls->GetCursorPosition(); + VECTOR2I cursorPos = m_controls->GetCursorPosition(); if( evt->IsCancel() ) { @@ -905,8 +888,8 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) else if( evt->IsClick( BUT_LEFT ) ) { - view->Add( target ); - board->Add( target ); + m_view->Add( target ); + m_board->Add( target ); target->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); break; } @@ -918,9 +901,9 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) } } - controls->SetSnapping( false ); - controls->SetAutoPan( false ); - view->Remove( &preview ); + m_controls->SetSnapping( false ); + m_controls->SetAutoPan( false ); + m_view->Remove( &preview ); setTransitions(); @@ -930,12 +913,8 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) { - KIGFX::VIEW* view = getView(); - KIGFX::VIEW_CONTROLS* controls = getViewControls(); - BOARD* board = getModel( PCB_T ); - PCB_EDIT_FRAME* editFrame = getEditFrame(); - MODULE* module = editFrame->LoadModuleFromLibrary( wxEmptyString, - editFrame->GetFootprintLibraryTable(), true, NULL ); + MODULE* module = m_frame->LoadModuleFromLibrary( wxEmptyString, + m_frame->GetFootprintLibraryTable(), true, NULL ); if( module == NULL ) { setTransitions(); @@ -943,28 +922,28 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) } // Init the new item attributes - VECTOR2I cursorPos = controls->GetCursorPosition(); + VECTOR2I cursorPos = m_controls->GetCursorPosition(); module->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); // Add a VIEW_GROUP that serves as a preview for the new item - KIGFX::VIEW_GROUP preview( view ); + KIGFX::VIEW_GROUP preview( m_view ); preview.Add( module ); module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW_GROUP::Add ), &preview ) ); - view->Add( &preview ); + m_view->Add( &preview ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - controls->SetSnapping( true ); + m_controls->SetSnapping( true ); Activate(); // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { - cursorPos = controls->GetCursorPosition(); + cursorPos = m_controls->GetCursorPosition(); if( evt->IsCancel() ) { - board->Delete( module ); + m_board->Delete( module ); break; } @@ -972,7 +951,7 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) { if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) { - module->Rotate( module->GetPosition(), getEditFrame()->GetRotationAngle() ); + module->Rotate( module->GetPosition(), m_frame->GetRotationAngle() ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) @@ -984,8 +963,8 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) else if( evt->IsClick( BUT_LEFT ) ) { - module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), view ) ); - view->Add( module ); + module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), m_view ) ); + m_view->Add( module ); module->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); break; } @@ -997,9 +976,9 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) } } - controls->SetSnapping( false ); - controls->SetAutoPan( false ); - view->Remove( &preview ); + m_controls->SetSnapping( false ); + m_controls->SetAutoPan( false ); + m_view->Remove( &preview ); setTransitions(); diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index 149eccda6a..9881e353c9 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -26,7 +26,14 @@ #define __DRAWING_TOOL_H #include -#include + +namespace KIGFX +{ + class VIEW; + class VIEW_CONTROLS; +} +class BOARD; +class PCB_EDIT_FRAME; /** * Class DRAWING_TOOL @@ -69,7 +76,7 @@ public: private: ///> Starts drawing a selected shape. - int draw( STROKE_T aShape ); + int draw( int aShape ); ///> Sets up handlers for various events. void setTransitions(); @@ -77,6 +84,11 @@ private: ///> Should drawing be stopped after drawing one object or should it continue with another one. bool m_continous; + KIGFX::VIEW* m_view; + KIGFX::VIEW_CONTROLS* m_controls; + BOARD* m_board; + PCB_EDIT_FRAME* m_frame; + // How does line width change after one -/+ key press. static const int WIDTH_STEP = 100000; }; From b7d43776218ec255ef4738b400362eb8485b8160 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 14 Feb 2014 10:47:43 +0100 Subject: [PATCH 024/134] Refactoring: zones and keepout areas are drawn using the same function. --- pcbnew/tools/drawing_tool.cpp | 677 ++++++++++++++-------------------- pcbnew/tools/drawing_tool.h | 7 +- 2 files changed, 291 insertions(+), 393 deletions(-) diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index f98372d8fa..af5b6f6a49 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -231,124 +231,6 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) } -int DRAWING_TOOL::draw( int aShape ) -{ - bool started = false; - DRAWSEGMENT graphic; - - // Init the new item attributes - graphic.SetShape( (STROKE_T) aShape ); - graphic.SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth ); - - // Add a VIEW_GROUP that serves as a preview for the new item - KIGFX::VIEW_GROUP preview( m_view ); - m_view->Add( &preview ); - - m_controls->ShowCursor( true ); - m_controls->SetSnapping( true ); - - Activate(); - - // Main loop: keep receiving events - while( OPT_TOOL_EVENT evt = Wait() ) - { - // Enable 45 degrees lines only mode by holding shift - bool linesAngle45 = evt->Modifier( MD_SHIFT ); - VECTOR2I cursorPos = m_controls->GetCursorPosition(); - - if( evt->IsCancel() ) - break; - - else if( evt->IsKeyUp() ) - { - int width = graphic.GetWidth(); - - // Modify the new item width - if( evt->KeyCode() == '-' && width > WIDTH_STEP ) - graphic.SetWidth( width - WIDTH_STEP ); - else if( evt->KeyCode() == '=' ) - graphic.SetWidth( width + WIDTH_STEP ); - - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - - else if( evt->IsClick( BUT_LEFT ) ) - { - if( !started ) - { - LAYER_NUM layer = m_frame->GetScreen()->m_Active_Layer; - - if( IsCopperLayer( layer ) ) - { - DisplayInfoMessage( NULL, _( "Graphic not allowed on Copper layers" ) ); - } - else - { - m_controls->SetAutoPan( true ); - - graphic.SetStart( wxPoint( cursorPos.x, cursorPos.y ) ); - graphic.SetLayer( layer ); - preview.Add( &graphic ); - - started = true; - } - } - else - { - if( wxPoint( cursorPos.x, cursorPos.y ) != graphic.GetStart() ) - { - DRAWSEGMENT* newItem = new DRAWSEGMENT( graphic ); - m_view->Add( newItem ); - m_board->Add( newItem ); - newItem->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - - if( m_continous ) - graphic.SetStart( graphic.GetEnd() ); // This is the origin point for a new item - else - break; - } - else // User has clicked twice in the same spot - break; // seems like a clear sign that the drawing is finished - } - } - - else if( evt->IsMotion() && started ) - { - // 45 degree lines - if( linesAngle45 && aShape == S_SEGMENT ) - { - VECTOR2D lineVector( wxPoint( cursorPos.x, cursorPos.y ) - graphic.GetStart() ); - double angle = lineVector.Angle(); - - double newAngle = round( angle / ( M_PI / 4.0 ) ) * M_PI / 4.0; - VECTOR2D newLineVector = lineVector.Rotate( newAngle - angle ); - - // Snap the new line to the grid // TODO fix it, does not work good.. - VECTOR2D newLineEnd = VECTOR2D( graphic.GetStart() ) + newLineVector; - VECTOR2D snapped = m_view->GetGAL()->GetGridPoint( newLineEnd ); - - graphic.SetEnd( wxPoint( snapped.x, snapped.y ) ); - } - else - { - graphic.SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); - } - - // Show a preview of the item - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - } - - m_controls->ShowCursor( false ); - m_controls->SetSnapping( false ); - m_controls->SetAutoPan( false ); - m_view->Remove( &preview ); - setTransitions(); - - return 0; -} - - int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) { // Init the new item attributes @@ -559,285 +441,13 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) int DRAWING_TOOL::DrawZone( TOOL_EVENT& aEvent ) { - ZONE_CONTAINER* zone = new ZONE_CONTAINER( m_board ); - - // Get the current, default settings for zones - ZONE_SETTINGS zoneInfo = m_frame->GetZoneSettings(); - - ZONE_EDIT_T dialogResult; - if( IsCopperLayer( m_frame->GetScreen()->m_Active_Layer ) ) - dialogResult = InvokeCopperZonesEditor( m_frame, &zoneInfo ); - else - dialogResult = InvokeNonCopperZonesEditor( m_frame, zone, &zoneInfo ); - - if( dialogResult == ZONE_ABORT ) - { - delete zone; - setTransitions(); - return 0; - } - - zoneInfo.ExportSetting( *zone ); - m_frame->SetTopLayer( zoneInfo.m_CurrentZone_Layer ); - - DRAWSEGMENT* helperLine = new DRAWSEGMENT; - helperLine->SetShape( S_SEGMENT ); - helperLine->SetLayer( zoneInfo.m_CurrentZone_Layer ); - helperLine->SetWidth( 1 ); - - // Add a VIEW_GROUP that serves as a preview for the new item - KIGFX::VIEW_GROUP preview( m_view ); - m_view->Add( &preview ); - - m_controls->ShowCursor( true ); - m_controls->SetSnapping( true ); - m_controls->SetAutoPan( true ); - - Activate(); - - VECTOR2I lastCursorPos = m_controls->GetCursorPosition(); - - // Main loop: keep receiving events - while( OPT_TOOL_EVENT evt = Wait() ) - { - // Enable 45 degrees lines only mode by holding shift - bool linesAngle45 = evt->Modifier( MD_SHIFT ); - VECTOR2I cursorPos = m_controls->GetCursorPosition(); - - if( evt->IsCancel() ) - { - delete zone; - break; - } - - else if( evt->IsClick( BUT_LEFT ) ) - { - if( lastCursorPos == cursorPos || - ( zone->GetNumCorners() > 0 && wxPoint( cursorPos.x, cursorPos.y ) == zone->Outline()->GetPos( 0 ) ) ) // TODO better conditions - { - if( zone->GetNumCorners() > 2 ) - { - // Finish the zone - zone->Outline()->CloseLastContour(); - zone->Outline()->RemoveNullSegments(); - - m_board->Add( zone ); - m_view->Add( zone ); - - m_frame->Fill_Zone( zone ); - zone->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - else - { - // That is not a valid zone - delete zone; - } - - break; - } - else - { - if( zone->GetNumCorners() == 0 ) - { - zone->Outline()->Start( zoneInfo.m_CurrentZone_Layer, - cursorPos.x, - cursorPos.y, - zone->GetHatchStyle() ); - helperLine->SetStart( wxPoint( cursorPos.x, cursorPos.y ) ); - preview.Add( helperLine ); - } - else - { - zone->AppendCorner( helperLine->GetEnd() ); - helperLine = new DRAWSEGMENT( *helperLine ); - preview.Add( helperLine ); - helperLine->SetStart( helperLine->GetEnd() ); - } - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - - lastCursorPos = cursorPos; - } - - else if( evt->IsMotion() ) - { - helperLine->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); - - // 45 degree lines - if( linesAngle45 ) - { - VECTOR2D lineVector( wxPoint( cursorPos.x, cursorPos.y ) - helperLine->GetStart() ); - double angle = lineVector.Angle(); - - double newAngle = round( angle / ( M_PI / 4.0 ) ) * M_PI / 4.0; - VECTOR2D newLineVector = lineVector.Rotate( newAngle - angle ); - - // Snap the new line to the grid // TODO fix it, does not work good.. - VECTOR2D newLineEnd = VECTOR2D( helperLine->GetStart() ) + newLineVector; - VECTOR2D snapped = m_view->GetGAL()->GetGridPoint( newLineEnd ); - - helperLine->SetEnd( wxPoint( snapped.x, snapped.y ) ); - } - else - { - helperLine->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); - } - - // Show a preview of the item - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - } - - m_controls->ShowCursor( false ); - m_controls->SetSnapping( false ); - m_controls->SetAutoPan( false ); - m_view->Remove( &preview ); - - // delete helper lines - preview.FreeItems(); - - setTransitions(); - - return 0; + return drawZone( false ); } int DRAWING_TOOL::DrawKeepout( TOOL_EVENT& aEvent ) { - ZONE_CONTAINER* keepout = new ZONE_CONTAINER( m_board ); - - // Get the current, default settings for zones - ZONE_SETTINGS zoneInfo = m_frame->GetZoneSettings(); - - ZONE_EDIT_T dialogResult = InvokeKeepoutAreaEditor( m_frame, &zoneInfo ); - if( dialogResult == ZONE_ABORT ) - { - delete keepout; - setTransitions(); - return 0; - } - - zoneInfo.ExportSetting( *keepout ); - m_frame->SetTopLayer( zoneInfo.m_CurrentZone_Layer ); - - DRAWSEGMENT* helperLine = new DRAWSEGMENT; - helperLine->SetShape( S_SEGMENT ); - helperLine->SetLayer( zoneInfo.m_CurrentZone_Layer ); - helperLine->SetWidth( 1 ); - - // Add a VIEW_GROUP that serves as a preview for the new item - KIGFX::VIEW_GROUP preview( m_view ); - m_view->Add( &preview ); - - m_controls->ShowCursor( true ); - m_controls->SetSnapping( true ); - m_controls->SetAutoPan( true ); - - Activate(); - - VECTOR2I lastCursorPos = m_controls->GetCursorPosition(); - - // Main loop: keep receiving events - while( OPT_TOOL_EVENT evt = Wait() ) - { - // Enable 45 degrees lines only mode by holding shift - bool linesAngle45 = evt->Modifier( MD_SHIFT ); - VECTOR2I cursorPos = m_controls->GetCursorPosition(); - - if( evt->IsCancel() ) - { - delete keepout; - break; - } - - else if( evt->IsClick( BUT_LEFT ) ) - { - if( lastCursorPos == cursorPos || - ( keepout->GetNumCorners() > 0 && wxPoint( cursorPos.x, cursorPos.y ) == keepout->Outline()->GetPos( 0 ) ) ) // TODO better conditions - { - if( keepout->GetNumCorners() > 2 ) - { - // Finish the zone - keepout->Outline()->CloseLastContour(); - keepout->Outline()->RemoveNullSegments(); - - m_board->Add( keepout ); - m_view->Add( keepout ); - - keepout->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - else - { - // That is not a valid zone - delete keepout; - } - - break; - } - else - { - if( keepout->GetNumCorners() == 0 ) - { - keepout->Outline()->Start( zoneInfo.m_CurrentZone_Layer, - cursorPos.x, - cursorPos.y, - keepout->GetHatchStyle() ); - helperLine->SetStart( wxPoint( cursorPos.x, cursorPos.y ) ); - preview.Add( helperLine ); - } - else - { - keepout->AppendCorner( helperLine->GetEnd() ); - helperLine = new DRAWSEGMENT( *helperLine ); - preview.Add( helperLine ); - helperLine->SetStart( helperLine->GetEnd() ); - } - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - - lastCursorPos = cursorPos; - } - - else if( evt->IsMotion() ) - { - helperLine->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); - - // 45 degree lines - if( linesAngle45 ) - { - VECTOR2D lineVector( wxPoint( cursorPos.x, cursorPos.y ) - helperLine->GetStart() ); - double angle = lineVector.Angle(); - - double newAngle = round( angle / ( M_PI / 4.0 ) ) * M_PI / 4.0; - VECTOR2D newLineVector = lineVector.Rotate( newAngle - angle ); - - // Snap the new line to the grid // TODO fix it, does not work good.. - VECTOR2D newLineEnd = VECTOR2D( helperLine->GetStart() ) + newLineVector; - VECTOR2D snapped = m_view->GetGAL()->GetGridPoint( newLineEnd ); - - helperLine->SetEnd( wxPoint( snapped.x, snapped.y ) ); - } - else - { - helperLine->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); - } - - // Show a preview of the item - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - } - - m_controls->ShowCursor( false ); - m_controls->SetSnapping( false ); - m_controls->SetAutoPan( false ); - m_view->Remove( &preview ); - - // delete helper lines - preview.FreeItems(); - - setTransitions(); - - return 0; + return drawZone( true ); } @@ -986,6 +596,289 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) } +int DRAWING_TOOL::draw( int aShape ) +{ + // Only two shapes are currently supported + assert( aShape == S_SEGMENT || aShape == S_CIRCLE ); + + bool started = false; + DRAWSEGMENT graphic; + + // Init the new item attributes + graphic.SetShape( (STROKE_T) aShape ); + graphic.SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth ); + + // Add a VIEW_GROUP that serves as a preview for the new item + KIGFX::VIEW_GROUP preview( m_view ); + m_view->Add( &preview ); + + m_controls->ShowCursor( true ); + m_controls->SetSnapping( true ); + + Activate(); + + // Main loop: keep receiving events + while( OPT_TOOL_EVENT evt = Wait() ) + { + // Enable 45 degrees lines only mode by holding shift + bool linesAngle45 = evt->Modifier( MD_SHIFT ); + VECTOR2I cursorPos = m_controls->GetCursorPosition(); + + if( evt->IsCancel() ) + break; + + else if( evt->IsKeyUp() ) + { + int width = graphic.GetWidth(); + + // Modify the new item width + if( evt->KeyCode() == '-' && width > WIDTH_STEP ) + graphic.SetWidth( width - WIDTH_STEP ); + else if( evt->KeyCode() == '=' ) + graphic.SetWidth( width + WIDTH_STEP ); + + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + + else if( evt->IsClick( BUT_LEFT ) ) + { + if( !started ) + { + LAYER_NUM layer = m_frame->GetScreen()->m_Active_Layer; + + if( IsCopperLayer( layer ) ) + { + DisplayInfoMessage( NULL, _( "Graphic not allowed on Copper layers" ) ); + } + else + { + m_controls->SetAutoPan( true ); + + graphic.SetStart( wxPoint( cursorPos.x, cursorPos.y ) ); + graphic.SetLayer( layer ); + preview.Add( &graphic ); + + started = true; + } + } + else + { + if( wxPoint( cursorPos.x, cursorPos.y ) != graphic.GetStart() ) + { + DRAWSEGMENT* newItem = new DRAWSEGMENT( graphic ); + m_view->Add( newItem ); + m_board->Add( newItem ); + newItem->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + + if( m_continous ) + graphic.SetStart( graphic.GetEnd() ); // This is the origin point for a new item + else + break; + } + else // User has clicked twice in the same spot + break; // seems like a clear sign that the drawing is finished + } + } + + else if( evt->IsMotion() && started ) + { + // 45 degree lines + if( linesAngle45 && aShape == S_SEGMENT ) + { + VECTOR2D lineVector( wxPoint( cursorPos.x, cursorPos.y ) - graphic.GetStart() ); + double angle = lineVector.Angle(); + + double newAngle = round( angle / ( M_PI / 4.0 ) ) * M_PI / 4.0; + VECTOR2D newLineVector = lineVector.Rotate( newAngle - angle ); + + // Snap the new line to the grid // TODO fix it, does not work good.. + VECTOR2D newLineEnd = VECTOR2D( graphic.GetStart() ) + newLineVector; + VECTOR2D snapped = m_view->GetGAL()->GetGridPoint( newLineEnd ); + + graphic.SetEnd( wxPoint( snapped.x, snapped.y ) ); + } + else + { + graphic.SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); + } + + // Show a preview of the item + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + } + + m_controls->ShowCursor( false ); + m_controls->SetSnapping( false ); + m_controls->SetAutoPan( false ); + m_view->Remove( &preview ); + setTransitions(); + + return 0; +} + + +int DRAWING_TOOL::drawZone( bool aKeepout ) +{ + ZONE_CONTAINER* zone = new ZONE_CONTAINER( m_board ); + + // Get the current, default settings for zones + ZONE_SETTINGS zoneInfo = m_frame->GetZoneSettings(); + zoneInfo.m_CurrentZone_Layer = m_frame->GetScreen()->m_Active_Layer; + + // Show options dialog + ZONE_EDIT_T dialogResult; + if( aKeepout ) + dialogResult = InvokeKeepoutAreaEditor( m_frame, &zoneInfo ); + else + { + if( IsCopperLayer( zoneInfo.m_CurrentZone_Layer ) ) + dialogResult = InvokeCopperZonesEditor( m_frame, &zoneInfo ); + else + dialogResult = InvokeNonCopperZonesEditor( m_frame, NULL, &zoneInfo ); + } + + if( dialogResult == ZONE_ABORT ) + { + delete zone; + setTransitions(); + + return 0; + } + + // Apply the selected settings + zoneInfo.ExportSetting( *zone ); + m_frame->SetTopLayer( zoneInfo.m_CurrentZone_Layer ); + + // Helper line represents the currently drawn line of the zone polygon + DRAWSEGMENT* helperLine = new DRAWSEGMENT; + helperLine->SetShape( S_SEGMENT ); + helperLine->SetLayer( zoneInfo.m_CurrentZone_Layer ); + helperLine->SetWidth( 1 ); + + // Add a VIEW_GROUP that serves as a preview for the new item + KIGFX::VIEW_GROUP preview( m_view ); + m_view->Add( &preview ); + + m_controls->ShowCursor( true ); + m_controls->SetSnapping( true ); + m_controls->SetAutoPan( true ); + + Activate(); + + VECTOR2I lastCursorPos = m_controls->GetCursorPosition(); + VECTOR2I origin; + int numPoints = 0; + + // Main loop: keep receiving events + while( OPT_TOOL_EVENT evt = Wait() ) + { + // Enable 45 degrees lines only mode by holding shift + bool linesAngle45 = evt->Modifier( MD_SHIFT ); + VECTOR2I cursorPos = m_controls->GetCursorPosition(); + + if( evt->IsCancel() ) + { + delete zone; + break; + } + + else if( evt->IsClick( BUT_LEFT ) ) + { + if( lastCursorPos == cursorPos || ( numPoints > 0 && cursorPos == origin ) ) + { + if( numPoints > 2 ) + { + // Finish the zone + zone->Outline()->CloseLastContour(); + zone->Outline()->RemoveNullSegments(); + + m_board->Add( zone ); + m_view->Add( zone ); + + if( !aKeepout ) + m_frame->Fill_Zone( zone ); + + zone->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + else + { + // If there are less than 3 points, then it is not a valid zone + delete zone; + } + + break; + } + else + { + if( numPoints == 0 ) + { + // Add the first point + zone->Outline()->Start( zoneInfo.m_CurrentZone_Layer, + cursorPos.x, + cursorPos.y, + zone->GetHatchStyle() ); + helperLine->SetStart( wxPoint( cursorPos.x, cursorPos.y ) ); + origin = cursorPos; + preview.Add( helperLine ); + } + else + { + zone->AppendCorner( helperLine->GetEnd() ); + helperLine = new DRAWSEGMENT( *helperLine ); + helperLine->SetStart( helperLine->GetEnd() ); + preview.Add( helperLine ); + } + ++numPoints; + + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + + lastCursorPos = cursorPos; + } + + else if( evt->IsMotion() ) + { + helperLine->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); + + // 45 degree lines + if( linesAngle45 ) + { + VECTOR2D lineVector( wxPoint( cursorPos.x, cursorPos.y ) - helperLine->GetStart() ); + double angle = lineVector.Angle(); + + double newAngle = round( angle / ( M_PI / 4.0 ) ) * M_PI / 4.0; + VECTOR2D newLineVector = lineVector.Rotate( newAngle - angle ); + + // Snap the new line to the grid // TODO fix it, does not work good.. + VECTOR2D newLineEnd = VECTOR2D( helperLine->GetStart() ) + newLineVector; + VECTOR2D snapped = m_view->GetGAL()->GetGridPoint( newLineEnd ); + + helperLine->SetEnd( wxPoint( snapped.x, snapped.y ) ); + } + else + { + helperLine->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); + } + + // Show a preview of the item + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + } + + m_controls->ShowCursor( false ); + m_controls->SetSnapping( false ); + m_controls->SetAutoPan( false ); + m_view->Remove( &preview ); + + // Delete helper lines + preview.FreeItems(); + + setTransitions(); + + return 0; +} + + void DRAWING_TOOL::setTransitions() { Go( &DRAWING_TOOL::DrawLine, COMMON_ACTIONS::drawLine.MakeEvent() ); diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index 9881e353c9..e9555d658c 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -75,9 +75,14 @@ public: int PlaceModule( TOOL_EVENT& aEvent ); private: - ///> Starts drawing a selected shape. + ///> Starts drawing a selected shape (i.e. DRAWSEGMENT). + ///> @param aShape is the type of created shape (@see STROKE_T). int draw( int aShape ); + ///> Draws a polygon, that is added as a zone or a keepout area. + ///> @param aKeepout decides if the drawn polygon is a zone or a keepout area. + int drawZone( bool aKeepout ); + ///> Sets up handlers for various events. void setTransitions(); From a7cb90deb8baefad7cc0403d49ed9c55824ced1d Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 14 Feb 2014 11:35:48 +0100 Subject: [PATCH 025/134] Some more minor refactorization. --- pcbnew/tools/drawing_tool.cpp | 123 ++++++++++++++++++---------------- pcbnew/tools/drawing_tool.h | 6 +- 2 files changed, 68 insertions(+), 61 deletions(-) diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index af5b6f6a49..fd00149b8d 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -67,35 +67,30 @@ void DRAWING_TOOL::Reset( RESET_REASON aReason ) int DRAWING_TOOL::DrawLine( TOOL_EVENT& aEvent ) { - m_continous = true; - - return draw( S_SEGMENT ); + return drawSegment( S_SEGMENT, true ); } int DRAWING_TOOL::DrawCircle( TOOL_EVENT& aEvent ) { - m_continous = false; - - return draw( S_CIRCLE ); + return drawSegment( S_CIRCLE, false ); } int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) { - m_continous = false; - - int step = 0; - - DRAWSEGMENT graphic; - DRAWSEGMENT helperLine; - bool positive = true; + bool clockwise = true; + double startAngle; // angle of the first arc line + VECTOR2I cursorPos = m_controls->GetCursorPosition(); // Init the new item attributes + DRAWSEGMENT graphic; graphic.SetShape( S_ARC ); graphic.SetAngle( 0.0 ); graphic.SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth ); + graphic.SetCenter( wxPoint( cursorPos.x, cursorPos.y ) ); + DRAWSEGMENT helperLine; helperLine.SetShape( S_SEGMENT ); helperLine.SetLayer( DRAW_N ); helperLine.SetWidth( 1 ); @@ -106,13 +101,23 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); + m_controls->SetAutoPan( true ); Activate(); + enum ARC_STEPS + { + SET_ORIGIN = 0, + SET_END, + SET_ANGLE, + FINISHED + }; + int step = SET_ORIGIN; + // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { - VECTOR2I cursorPos = m_controls->GetCursorPosition(); + cursorPos = m_controls->GetCursorPosition(); if( evt->IsCancel() ) break; @@ -126,14 +131,14 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) graphic.SetWidth( width - WIDTH_STEP ); else if( evt->KeyCode() == '=' ) graphic.SetWidth( width + WIDTH_STEP ); - else if( evt->KeyCode() == ' ' ) + else if( evt->KeyCode() == '/' ) { - if( positive ) + if( clockwise ) graphic.SetAngle( graphic.GetAngle() - 3600.0 ); else graphic.SetAngle( graphic.GetAngle() + 3600.0 ); - positive = !positive; + clockwise = !clockwise; } preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); @@ -143,9 +148,9 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) { switch( step ) { - case 0: + case SET_ORIGIN: { - LAYER_NUM layer = getEditFrame()->GetScreen()->m_Active_Layer; + LAYER_NUM layer = m_frame->GetScreen()->m_Active_Layer; if( IsCopperLayer( layer ) ) { @@ -154,8 +159,6 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) } else { - m_controls->SetAutoPan( true ); - helperLine.SetStart( graphic.GetCenter() ); graphic.SetLayer( layer ); preview.Add( &graphic ); @@ -164,7 +167,14 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) } break; - case 2: + case SET_END: + { + VECTOR2D startLine( graphic.GetArcStart() - graphic.GetCenter() ); + startAngle = startLine.Angle(); + } + break; + + case SET_ANGLE: { if( wxPoint( cursorPos.x, cursorPos.y ) != graphic.GetCenter() ) { @@ -175,10 +185,9 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) } } break; - } - if( ++step == 3 ) + if( ++step == FINISHED ) break; } @@ -186,31 +195,27 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) { switch( step ) { - case 0: + case SET_ORIGIN: graphic.SetCenter( wxPoint( cursorPos.x, cursorPos.y ) ); break; - case 1: + case SET_END: helperLine.SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); graphic.SetArcStart( wxPoint( cursorPos.x, cursorPos.y ) ); break; - case 2: + case SET_ANGLE: { - VECTOR2D firstLine( graphic.GetArcStart() - graphic.GetCenter() ); - double firstAngle = firstLine.Angle(); + // Compute the current angle + VECTOR2D endLine( wxPoint( cursorPos.x, cursorPos.y ) - graphic.GetCenter() ); + double newAngle = RAD2DECIDEG( endLine.Angle() - startAngle ); - VECTOR2D secondLine( wxPoint( cursorPos.x, cursorPos.y ) - graphic.GetCenter() ); - double secondAngle = secondLine.Angle(); + if( clockwise && newAngle < 0.0 ) + newAngle += 3600.0; + else if( !clockwise && newAngle > 0.0 ) + newAngle -= 3600.0; - double angle = RAD2DECIDEG( secondAngle - firstAngle ); - - if( positive && angle < 0.0 ) - angle += 3600.0; - else if( !positive && angle > 0.0 ) - angle -= 3600.0; - - graphic.SetAngle( angle ); + graphic.SetAngle( newAngle ); } break; } @@ -309,23 +314,18 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) { - m_continous = false; - - int step = 0; - DIMENSION* dimension = new DIMENSION( m_board ); // Init the new item attributes dimension->Text().SetSize( m_board->GetDesignSettings().m_PcbTextSize ); int width = m_board->GetDesignSettings().m_PcbTextWidth; - int maxthickness = Clamp_Text_PenSize( width, dimension->Text().GetSize() ); + int maxThickness = Clamp_Text_PenSize( width, dimension->Text().GetSize() ); - if( width > maxthickness ) - width = maxthickness; + if( width > maxThickness ) + width = maxThickness; dimension->Text().SetThickness( width ); dimension->SetWidth( width ); - dimension->SetFlags( IS_NEW ); dimension->AdjustDimensionDetails(); // Add a VIEW_GROUP that serves as a preview for the new item @@ -337,6 +337,15 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) Activate(); + enum DIMENSION_STEPS + { + SET_ORIGIN = 0, + SET_END, + SET_HEIGHT, + FINISHED + }; + int step = SET_ORIGIN; + // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { @@ -350,7 +359,7 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) else if( evt->IsKeyUp() ) { - int width = dimension->GetWidth(); + width = dimension->GetWidth(); // Modify the new item width if( evt->KeyCode() == '-' && width > WIDTH_STEP ) @@ -365,7 +374,7 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) { switch( step ) { - case 0: + case SET_ORIGIN: { LAYER_NUM layer = m_frame->GetScreen()->m_Active_Layer; @@ -386,7 +395,7 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) } break; - case 2: + case SET_HEIGHT: { if( wxPoint( cursorPos.x, cursorPos.y ) != dimension->GetPosition() ) { @@ -398,7 +407,7 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) break; } - if( ++step == 3 ) + if( ++step == FINISHED ) break; } @@ -406,13 +415,13 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) { switch( step ) { - case 1: + case SET_END: dimension->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); break; - case 2: + case SET_HEIGHT: { - /* Calculating the direction of travel perpendicular to the selected axis. */ + // Calculating the direction of travel perpendicular to the selected axis double angle = dimension->GetAngle() + ( M_PI / 2 ); wxPoint pos( cursorPos.x, cursorPos.y ); @@ -475,7 +484,7 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { - VECTOR2I cursorPos = m_controls->GetCursorPosition(); + cursorPos = m_controls->GetCursorPosition(); if( evt->IsCancel() ) { @@ -596,7 +605,7 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) } -int DRAWING_TOOL::draw( int aShape ) +int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) { // Only two shapes are currently supported assert( aShape == S_SEGMENT || aShape == S_CIRCLE ); @@ -670,7 +679,7 @@ int DRAWING_TOOL::draw( int aShape ) m_board->Add( newItem ); newItem->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - if( m_continous ) + if( aContinous ) graphic.SetStart( graphic.GetEnd() ); // This is the origin point for a new item else break; diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index e9555d658c..baafa9dbc9 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -77,7 +77,8 @@ public: private: ///> Starts drawing a selected shape (i.e. DRAWSEGMENT). ///> @param aShape is the type of created shape (@see STROKE_T). - int draw( int aShape ); + ///> @param aContinous decides if there is only one or multiple shapes to draw. + int drawSegment( int aShape, bool aContinous ); ///> Draws a polygon, that is added as a zone or a keepout area. ///> @param aKeepout decides if the drawn polygon is a zone or a keepout area. @@ -86,9 +87,6 @@ private: ///> Sets up handlers for various events. void setTransitions(); - ///> Should drawing be stopped after drawing one object or should it continue with another one. - bool m_continous; - KIGFX::VIEW* m_view; KIGFX::VIEW_CONTROLS* m_controls; BOARD* m_board; From 3ecae4fa52a507a536568249cf383754b37dc2d5 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 14 Feb 2014 14:16:08 +0100 Subject: [PATCH 026/134] GAL::GetGridPoint() returns point in world coordinates. --- common/gal/graphics_abstraction_layer.cpp | 8 ++++---- common/view/wx_view_controls.cpp | 2 +- include/gal/graphics_abstraction_layer.h | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/common/gal/graphics_abstraction_layer.cpp b/common/gal/graphics_abstraction_layer.cpp index 9bc79b5ab7..7f57d652c4 100644 --- a/common/gal/graphics_abstraction_layer.cpp +++ b/common/gal/graphics_abstraction_layer.cpp @@ -237,10 +237,10 @@ void GAL::DrawGrid() VECTOR2D GAL::GetGridPoint( const VECTOR2D& aPoint ) const { - VECTOR2D pointWorld = ToWorld( aPoint ); + VECTOR2D gridPoint; - pointWorld.x = round( pointWorld.x / gridSize.x ) * gridSize.x; - pointWorld.y = round( pointWorld.y / gridSize.y ) * gridSize.y; + gridPoint.x = round( aPoint.x / gridSize.x ) * gridSize.x; + gridPoint.y = round( aPoint.y / gridSize.y ) * gridSize.y; - return ToScreen( pointWorld ); + return gridPoint; } diff --git a/common/view/wx_view_controls.cpp b/common/view/wx_view_controls.cpp index df8b9849c3..4ecfa953fd 100644 --- a/common/view/wx_view_controls.cpp +++ b/common/view/wx_view_controls.cpp @@ -247,7 +247,7 @@ VECTOR2D WX_VIEW_CONTROLS::GetCursorPosition() const VECTOR2D mousePosition = GetMousePosition(); if( m_snappingEnabled ) - return m_view->ToWorld( m_view->GetGAL()->GetGridPoint( mousePosition ) ); + return m_view->GetGAL()->GetGridPoint( m_view->ToWorld( mousePosition ) ); else return m_view->ToWorld( mousePosition ); } diff --git a/include/gal/graphics_abstraction_layer.h b/include/gal/graphics_abstraction_layer.h index 5b6c656e32..d49e5e2fad 100644 --- a/include/gal/graphics_abstraction_layer.h +++ b/include/gal/graphics_abstraction_layer.h @@ -717,15 +717,15 @@ public: gridLineWidth = aGridLineWidth; } - /// @brief Draw the grid + ///> @brief Draw the grid void DrawGrid(); /** * Function GetGridPoint() - * For a given point it returns the nearest point belonging to the grid in screen coordinates. + * For a given point it returns the nearest point belonging to the grid in world coordinates. * * @param aPoint is the point for which the grid point is searched. - * @return The nearest grid point in screen coordinates. + * @return The nearest grid point in world coordinates. */ VECTOR2D GetGridPoint( const VECTOR2D& aPoint ) const; From b1fb59ad13154aca29c2a3e023ef3c7a99efbe2f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 14 Feb 2014 14:24:12 +0100 Subject: [PATCH 027/134] Refactorization: moved drawing 45 degree multiple line to a function. --- pcbnew/tools/drawing_tool.cpp | 55 +++++++++++++++-------------------- pcbnew/tools/drawing_tool.h | 6 ++++ 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index fd00149b8d..a059366663 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -693,23 +693,9 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) { // 45 degree lines if( linesAngle45 && aShape == S_SEGMENT ) - { - VECTOR2D lineVector( wxPoint( cursorPos.x, cursorPos.y ) - graphic.GetStart() ); - double angle = lineVector.Angle(); - - double newAngle = round( angle / ( M_PI / 4.0 ) ) * M_PI / 4.0; - VECTOR2D newLineVector = lineVector.Rotate( newAngle - angle ); - - // Snap the new line to the grid // TODO fix it, does not work good.. - VECTOR2D newLineEnd = VECTOR2D( graphic.GetStart() ) + newLineVector; - VECTOR2D snapped = m_view->GetGAL()->GetGridPoint( newLineEnd ); - - graphic.SetEnd( wxPoint( snapped.x, snapped.y ) ); - } + make45DegLine( &graphic ); else - { graphic.SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); - } // Show a preview of the item preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); @@ -847,27 +833,11 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) else if( evt->IsMotion() ) { - helperLine->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); - // 45 degree lines if( linesAngle45 ) - { - VECTOR2D lineVector( wxPoint( cursorPos.x, cursorPos.y ) - helperLine->GetStart() ); - double angle = lineVector.Angle(); - - double newAngle = round( angle / ( M_PI / 4.0 ) ) * M_PI / 4.0; - VECTOR2D newLineVector = lineVector.Rotate( newAngle - angle ); - - // Snap the new line to the grid // TODO fix it, does not work good.. - VECTOR2D newLineEnd = VECTOR2D( helperLine->GetStart() ) + newLineVector; - VECTOR2D snapped = m_view->GetGAL()->GetGridPoint( newLineEnd ); - - helperLine->SetEnd( wxPoint( snapped.x, snapped.y ) ); - } + make45DegLine( helperLine ); else - { helperLine->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); - } // Show a preview of the item preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); @@ -888,6 +858,27 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) } +void DRAWING_TOOL::make45DegLine( DRAWSEGMENT* aSegment ) const +{ + VECTOR2I cursorPos = m_controls->GetCursorPosition(); + + // Current line vector + VECTOR2D lineVector( wxPoint( cursorPos.x, cursorPos.y ) - aSegment->GetStart() ); + double angle = lineVector.Angle(); + + // Find the closest angle, which is a multiple of 45 degrees + double newAngle = round( angle / ( M_PI / 4.0 ) ) * M_PI / 4.0; + + VECTOR2D newLineVector = lineVector.Rotate( newAngle - angle ); + VECTOR2D newLineEnd = VECTOR2D( aSegment->GetStart() ) + newLineVector; + + // Snap the new line to the grid + newLineEnd = m_view->GetGAL()->GetGridPoint( newLineEnd ); + + aSegment->SetEnd( wxPoint( newLineEnd.x, newLineEnd.y ) ); +} + + void DRAWING_TOOL::setTransitions() { Go( &DRAWING_TOOL::DrawLine, COMMON_ACTIONS::drawLine.MakeEvent() ); diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index baafa9dbc9..d34113e126 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -34,6 +34,7 @@ namespace KIGFX } class BOARD; class PCB_EDIT_FRAME; +class DRAWSEGMENT; /** * Class DRAWING_TOOL @@ -84,6 +85,11 @@ private: ///> @param aKeepout decides if the drawn polygon is a zone or a keepout area. int drawZone( bool aKeepout ); + ///> Forces a DRAWSEGMENT to be drawn at multiple of 45 degrees. The origin + ///> stays the same, the end of the aSegment is modified according to the + ///> current cursor position. + void make45DegLine( DRAWSEGMENT* aSegment ) const; + ///> Sets up handlers for various events. void setTransitions(); From 9d3f7230ee9d8adcfa841512206e4d850c150ea9 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 14 Feb 2014 15:13:42 +0100 Subject: [PATCH 028/134] New items are created using pointers (instead of copying automatic variables when drawing is finished). --- pcbnew/tools/drawing_tool.cpp | 118 ++++++++++++++++++++-------------- pcbnew/tools/drawing_tool.h | 47 +++++++++++++- 2 files changed, 117 insertions(+), 48 deletions(-) diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index a059366663..b4c6485d6f 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -40,7 +40,6 @@ #include #include #include -#include // TODO to be removed if we do not need the flags DRAWING_TOOL::DRAWING_TOOL() : TOOL_INTERACTIVE( "pcbnew.InteractiveDrawing" ) @@ -79,16 +78,16 @@ int DRAWING_TOOL::DrawCircle( TOOL_EVENT& aEvent ) int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) { - bool clockwise = true; + bool clockwise = true; // drawing direction of the arc double startAngle; // angle of the first arc line VECTOR2I cursorPos = m_controls->GetCursorPosition(); // Init the new item attributes - DRAWSEGMENT graphic; - graphic.SetShape( S_ARC ); - graphic.SetAngle( 0.0 ); - graphic.SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth ); - graphic.SetCenter( wxPoint( cursorPos.x, cursorPos.y ) ); + DRAWSEGMENT* graphic = new DRAWSEGMENT( m_board ); + graphic->SetShape( S_ARC ); + graphic->SetAngle( 0.0 ); + graphic->SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth ); + graphic->SetCenter( wxPoint( cursorPos.x, cursorPos.y ) ); DRAWSEGMENT helperLine; helperLine.SetShape( S_SEGMENT ); @@ -120,23 +119,26 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) cursorPos = m_controls->GetCursorPosition(); if( evt->IsCancel() ) + { + delete graphic; break; + } else if( evt->IsKeyUp() ) { - int width = graphic.GetWidth(); + int width = graphic->GetWidth(); // Modify the new item width if( evt->KeyCode() == '-' && width > WIDTH_STEP ) - graphic.SetWidth( width - WIDTH_STEP ); + graphic->SetWidth( width - WIDTH_STEP ); else if( evt->KeyCode() == '=' ) - graphic.SetWidth( width + WIDTH_STEP ); + graphic->SetWidth( width + WIDTH_STEP ); else if( evt->KeyCode() == '/' ) { if( clockwise ) - graphic.SetAngle( graphic.GetAngle() - 3600.0 ); + graphic->SetAngle( graphic->GetAngle() - 3600.0 ); else - graphic.SetAngle( graphic.GetAngle() + 3600.0 ); + graphic->SetAngle( graphic->GetAngle() + 3600.0 ); clockwise = !clockwise; } @@ -159,9 +161,9 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) } else { - helperLine.SetStart( graphic.GetCenter() ); - graphic.SetLayer( layer ); - preview.Add( &graphic ); + helperLine.SetStart( graphic->GetCenter() ); + graphic->SetLayer( layer ); + preview.Add( graphic ); preview.Add( &helperLine ); } } @@ -169,19 +171,23 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) case SET_END: { - VECTOR2D startLine( graphic.GetArcStart() - graphic.GetCenter() ); + VECTOR2D startLine( graphic->GetArcStart() - graphic->GetCenter() ); startAngle = startLine.Angle(); } break; case SET_ANGLE: { - if( wxPoint( cursorPos.x, cursorPos.y ) != graphic.GetCenter() ) + if( wxPoint( cursorPos.x, cursorPos.y ) != graphic->GetCenter() ) { - DRAWSEGMENT* newItem = new DRAWSEGMENT( graphic ); - m_view->Add( newItem ); - m_board->Add( newItem ); - newItem->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + m_view->Add( graphic ); + m_board->Add( graphic ); + graphic->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + else + { + // Let's give the user another chance of drawing a proper arc (i.e. angle > 0) + --step; } } break; @@ -196,18 +202,18 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) switch( step ) { case SET_ORIGIN: - graphic.SetCenter( wxPoint( cursorPos.x, cursorPos.y ) ); + graphic->SetCenter( wxPoint( cursorPos.x, cursorPos.y ) ); break; case SET_END: helperLine.SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); - graphic.SetArcStart( wxPoint( cursorPos.x, cursorPos.y ) ); + graphic->SetArcStart( wxPoint( cursorPos.x, cursorPos.y ) ); break; case SET_ANGLE: { // Compute the current angle - VECTOR2D endLine( wxPoint( cursorPos.x, cursorPos.y ) - graphic.GetCenter() ); + VECTOR2D endLine( wxPoint( cursorPos.x, cursorPos.y ) - graphic->GetCenter() ); double newAngle = RAD2DECIDEG( endLine.Angle() - startAngle ); if( clockwise && newAngle < 0.0 ) @@ -215,7 +221,7 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) else if( !clockwise && newAngle > 0.0 ) newAngle -= 3600.0; - graphic.SetAngle( newAngle ); + graphic->SetAngle( newAngle ); } break; } @@ -395,6 +401,12 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) } break; + case SET_END: + // Dimensions that have origin and end in the same spot are not valid + if( dimension->GetOrigin() == wxPoint( cursorPos.x, cursorPos.y ) ) + --step; + break; + case SET_HEIGHT: { if( wxPoint( cursorPos.x, cursorPos.y ) != dimension->GetPosition() ) @@ -610,12 +622,11 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) // Only two shapes are currently supported assert( aShape == S_SEGMENT || aShape == S_CIRCLE ); - bool started = false; - DRAWSEGMENT graphic; + DRAWSEGMENT* graphic = new DRAWSEGMENT( m_board ); // Init the new item attributes - graphic.SetShape( (STROKE_T) aShape ); - graphic.SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth ); + graphic->SetShape( (STROKE_T) aShape ); + graphic->SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth ); // Add a VIEW_GROUP that serves as a preview for the new item KIGFX::VIEW_GROUP preview( m_view ); @@ -626,6 +637,7 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) Activate(); + bool started = false; // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { @@ -634,17 +646,22 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) VECTOR2I cursorPos = m_controls->GetCursorPosition(); if( evt->IsCancel() ) + { + preview.FreeItems(); + if( !started ) + delete graphic; break; + } else if( evt->IsKeyUp() ) { - int width = graphic.GetWidth(); + int width = graphic->GetWidth(); // Modify the new item width if( evt->KeyCode() == '-' && width > WIDTH_STEP ) - graphic.SetWidth( width - WIDTH_STEP ); + graphic->SetWidth( width - WIDTH_STEP ); else if( evt->KeyCode() == '=' ) - graphic.SetWidth( width + WIDTH_STEP ); + graphic->SetWidth( width + WIDTH_STEP ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } @@ -663,29 +680,37 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) { m_controls->SetAutoPan( true ); - graphic.SetStart( wxPoint( cursorPos.x, cursorPos.y ) ); - graphic.SetLayer( layer ); - preview.Add( &graphic ); + graphic->SetStart( wxPoint( cursorPos.x, cursorPos.y ) ); + graphic->SetLayer( layer ); + preview.Add( graphic ); started = true; } } else { - if( wxPoint( cursorPos.x, cursorPos.y ) != graphic.GetStart() ) + if( wxPoint( cursorPos.x, cursorPos.y ) != graphic->GetStart() ) { - DRAWSEGMENT* newItem = new DRAWSEGMENT( graphic ); - m_view->Add( newItem ); - m_board->Add( newItem ); - newItem->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + m_view->Add( graphic ); + m_board->Add( graphic ); + graphic->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + preview.Remove( graphic ); if( aContinous ) - graphic.SetStart( graphic.GetEnd() ); // This is the origin point for a new item + { + graphic = new DRAWSEGMENT( *graphic ); + // Start the new line in the same spot where the previous one has ended + graphic->SetStart( graphic->GetEnd() ); + preview.Add( graphic ); + } else break; } - else // User has clicked twice in the same spot - break; // seems like a clear sign that the drawing is finished + else + { // User has clicked twice in the same spot + delete graphic; // seems like a clear sign that the drawing is finished + break; // and we should remove the latest DRAWSEGMENT we have created + } } } @@ -693,9 +718,9 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) { // 45 degree lines if( linesAngle45 && aShape == S_SEGMENT ) - make45DegLine( &graphic ); + make45DegLine( graphic ); else - graphic.SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); + graphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); // Show a preview of the item preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); @@ -809,8 +834,7 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) { // Add the first point zone->Outline()->Start( zoneInfo.m_CurrentZone_Layer, - cursorPos.x, - cursorPos.y, + cursorPos.x, cursorPos.y, zone->GetHatchStyle() ); helperLine->SetStart( wxPoint( cursorPos.x, cursorPos.y ) ); origin = cursorPos; diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index d34113e126..2b759670c8 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -54,25 +54,70 @@ public: /** * Function DrawLine() * Starts interactively drawing a line. After invoking the function it expects the user - * to click at least twice to determine the origin and the end for a line. If there are + * to click at least two times to determine the origin and the end for a line. If there are * more clicks, the line is drawn as a continous polyline. */ int DrawLine( TOOL_EVENT& aEvent ); + /** + * Function DrawCircle() + * Starts interactively drawing a circle. After invoking the function it expects the user + * to first click on a point that is going to be used as the center of the circle. The second + * click determines the circle radius. + */ int DrawCircle( TOOL_EVENT& aEvent ); + /** + * Function DrawArc() + * Starts interactively drawing an arc. After invoking the function it expects the user + * to first click on a point that is going to be used as the center of the arc. The second + * click determines the origin and radius, the third one - the angle. + */ int DrawArc( TOOL_EVENT& aEvent ); + /** + * Function DrawText() + * Displays a dialog that allows to input text and its settings and then lets the user decide + * where to place the text. + */ int DrawText( TOOL_EVENT& aEvent ); + /** + * Function DrawDimension() + * Starts interactively drawing a dimension. After invoking the function it expects the user + * to first click on a point that is going to be used as the origin of the dimension. + * The second click determines the end and the third click modifies its height. + */ int DrawDimension( TOOL_EVENT& aEvent ); + /** + * Function DrawZone() + * Starts interactively drawing a zone. After invoking the function a zone settings dialog + * is displayed. After confirmation it allows the user to set points that are going to be used + * as a boundary polygon of the zone. Double click or clicking on the origin of the boundary + * polyline finishes the drawing. + */ int DrawZone( TOOL_EVENT& aEvent ); + /** + * Function DrawKeepout() + * Starts interactively drawing a keepout area. After invoking the function an area settings + * dialog is displayed. After confirmation it allows the user to set points that are going to + * be used as a boundary polygon of the area. Double click or clicking on the origin of the + * boundary polyline finishes the drawing. + */ int DrawKeepout( TOOL_EVENT& aEvent ); + /** + * Function PlaceTarget() + * Allows user to place a layer alignment target. + */ int PlaceTarget( TOOL_EVENT& aEvent ); + /** + * Function PlaceModule() + * Displays a dialog to selected a module to be added and then allows user to set its position.. + */ int PlaceModule( TOOL_EVENT& aEvent ); private: From c1c8f54e8b41517647fcb9d3281ca83caf1ac74a Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 14 Feb 2014 15:52:13 +0100 Subject: [PATCH 029/134] Added a few asserts. Made some steps idiotproof. --- pcbnew/tools/drawing_tool.cpp | 116 +++++++++++++++++++++------------- 1 file changed, 72 insertions(+), 44 deletions(-) diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index b4c6485d6f..aefc7e3a3d 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -83,11 +83,11 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) VECTOR2I cursorPos = m_controls->GetCursorPosition(); // Init the new item attributes - DRAWSEGMENT* graphic = new DRAWSEGMENT( m_board ); - graphic->SetShape( S_ARC ); - graphic->SetAngle( 0.0 ); - graphic->SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth ); - graphic->SetCenter( wxPoint( cursorPos.x, cursorPos.y ) ); + DRAWSEGMENT* arc = new DRAWSEGMENT( m_board ); + arc->SetShape( S_ARC ); + arc->SetAngle( 0.0 ); + arc->SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth ); + arc->SetCenter( wxPoint( cursorPos.x, cursorPos.y ) ); DRAWSEGMENT helperLine; helperLine.SetShape( S_SEGMENT ); @@ -100,7 +100,6 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); - m_controls->SetAutoPan( true ); Activate(); @@ -120,25 +119,25 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) if( evt->IsCancel() ) { - delete graphic; + delete arc; break; } else if( evt->IsKeyUp() ) { - int width = graphic->GetWidth(); + int width = arc->GetWidth(); // Modify the new item width if( evt->KeyCode() == '-' && width > WIDTH_STEP ) - graphic->SetWidth( width - WIDTH_STEP ); + arc->SetWidth( width - WIDTH_STEP ); else if( evt->KeyCode() == '=' ) - graphic->SetWidth( width + WIDTH_STEP ); + arc->SetWidth( width + WIDTH_STEP ); else if( evt->KeyCode() == '/' ) { if( clockwise ) - graphic->SetAngle( graphic->GetAngle() - 3600.0 ); + arc->SetAngle( arc->GetAngle() - 3600.0 ); else - graphic->SetAngle( graphic->GetAngle() + 3600.0 ); + arc->SetAngle( arc->GetAngle() + 3600.0 ); clockwise = !clockwise; } @@ -161,34 +160,45 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) } else { - helperLine.SetStart( graphic->GetCenter() ); - graphic->SetLayer( layer ); - preview.Add( graphic ); + helperLine.SetStart( arc->GetCenter() ); + arc->SetCenter( wxPoint( cursorPos.x, cursorPos.y ) ); + arc->SetLayer( layer ); + preview.Add( arc ); preview.Add( &helperLine ); + + m_controls->SetAutoPan( true ); } } break; case SET_END: { - VECTOR2D startLine( graphic->GetArcStart() - graphic->GetCenter() ); - startAngle = startLine.Angle(); + if( wxPoint( cursorPos.x, cursorPos.y ) != arc->GetCenter() ) + { + VECTOR2D startLine( arc->GetArcStart() - arc->GetCenter() ); + startAngle = startLine.Angle(); + arc->SetArcStart( wxPoint( cursorPos.x, cursorPos.y ) ); + } + else + --step; // one another chance to draw a proper arc + } break; case SET_ANGLE: { - if( wxPoint( cursorPos.x, cursorPos.y ) != graphic->GetCenter() ) + if( wxPoint( cursorPos.x, cursorPos.y ) != arc->GetArcStart() ) { - m_view->Add( graphic ); - m_board->Add( graphic ); - graphic->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + assert( arc->GetAngle() > 0 ); + assert( arc->GetArcStart() != arc->GetArcEnd() ); + assert( arc->GetWidth() > 0 ); + + m_view->Add( arc ); + m_board->Add( arc ); + arc->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } else - { - // Let's give the user another chance of drawing a proper arc (i.e. angle > 0) - --step; - } + --step; // one another chance to draw a proper arc } break; } @@ -202,18 +212,18 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) switch( step ) { case SET_ORIGIN: - graphic->SetCenter( wxPoint( cursorPos.x, cursorPos.y ) ); + arc->SetCenter( wxPoint( cursorPos.x, cursorPos.y ) ); break; case SET_END: helperLine.SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); - graphic->SetArcStart( wxPoint( cursorPos.x, cursorPos.y ) ); + arc->SetArcStart( wxPoint( cursorPos.x, cursorPos.y ) ); break; case SET_ANGLE: { // Compute the current angle - VECTOR2D endLine( wxPoint( cursorPos.x, cursorPos.y ) - graphic->GetCenter() ); + VECTOR2D endLine( wxPoint( cursorPos.x, cursorPos.y ) - arc->GetCenter() ); double newAngle = RAD2DECIDEG( endLine.Angle() - startAngle ); if( clockwise && newAngle < 0.0 ) @@ -221,7 +231,7 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) else if( !clockwise && newAngle > 0.0 ) newAngle -= 3600.0; - graphic->SetAngle( newAngle ); + arc->SetAngle( newAngle ); } break; } @@ -245,8 +255,8 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) { // Init the new item attributes - TEXTE_PCB* newText = m_frame->CreateTextePcb( NULL ); - if( newText == NULL ) + TEXTE_PCB* text = m_frame->CreateTextePcb( NULL ); + if( text == NULL ) { setTransitions(); return 0; @@ -254,7 +264,7 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) // Add a VIEW_GROUP that serves as a preview for the new item KIGFX::VIEW_GROUP preview( m_view ); - preview.Add( newText ); + preview.Add( text ); m_view->Add( &preview ); m_controls->ShowCursor( true ); @@ -271,7 +281,7 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) if( evt->IsCancel() ) { // it was already added by CreateTextPcb() - m_board->Delete( newText ); + m_board->Delete( text ); break; } @@ -279,28 +289,31 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) { if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) { - newText->Rotate( newText->GetPosition(), m_frame->GetRotationAngle() ); + text->Rotate( text->GetPosition(), m_frame->GetRotationAngle() ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) { - newText->Flip( newText->GetPosition() ); + text->Flip( text->GetPosition() ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } } else if( evt->IsClick( BUT_LEFT ) ) { - newText->ClearFlags(); - m_view->Add( newText ); - // m_board->Add( newText ); // it is already added by CreateTextePcb() - newText->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + assert( text->GetText().Length() > 0 ); + assert( text->GetSize().x > 0 && text->GetSize().y > 0 ); + + text->ClearFlags(); + m_view->Add( text ); + // m_board->Add( text ); // it is already added by CreateTextePcb() + text->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); break; } else if( evt->IsMotion() ) { - newText->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) ); + text->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) ); // Show a preview of the item preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); @@ -411,6 +424,9 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) { if( wxPoint( cursorPos.x, cursorPos.y ) != dimension->GetPosition() ) { + assert( dimension->GetOrigin() != dimension->GetEnd() ); + assert( dimension->GetWidth() > 0 ); + m_view->Add( dimension ); m_board->Add( dimension ); dimension->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); @@ -519,6 +535,9 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) else if( evt->IsClick( BUT_LEFT ) ) { + assert( target->GetSize() > 0 ); + assert( target->GetWidth() > 0 ); + m_view->Add( target ); m_board->Add( target ); target->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); @@ -638,6 +657,7 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) Activate(); bool started = false; + int addedSegments = 0; // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { @@ -648,7 +668,7 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) if( evt->IsCancel() ) { preview.FreeItems(); - if( !started ) + if( !started ) // TODO check it delete graphic; break; } @@ -691,10 +711,14 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) { if( wxPoint( cursorPos.x, cursorPos.y ) != graphic->GetStart() ) { + assert( graphic->GetLength() > 0 ); + assert( graphic->GetWidth() > 0 ); + m_view->Add( graphic ); - m_board->Add( graphic ); + m_board->Add( graphic ); graphic->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); preview.Remove( graphic ); + ++addedSegments; if( aContinous ) { @@ -704,10 +728,12 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) preview.Add( graphic ); } else + { break; + } } - else - { // User has clicked twice in the same spot + else if( addedSegments > 0 ) // User has clicked twice in the same spot + { delete graphic; // seems like a clear sign that the drawing is finished break; // and we should remove the latest DRAWSEGMENT we have created } @@ -808,6 +834,8 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) { if( numPoints > 2 ) { + assert( zone->GetNumCorners() > 2 ); + // Finish the zone zone->Outline()->CloseLastContour(); zone->Outline()->RemoveNullSegments(); From f82e07849ba3f6779cb22c3543e17f7dbcbf0d93 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 17 Feb 2014 11:33:03 +0100 Subject: [PATCH 030/134] Improved way of drawing 45-degree lines. --- include/geometry/shape_line_chain.h | 2 +- pcbnew/router/direction.h | 5 +- pcbnew/tools/drawing_tool.cpp | 133 ++++++++++++++++++++-------- pcbnew/tools/drawing_tool.h | 4 +- 4 files changed, 103 insertions(+), 41 deletions(-) diff --git a/include/geometry/shape_line_chain.h b/include/geometry/shape_line_chain.h index 5108191bb7..da6494e91a 100644 --- a/include/geometry/shape_line_chain.h +++ b/include/geometry/shape_line_chain.h @@ -415,7 +415,7 @@ public: * @param aP the point to be looked for * @return index of the correspoinding point in the line chain or negative when not found. */ - int Find ( const VECTOR2I& aP ) const; + int Find( const VECTOR2I& aP ) const; /** * Function Slice() diff --git a/pcbnew/router/direction.h b/pcbnew/router/direction.h index 0b7d8cb62d..ad38fcbdef 100644 --- a/pcbnew/router/direction.h +++ b/pcbnew/router/direction.h @@ -133,10 +133,7 @@ public: */ DIRECTION_45 Opposite() const { - if( m_dir == UNDEFINED ) - return UNDEFINED; - - const Directions OppositeMap[] = { S, SW, W, NW, N, NE, E, SE }; + const Directions OppositeMap[] = { S, SW, W, NW, N, NE, E, SE, UNDEFINED }; return OppositeMap[m_dir]; } diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index aefc7e3a3d..a80b605da4 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -641,12 +642,13 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) // Only two shapes are currently supported assert( aShape == S_SEGMENT || aShape == S_CIRCLE ); - DRAWSEGMENT* graphic = new DRAWSEGMENT( m_board ); - // Init the new item attributes + DRAWSEGMENT* graphic = new DRAWSEGMENT( m_board ); graphic->SetShape( (STROKE_T) aShape ); graphic->SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth ); + DRAWSEGMENT line45( *graphic ); // used only for direction 45 mode with lines + // Add a VIEW_GROUP that serves as a preview for the new item KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); @@ -657,19 +659,43 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) Activate(); bool started = false; + bool direction45 = false; // 45 degrees only mode int addedSegments = 0; + // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { - // Enable 45 degrees lines only mode by holding shift - bool linesAngle45 = evt->Modifier( MD_SHIFT ); + bool updatePreview = false; // should preview be updated VECTOR2I cursorPos = m_controls->GetCursorPosition(); + // Enable 45 degrees lines only mode by holding control + if( direction45 != ( evt->Modifier( MD_CTRL ) && aShape == S_SEGMENT && started ) ) + { + direction45 = evt->Modifier( MD_CTRL ); + + if( direction45 ) + { + preview.Add( &line45 ); + make45DegLine( graphic, &line45 ); + } + else + { + preview.Remove( &line45 ); + graphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); + } + + updatePreview = true; + } + if( evt->IsCancel() ) { + if( direction45 ) + preview.Remove( &line45 ); + preview.FreeItems(); - if( !started ) // TODO check it + if( !started ) delete graphic; + break; } @@ -683,7 +709,7 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) else if( evt->KeyCode() == '=' ) graphic->SetWidth( width + WIDTH_STEP ); - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + updatePreview = true; } else if( evt->IsClick( BUT_LEFT ) ) @@ -701,7 +727,9 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) m_controls->SetAutoPan( true ); graphic->SetStart( wxPoint( cursorPos.x, cursorPos.y ) ); + graphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); graphic->SetLayer( layer ); + line45.SetLayer( layer ); preview.Add( graphic ); started = true; @@ -709,7 +737,7 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) } else { - if( wxPoint( cursorPos.x, cursorPos.y ) != graphic->GetStart() ) + if( graphic->GetEnd() != graphic->GetStart() ) { assert( graphic->GetLength() > 0 ); assert( graphic->GetWidth() > 0 ); @@ -725,6 +753,10 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) graphic = new DRAWSEGMENT( *graphic ); // Start the new line in the same spot where the previous one has ended graphic->SetStart( graphic->GetEnd() ); + + if( direction45 ) + graphic->SetEnd( line45.GetEnd() ); + preview.Add( graphic ); } else @@ -743,14 +775,16 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) else if( evt->IsMotion() && started ) { // 45 degree lines - if( linesAngle45 && aShape == S_SEGMENT ) - make45DegLine( graphic ); + if( direction45 && aShape == S_SEGMENT ) + make45DegLine( graphic, &line45 ); else graphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); - // Show a preview of the item - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + updatePreview = true; } + + if( updatePreview ) + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } m_controls->ShowCursor( false ); @@ -800,6 +834,7 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) helperLine->SetShape( S_SEGMENT ); helperLine->SetLayer( zoneInfo.m_CurrentZone_Layer ); helperLine->SetWidth( 1 ); + DRAWSEGMENT line45( *helperLine ); // Add a VIEW_GROUP that serves as a preview for the new item KIGFX::VIEW_GROUP preview( m_view ); @@ -814,17 +849,37 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) VECTOR2I lastCursorPos = m_controls->GetCursorPosition(); VECTOR2I origin; int numPoints = 0; + bool direction45 = false; // 45 degrees only mode + bool cancelled = false; // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { - // Enable 45 degrees lines only mode by holding shift - bool linesAngle45 = evt->Modifier( MD_SHIFT ); + bool updatePreview = false; // should preview be updated VECTOR2I cursorPos = m_controls->GetCursorPosition(); + // Enable 45 degrees lines only mode by holding control + if( direction45 != ( evt->Modifier( MD_CTRL ) && numPoints > 0 ) ) + { + direction45 = evt->Modifier( MD_CTRL ); + + if( direction45 ) + { + preview.Add( &line45 ); + make45DegLine( helperLine, &line45 ); + } + else + { + preview.Remove( &line45 ); + helperLine->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); + } + + updatePreview = true; + } + if( evt->IsCancel() ) { - delete zone; + cancelled = true; break; } @@ -851,7 +906,7 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) else { // If there are less than 3 points, then it is not a valid zone - delete zone; + cancelled = true; } break; @@ -877,7 +932,7 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) } ++numPoints; - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + updatePreview = true; } lastCursorPos = cursorPos; @@ -886,14 +941,17 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) else if( evt->IsMotion() ) { // 45 degree lines - if( linesAngle45 ) - make45DegLine( helperLine ); + if( direction45 ) + make45DegLine( helperLine, &line45 ); else helperLine->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); // Show a preview of the item - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + updatePreview = true; } + + if( updatePreview ) + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } m_controls->ShowCursor( false ); @@ -901,7 +959,11 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) m_controls->SetAutoPan( false ); m_view->Remove( &preview ); - // Delete helper lines + // Clean + if( cancelled ) + delete zone; + if( direction45 ) + preview.Remove( &line45 ); preview.FreeItems(); setTransitions(); @@ -910,24 +972,25 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) } -void DRAWING_TOOL::make45DegLine( DRAWSEGMENT* aSegment ) const +void DRAWING_TOOL::make45DegLine( DRAWSEGMENT* aSegment, DRAWSEGMENT* aHelper ) const { VECTOR2I cursorPos = m_controls->GetCursorPosition(); + VECTOR2I origin( aSegment->GetStart() ); + DIRECTION_45 direction( origin - cursorPos ); + SHAPE_LINE_CHAIN newChain = direction.BuildInitialTrace( origin, cursorPos ); - // Current line vector - VECTOR2D lineVector( wxPoint( cursorPos.x, cursorPos.y ) - aSegment->GetStart() ); - double angle = lineVector.Angle(); - - // Find the closest angle, which is a multiple of 45 degrees - double newAngle = round( angle / ( M_PI / 4.0 ) ) * M_PI / 4.0; - - VECTOR2D newLineVector = lineVector.Rotate( newAngle - angle ); - VECTOR2D newLineEnd = VECTOR2D( aSegment->GetStart() ) + newLineVector; - - // Snap the new line to the grid - newLineEnd = m_view->GetGAL()->GetGridPoint( newLineEnd ); - - aSegment->SetEnd( wxPoint( newLineEnd.x, newLineEnd.y ) ); + if( newChain.PointCount() > 2 ) + { + aSegment->SetEnd( wxPoint( newChain.Point( -2 ).x, newChain.Point( -2 ).y ) ); + aHelper->SetStart( wxPoint( newChain.Point( -2 ).x, newChain.Point( -2 ).y ) ); + aHelper->SetEnd( wxPoint( newChain.Point( -1 ).x, newChain.Point( -1 ).y ) ); + } + else + { + aSegment->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); + aHelper->SetStart( wxPoint( cursorPos.x, cursorPos.y ) ); + aHelper->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); + } } diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index 2b759670c8..775351efaf 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -133,7 +133,9 @@ private: ///> Forces a DRAWSEGMENT to be drawn at multiple of 45 degrees. The origin ///> stays the same, the end of the aSegment is modified according to the ///> current cursor position. - void make45DegLine( DRAWSEGMENT* aSegment ) const; + ///> @param aSegment is the segment that is currently drawn. + ///> @param aHelper is a helper line that shows the next possible segment. + void make45DegLine( DRAWSEGMENT* aSegment, DRAWSEGMENT* aHelper ) const; ///> Sets up handlers for various events. void setTransitions(); From 6e52e193672ca4a1386770c4237d83907515d172 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 17 Feb 2014 14:36:51 +0100 Subject: [PATCH 031/134] Small leak fix. --- pcbnew/router/pns_router.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pcbnew/router/pns_router.cpp b/pcbnew/router/pns_router.cpp index b655ac363f..8ab4fb2fc9 100644 --- a/pcbnew/router/pns_router.cpp +++ b/pcbnew/router/pns_router.cpp @@ -339,9 +339,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; } From 05de84d5425f10515126f0ab9afc6f627df92dd3 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 17 Feb 2014 14:53:01 +0100 Subject: [PATCH 032/134] Undo/redo support. --- pcbnew/tools/drawing_tool.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index a80b605da4..aefcdd76ab 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -197,6 +197,9 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) m_view->Add( arc ); m_board->Add( arc ); arc->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( arc, UR_NEW ); } else --step; // one another chance to draw a proper arc @@ -309,6 +312,10 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) m_view->Add( text ); // m_board->Add( text ); // it is already added by CreateTextePcb() text->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( text, UR_NEW ); + break; } @@ -431,6 +438,9 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) m_view->Add( dimension ); m_board->Add( dimension ); dimension->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( dimension, UR_NEW ); } } break; @@ -507,6 +517,7 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); m_controls->SetSnapping( true ); + m_controls->SetAutoPan( true ); Activate(); @@ -542,6 +553,10 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) m_view->Add( target ); m_board->Add( target ); target->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( target, UR_NEW ); + break; } @@ -584,6 +599,7 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); m_controls->SetSnapping( true ); + m_controls->SetAutoPan( true ); Activate(); @@ -617,6 +633,10 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), m_view ) ); m_view->Add( module ); module->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( module, UR_NEW ); + break; } @@ -748,6 +768,9 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) preview.Remove( graphic ); ++addedSegments; + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( graphic, UR_NEW ); + if( aContinous ) { graphic = new DRAWSEGMENT( *graphic ); @@ -902,6 +925,9 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) m_frame->Fill_Zone( zone ); zone->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( zone, UR_NEW ); } else { From e14d9aaf8fe5b11bc9034385b1245d17b5923f01 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 17 Feb 2014 17:20:44 +0100 Subject: [PATCH 033/134] Fixed wrongly formulated assert. --- pcbnew/tools/drawing_tool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index aefcdd76ab..1397ce9664 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -190,7 +190,7 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) { if( wxPoint( cursorPos.x, cursorPos.y ) != arc->GetArcStart() ) { - assert( arc->GetAngle() > 0 ); + assert( arc->GetAngle() != 0 ); assert( arc->GetArcStart() != arc->GetArcEnd() ); assert( arc->GetWidth() > 0 ); From a802ca87e0b3176ba223c7bbd9b024a0e3c94e85 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 17 Feb 2014 18:21:00 +0100 Subject: [PATCH 034/134] Added TOOL_ACTION for PNS router activation. Most of the GAL tools are activated by corresponding buttons on the right toolbar. Removed menu entry for PNS router (as it is activated as the usual "Add track" tool). --- common/tool/tool_dispatcher.cpp | 18 +--------- pcbnew/edit.cpp | 12 +++++++ pcbnew/menubar_pcbframe.cpp | 7 ---- pcbnew/pcbframe.cpp | 6 ---- pcbnew/pcbnew_id.h | 4 +-- pcbnew/router/router_tool.cpp | 3 +- pcbnew/tools/common_actions.cpp | 63 ++++++++++++++++++++++++++++----- pcbnew/tools/common_actions.h | 12 +++++++ pcbnew/tools/pcb_tools.cpp | 1 + 9 files changed, 83 insertions(+), 43 deletions(-) diff --git a/common/tool/tool_dispatcher.cpp b/common/tool/tool_dispatcher.cpp index 83e9e20d41..b19da891e2 100644 --- a/common/tool/tool_dispatcher.cpp +++ b/common/tool/tool_dispatcher.cpp @@ -32,8 +32,6 @@ #include -#include - #include #include @@ -273,19 +271,5 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) void TOOL_DISPATCHER::DispatchWxCommand( const wxCommandEvent& aEvent ) { - bool activateTool = false; - std::string toolName; - - // fixme: use TOOL_ACTIONs here - switch( aEvent.GetId() ) - { - case ID_PNS_ROUTER_TOOL: - toolName = "pcbnew.InteractiveRouter"; - activateTool = true; - break; - } - - // do nothing if the legacy view is active - if( activateTool && m_editFrame->IsGalCanvasActive() ) - m_toolMgr->InvokeTool( toolName ); + // no events to dispatch currently } diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index 7b3ddc2846..6846dda597 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -54,6 +54,9 @@ #include #include +#include +#include + // Handles the selection of command events. void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) { @@ -1451,4 +1454,13 @@ void PCB_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent ) break; } + + if( IsGalCanvasActive() ) + { + std::string actionName = COMMON_ACTIONS::TranslateLegacyId( id ); + if( !actionName.empty() ) + m_toolManager->RunAction( actionName ); + + return; + } } diff --git a/pcbnew/menubar_pcbframe.cpp b/pcbnew/menubar_pcbframe.cpp index 3bb2763081..4d88d95ff3 100644 --- a/pcbnew/menubar_pcbframe.cpp +++ b/pcbnew/menubar_pcbframe.cpp @@ -312,13 +312,6 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() _( "Reset text size and width of all module fields to current defaults" ), KiBitmap( reset_text_xpm ) ); - editMenu->AppendSeparator(); - - AddMenuItem( editMenu, ID_PNS_ROUTER_TOOL, - _( "Interactive router" ), - _( "Interactive router drag&drop tool." ), - KiBitmap( tools_xpm ) ); - /** Create View menu **/ wxMenu* viewMenu = new wxMenu; diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 967f8dde9c..f87ae2e959 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -126,12 +126,6 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME ) EVT_MENU( wxID_EXIT, PCB_EDIT_FRAME::OnQuit ) // menu Config - - /* Tom's hacks start */ - EVT_MENU ( ID_PNS_ROUTER_TOOL, PCB_EDIT_FRAME::onGenericCommand ) - EVT_TOOL ( ID_PNS_ROUTER_TOOL, PCB_EDIT_FRAME::onGenericCommand ) - /* Tom's hacks end */ - EVT_MENU( ID_PCB_DRAWINGS_WIDTHS_SETUP, PCB_EDIT_FRAME::OnConfigurePcbOptions ) EVT_MENU( ID_PCB_LIB_TABLE_EDIT, PCB_EDIT_FRAME::Process_Config ) EVT_MENU( ID_CONFIG_SAVE, PCB_EDIT_FRAME::Process_Config ) diff --git a/pcbnew/pcbnew_id.h b/pcbnew/pcbnew_id.h index 3dad96290a..83a620c256 100644 --- a/pcbnew/pcbnew_id.h +++ b/pcbnew/pcbnew_id.h @@ -369,9 +369,7 @@ enum pcbnew_ids ID_FOOTPRINT_WIZARD_PAGES_WINDOW, ID_FOOTPRINT_WIZARD_PARAMETERS_WINDOW, ID_FOOTPRINT_WIZARD_SELECT_WIZARD, - ID_FOOTPRINT_WIZARD_EXPORT_TO_BOARD, - - ID_PNS_ROUTER_TOOL + ID_FOOTPRINT_WIZARD_EXPORT_TO_BOARD }; #endif // PCBNEW_ID_H_ diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 6896bb5a15..24073dc6cd 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -31,6 +31,7 @@ #include #include +#include #include @@ -88,7 +89,7 @@ void ROUTER_TOOL::Reset( RESET_REASON aReason ) if( getView() ) m_router->SetView( getView() ); - Go( &ROUTER_TOOL::Main, TOOL_EVENT( TC_COMMAND, TA_ACTION, GetName() ) ); + Go( &ROUTER_TOOL::Main, COMMON_ACTIONS::routerActivate.MakeEvent() ); } diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 339087bdb8..64dc5f760d 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -24,6 +24,7 @@ #include "common_actions.h" #include +#include #include // Selection tool actions @@ -57,38 +58,82 @@ TOOL_ACTION COMMON_ACTIONS::properties( "pcbnew.InteractiveEdit.properties", AS_GLOBAL, 'E', "Properties...", "Displays properties window" ); +// Drawing tool actions TOOL_ACTION COMMON_ACTIONS::drawLine( "pcbnew.InteractiveDrawing.line", - AS_GLOBAL, 'D', + AS_GLOBAL, 0, "Draw a line", "Draw a line" ); TOOL_ACTION COMMON_ACTIONS::drawCircle( "pcbnew.InteractiveDrawing.circle", - AS_GLOBAL, 'S', + AS_GLOBAL, 0, "Draw a circle", "Draw a circle" ); TOOL_ACTION COMMON_ACTIONS::drawArc( "pcbnew.InteractiveDrawing.arc", - AS_GLOBAL, 'A', + AS_GLOBAL, 0, "Draw an arc", "Draw an arc" ); TOOL_ACTION COMMON_ACTIONS::drawText( "pcbnew.InteractiveDrawing.text", - AS_GLOBAL, 'T', + AS_GLOBAL, 0, "Add a text", "Add a text" ); TOOL_ACTION COMMON_ACTIONS::drawDimension( "pcbnew.InteractiveDrawing.dimension", - AS_GLOBAL, 'X', + AS_GLOBAL, 0, "Add a dimension", "Add a dimension" ); TOOL_ACTION COMMON_ACTIONS::drawZone( "pcbnew.InteractiveDrawing.zone", - AS_GLOBAL, 'B', + AS_GLOBAL, 0, "Add a filled zone", "Add a filled zone" ); TOOL_ACTION COMMON_ACTIONS::drawKeepout( "pcbnew.InteractiveDrawing.keepout", - AS_GLOBAL, 'N', + AS_GLOBAL, 0, "Add a keepout area", "Add a keepout area" ); TOOL_ACTION COMMON_ACTIONS::placeTarget( "pcbnew.InteractiveDrawing.placeTarget", - AS_GLOBAL, 'C', + AS_GLOBAL, 0, "Add layer alignment target", "Add layer alignment target" ); TOOL_ACTION COMMON_ACTIONS::placeModule( "pcbnew.InteractiveDrawing.placeModule", - AS_GLOBAL, 'V', + AS_GLOBAL, 0, "Add modules", "Add modules" ); + +TOOL_ACTION COMMON_ACTIONS::routerActivate( "pcbnew.InteractiveRouter", + AS_GLOBAL, 0, + "Run push & shove router", "Run push & shove router" ); + + +std::string COMMON_ACTIONS::TranslateLegacyId( int aId ) +{ + switch( aId ) + { + case ID_PCB_MODULE_BUTT: + return COMMON_ACTIONS::placeModule.GetName(); + + case ID_TRACK_BUTT: + return COMMON_ACTIONS::routerActivate.GetName(); + + case ID_PCB_ZONES_BUTT: + return COMMON_ACTIONS::drawZone.GetName(); + + case ID_PCB_KEEPOUT_AREA_BUTT: + return COMMON_ACTIONS::drawKeepout.GetName(); + + case ID_PCB_ADD_LINE_BUTT: + return COMMON_ACTIONS::drawLine.GetName(); + + case ID_PCB_CIRCLE_BUTT: + return COMMON_ACTIONS::drawCircle.GetName(); + + case ID_PCB_ARC_BUTT: + return COMMON_ACTIONS::drawArc.GetName(); + + case ID_PCB_ADD_TEXT_BUTT: + return COMMON_ACTIONS::drawText.GetName(); + + case ID_PCB_DIMENSION_BUTT: + return COMMON_ACTIONS::drawDimension.GetName(); + + case ID_PCB_MIRE_BUTT: + return COMMON_ACTIONS::placeTarget.GetName(); + } + + return ""; +} diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index fc66573988..5d4908ac59 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -83,4 +83,16 @@ public: /// Activation of the drawing tool (placing a MODULE) static TOOL_ACTION placeModule; + + /// Activation of the Push and Shove router + static TOOL_ACTION routerActivate; + + /** + * Function TranslateLegacyId() + * Translates legacy tool ids to the corresponding TOOL_ACTION name. + * @param aId is legacy tool id to be translated. + * @return std::string is name of the corresponding TOOL_ACTION. It may be empty, if there is + * no corresponding TOOL_ACTION. + */ + static std::string TranslateLegacyId( int aId ); }; diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index 23c899b2fa..9ddfccc34d 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -64,6 +64,7 @@ void PCB_EDIT_FRAME::setupTools() m_toolManager->RegisterAction( &COMMON_ACTIONS::drawKeepout ); m_toolManager->RegisterAction( &COMMON_ACTIONS::placeTarget ); m_toolManager->RegisterAction( &COMMON_ACTIONS::placeModule ); + m_toolManager->RegisterAction( &COMMON_ACTIONS::routerActivate ); // Register tools m_toolManager->RegisterTool( new SELECTION_TOOL ); From 57c69b41dbc9d516bed698af14f25d042c0b1416 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 19 Feb 2014 13:51:32 +0100 Subject: [PATCH 035/134] Continous mode for drawing tools (i.e. they do not finish after adding a single object). --- include/tool/tool_event.h | 2 +- pcbnew/router/router_tool.cpp | 3 + pcbnew/tools/drawing_tool.cpp | 455 +++++++++++++++++++++------------- pcbnew/tools/drawing_tool.h | 2 +- 4 files changed, 287 insertions(+), 175 deletions(-) diff --git a/include/tool/tool_event.h b/include/tool/tool_event.h index 46b06e1eed..3f7971ed77 100644 --- a/include/tool/tool_event.h +++ b/include/tool/tool_event.h @@ -207,7 +207,7 @@ public: ///> Returns information about difference between current mouse cursor position and the place ///> where dragging has started. - const VECTOR2D Delta() const + const VECTOR2D& Delta() const { assert( m_category == TC_MOUSE ); // this should be used only with mouse events return m_mouseDelta; diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 24073dc6cd..adb3490de3 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -26,6 +26,7 @@ #include "class_board.h" #include +#include #include #include #include @@ -464,6 +465,8 @@ int ROUTER_TOOL::Main( TOOL_EVENT& aEvent ) ctls->ShowCursor( false ); ctls->ForceCursorPosition( false ); + getEditFrame()->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); + return 0; } diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 1397ce9664..c120c4ac12 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -26,6 +26,7 @@ #include "common_actions.h" #include +#include #include #include @@ -83,13 +84,7 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) double startAngle; // angle of the first arc line VECTOR2I cursorPos = m_controls->GetCursorPosition(); - // Init the new item attributes - DRAWSEGMENT* arc = new DRAWSEGMENT( m_board ); - arc->SetShape( S_ARC ); - arc->SetAngle( 0.0 ); - arc->SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth ); - arc->SetCenter( wxPoint( cursorPos.x, cursorPos.y ) ); - + DRAWSEGMENT* arc; DRAWSEGMENT helperLine; helperLine.SetShape( S_SEGMENT ); helperLine.SetLayer( DRAW_N ); @@ -120,11 +115,19 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) if( evt->IsCancel() ) { - delete arc; - break; + if( step != SET_ORIGIN ) // start from the beginning + { + preview.Clear(); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + + delete arc; + step = SET_ORIGIN; + } + else + break; } - else if( evt->IsKeyUp() ) + else if( evt->IsKeyUp() && step != SET_ORIGIN ) { int width = arc->GetWidth(); @@ -161,9 +164,17 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) } else { - helperLine.SetStart( arc->GetCenter() ); + // Init the new item attributes + arc = new DRAWSEGMENT( m_board ); + arc->SetShape( S_ARC ); + arc->SetAngle( 0.0 ); + arc->SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth ); arc->SetCenter( wxPoint( cursorPos.x, cursorPos.y ) ); arc->SetLayer( layer ); + + helperLine.SetStart( arc->GetCenter() ); + helperLine.SetEnd( arc->GetCenter() ); + preview.Add( arc ); preview.Add( &helperLine ); @@ -200,6 +211,9 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) m_frame->OnModify(); m_frame->SaveCopyInUndoList( arc, UR_NEW ); + + preview.Remove( arc ); + preview.Remove( &helperLine ); } else --step; // one another chance to draw a proper arc @@ -208,17 +222,16 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) } if( ++step == FINISHED ) - break; + { + step = SET_ORIGIN; + m_controls->SetAutoPan( false ); + } } else if( evt->IsMotion() ) { switch( step ) { - case SET_ORIGIN: - arc->SetCenter( wxPoint( cursorPos.x, cursorPos.y ) ); - break; - case SET_END: helperLine.SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); arc->SetArcStart( wxPoint( cursorPos.x, cursorPos.y ) ); @@ -226,10 +239,10 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) case SET_ANGLE: { - // Compute the current angle VECTOR2D endLine( wxPoint( cursorPos.x, cursorPos.y ) - arc->GetCenter() ); double newAngle = RAD2DECIDEG( endLine.Angle() - startAngle ); + // Adjust the new angle to (counter)clockwise setting if( clockwise && newAngle < 0.0 ) newAngle += 3600.0; else if( !clockwise && newAngle > 0.0 ) @@ -251,6 +264,7 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) m_view->Remove( &preview ); setTransitions(); + m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); return 0; } @@ -258,17 +272,10 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) { - // Init the new item attributes - TEXTE_PCB* text = m_frame->CreateTextePcb( NULL ); - if( text == NULL ) - { - setTransitions(); - return 0; - } + TEXTE_PCB* text; // Add a VIEW_GROUP that serves as a preview for the new item KIGFX::VIEW_GROUP preview( m_view ); - preview.Add( text ); m_view->Add( &preview ); m_controls->ShowCursor( true ); @@ -276,6 +283,7 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) m_controls->SetAutoPan( true ); Activate(); + bool created = false; // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) @@ -284,12 +292,20 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) if( evt->IsCancel() ) { - // it was already added by CreateTextPcb() - m_board->Delete( text ); - break; + if( created ) + { + // Delete the old text and have another try + m_board->Delete( text ); // it was already added by CreateTextPcb() + preview.Clear(); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + created = false; + m_controls->ShowCursor( true ); + } + else + break; } - else if( evt->Category() == TC_COMMAND ) + else if( created && evt->Category() == TC_COMMAND ) { if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) { @@ -305,21 +321,37 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) else if( evt->IsClick( BUT_LEFT ) ) { - assert( text->GetText().Length() > 0 ); - assert( text->GetSize().x > 0 && text->GetSize().y > 0 ); + if( !created ) + { + // Init the new item attributes + text = m_frame->CreateTextePcb( NULL ); + if( text == NULL ) + continue; - text->ClearFlags(); - m_view->Add( text ); - // m_board->Add( text ); // it is already added by CreateTextePcb() - text->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + m_controls->ShowCursor( false ); + preview.Add( text ); + } + else + { + assert( text->GetText().Length() > 0 ); + assert( text->GetSize().x > 0 && text->GetSize().y > 0 ); - m_frame->OnModify(); - m_frame->SaveCopyInUndoList( text, UR_NEW ); + text->ClearFlags(); + m_view->Add( text ); + // m_board->Add( text ); // it is already added by CreateTextePcb() + text->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - break; + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( text, UR_NEW ); + + preview.Remove( text ); + m_controls->ShowCursor( true ); + } + + created = !created; } - else if( evt->IsMotion() ) + else if( created && evt->IsMotion() ) { text->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) ); @@ -334,6 +366,7 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) m_view->Remove( &preview ); setTransitions(); + m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); return 0; } @@ -341,19 +374,8 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) { - DIMENSION* dimension = new DIMENSION( m_board ); - - // Init the new item attributes - dimension->Text().SetSize( m_board->GetDesignSettings().m_PcbTextSize ); - int width = m_board->GetDesignSettings().m_PcbTextWidth; - int maxThickness = Clamp_Text_PenSize( width, dimension->Text().GetSize() ); - - if( width > maxThickness ) - width = maxThickness; - - dimension->Text().SetThickness( width ); - dimension->SetWidth( width ); - dimension->AdjustDimensionDetails(); + DIMENSION* dimension; + int width, maxThickness; // Add a VIEW_GROUP that serves as a preview for the new item KIGFX::VIEW_GROUP preview( m_view ); @@ -380,11 +402,19 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) if( evt->IsCancel() ) { - delete dimension; - break; + if( step != SET_ORIGIN ) // start from the beginning + { + preview.Clear(); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + + delete dimension; + step = SET_ORIGIN; + } + else + break; } - else if( evt->IsKeyUp() ) + else if( evt->IsKeyUp() && step != SET_ORIGIN ) { width = dimension->GetWidth(); @@ -405,19 +435,33 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) { LAYER_NUM layer = m_frame->GetScreen()->m_Active_Layer; - if( IsCopperLayer( layer ) ) + if( IsCopperLayer( layer ) || layer == EDGE_N ) { - DisplayInfoMessage( NULL, _( "Graphic not allowed on Copper layers" ) ); + DisplayInfoMessage( NULL, _( "Dimension not allowed on Copper or Edge Cut layers" ) ); --step; } else { - m_controls->SetAutoPan( true ); - + // Init the new item attributes + dimension = new DIMENSION( m_board ); dimension->SetLayer( layer ); dimension->SetOrigin( wxPoint( cursorPos.x, cursorPos.y ) ); + dimension->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); + dimension->Text().SetSize( m_board->GetDesignSettings().m_PcbTextSize ); + + width = m_board->GetDesignSettings().m_PcbTextWidth; + maxThickness = Clamp_Text_PenSize( width, dimension->Text().GetSize() ); + + if( width > maxThickness ) + width = maxThickness; + + dimension->Text().SetThickness( width ); + dimension->SetWidth( width ); + dimension->AdjustDimensionDetails(); preview.Add( dimension ); + + m_controls->SetAutoPan( true ); } } break; @@ -441,13 +485,18 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) m_frame->OnModify(); m_frame->SaveCopyInUndoList( dimension, UR_NEW ); + + preview.Remove( dimension ); } } break; } if( ++step == FINISHED ) - break; + { + step = SET_ORIGIN; + m_controls->SetAutoPan( false ); + } } else if( evt->IsMotion() ) @@ -476,12 +525,16 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) } } + if( step != SET_ORIGIN ) + delete dimension; + m_controls->ShowCursor( false ); m_controls->SetSnapping( false ); m_controls->SetAutoPan( false ); m_view->Remove( &preview ); setTransitions(); + m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); return 0; } @@ -527,10 +580,7 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) cursorPos = m_controls->GetCursorPosition(); if( evt->IsCancel() ) - { - delete target; break; - } else if( evt->IsKeyUp() ) { @@ -557,7 +607,11 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) m_frame->OnModify(); m_frame->SaveCopyInUndoList( target, UR_NEW ); - break; + preview.Remove( target ); + + // Create next PCB_TARGET + target = new PCB_TARGET( *target ); + preview.Add( target ); } else if( evt->IsMotion() ) @@ -567,11 +621,14 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) } } + delete target; + m_controls->SetSnapping( false ); m_controls->SetAutoPan( false ); m_view->Remove( &preview ); setTransitions(); + m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); return 0; } @@ -579,42 +636,42 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) { - MODULE* module = m_frame->LoadModuleFromLibrary( wxEmptyString, - m_frame->GetFootprintLibraryTable(), true, NULL ); - if( module == NULL ) - { - setTransitions(); - return 0; - } - - // Init the new item attributes - VECTOR2I cursorPos = m_controls->GetCursorPosition(); - module->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); + MODULE* module; // Add a VIEW_GROUP that serves as a preview for the new item KIGFX::VIEW_GROUP preview( m_view ); - preview.Add( module ); - module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW_GROUP::Add ), &preview ) ); m_view->Add( &preview ); - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); m_controls->SetAutoPan( true ); Activate(); + bool created = false; + // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { - cursorPos = m_controls->GetCursorPosition(); + VECTOR2I cursorPos = m_controls->GetCursorPosition(); if( evt->IsCancel() ) { - m_board->Delete( module ); - break; + if( created ) + { + m_board->Delete( module ); // it was added by LoadModuleFromLibrary + m_controls->ShowCursor( true ); + + preview.Clear(); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + + created = false; + } + else + break; } - else if( evt->Category() == TC_COMMAND ) + else if( created && evt->Category() == TC_COMMAND ) { if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) { @@ -630,28 +687,59 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) else if( evt->IsClick( BUT_LEFT ) ) { - module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), m_view ) ); - m_view->Add( module ); - module->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + if( !created ) + { + // Init the new item attributes + module = m_frame->LoadModuleFromLibrary( wxEmptyString, + m_frame->GetFootprintLibraryTable(), + true, NULL ); + if( module == NULL ) + continue; - m_frame->OnModify(); - m_frame->SaveCopyInUndoList( module, UR_NEW ); + m_controls->ShowCursor( false ); + module->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); - break; + // Add all the drawable parts to preview + preview.Add( module ); + module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW_GROUP::Add ), + &preview ) ); + + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + else + { + module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), m_view ) ); + m_view->Add( module ); + module->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( module, UR_NEW ); + + // Remove from preview + preview.Remove( module ); + module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW_GROUP::Remove ), + &preview ) ); + + m_controls->ShowCursor( true ); + } + + created = !created; } - else if( evt->IsMotion() ) + else if( created && evt->IsMotion() ) { module->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } } + m_controls->ShowCursor( false ); m_controls->SetSnapping( false ); m_controls->SetAutoPan( false ); m_view->Remove( &preview ); setTransitions(); + m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); return 0; } @@ -662,12 +750,8 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) // Only two shapes are currently supported assert( aShape == S_SEGMENT || aShape == S_CIRCLE ); - // Init the new item attributes - DRAWSEGMENT* graphic = new DRAWSEGMENT( m_board ); - graphic->SetShape( (STROKE_T) aShape ); - graphic->SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth ); - - DRAWSEGMENT line45( *graphic ); // used only for direction 45 mode with lines + DRAWSEGMENT* graphic = NULL; + DRAWSEGMENT line45; // Add a VIEW_GROUP that serves as a preview for the new item KIGFX::VIEW_GROUP preview( m_view ); @@ -678,9 +762,9 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) Activate(); - bool started = false; bool direction45 = false; // 45 degrees only mode int addedSegments = 0; + bool created = false; // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) @@ -689,7 +773,7 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) VECTOR2I cursorPos = m_controls->GetCursorPosition(); // Enable 45 degrees lines only mode by holding control - if( direction45 != ( evt->Modifier( MD_CTRL ) && aShape == S_SEGMENT && started ) ) + if( direction45 != evt->Modifier( MD_CTRL ) && created && aShape == S_SEGMENT ) { direction45 = evt->Modifier( MD_CTRL ); @@ -710,16 +794,20 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) if( evt->IsCancel() ) { if( direction45 ) - preview.Remove( &line45 ); + preview.Remove( &line45 ); // prevent line45 from being deleted preview.FreeItems(); - if( !started ) - delete graphic; + updatePreview = true; - break; + if( !created ) + break; + + // We did not exit the loop? So go once again + created = false; + m_controls->SetAutoPan( false ); } - else if( evt->IsKeyUp() ) + else if( created && evt->IsKeyUp() ) { int width = graphic->GetWidth(); @@ -734,7 +822,7 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) else if( evt->IsClick( BUT_LEFT ) ) { - if( !started ) + if( !created ) { LAYER_NUM layer = m_frame->GetScreen()->m_Active_Layer; @@ -744,15 +832,23 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) } else { - m_controls->SetAutoPan( true ); - + // Init the new item attributes + graphic = new DRAWSEGMENT( m_board ); + graphic->SetShape( (STROKE_T) aShape ); + graphic->SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth ); graphic->SetStart( wxPoint( cursorPos.x, cursorPos.y ) ); graphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); graphic->SetLayer( layer ); - line45.SetLayer( layer ); - preview.Add( graphic ); - started = true; + if( aShape == S_SEGMENT ) + { + line45 = *graphic; // used only for direction 45 mode with lines + line45.SetLayer( layer ); + } + + preview.Add( graphic ); + created = true; + m_controls->SetAutoPan( true ); } } else @@ -765,15 +861,17 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) m_view->Add( graphic ); m_board->Add( graphic ); graphic->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - preview.Remove( graphic ); - ++addedSegments; m_frame->OnModify(); m_frame->SaveCopyInUndoList( graphic, UR_NEW ); + preview.Remove( graphic ); + ++addedSegments; + if( aContinous ) { graphic = new DRAWSEGMENT( *graphic ); + // Start the new line in the same spot where the previous one has ended graphic->SetStart( graphic->GetEnd() ); @@ -782,20 +880,24 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) preview.Add( graphic ); } - else + else // start a new graphic { - break; + addedSegments = 0; + created = false; + m_controls->SetAutoPan( false ); } } else if( addedSegments > 0 ) // User has clicked twice in the same spot - { - delete graphic; // seems like a clear sign that the drawing is finished - break; // and we should remove the latest DRAWSEGMENT we have created + { // a clear sign that the current drawing is finished + created = false; // but only if at least one graphic was created + preview.Remove( graphic ); // otherwise - force user to draw or cancel + delete graphic; + m_controls->SetAutoPan( false ); } } } - else if( evt->IsMotion() && started ) + else if( created && evt->IsMotion() ) { // 45 degree lines if( direction45 && aShape == S_SEGMENT ) @@ -814,7 +916,9 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) m_controls->SetSnapping( false ); m_controls->SetAutoPan( false ); m_view->Remove( &preview ); + setTransitions(); + m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); return 0; } @@ -822,42 +926,9 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) int DRAWING_TOOL::drawZone( bool aKeepout ) { - ZONE_CONTAINER* zone = new ZONE_CONTAINER( m_board ); - - // Get the current, default settings for zones - ZONE_SETTINGS zoneInfo = m_frame->GetZoneSettings(); - zoneInfo.m_CurrentZone_Layer = m_frame->GetScreen()->m_Active_Layer; - - // Show options dialog - ZONE_EDIT_T dialogResult; - if( aKeepout ) - dialogResult = InvokeKeepoutAreaEditor( m_frame, &zoneInfo ); - else - { - if( IsCopperLayer( zoneInfo.m_CurrentZone_Layer ) ) - dialogResult = InvokeCopperZonesEditor( m_frame, &zoneInfo ); - else - dialogResult = InvokeNonCopperZonesEditor( m_frame, NULL, &zoneInfo ); - } - - if( dialogResult == ZONE_ABORT ) - { - delete zone; - setTransitions(); - - return 0; - } - - // Apply the selected settings - zoneInfo.ExportSetting( *zone ); - m_frame->SetTopLayer( zoneInfo.m_CurrentZone_Layer ); - - // Helper line represents the currently drawn line of the zone polygon - DRAWSEGMENT* helperLine = new DRAWSEGMENT; - helperLine->SetShape( S_SEGMENT ); - helperLine->SetLayer( zoneInfo.m_CurrentZone_Layer ); - helperLine->SetWidth( 1 ); - DRAWSEGMENT line45( *helperLine ); + ZONE_CONTAINER* zone; + DRAWSEGMENT line45; + DRAWSEGMENT* helperLine; // we will need more than one helper line // Add a VIEW_GROUP that serves as a preview for the new item KIGFX::VIEW_GROUP preview( m_view ); @@ -865,7 +936,6 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); - m_controls->SetAutoPan( true ); Activate(); @@ -873,7 +943,6 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) VECTOR2I origin; int numPoints = 0; bool direction45 = false; // 45 degrees only mode - bool cancelled = false; // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) @@ -902,15 +971,28 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) if( evt->IsCancel() ) { - cancelled = true; - break; + if( numPoints > 0 ) // cancel the current zone + { + delete zone; + m_controls->SetAutoPan( false ); + + if( direction45 ) + preview.Remove( &line45 ); + preview.FreeItems(); + updatePreview = true; + + numPoints = 0; + } + else // there is no zone currently drawn - just stop the tool + break; } else if( evt->IsClick( BUT_LEFT ) ) { + // Check if it is double click / closing line (so we have to finish the zone) if( lastCursorPos == cursorPos || ( numPoints > 0 && cursorPos == origin ) ) { - if( numPoints > 2 ) + if( numPoints > 2 ) // valid zone consists of more than 2 points { assert( zone->GetNumCorners() > 2 ); @@ -930,23 +1012,56 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) m_frame->SaveCopyInUndoList( zone, UR_NEW ); } else - { - // If there are less than 3 points, then it is not a valid zone - cancelled = true; - } + delete zone; - break; + numPoints = 0; + m_controls->SetAutoPan( false ); + preview.FreeItems(); + updatePreview = true; } else { - if( numPoints == 0 ) + if( numPoints == 0 ) // it's the first click { + // Get the current default settings for zones + ZONE_SETTINGS zoneInfo = m_frame->GetZoneSettings(); + zoneInfo.m_CurrentZone_Layer = m_frame->GetScreen()->m_Active_Layer; + + // Show options dialog + ZONE_EDIT_T dialogResult; + if( aKeepout ) + dialogResult = InvokeKeepoutAreaEditor( m_frame, &zoneInfo ); + else + { + if( IsCopperLayer( zoneInfo.m_CurrentZone_Layer ) ) + dialogResult = InvokeCopperZonesEditor( m_frame, &zoneInfo ); + else + dialogResult = InvokeNonCopperZonesEditor( m_frame, NULL, &zoneInfo ); + } + + if( dialogResult == ZONE_ABORT ) + continue; + + // Apply the selected settings + zone = new ZONE_CONTAINER( m_board ); + zoneInfo.ExportSetting( *zone ); + m_frame->SetTopLayer( zoneInfo.m_CurrentZone_Layer ); + // Add the first point zone->Outline()->Start( zoneInfo.m_CurrentZone_Layer, cursorPos.x, cursorPos.y, zone->GetHatchStyle() ); - helperLine->SetStart( wxPoint( cursorPos.x, cursorPos.y ) ); origin = cursorPos; + + // Helper line represents the currently drawn line of the zone polygon + helperLine = new DRAWSEGMENT; + helperLine->SetShape( S_SEGMENT ); + helperLine->SetWidth( 1 ); + helperLine->SetLayer( zoneInfo.m_CurrentZone_Layer ); + helperLine->SetStart( wxPoint( cursorPos.x, cursorPos.y ) ); + helperLine->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); + line45 = *helperLine; + preview.Add( helperLine ); } else @@ -956,15 +1071,15 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) helperLine->SetStart( helperLine->GetEnd() ); preview.Add( helperLine ); } - ++numPoints; + ++numPoints; updatePreview = true; } lastCursorPos = cursorPos; } - else if( evt->IsMotion() ) + else if( evt->IsMotion() && numPoints > 0 ) { // 45 degree lines if( direction45 ) @@ -985,14 +1100,8 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) m_controls->SetAutoPan( false ); m_view->Remove( &preview ); - // Clean - if( cancelled ) - delete zone; - if( direction45 ) - preview.Remove( &line45 ); - preview.FreeItems(); - setTransitions(); + m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); return 0; } diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index 775351efaf..2339cb3a9c 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -116,7 +116,7 @@ public: /** * Function PlaceModule() - * Displays a dialog to selected a module to be added and then allows user to set its position.. + * Displays a dialog to selected a module to be added and then allows user to set its position. */ int PlaceModule( TOOL_EVENT& aEvent ); From 87785441bc62474aedcf469f37379c56b995e7d3 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 19 Feb 2014 15:20:42 +0100 Subject: [PATCH 036/134] Removed some excessive variables. --- pcbnew/tools/drawing_tool.cpp | 80 +++++++++++++++++------------------ 1 file changed, 38 insertions(+), 42 deletions(-) diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index c120c4ac12..b3ea0c6a3a 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -272,7 +272,7 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) { - TEXTE_PCB* text; + TEXTE_PCB* text = NULL; // Add a VIEW_GROUP that serves as a preview for the new item KIGFX::VIEW_GROUP preview( m_view ); @@ -283,7 +283,6 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) m_controls->SetAutoPan( true ); Activate(); - bool created = false; // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) @@ -292,20 +291,21 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) if( evt->IsCancel() ) { - if( created ) + if( text ) { // Delete the old text and have another try m_board->Delete( text ); // it was already added by CreateTextPcb() + text = NULL; + preview.Clear(); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - created = false; m_controls->ShowCursor( true ); } else break; } - else if( created && evt->Category() == TC_COMMAND ) + else if( text && evt->Category() == TC_COMMAND ) { if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) { @@ -321,7 +321,7 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) else if( evt->IsClick( BUT_LEFT ) ) { - if( !created ) + if( !text ) { // Init the new item attributes text = m_frame->CreateTextePcb( NULL ); @@ -346,12 +346,12 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) preview.Remove( text ); m_controls->ShowCursor( true ); - } - created = !created; + text = NULL; + } } - else if( created && evt->IsMotion() ) + else if( text && evt->IsMotion() ) { text->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) ); @@ -467,8 +467,10 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) break; case SET_END: + dimension->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); + // Dimensions that have origin and end in the same spot are not valid - if( dimension->GetOrigin() == wxPoint( cursorPos.x, cursorPos.y ) ) + if( dimension->GetOrigin() == dimension->GetEnd() ) --step; break; @@ -636,7 +638,7 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) { - MODULE* module; + MODULE* module = NULL; // Add a VIEW_GROUP that serves as a preview for the new item KIGFX::VIEW_GROUP preview( m_view ); @@ -648,8 +650,6 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) Activate(); - bool created = false; - // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { @@ -657,21 +657,20 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) if( evt->IsCancel() ) { - if( created ) + if( module ) { m_board->Delete( module ); // it was added by LoadModuleFromLibrary - m_controls->ShowCursor( true ); + module = NULL; preview.Clear(); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - - created = false; + m_controls->ShowCursor( true ); } else break; } - else if( created && evt->Category() == TC_COMMAND ) + else if( module && evt->Category() == TC_COMMAND ) { if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) { @@ -687,7 +686,7 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) else if( evt->IsClick( BUT_LEFT ) ) { - if( !created ) + if( !module ) { // Init the new item attributes module = m_frame->LoadModuleFromLibrary( wxEmptyString, @@ -719,14 +718,13 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) preview.Remove( module ); module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW_GROUP::Remove ), &preview ) ); + module = NULL; // to indicate that there is no module that we currently modify m_controls->ShowCursor( true ); } - - created = !created; } - else if( created && evt->IsMotion() ) + else if( module && evt->IsMotion() ) { module->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); @@ -764,7 +762,6 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) bool direction45 = false; // 45 degrees only mode int addedSegments = 0; - bool created = false; // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) @@ -773,7 +770,7 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) VECTOR2I cursorPos = m_controls->GetCursorPosition(); // Enable 45 degrees lines only mode by holding control - if( direction45 != evt->Modifier( MD_CTRL ) && created && aShape == S_SEGMENT ) + if( direction45 != evt->Modifier( MD_CTRL ) && graphic && aShape == S_SEGMENT ) { direction45 = evt->Modifier( MD_CTRL ); @@ -793,21 +790,19 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) if( evt->IsCancel() ) { - if( direction45 ) - preview.Remove( &line45 ); // prevent line45 from being deleted - - preview.FreeItems(); - updatePreview = true; - - if( !created ) + if( !graphic ) break; - // We did not exit the loop? So go once again - created = false; + preview.Clear(); + updatePreview = true; + + delete graphic; + graphic = NULL; + m_controls->SetAutoPan( false ); } - else if( created && evt->IsKeyUp() ) + else if( graphic && evt->IsKeyUp() ) { int width = graphic->GetWidth(); @@ -822,7 +817,7 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) else if( evt->IsClick( BUT_LEFT ) ) { - if( !created ) + if( !graphic ) { LAYER_NUM layer = m_frame->GetScreen()->m_Active_Layer; @@ -847,7 +842,6 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) } preview.Add( graphic ); - created = true; m_controls->SetAutoPan( true ); } } @@ -883,21 +877,23 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) else // start a new graphic { addedSegments = 0; - created = false; m_controls->SetAutoPan( false ); + graphic = NULL; } } - else if( addedSegments > 0 ) // User has clicked twice in the same spot - { // a clear sign that the current drawing is finished - created = false; // but only if at least one graphic was created - preview.Remove( graphic ); // otherwise - force user to draw or cancel + else if( addedSegments > 0 ) // User has clicked twice in the same spot + { // a clear sign that the current drawing is finished + preview.Clear(); // but only if at least one graphic was created + // otherwise - force user to draw more or cancel delete graphic; + graphic = NULL; + m_controls->SetAutoPan( false ); } } } - else if( created && evt->IsMotion() ) + else if( graphic && evt->IsMotion() ) { // 45 degree lines if( direction45 && aShape == S_SEGMENT ) From 5ac699776deecf118bc6bd065a630129c6880700 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 21 Feb 2014 16:57:18 +0100 Subject: [PATCH 037/134] Revisiting GAL: - VIEW_ITEM::ViewUpdate() does not update items immediately. Now it marks them to be updated and the real update occurs on the next rendering frame. - VIEW::InvalidateItem() made private. - VIEW_LAYER::enabled -> visible - Some functions moved to header files. --- common/drawpanel_gal.cpp | 20 ++++-- common/view/view.cpp | 136 ++++++++++++++++---------------------- common/view/view_item.cpp | 21 ++---- include/view/view.h | 106 ++++++++++++++++++----------- include/view/view_item.h | 42 ++++++++++-- pcbnew/class_module.cpp | 14 ++-- 6 files changed, 187 insertions(+), 152 deletions(-) diff --git a/common/drawpanel_gal.cpp b/common/drawpanel_gal.cpp index 2a03dcc571..6a7e4f9d6a 100644 --- a/common/drawpanel_gal.cpp +++ b/common/drawpanel_gal.cpp @@ -124,17 +124,22 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) ) { m_drawing = true; + m_view->UpdateItems(); m_gal->BeginDrawing(); - m_gal->SetBackgroundColor( KIGFX::COLOR4D( 0.0, 0.0, 0.0, 1.0 ) ); m_gal->ClearScreen(); - m_view->ClearTargets(); - // Grid has to be redrawn only when the NONCACHED target is redrawn - if( m_view->IsTargetDirty( KIGFX::TARGET_NONCACHED ) ) - m_gal->DrawGrid(); - m_view->Redraw(); - m_gal->DrawCursor( m_viewControls->GetCursorPosition() ); + if( m_view->IsDirty() ) + { + m_view->ClearTargets(); + // Grid has to be redrawn only when the NONCACHED target is redrawn + if( m_view->IsTargetDirty( KIGFX::TARGET_NONCACHED ) ) + m_gal->DrawGrid(); + + m_view->Redraw(); + } + + m_gal->DrawCursor( m_viewControls->GetCursorPosition() ); m_gal->EndDrawing(); m_drawing = false; @@ -215,6 +220,7 @@ void EDA_DRAW_PANEL_GAL::SwitchBackend( GalType aGalType ) wxSize size = GetClientSize(); m_gal->ResizeScreen( size.GetX(), size.GetY() ); + m_gal->SetBackgroundColor( KIGFX::COLOR4D( 0.0, 0.0, 0.0, 1.0 ) ); if( m_painter ) m_painter->SetGAL( m_gal ); diff --git a/common/view/view.cpp b/common/view/view.cpp index e9c6324012..0a18d42711 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -49,28 +49,24 @@ VIEW::VIEW( bool aIsDynamic ) : m_scaleLimits( 15000.0, 1.0 ) { m_panBoundary.SetMaximum(); + m_needsUpdate.reserve( 32768 ); // Redraw everything at the beginning - for( int i = 0; i < TARGETS_NUMBER; ++i ) - MarkTargetDirty( i ); + MarkDirty(); // View uses layers to display EDA_ITEMs (item may be displayed on several layers, for example // pad may be shown on pad, pad hole and solder paste layers). There are usual copper layers // (eg. F.Cu, B.Cu, internal and so on) and layers for displaying objects such as texts, // silkscreen, pads, vias, etc. for( int i = 0; i < VIEW_MAX_LAYERS; i++ ) - { AddLayer( i ); - } } VIEW::~VIEW() { BOOST_FOREACH( LAYER_MAP::value_type& l, m_layers ) - { delete l.second.items; - } } @@ -82,7 +78,7 @@ void VIEW::AddLayer( int aLayer, bool aDisplayOnly ) m_layers[aLayer].id = aLayer; m_layers[aLayer].items = new VIEW_RTREE(); m_layers[aLayer].renderingOrder = aLayer; - m_layers[aLayer].enabled = true; + m_layers[aLayer].visible = true; m_layers[aLayer].displayOnly = aDisplayOnly; m_layers[aLayer].target = TARGET_CACHED; } @@ -172,12 +168,12 @@ struct queryVisitor }; -int VIEW::Query( const BOX2I& aRect, std::vector& aResult ) +int VIEW::Query( const BOX2I& aRect, std::vector& aResult ) const { if( m_orderedLayers.empty() ) return 0; - std::vector::reverse_iterator i; + std::vector::const_reverse_iterator i; // execute queries in reverse direction, so that items that are on the top of // the rendering stack are returned first. @@ -257,12 +253,6 @@ void VIEW::SetGAL( GAL* aGal ) } -void VIEW::SetPainter( PAINTER* aPainter ) -{ - m_painter = aPainter; -} - - BOX2D VIEW::GetViewport() const { BOX2D rect; @@ -293,12 +283,6 @@ void VIEW::SetMirror( bool aMirrorX, bool aMirrorY ) } -void VIEW::SetScale( double aScale ) -{ - SetScale( aScale, m_center ); -} - - void VIEW::SetScale( double aScale, const VECTOR2D& aAnchor ) { if( aScale > m_scaleLimits.x ) @@ -578,8 +562,8 @@ void VIEW::UpdateAllLayersOrder() struct VIEW::drawItem { - drawItem( VIEW* aView, const VIEW_LAYER* aCurrentLayer ) : - currentLayer( aCurrentLayer ), view( aView ) + drawItem( VIEW* aView, int aLayer ) : + view( aView ), layer( aLayer ) { } @@ -587,18 +571,17 @@ struct VIEW::drawItem { // Conditions that have te be fulfilled for an item to be drawn bool drawCondition = aItem->ViewIsVisible() && - aItem->ViewGetLOD( currentLayer->id ) < view->m_scale; + aItem->ViewGetLOD( layer ) < view->m_scale; if( !drawCondition ) return true; - view->draw( aItem, currentLayer->id ); + view->draw( aItem, layer ); return true; } - const VIEW_LAYER* currentLayer; VIEW* view; - int layersCount, layers[VIEW_MAX_LAYERS]; + int layer, layersCount, layers[VIEW_MAX_LAYERS]; }; @@ -606,9 +589,9 @@ void VIEW::redrawRect( const BOX2I& aRect ) { BOOST_FOREACH( VIEW_LAYER* l, m_orderedLayers ) { - if( l->enabled && IsTargetDirty( l->target ) && areRequiredLayersEnabled( l->id ) ) + if( l->visible && IsTargetDirty( l->target ) && areRequiredLayersEnabled( l->id ) ) { - drawItem drawFunc( this, l ); + drawItem drawFunc( this, l->id ); m_gal->SetTarget( l->target ); m_gal->SetLayerDepth( l->renderingOrder ); @@ -618,7 +601,7 @@ void VIEW::redrawRect( const BOX2I& aRect ) } -void VIEW::draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate ) const +void VIEW::draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate ) { if( IsCached( aLayer ) && !aImmediate ) { @@ -649,11 +632,12 @@ void VIEW::draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate ) const } -void VIEW::draw( VIEW_ITEM* aItem, bool aImmediate ) const +void VIEW::draw( VIEW_ITEM* aItem, bool aImmediate ) { int layers[VIEW_MAX_LAYERS], layers_count; aItem->ViewGetLayers( layers, layers_count ); + // Sorting is needed for drawing order dependent GALs (like Cairo) SortLayers( layers, layers_count ); @@ -665,26 +649,12 @@ void VIEW::draw( VIEW_ITEM* aItem, bool aImmediate ) const } -void VIEW::draw( VIEW_GROUP* aGroup, bool aImmediate ) const +void VIEW::draw( VIEW_GROUP* aGroup, bool aImmediate ) { std::set::const_iterator it; for( it = aGroup->Begin(); it != aGroup->End(); ++it ) - { draw( *it, aImmediate ); - } -} - - -bool VIEW::IsDirty() const -{ - for( int i = 0; i < TARGETS_NUMBER; ++i ) - { - if( IsTargetDirty( i ) ) - return true; - } - - return false; } @@ -709,14 +679,14 @@ struct VIEW::recacheItem bool operator()( VIEW_ITEM* aItem ) { // Remove previously cached group - int prevGroup = aItem->getGroup( layer ); + int group = aItem->getGroup( layer ); - if( prevGroup >= 0 ) - gal->DeleteGroup( prevGroup ); + if( group >= 0 ) + gal->DeleteGroup( group ); if( immediately ) { - int group = gal->BeginGroup(); + group = gal->BeginGroup(); aItem->setGroup( layer, group ); if( !view->m_painter->Draw( aItem, layer ) ) @@ -791,13 +761,13 @@ void VIEW::Redraw() redrawRect( rect ); // All targets were redrawn, so nothing is dirty - clearTargetDirty( TARGET_CACHED ); - clearTargetDirty( TARGET_NONCACHED ); - clearTargetDirty( TARGET_OVERLAY ); + markTargetClean( TARGET_CACHED ); + markTargetClean( TARGET_NONCACHED ); + markTargetClean( TARGET_OVERLAY ); } -VECTOR2D VIEW::GetScreenPixelSize() const +const VECTOR2D& VIEW::GetScreenPixelSize() const { return m_gal->GetScreenPixelSize(); } @@ -839,7 +809,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 ) @@ -851,24 +821,23 @@ void VIEW::InvalidateItem( VIEW_ITEM* aItem, int aUpdateFlags ) aItem->ViewGetLayers( layers, layers_count ); // Iterate through layers used by the item and recache it immediately - for( int i = 0; i < layers_count; i++ ) + for( int i = 0; i < layers_count; ++i ) { int layerId = layers[i]; - if( aUpdateFlags & ( VIEW_ITEM::GEOMETRY | VIEW_ITEM::LAYERS ) ) + if( IsCached( layerId ) ) { - // Redraw - if( IsCached( layerId ) ) + if( aUpdateFlags & ( VIEW_ITEM::GEOMETRY | VIEW_ITEM::LAYERS ) ) updateItemGeometry( aItem, layerId ); - } - else if( aUpdateFlags & VIEW_ITEM::COLOR ) - { - updateItemColor( aItem, layerId ); + else if( aUpdateFlags & VIEW_ITEM::COLOR ) + updateItemColor( aItem, layerId ); } // Mark those layers as dirty, so the VIEW will be refreshed MarkTargetDirty( m_layers[layerId].target ); } + + aItem->clearUpdateFlags(); } @@ -890,6 +859,7 @@ void VIEW::sortLayers() void VIEW::updateItemColor( VIEW_ITEM* aItem, int aLayer ) { wxASSERT( (unsigned) aLayer < m_layers.size() ); + wxASSERT( IsCached( aLayer ) ); // Obtain the color that should be used for coloring the item on the specific layerId const COLOR4D color = m_painter->GetSettings()->GetColor( aItem, aLayer ); @@ -904,18 +874,20 @@ void VIEW::updateItemColor( VIEW_ITEM* aItem, int aLayer ) void VIEW::updateItemGeometry( VIEW_ITEM* aItem, int aLayer ) { wxASSERT( (unsigned) aLayer < m_layers.size() ); + wxASSERT( IsCached( aLayer ) ); + VIEW_LAYER& l = m_layers.at( aLayer ); m_gal->SetTarget( l.target ); m_gal->SetLayerDepth( l.renderingOrder ); // Redraw the item from scratch - int prevGroup = aItem->getGroup( aLayer ); + int group = aItem->getGroup( aLayer ); - if( prevGroup >= 0 ) - m_gal->DeleteGroup( prevGroup ); + if( group >= 0 ) + m_gal->DeleteGroup( group ); - int group = m_gal->BeginGroup(); + group = m_gal->BeginGroup(); aItem->setGroup( aLayer, group ); m_painter->Draw( static_cast( aItem ), aLayer ); m_gal->EndGroup(); @@ -951,11 +923,17 @@ void VIEW::updateLayers( VIEW_ITEM* aItem ) l.items->Remove( aItem ); MarkTargetDirty( l.target ); - // Redraw the item from scratch - int prevGroup = aItem->getGroup( layers[i] ); + if( IsCached( l.id ) ) + { + // Redraw the item from scratch + int prevGroup = aItem->getGroup( layers[i] ); - if( prevGroup >= 0 ) - m_gal->DeleteGroup( prevGroup ); + if( prevGroup >= 0 ) + { + m_gal->DeleteGroup( prevGroup ); + aItem->setGroup( l.id, -1 ); + } + } } // Add the item to new layer set @@ -981,7 +959,7 @@ bool VIEW::areRequiredLayersEnabled( int aLayerId ) const it_end = m_layers.at( aLayerId ).requiredLayers.end(); it != it_end; ++it ) { // That is enough if just one layer is not enabled - if( !m_layers.at( *it ).enabled ) + if( !m_layers.at( *it ).visible ) return false; } @@ -1023,13 +1001,15 @@ void VIEW::RecacheAllItems( bool aImmediately ) } -bool VIEW::IsTargetDirty( int aTarget ) const +void VIEW::UpdateItems() { - wxASSERT( aTarget < TARGETS_NUMBER ); + // Update items that need this + BOOST_FOREACH( VIEW_ITEM* item, m_needsUpdate ) + { + assert( item->viewRequiredUpdate() != VIEW_ITEM::NONE ); - // Check the target status - if( m_dirtyTargets[aTarget] ) - return true; + invalidateItem( item, item->viewRequiredUpdate() ); + } - return false; + m_needsUpdate.clear(); } diff --git a/common/view/view_item.cpp b/common/view/view_item.cpp index 305ab68579..900e030e61 100644 --- a/common/view/view_item.cpp +++ b/common/view/view_item.cpp @@ -31,25 +31,12 @@ using namespace KIGFX; 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 ) + if( m_visible != aIsVisible ) + { + m_visible = aIsVisible; ViewUpdate( APPEARANCE ); -} - - -void VIEW_ITEM::ViewUpdate( int aUpdateFlags ) -{ - if( !m_view ) - return; - - m_view->InvalidateItem( this, aUpdateFlags ); + } } diff --git a/include/view/view.h b/include/view/view.h index f7a7e90984..4a7965bb94 100644 --- a/include/view/view.h +++ b/include/view/view.h @@ -94,7 +94,7 @@ public: * first). * @return Number of found items. */ - int Query( const BOX2I& aRect, std::vector& aResult ); + int Query( const BOX2I& aRect, std::vector& aResult ) const; /** * Function SetRequired() @@ -140,7 +140,10 @@ public: * Function SetPainter() * Sets the painter object used by the view for drawing VIEW_ITEMS. */ - void SetPainter( PAINTER* aPainter ); + void SetPainter( PAINTER* aPainter ) + { + m_painter = aPainter; + } /** * Function GetPainter() @@ -181,7 +184,10 @@ public: * (depending on correct GAL unit length & DPI settings). * @param aScale: the scalefactor */ - void SetScale( double aScale ); + void SetScale( double aScale ) + { + SetScale( aScale, m_center ); + } /** * Function SetScale() @@ -247,7 +253,7 @@ public: * Returns the size of the our rendering area, in pixels. * @return viewport screen size */ - VECTOR2D GetScreenPixelSize() const; + const VECTOR2D& GetScreenPixelSize() const; /** * Function AddLayer() @@ -279,11 +285,11 @@ public: */ inline void SetLayerVisible( int aLayer, bool aVisible = true ) { - if( m_layers[aLayer].enabled != aVisible ) + if( m_layers[aLayer].visible != aVisible ) { // Target has to be redrawn after changing its visibility MarkTargetDirty( m_layers[aLayer].target ); - m_layers[aLayer].enabled = aVisible; + m_layers[aLayer].visible = aVisible; } } @@ -294,7 +300,7 @@ public: */ inline bool IsLayerVisible( int aLayer ) const { - return m_layers.at( aLayer ).enabled; + return m_layers.at( aLayer ).visible; } /** @@ -402,18 +408,11 @@ public: */ void Redraw(); - /** - * Function PartialRedraw() - * Redraws only the parts of the view that have been affected by items - * for which ViewUpdate() function has been called since last redraw. - */ - void PartialRedraw(); - /** * Function RecacheAllItems() * Rebuilds GAL display lists. * @param aForceNow decides if every item should be instantly recached. Otherwise items are - * going to be recached when they become visible. + * going to be recached when they become visible. */ void RecacheAllItems( bool aForceNow = false ); @@ -432,7 +431,16 @@ public: * Returns true if any of the VIEW layers needs to be refreshened. * @return True in case if any of layers is marked as dirty. */ - bool IsDirty() const; + bool IsDirty() const + { + for( int i = 0; i < TARGETS_NUMBER; ++i ) + { + if( IsTargetDirty( i ) ) + return true; + } + + return false; + } /** * Function IsTargetDirty() @@ -440,7 +448,12 @@ public: * redrawn. * @return True if the above condition is fulfilled. */ - bool IsTargetDirty( int aTarget ) const; + bool IsTargetDirty( int aTarget ) const + { + wxASSERT( aTarget < TARGETS_NUMBER ); + + return m_dirtyTargets[aTarget]; + } /** * Function MarkTargetDirty() @@ -470,6 +483,22 @@ public: m_dirtyTargets[i] = true; } + /** + * Function MarkForUpdate() + * Adds an item to a list of items that are going to be refreshed upon the next frame rendering. + * @param aItem is the item to be refreshed. + */ + void MarkForUpdate( VIEW_ITEM* aItem ) + { + m_needsUpdate.push_back( aItem ); + } + + /** + * Function UpdateItems() + * Iterates through the list of items that asked for updating and updates them. + */ + void UpdateItems(); + /** * Function SetPanBoundary() * Sets limits for panning area. @@ -493,26 +522,18 @@ 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 + static const int VIEW_MAX_LAYERS = 128; ///< maximum number of layers that may be shown private: struct VIEW_LAYER { - bool enabled; ///* is the layer to be rendered? - bool displayOnly; ///* is the layer display only? - VIEW_RTREE* items; ///* R-tree indexing all items on this layer. - int renderingOrder; ///* rendering order of this layer - int id; ///* layer ID - RENDER_TARGET target; ///* where the layer should be rendered - std::set requiredLayers; ///* layers that have to be enabled to show the layer + bool visible; ///< is the layer to be rendered? + bool displayOnly; ///< is the layer display only? + VIEW_RTREE* items; ///< R-tree indexing all items on this layer. + int renderingOrder; ///< rendering order of this layer + int id; ///< layer ID + RENDER_TARGET target; ///< where the layer should be rendered + std::set requiredLayers; ///< layers that have to be enabled to show the layer }; // Convenience typedefs @@ -532,7 +553,7 @@ private: ///* Redraws contents within rect aRect void redrawRect( const BOX2I& aRect ); - inline void clearTargetDirty( int aTarget ) + inline void markTargetClean( int aTarget ) { wxASSERT( aTarget < TARGETS_NUMBER ); @@ -549,7 +570,7 @@ private: * @param aImmediate dictates the way of drawing - it allows to force immediate drawing mode * for cached items. */ - void draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate = false ) const; + void draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate = false ); /** * Function draw() @@ -559,7 +580,7 @@ private: * @param aImmediate dictates the way of drawing - it allows to force immediate drawing mode * for cached items. */ - void draw( VIEW_ITEM* aItem, bool aImmediate = false ) const; + void draw( VIEW_ITEM* aItem, bool aImmediate = false ); /** * Function draw() @@ -569,7 +590,7 @@ private: * @param aImmediate dictates the way of drawing - it allows to force immediate drawing mode * for cached items. */ - void draw( VIEW_GROUP* aGroup, bool aImmediate = false ) const; + void draw( VIEW_GROUP* aGroup, bool aImmediate = false ); ///* Sorts m_orderedLayers when layer rendering order has changed void sortLayers(); @@ -578,6 +599,14 @@ private: ///* used by GAL) void clearGroupCache(); + /** + * 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 ); + /// Updates colors that are used for an item to be drawn void updateItemColor( VIEW_ITEM* aItem, int aLayer ); @@ -638,6 +667,9 @@ private: /// Zoom limits VECTOR2D m_scaleLimits; + + /// Items to be updated + std::vector m_needsUpdate; }; } // namespace KIGFX diff --git a/include/view/view_item.h b/include/view/view_item.h index c06538b224..a64b1b22db 100644 --- a/include/view/view_item.h +++ b/include/view/view_item.h @@ -157,12 +157,16 @@ public: /** * Enum VIEW_UPDATE_FLAGS. * Defines the how severely the shape/appearance of the item has been changed: + * - NONE: TODO * - APPEARANCE: shape or layer set of the item have not been affected, * only colors or visibility. + * - COLOR: * - GEOMETRY: shape or layer set of the item have changed, VIEW may need to reindex it. - * - ALL: all flags above */ + * - LAYERS: TODO + * - ALL: all the flags above */ enum VIEW_UPDATE_FLAGS { + NONE = 0x00, /// No updates are required APPEARANCE = 0x01, /// Visibility flag has changed COLOR = 0x02, /// Color has changed GEOMETRY = 0x04, /// Position or shape has changed @@ -170,7 +174,8 @@ public: ALL = 0xff }; - VIEW_ITEM() : m_view( NULL ), m_visible( true ), m_groups( NULL ), m_groupsSize( 0 ) {} + VIEW_ITEM() : m_view( NULL ), m_visible( true ), m_requiredUpdate( NONE ), + m_groups( NULL ), m_groupsSize( 0 ) {} /** * Destructor. For dynamic views, removes the item from the view. @@ -262,9 +267,15 @@ public: * For dynamic VIEWs, informs the associated VIEW that the graphical representation of * this item has changed. For static views calling has no effect. * - * @param aUpdateFlags: how much the object has changed + * @param aUpdateFlags: how much the object has changed. */ - virtual void ViewUpdate( int aUpdateFlags = ALL ); + virtual void ViewUpdate( int aUpdateFlags = ALL ) + { + if( m_view && m_requiredUpdate == NONE ) + m_view->MarkForUpdate( this ); + + m_requiredUpdate |= aUpdateFlags; + } /** * Function ViewRelease() @@ -298,8 +309,9 @@ protected: deleteGroups(); } - VIEW* m_view; ///* Current dynamic view the item is assigned to. - bool m_visible; ///* Are we visible in the current dynamic VIEW. + VIEW* m_view; ///< Current dynamic view the item is assigned to. + bool m_visible; ///< Are we visible in the current dynamic VIEW. + int m_requiredUpdate; ///< Flag required for updating ///* Helper for storing cached items group ids typedef std::pair GroupPair; @@ -374,6 +386,24 @@ protected: m_layers.set( aLayers[i] ); } } + + /** + * Function viewRequiredUpdate() + * Returns current update flag for an item. + */ + virtual int viewRequiredUpdate() const + { + return m_requiredUpdate; + } + + /** + * Function clearUpdateFlags() + * Marks an item as already updated, so it is not going to be redrawn. + */ + void clearUpdateFlags() + { + m_requiredUpdate = NONE; + } }; } // namespace KIGFX diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp index 60b59d8501..e12f3bcf3a 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -746,20 +746,20 @@ void MODULE::ViewUpdate( int aUpdateFlags ) if( !m_view ) return; + // Update the module itself + VIEW_ITEM::ViewUpdate( aUpdateFlags ); + // Update pads for( D_PAD* pad = m_Pads.GetFirst(); pad; pad = pad->Next() ) - m_view->InvalidateItem( pad, aUpdateFlags ); + pad->ViewUpdate( aUpdateFlags ); // Update module's drawing (mostly silkscreen) for( BOARD_ITEM* drawing = m_Drawings.GetFirst(); drawing; drawing = drawing->Next() ) - m_view->InvalidateItem( drawing, aUpdateFlags ); + drawing->ViewUpdate( 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 ); + m_Reference->ViewUpdate( aUpdateFlags ); + m_Value->ViewUpdate( aUpdateFlags ); } From 1c253bfba0dd3998c8d13c1d93def2092825251f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 24 Feb 2014 11:17:49 +0100 Subject: [PATCH 038/134] Some variables initialized to NULL. --- common/gal/opengl/opengl_compositor.cpp | 2 +- pcbnew/tools/drawing_tool.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/common/gal/opengl/opengl_compositor.cpp b/common/gal/opengl/opengl_compositor.cpp index af7b52ba5b..3a6721e5c9 100644 --- a/common/gal/opengl/opengl_compositor.cpp +++ b/common/gal/opengl/opengl_compositor.cpp @@ -17,7 +17,7 @@ * 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:O//www.gnu.org website for the version 2 license, + * 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 */ diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index b3ea0c6a3a..a1eddfca16 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -84,7 +84,7 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) double startAngle; // angle of the first arc line VECTOR2I cursorPos = m_controls->GetCursorPosition(); - DRAWSEGMENT* arc; + DRAWSEGMENT* arc = NULL; DRAWSEGMENT helperLine; helperLine.SetShape( S_SEGMENT ); helperLine.SetLayer( DRAW_N ); @@ -374,7 +374,7 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) { - DIMENSION* dimension; + DIMENSION* dimension = NULL; int width, maxThickness; // Add a VIEW_GROUP that serves as a preview for the new item @@ -922,9 +922,9 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) int DRAWING_TOOL::drawZone( bool aKeepout ) { - ZONE_CONTAINER* zone; + ZONE_CONTAINER* zone = NULL; DRAWSEGMENT line45; - DRAWSEGMENT* helperLine; // we will need more than one helper line + DRAWSEGMENT* helperLine = NULL; // we will need more than one helper line // Add a VIEW_GROUP that serves as a preview for the new item KIGFX::VIEW_GROUP preview( m_view ); From de637d2b8d014539e950eca5f8195921198ddd54 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 24 Feb 2014 12:56:47 +0100 Subject: [PATCH 039/134] Fixed a missing group clearing and update for restored VIEW_ITEMs.Fixed a missing group clearing and update for restored VIEW_ITEMs. --- common/view/view.cpp | 18 +++++++++--------- pcbnew/pcb_painter.cpp | 6 +----- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/common/view/view.cpp b/common/view/view.cpp index 0a18d42711..38051b094e 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -94,13 +94,16 @@ void VIEW::Add( VIEW_ITEM* aItem ) aItem->ViewGetLayers( layers, layers_count ); aItem->saveLayers( layers, layers_count ); - for( int i = 0; i < layers_count; i++ ) + for( int i = 0; i < layers_count; ++i ) { VIEW_LAYER& l = m_layers[layers[i]]; l.items->Insert( aItem ); MarkTargetDirty( l.target ); } + if( aItem->viewRequiredUpdate() != VIEW_ITEM::NONE ) + MarkForUpdate( aItem ); + if( m_dynamic ) aItem->viewAssign( this ); } @@ -122,8 +125,12 @@ void VIEW::Remove( VIEW_ITEM* aItem ) // Clear the GAL cache int prevGroup = aItem->getGroup( layers[i] ); + if( prevGroup >= 0 ) + { m_gal->DeleteGroup( prevGroup ); + aItem->setGroup( layers[i], -1 ); + } } } @@ -134,13 +141,9 @@ void VIEW::SetRequired( int aLayerId, int aRequiredId, bool aRequired ) wxASSERT( (unsigned) aRequiredId < m_layers.size() ); if( aRequired ) - { m_layers[aLayerId].requiredLayers.insert( aRequiredId ); - } else - { m_layers[aLayerId].requiredLayers.erase( aRequired ); - } } @@ -782,10 +785,7 @@ struct VIEW::clearLayerCache bool operator()( VIEW_ITEM* aItem ) { - if( aItem->storesGroups() ) - { - aItem->deleteGroups(); - } + aItem->deleteGroups(); return true; } diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 93414fc3e0..72fd6dd0c3 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -275,10 +275,6 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer ) if( length < 10 * width ) return; - NETINFO_ITEM* net = ( (BOARD*) aTrack->GetParent() )->FindNet( netNumber ); - if( !net ) - return; - const wxString& netName = aTrack->GetShortNetname(); VECTOR2D textPosition = start + line / 2.0; // center of the track double textOrientation = -atan( line.y / line.x ); @@ -303,7 +299,7 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer ) m_gal->StrokeText( netName, textPosition, textOrientation ); } } - else if( IsCopperLayer( aLayer )) + else if( IsCopperLayer( aLayer ) ) { // Draw a regular track const COLOR4D& color = m_pcbSettings->GetColor( aTrack, aLayer ); From d583280bb07b6637649418f0a848c07c25deeb6d Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 24 Feb 2014 14:31:55 +0100 Subject: [PATCH 040/134] Minor code cleaning and optimizations. --- common/view/view.cpp | 24 ++++++++++-------------- pcbnew/pcbframe.cpp | 12 +++--------- 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/common/view/view.cpp b/common/view/view.cpp index 38051b094e..428dd7e594 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -127,11 +127,10 @@ void VIEW::Remove( VIEW_ITEM* aItem ) int prevGroup = aItem->getGroup( layers[i] ); if( prevGroup >= 0 ) - { m_gal->DeleteGroup( prevGroup ); - aItem->setGroup( layers[i], -1 ); - } } + + aItem->deleteGroups(); } @@ -199,13 +198,9 @@ VECTOR2D VIEW::ToWorld( const VECTOR2D& aCoord, bool aAbsolute ) const const MATRIX3x3D& matrix = m_gal->GetScreenWorldMatrix(); if( aAbsolute ) - { return VECTOR2D( matrix * aCoord ); - } else - { return VECTOR2D( matrix.GetScale().x * aCoord.x, matrix.GetScale().y * aCoord.y ); - } } @@ -214,13 +209,9 @@ VECTOR2D VIEW::ToScreen( const VECTOR2D& aCoord, bool aAbsolute ) const const MATRIX3x3D& matrix = m_gal->GetWorldScreenMatrix(); if( aAbsolute ) - { return VECTOR2D( matrix * aCoord ); - } else - { return VECTOR2D( matrix.GetScale().x * aCoord.x, matrix.GetScale().y * aCoord.y ); - } } @@ -699,6 +690,7 @@ struct VIEW::recacheItem } else { + aItem->ViewUpdate( VIEW_ITEM::ALL ); aItem->setGroup( layer, -1 ); } @@ -730,6 +722,7 @@ void VIEW::Clear() } m_gal->ClearCache(); + m_needsUpdate.clear(); } @@ -889,7 +882,10 @@ void VIEW::updateItemGeometry( VIEW_ITEM* aItem, int aLayer ) group = m_gal->BeginGroup(); aItem->setGroup( aLayer, group ); - m_painter->Draw( static_cast( aItem ), aLayer ); + + if( !m_painter->Draw( static_cast( aItem ), aLayer ) ); + aItem->ViewDraw( aLayer, m_gal ); // Alternative drawing method + m_gal->EndGroup(); } @@ -900,7 +896,7 @@ void VIEW::updateBbox( VIEW_ITEM* aItem ) aItem->ViewGetLayers( layers, layers_count ); - for( int i = 0; i < layers_count; i++ ) + for( int i = 0; i < layers_count; ++i ) { VIEW_LAYER& l = m_layers[layers[i]]; l.items->Remove( aItem ); @@ -917,7 +913,7 @@ void VIEW::updateLayers( VIEW_ITEM* aItem ) // Remove the item from previous layer set aItem->getLayers( layers, layers_count ); - for( int i = 0; i < layers_count; i++ ) + for( int i = 0; i < layers_count; ++i ) { VIEW_LAYER& l = m_layers[layers[i]]; l.items->Remove( aItem ); diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index f87ae2e959..4ec121c99e 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -578,13 +578,7 @@ void PCB_EDIT_FRAME::ViewReloadBoard( const BOARD* aBoard ) const std::string( aBoard->GetFileName().mb_str() ), std::string( GetScreenDesc().mb_str() ), &GetPageSettings(), &GetTitleBlock() ); - BASE_SCREEN* screen = GetScreen(); - if( screen != NULL ) - { - worksheet->SetSheetNumber( GetScreen()->m_ScreenNumber ); - worksheet->SetSheetCount( GetScreen()->m_NumberOfScreens ); - } - + worksheet->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); view->Add( worksheet ); // Add an entry for the ratsnest @@ -715,10 +709,10 @@ void PCB_EDIT_FRAME::UseGalCanvas( bool aEnable ) { EDA_DRAW_FRAME::UseGalCanvas( aEnable ); - ViewReloadBoard( m_Pcb ); - if( aEnable ) { + ViewReloadBoard( m_Pcb ); + // Update potential changes in the ratsnest m_Pcb->GetRatsnest()->Recalculate(); From f7d00a393bb848ef1ab67b67ad6e18d160cb4002 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 25 Feb 2014 11:47:27 +0100 Subject: [PATCH 041/134] 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 | 5 +-- 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, 309 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 4f991f8853..093f511570 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 89c52bb9f9..dcd1a2a23a 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 6846dda597..be15d90c64 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -331,7 +331,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(); } @@ -471,11 +471,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: @@ -489,7 +489,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 ); @@ -526,7 +526,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 ); @@ -607,7 +607,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(); @@ -636,7 +636,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; @@ -1153,7 +1153,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; @@ -1245,7 +1245,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 36342dcd47..90bd3d8772 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 97777200ea..c4594c9264 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 e73e8d829a..89cb8717a5 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( 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 72fd6dd0c3..1a492ad47d 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 @@ -261,12 +261,11 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer ) VECTOR2D start( aTrack->GetStart() ); VECTOR2D end( aTrack->GetEnd() ); int width = aTrack->GetWidth(); - int netNumber = aTrack->GetNet(); if( m_pcbSettings->m_netNamesOnTracks && IsNetnameLayer( aLayer ) ) { // If there is a net name - display it on the track - if( netNumber > 0 ) + if( aTrack->GetNetCode() > NETINFO_LIST::UNCONNECTED ) { VECTOR2D line = ( end - start ); double length = line.EuclideanNorm(); diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index 33bfd5e587..f82814311e 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 80d082a9b3..b3061cc19b 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 8ab4fb2fc9..f483d1c428 100644 --- a/pcbnew/router/pns_router.cpp +++ b/pcbnew/router/pns_router.cpp @@ -130,7 +130,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(); @@ -181,7 +181,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() ) ); @@ -196,7 +196,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; @@ -612,7 +612,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; } @@ -623,7 +623,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 c5a3c1082a5d8518cda8a1d02331414f60aa90be Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 25 Feb 2014 14:28:09 +0100 Subject: [PATCH 042/134] Removed a few RecacheAllItems() calls, some of them changed to specific type recaching (using TYPE_COLLECTOR & VIEW_ITEM::ViewUpdate() ). Removed OPENGL_GAL::SetStrokeColor(). --- common/drawpanel_gal.cpp | 3 -- common/gal/cairo/cairo_gal.cpp | 5 ++- common/gal/opengl/opengl_gal.cpp | 42 +++++++++++++++-------- include/gal/opengl/opengl_gal.h | 9 +---- pcbnew/basepcbframe.cpp | 9 ++++- pcbnew/dialogs/dialog_display_options.cpp | 5 +-- pcbnew/dialogs/dialog_general_options.cpp | 24 ++++++++----- pcbnew/pcbframe.cpp | 10 +----- 8 files changed, 58 insertions(+), 49 deletions(-) diff --git a/common/drawpanel_gal.cpp b/common/drawpanel_gal.cpp index 6a7e4f9d6a..947e854fa6 100644 --- a/common/drawpanel_gal.cpp +++ b/common/drawpanel_gal.cpp @@ -226,10 +226,7 @@ void EDA_DRAW_PANEL_GAL::SwitchBackend( GalType aGalType ) m_painter->SetGAL( m_gal ); if( m_view ) - { m_view->SetGAL( m_gal ); - m_view->RecacheAllItems( true ); - } m_currentGal = aGalType; m_pendingRefresh = false; diff --git a/common/gal/cairo/cairo_gal.cpp b/common/gal/cairo/cairo_gal.cpp index 5d1d4f6cd7..790fb06049 100644 --- a/common/gal/cairo/cairo_gal.cpp +++ b/common/gal/cairo/cairo_gal.cpp @@ -77,6 +77,8 @@ CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, // Allocate memory for pixel storage allocateBitmaps(); + + initSurface(); } @@ -954,7 +956,8 @@ void CAIRO_GAL::deleteBitmaps() void CAIRO_GAL::initSurface() { - wxASSERT( !isInitialized ); + if( isInitialized ) + return; // Create the Cairo surface surface = cairo_image_surface_create_for_data( (unsigned char*) bitmapBuffer, GAL_FORMAT, diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index 84b8225ac3..5eb63c31c4 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -101,6 +101,8 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, } gluTessProperty( tesselator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE ); + + currentManager = &nonCachedManager; } @@ -248,6 +250,8 @@ void OPENGL_GAL::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoin const VECTOR2D startEndVector = aEndPoint - aStartPoint; double lineAngle = startEndVector.Angle(); + currentManager->Color( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a ); + drawLineQuad( aStartPoint, aEndPoint ); // Line caps @@ -468,6 +472,8 @@ void OPENGL_GAL::DrawPolyline( std::deque& aPointList ) if( aPointList.empty() ) return; + currentManager->Color( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a ); + std::deque::const_iterator it = aPointList.begin(); // Start from the second point @@ -590,15 +596,6 @@ void OPENGL_GAL::ClearScreen() } -void OPENGL_GAL::SetStrokeColor( const COLOR4D& aColor ) -{ - strokeColor = aColor; - - // This is the default drawing color - currentManager->Color( aColor.r, aColor.g, aColor.b, aColor.a ); -} - - void OPENGL_GAL::Transform( const MATRIX3x3D& aTransformation ) { GLdouble matrixData[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }; @@ -795,8 +792,23 @@ void OPENGL_GAL::drawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEnd } -inline void OPENGL_GAL::drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) +void OPENGL_GAL::drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) { + /* Helper drawing: ____--- v3 ^ + * ____---- ... \ \ + * ____---- ... \ end \ + * v1 ____---- ... ____---- \ width + * ---- ...___---- \ \ + * \ ___...-- \ v + * \ ____----... ____---- v2 + * ---- ... ____---- + * start \ ... ____---- + * \... ____---- + * ---- + * v0 + * dots mark triangles' hypotenuses + */ + VECTOR2D startEndVector = aEndPoint - aStartPoint; double lineLength = startEndVector.EuclideanNorm(); double scale = 0.5 * lineWidth / lineLength; @@ -854,8 +866,8 @@ void OPENGL_GAL::drawFilledSemiCircle( const VECTOR2D& aCenterPoint, double aRad /* Draw a triangle that contains the semicircle, then shade it to leave only * the semicircle. Parameters given to setShader are indices of the triangle's vertices - * (if you want to understand more, check the vertex shader source [shader.vert]). - * Shader uses this coordinates to determine if fragments are inside the semicircle or not. + * (if you want to understand more, check the vertex shader source [shader.vert]). + * Shader uses these coordinates to determine if fragments are inside the semicircle or not. * v2 * /\ * /__\ @@ -885,9 +897,9 @@ void OPENGL_GAL::drawStrokedSemiCircle( const VECTOR2D& aCenterPoint, double aRa /* Draw a triangle that contains the semicircle, then shade it to leave only * the semicircle. Parameters given to setShader are indices of the triangle's vertices - * (if you want to understand more, check the vertex shader source [shader.vert]), the - * radius and the line width. Shader uses this coordinates to determine if fragments are - * inside the semicircle or not. + * (if you want to understand more, check the vertex shader source [shader.vert]), the + * radius and the line width. Shader uses these coordinates to determine if fragments are + * inside the semicircle or not. * v2 * /\ * /__\ diff --git a/include/gal/opengl/opengl_gal.h b/include/gal/opengl/opengl_gal.h index 7a1879d085..d5c97aada9 100644 --- a/include/gal/opengl/opengl_gal.h +++ b/include/gal/opengl/opengl_gal.h @@ -145,13 +145,6 @@ public: /// @copydoc GAL::ClearScreen() virtual void ClearScreen(); - // ----------------- - // Attribute setting - // ----------------- - - /// @copydoc GAL::SetStrokeColor() - virtual void SetStrokeColor( const COLOR4D& aColor ); - // -------------- // Transformation // -------------- @@ -311,7 +304,7 @@ private: * @param aStartPoint is the start point of the line. * @param aEndPoint is the end point of the line. */ - inline void drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ); + void drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ); /** * @brief Draw a semicircle. Depending on settings (isStrokeEnabled & isFilledEnabled) it runs diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index 858aa40c0e..8b670883f9 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -443,7 +443,14 @@ void PCB_BASE_FRAME::OnTogglePadDrawMode( wxCommandEvent& aEvent ) KIGFX::PCB_RENDER_SETTINGS* settings = static_cast ( painter->GetSettings() ); settings->LoadDisplayOptions( DisplayOpt ); - GetGalCanvas()->GetView()->RecacheAllItems( true ); + + // Update pads + BOARD* board = GetBoard(); + for( MODULE* module = board->m_Modules; module; module = module->Next() ) + { + for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() ) + pad->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } m_canvas->Refresh(); } diff --git a/pcbnew/dialogs/dialog_display_options.cpp b/pcbnew/dialogs/dialog_display_options.cpp index 0aa91d1302..1e140d94d9 100644 --- a/pcbnew/dialogs/dialog_display_options.cpp +++ b/pcbnew/dialogs/dialog_display_options.cpp @@ -177,10 +177,7 @@ void DIALOG_DISPLAY_OPTIONS::OnOkClick(wxCommandEvent& event) settings->LoadDisplayOptions( DisplayOpt ); view->RecacheAllItems( true ); - if( m_Parent->IsGalCanvasActive() ) - m_Parent->GetGalCanvas()->Refresh(); - else - m_Parent->GetCanvas()->Refresh(); + m_Parent->GetCanvas()->Refresh(); EndModal( 1 ); } diff --git a/pcbnew/dialogs/dialog_general_options.cpp b/pcbnew/dialogs/dialog_general_options.cpp index c01e433f3e..c4ccd1ddbf 100644 --- a/pcbnew/dialogs/dialog_general_options.cpp +++ b/pcbnew/dialogs/dialog_general_options.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -157,7 +158,7 @@ void PCB_EDIT_FRAME::OnSelectOptionToolbar( wxCommandEvent& event ) static_cast ( GetGalCanvas()->GetView()->GetPainter() ); KIGFX::PCB_RENDER_SETTINGS* settings = static_cast ( painter->GetSettings() ); - bool recache = false; + KICAD_T updateType = EOT; switch( id ) { @@ -192,31 +193,31 @@ void PCB_EDIT_FRAME::OnSelectOptionToolbar( wxCommandEvent& event ) case ID_TB_OPTIONS_SHOW_ZONES: DisplayOpt.DisplayZonesMode = 0; - recache = true; + updateType = PCB_ZONE_T; m_canvas->Refresh(); break; case ID_TB_OPTIONS_SHOW_ZONES_DISABLE: DisplayOpt.DisplayZonesMode = 1; - recache = true; + updateType = PCB_ZONE_T; m_canvas->Refresh(); break; case ID_TB_OPTIONS_SHOW_ZONES_OUTLINES_ONLY: DisplayOpt.DisplayZonesMode = 2; - recache = true; + updateType = PCB_ZONE_T; m_canvas->Refresh(); break; case ID_TB_OPTIONS_SHOW_VIAS_SKETCH: m_DisplayViaFill = DisplayOpt.DisplayViaFill = !state; - recache = true; + updateType = PCB_VIA_T; m_canvas->Refresh(); break; case ID_TB_OPTIONS_SHOW_TRACKS_SKETCH: m_DisplayPcbTrackFill = DisplayOpt.DisplayPcbTrackFill = !state; - recache = true; + updateType = PCB_TRACE_T; m_canvas->Refresh(); break; @@ -256,11 +257,18 @@ void PCB_EDIT_FRAME::OnSelectOptionToolbar( wxCommandEvent& event ) break; } - if( recache ) + if( updateType != EOT ) { // Apply new display options to the GAL canvas settings->LoadDisplayOptions( DisplayOpt ); - GetGalCanvas()->GetView()->RecacheAllItems( true ); + + // Find items that require update + KICAD_T scanList[] = { updateType, EOT }; + TYPE_COLLECTOR collector; + collector.Collect( GetBoard(), scanList ); + + for( int i = 0; i < collector.GetCount(); ++i ) + collector[i]->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } if( IsGalCanvasActive() ) diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 4ec121c99e..9f1df9b5f5 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -544,21 +544,15 @@ void PCB_EDIT_FRAME::ViewReloadBoard( const BOARD* aBoard ) const // 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() ) @@ -569,9 +563,7 @@ void PCB_EDIT_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( @@ -587,7 +579,7 @@ void PCB_EDIT_FRAME::ViewReloadBoard( const BOARD* aBoard ) const view->Add( new KIGFX::RATSNEST_VIEWITEM( ratsnest ) ); view->SetPanBoundary( worksheet->ViewBBox() ); - view->RecacheAllItems( true ); + view->RecacheAllItems( false ); if( IsGalCanvasActive() ) GetGalCanvas()->Refresh(); From a42a83a3947deddca693ba6e31ab6614d8056c1c Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 25 Feb 2014 18:08:33 +0100 Subject: [PATCH 043/134] Minor changes to BRIGHT_BOX class. --- pcbnew/tools/bright_box.cpp | 27 +++++++-------------------- pcbnew/tools/bright_box.h | 19 +++++++++++++------ 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/pcbnew/tools/bright_box.cpp b/pcbnew/tools/bright_box.cpp index b0fd4aec81..689b6169b5 100644 --- a/pcbnew/tools/bright_box.cpp +++ b/pcbnew/tools/bright_box.cpp @@ -30,44 +30,31 @@ using namespace KIGFX; BRIGHT_BOX::BRIGHT_BOX( BOARD_ITEM* aItem ) : EDA_ITEM( NOT_USED ), // this item is never added to a BOARD so it needs no type - item( aItem ) + m_item( aItem ) { } -const BOX2I BRIGHT_BOX::ViewBBox() const -{ - return item->ViewBBox(); -} - - -void BRIGHT_BOX::ViewGetLayers( int aLayers[], int& aCount ) const -{ - aLayers[0] = BrightBoxLayer; - aCount = 1; -} - - void BRIGHT_BOX::ViewDraw( int aLayer, GAL* aGal ) const { aGal->SetIsStroke( true ); aGal->SetIsFill( false ); - aGal->SetLineWidth( LineWidth ); - aGal->SetStrokeColor( BrightColor ); + aGal->SetLineWidth( LINE_WIDTH ); + aGal->SetStrokeColor( BOX_COLOR ); - if( item->Type() == PCB_TRACE_T ) + if( m_item->Type() == PCB_TRACE_T ) { - const TRACK* track = static_cast( item ); + const TRACK* track = static_cast( m_item ); aGal->DrawSegment( track->GetStart(), track->GetEnd(), track->GetWidth() ); } else { - BOX2I box = item->ViewBBox(); + BOX2I box = m_item->ViewBBox(); aGal->DrawRectangle( box.GetOrigin(), box.GetOrigin() + box.GetSize() ); } } -const COLOR4D BRIGHT_BOX::BrightColor = KIGFX::COLOR4D( 0.0, 1.0, 0.0, 1.0 ); +const COLOR4D BRIGHT_BOX::BOX_COLOR = KIGFX::COLOR4D( 0.0, 1.0, 0.0, 1.0 ); diff --git a/pcbnew/tools/bright_box.h b/pcbnew/tools/bright_box.h index 14966db9ac..8a6a583335 100644 --- a/pcbnew/tools/bright_box.h +++ b/pcbnew/tools/bright_box.h @@ -42,21 +42,28 @@ public: BRIGHT_BOX( BOARD_ITEM* aItem ); ~BRIGHT_BOX() {}; - virtual const BOX2I ViewBBox() const; + virtual const BOX2I ViewBBox() const + { + return m_item->ViewBBox(); + } void ViewDraw( int aLayer, KIGFX::GAL* aGal ) const; - void ViewGetLayers( int aLayers[], int& aCount ) const; + + void ViewGetLayers( int aLayers[], int& aCount ) const + { + aLayers[0] = ITEM_GAL_LAYER( GP_OVERLAY ); + aCount = 1; + } void Show( int x, std::ostream& st ) const { } private: - static const int BrightBoxLayer = ITEM_GAL_LAYER( GP_OVERLAY ); - static const KIGFX::COLOR4D BrightColor; - static const double LineWidth = 100000.0; + static const KIGFX::COLOR4D BOX_COLOR; + static const double LINE_WIDTH = 100000.0; - BOARD_ITEM* item; + BOARD_ITEM* m_item; }; #endif From e6598e9d41434c2389da642eea5c0993ab00dd09 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 27 Feb 2014 16:13:27 +0100 Subject: [PATCH 044/134] Added VIEW::ToWorld( double ). TOOL_EVENT message is supposed to contain string as parameter. Added missing header for class_drawsegment.h (KiROUND). Renamed SELECTION_TOOL::containsSelected() to SELECTION_TOOL::selectionContains(). --- common/view/view.cpp | 8 ++++++++ include/tool/tool_event.h | 4 ++-- include/view/view.h | 8 ++++++++ pcbnew/class_drawsegment.h | 1 + pcbnew/tools/edit_tool.h | 2 +- pcbnew/tools/selection_tool.cpp | 4 ++-- pcbnew/tools/selection_tool.h | 2 +- 7 files changed, 23 insertions(+), 6 deletions(-) diff --git a/common/view/view.cpp b/common/view/view.cpp index 428dd7e594..1baa2599fc 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -204,6 +204,14 @@ VECTOR2D VIEW::ToWorld( const VECTOR2D& aCoord, bool aAbsolute ) const } +double VIEW::ToWorld( double aSize ) const +{ + const MATRIX3x3D& matrix = m_gal->GetScreenWorldMatrix(); + + return matrix.GetScale().x * aSize; +} + + VECTOR2D VIEW::ToScreen( const VECTOR2D& aCoord, bool aAbsolute ) const { const MATRIX3x3D& matrix = m_gal->GetWorldScreenMatrix(); diff --git a/include/tool/tool_event.h b/include/tool/tool_event.h index 3f7971ed77..4571b5a9f8 100644 --- a/include/tool/tool_event.h +++ b/include/tool/tool_event.h @@ -189,7 +189,7 @@ public: m_scope( aScope ), m_mouseButtons( 0 ) { - if( aCategory == TC_COMMAND ) + if( aCategory == TC_COMMAND || aCategory == TC_MESSAGE ) m_commandStr = aExtraParam; } @@ -317,7 +317,7 @@ public: if( !( m_actions & aEvent.m_actions ) ) return false; - if( m_category == TC_COMMAND ) + if( m_category == TC_COMMAND || m_category == TC_MESSAGE ) { if( m_commandStr && aEvent.m_commandStr ) return *m_commandStr == *aEvent.m_commandStr; diff --git a/include/view/view.h b/include/view/view.h index 4a7965bb94..dbb82954a0 100644 --- a/include/view/view.h +++ b/include/view/view.h @@ -232,6 +232,14 @@ public: */ VECTOR2D ToWorld( const VECTOR2D& aCoord, bool aAbsolute = true ) const; + /** + * Function ToWorld() + * Converts a screen space one dimensional size to a one dimensional size in world + * space coordinates. + * @param aCoord: the size to be converted + */ + double ToWorld( double aSize ) const; + /** * Function ToScreen() * Converts a world space point/vector to a point/vector in screen space coordinates. diff --git a/pcbnew/class_drawsegment.h b/pcbnew/class_drawsegment.h index 635a3235d7..56862aa7db 100644 --- a/pcbnew/class_drawsegment.h +++ b/pcbnew/class_drawsegment.h @@ -34,6 +34,7 @@ #include #include #include +#include class LINE_READER; diff --git a/pcbnew/tools/edit_tool.h b/pcbnew/tools/edit_tool.h index 49fbe48450..b5f6f1fc0d 100644 --- a/pcbnew/tools/edit_tool.h +++ b/pcbnew/tools/edit_tool.h @@ -101,7 +101,7 @@ private: ///> Removes and frees a single BOARD_ITEM. void remove( BOARD_ITEM* aItem ); - ///> Sets up handlers for various events + ///> Sets up handlers for various events. void setTransitions(); ///> The required update flag for modified items diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 366c81659a..0e1a241868 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -133,7 +133,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) else { // Check if dragging has started within any of selected items bounding box - if( containsSelected( evt->Position() ) ) + if( selectionContains( evt->Position() ) ) { // Yes -> run the move tool and wait till it finishes m_toolMgr->InvokeTool( "pcbnew.InteractiveEdit" ); @@ -566,7 +566,7 @@ void SELECTION_TOOL::deselectVisually( BOARD_ITEM* aItem ) const } -bool SELECTION_TOOL::containsSelected( const VECTOR2I& aPoint ) const +bool SELECTION_TOOL::selectionContains( const VECTOR2I& aPoint ) const { const unsigned GRIP_MARGIN = 20; VECTOR2D margin = getView()->ToWorld( VECTOR2D( GRIP_MARGIN, GRIP_MARGIN ), false ); diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h index 4c5e4b2d9a..ab320b1d5e 100644 --- a/pcbnew/tools/selection_tool.h +++ b/pcbnew/tools/selection_tool.h @@ -207,7 +207,7 @@ private: * * @return True if the given point is contained in any of selected items' bouding box. */ - bool containsSelected( const VECTOR2I& aPoint ) const; + bool selectionContains( const VECTOR2I& aPoint ) const; /// Visual representation of selection box SELECTION_AREA* m_selArea; From 235da6084b2ad36fd122f6cb8e8976a518088609 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 27 Feb 2014 17:27:58 +0100 Subject: [PATCH 045/134] SELECTION_TOOL emits event notifying about selecting/deselecting/clearing selection. --- pcbnew/tools/selection_tool.cpp | 41 +++++++++++++++++++++++++++++---- pcbnew/tools/selection_tool.h | 5 ++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 0e1a241868..24d00f2439 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -50,7 +50,11 @@ using boost::optional; SELECTION_TOOL::SELECTION_TOOL() : - TOOL_INTERACTIVE( "pcbnew.InteractiveSelection" ), m_additive( false ), m_multiple( false ) + TOOL_INTERACTIVE( "pcbnew.InteractiveSelection" ), + SelectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.selected" ), + DeselectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.deselected" ), + ClearedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.cleared" ), + m_additive( false ), m_multiple( false ) { m_selArea = new SELECTION_AREA; m_selection.group = new KIGFX::VIEW_GROUP; @@ -94,6 +98,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) if( evt->IsAction( &COMMON_ACTIONS::selectionSingle ) ) { + // GetMousePosition() is used to be independent of snapping settings selectSingle( getView()->ToWorld( getViewControls()->GetMousePosition() ) ); } @@ -167,6 +172,10 @@ void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem ) if( aItem->IsSelected() ) { deselect( aItem ); + + // Inform other potentially interested tools + TOOL_EVENT deselectEvent( DeselectedEvent ); + m_toolMgr->ProcessEvent( deselectEvent ); } else { @@ -175,7 +184,13 @@ void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem ) // Prevent selection of invisible or inactive items if( selectable( aItem ) ) + { select( aItem ); + + // Inform other potentially interested tools + TOOL_EVENT selectEvent( SelectedEvent ); + m_toolMgr->ProcessEvent( selectEvent ); + } } } @@ -203,7 +218,7 @@ void SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere ) default: // Remove unselectable items - for( int i = collector.GetCount() - 1; i >= 0 ; --i ) + for( int i = collector.GetCount() - 1; i >= 0; --i ) { if( !selectable( collector[i] ) ) collector.Remove( i ); @@ -273,13 +288,21 @@ 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( !item->IsSelected() && selectable( item ) && selectionBox.Contains( item->ViewBBox() ) ) + if( !item->IsSelected() && selectable( item ) + && selectionBox.Contains( item->ViewBBox() ) ) select( item ); } // Do not display information about selected item,as there is more than one getEditFrame()->SetCurItem( NULL ); + if( !m_selection.Empty() ) + { + // Inform other potentially interested tools + TOOL_EVENT selectEvent( SelectedEvent ); + m_toolMgr->ProcessEvent( selectEvent ); + } + break; // Stop waiting for events } } @@ -313,6 +336,10 @@ void SELECTION_TOOL::clearSelection() // Do not show the context menu when there is nothing selected SetContextMenu( &m_menu, CMENU_OFF ); + + // Inform other potentially interested tools + TOOL_EVENT clearEvent( ClearedEvent ); + m_toolMgr->ProcessEvent( clearEvent ); } @@ -351,7 +378,9 @@ BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector ) current->SetBrightened(); } else + { current = NULL; + } } else if( evt->Action() == TA_CONTEXT_MENU_CHOICE ) { @@ -412,7 +441,7 @@ BOARD_ITEM* SELECTION_TOOL::pickSmallestComponent( GENERAL_COLLECTOR* aCollector } } - return (*aCollector)[minNdx]; + return ( *aCollector )[minNdx]; } @@ -543,6 +572,10 @@ void SELECTION_TOOL::deselect( BOARD_ITEM* aItem ) SetContextMenu( &m_menu, CMENU_OFF ); getEditFrame()->SetCurItem( NULL ); } + + // Inform other potentially interested tools + TOOL_EVENT dupa( DeselectedEvent ); + m_toolMgr->ProcessEvent( dupa ); } diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h index ab320b1d5e..9ef61fbd4b 100644 --- a/pcbnew/tools/selection_tool.h +++ b/pcbnew/tools/selection_tool.h @@ -114,6 +114,11 @@ public: */ void AddMenuItem( const TOOL_ACTION& aAction ); + // TODO comments + const TOOL_EVENT SelectedEvent; + const TOOL_EVENT DeselectedEvent; + const TOOL_EVENT ClearedEvent; + private: /** * Function selectSingle() From 94cfed4b9e3e359868360f332a56da2bc6cd9686 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 27 Feb 2014 17:29:08 +0100 Subject: [PATCH 046/134] Initial version of POINT_EDITOR. --- pcbnew/CMakeLists.txt | 4 +- pcbnew/tools/edit_points.cpp | 74 +++++++++ pcbnew/tools/edit_points.h | 247 +++++++++++++++++++++++++++ pcbnew/tools/pcb_tools.cpp | 4 +- pcbnew/tools/point_editor.cpp | 304 ++++++++++++++++++++++++++++++++++ pcbnew/tools/point_editor.h | 74 +++++++++ 6 files changed, 705 insertions(+), 2 deletions(-) create mode 100644 pcbnew/tools/edit_points.cpp create mode 100644 pcbnew/tools/edit_points.h create mode 100644 pcbnew/tools/point_editor.cpp create mode 100644 pcbnew/tools/point_editor.h diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index e697375ec2..43ce8ba3f3 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -251,7 +251,9 @@ set( PCBNEW_CLASS_SRCS tools/selection_tool.cpp tools/selection_area.cpp tools/bright_box.cpp - tools/drawing_tool.cpp + tools/edit_points.cpp + tools/point_editor.cpp + tools/drawing_tool.cpp tools/edit_tool.cpp tools/pcb_tools.cpp tools/common_actions.cpp diff --git a/pcbnew/tools/edit_points.cpp b/pcbnew/tools/edit_points.cpp new file mode 100644 index 0000000000..5efe90bae0 --- /dev/null +++ b/pcbnew/tools/edit_points.cpp @@ -0,0 +1,74 @@ +/* + * This program source code file is part of KICAD, a free EDA CAD application. + * + * Copyright (C) 2014 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 "edit_points.h" +#include + +#include + +EDIT_POINTS::EDIT_POINTS( EDA_ITEM* aParent ) : + EDA_ITEM( NOT_USED ), m_parent( aParent ) +{ +} + + +EDIT_POINTS::~EDIT_POINTS() +{ +} + + +EDIT_POINT* EDIT_POINTS::FindPoint( const VECTOR2I& aLocation ) +{ + float size = m_view->ToWorld( EDIT_POINT::POINT_SIZE ); + + std::deque::iterator it, itEnd; + for( it = m_points.begin(), itEnd = m_points.end(); it != itEnd; ++it ) + { + EDIT_POINT& point = *it; + + if( point.WithinPoint( aLocation, size ) ) + return &point; + } + + return NULL; +} + + +void EDIT_POINTS::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const +{ + aGal->SetFillColor( KIGFX::COLOR4D( 1.0, 1.0, 1.0, 1.0 ) ); // TODO dynamic color depending on parent's color + aGal->SetIsFill( true ); + aGal->SetIsStroke( false ); + aGal->PushDepth(); + aGal->SetLayerDepth( -512.0 ); // TODO no hardcoded depths? + + float size = m_view->ToWorld( EDIT_POINT::POINT_SIZE ); + + BOOST_FOREACH( const EDIT_POINT& point, m_points ) + aGal->DrawRectangle( point.GetPosition() - size / 2, point.GetPosition() + size / 2 ); + + aGal->PopDepth(); +} diff --git a/pcbnew/tools/edit_points.h b/pcbnew/tools/edit_points.h new file mode 100644 index 0000000000..7ddfa2fcf9 --- /dev/null +++ b/pcbnew/tools/edit_points.h @@ -0,0 +1,247 @@ +/* + * This program source code file is part of KICAD, a free EDA CAD application. + * + * Copyright (C) 2014 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_POINTS_H_ +#define EDIT_POINTS_H_ + +#include +#include +#include + +#include +#include + +class EDIT_POINT; + +class EDIT_POINT_CONSTRAINT +{ +public: + EDIT_POINT_CONSTRAINT( EDIT_POINT* aConstrained ) : m_constrained( aConstrained ) {}; + virtual ~EDIT_POINT_CONSTRAINT() {}; + + virtual void Apply() = 0; + +protected: + EDIT_POINT* m_constrained; +}; + + +// TODO docs +class EDIT_POINT +{ +public: + EDIT_POINT( const VECTOR2I& aPoint ) : + m_point( aPoint ), m_constraint( NULL ) {}; + ~EDIT_POINT() + { + delete m_constraint; + } + + const VECTOR2I& GetPosition() const + { + return m_point; + } + + void SetPosition( const VECTOR2I& aPosition ) + { + m_point = aPosition; + } + + bool WithinPoint( const VECTOR2I& aPoint, unsigned int aSize ) const + { + VECTOR2I topLeft = GetPosition() - aSize; + VECTOR2I bottomRight = GetPosition() + aSize; + + return ( aPoint.x > topLeft.x && aPoint.y > topLeft.y && + aPoint.x < bottomRight.x && aPoint.y < bottomRight.y ); + } + + void SetConstraint( EDIT_POINT_CONSTRAINT* aConstraint ) + { + m_constraint = aConstraint; + } + + void ClearConstraint( EDIT_POINT_CONSTRAINT* aConstraint ) + { + delete m_constraint; + m_constraint = NULL; + } + + EDIT_POINT_CONSTRAINT* GetConstraint() const + { + return m_constraint; + } + + void ApplyConstraint() + { + if( m_constraint ) + m_constraint->Apply(); + } + + ///> Single point size in pixels + static const int POINT_SIZE = 10; + +private: + VECTOR2I m_point; + EDIT_POINT_CONSTRAINT* m_constraint; +}; + + +class EDIT_POINTS : public EDA_ITEM +{ +public: + EDIT_POINTS( EDA_ITEM* aParent ); + ~EDIT_POINTS(); + + /** + * Function FindPoint + * Returns a point that is at given coordinates or NULL if there is no such point. + * @param aLocation is the location for searched point. + */ + EDIT_POINT* FindPoint( const VECTOR2I& aLocation ); + + void Add( const EDIT_POINT& aPoint ) + { + m_points.push_back( aPoint ); + } + + void Add( const VECTOR2I& aPoint ) + { + m_points.push_back( EDIT_POINT( aPoint ) ); + } + + EDIT_POINT& operator[]( unsigned int aIndex ) + { + return m_points[aIndex]; + } + + const EDIT_POINT& operator[]( unsigned int aIndex ) const + { + return m_points[aIndex]; + } + + unsigned int Size() const + { + return m_points.size(); + } + + virtual const BOX2I ViewBBox() const + { + return m_parent->ViewBBox(); + } + + virtual void ViewDraw( int aLayer, KIGFX::GAL* aGal ) const; + + virtual void ViewGetLayers( int aLayers[], int& aCount ) const + { + aCount = 1; + aLayers[0] = ITEM_GAL_LAYER( GP_OVERLAY ); + } + + void Show( int x, std::ostream& st ) const + { + } + +private: + EDA_ITEM* m_parent; + std::deque m_points; +}; + + +class EPC_VERTICAL : public EDIT_POINT_CONSTRAINT +{ +public: + EPC_VERTICAL( EDIT_POINT* aConstrained, EDIT_POINT& aConstrainer ) : + EDIT_POINT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) + {} + + virtual ~EPC_VERTICAL() {}; + + virtual void Apply() + { + VECTOR2I point = m_constrained->GetPosition(); + point.x = m_constrainer.GetPosition().x; + m_constrained->SetPosition( point ); + } + + virtual std::list GetConstrainers() const + { + return std::list( 1, &m_constrainer ); + } + +private: + EDIT_POINT& m_constrainer; +}; + + +class EPC_HORIZONTAL : public EDIT_POINT_CONSTRAINT +{ +public: + EPC_HORIZONTAL( EDIT_POINT* aConstrained, EDIT_POINT& aConstrainer ) : + EDIT_POINT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) + {} + + virtual ~EPC_HORIZONTAL() {}; + + virtual void Apply() + { + VECTOR2I point = m_constrained->GetPosition(); + point.y = m_constrainer.GetPosition().y; + m_constrained->SetPosition( point ); + } + +private: + EDIT_POINT& m_constrainer; +}; + + +class EPC_CIRCLE : public EDIT_POINT_CONSTRAINT +{ +public: + EPC_CIRCLE( EDIT_POINT* aConstrained, EDIT_POINT& aCenter, EDIT_POINT& aEnd ) : + EDIT_POINT_CONSTRAINT( aConstrained ), m_center( aCenter ), m_end( aEnd ) + {} + + virtual ~EPC_CIRCLE() {}; + + virtual void Apply() + { + VECTOR2I centerToEnd = m_end.GetPosition() - m_center.GetPosition(); + VECTOR2I centerToPoint = m_constrained->GetPosition() - m_center.GetPosition(); + + int radius = centerToEnd.EuclideanNorm(); + double angle = centerToPoint.Angle(); + + VECTOR2I newLine( radius, 0 ); + newLine = newLine.Rotate( angle ); + + m_constrained->SetPosition( m_center.GetPosition() + newLine ); + } + +private: + EDIT_POINT& m_center; + EDIT_POINT& m_end; +}; + +#endif /* EDIT_POINTS_H_ */ diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index 9ddfccc34d..53683e1a55 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -37,6 +37,7 @@ #include "selection_tool.h" #include "edit_tool.h" #include "drawing_tool.h" +#include "point_editor.h" #include "common_actions.h" #include @@ -70,7 +71,8 @@ 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->RegisterTool( new DRAWING_TOOL ); + m_toolManager->RegisterTool( new DRAWING_TOOL ); + m_toolManager->RegisterTool( new POINT_EDITOR ); m_toolManager->SetEnvironment( NULL, GetGalCanvas()->GetView(), GetGalCanvas()->GetViewControls(), this ); diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp new file mode 100644 index 0000000000..efd1c35094 --- /dev/null +++ b/pcbnew/tools/point_editor.cpp @@ -0,0 +1,304 @@ +/* + * 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 "common_actions.h" +#include "selection_tool.h" +#include "point_editor.h" + +#include + +/** + * Class POINT_EDITOR + * + * Tool that displays edit points allowing to modify items by dragging the points. + */ + +class EDIT_POINTS_FACTORY +{ +public: + static EDIT_POINTS Make( EDA_ITEM* aItem ) + { + // TODO generate list of points basing on the type + EDIT_POINTS points( aItem ); + + switch( aItem->Type() ) + { + case PCB_LINE_T: + { + DRAWSEGMENT* segment = static_cast( aItem ); + + switch( segment->GetShape() ) + { + case S_SEGMENT: + points.Add( segment->GetStart() ); + points.Add( segment->GetEnd() ); + + break; + + case S_ARC: + points.Add( segment->GetCenter() ); // points[0] + points.Add( segment->GetArcStart() ); // points[1] + points.Add( segment->GetArcEnd() ); // points[2] + + // Set constraints + // Arc end has to stay at the same radius as the start + points[2].SetConstraint( new EPC_CIRCLE( &points[2], points[0], points[1] ) ); + break; + + default: // suppress warnings + break; + } + } + break; + + default: + break; + } + + return points; + } + +private: + EDIT_POINTS_FACTORY() {}; +}; + + +POINT_EDITOR::POINT_EDITOR() : + TOOL_INTERACTIVE( "pcbnew.PointEditor" ), m_selectionTool( NULL ) +{ +} + + +bool POINT_EDITOR::Init() +{ + // Find the selection tool, so they can cooperate + m_selectionTool = static_cast( m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ) ); + + if( !m_selectionTool ) + { + DisplayError( NULL, wxT( "pcbnew.InteractiveSelection tool is not available" ) ); + return false; + } + + setTransitions(); + + return true; +} + + +int POINT_EDITOR::OnSelected( TOOL_EVENT& aEvent ) +{ + std::cout << "point editor activated" << std::endl; + std::cout << aEvent.Format() << std::endl; + + const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + KIGFX::VIEW_CONTROLS* controls = getViewControls(); + m_dragPoint = NULL; + + if( selection.Size() == 1 ) + { + Activate(); + + EDA_ITEM* item = selection.items.GetPickedItem( 0 ); + EDIT_POINTS editPoints = EDIT_POINTS_FACTORY::Make( item ); + m_toolMgr->GetView()->Add( &editPoints ); + + // Main loop: keep receiving events + while( OPT_TOOL_EVENT evt = Wait() ) + { + if( evt->IsCancel() || + evt->Matches( m_selectionTool->ClearedEvent ) || + evt->Matches( m_selectionTool->DeselectedEvent ) || + evt->Matches( m_selectionTool->SelectedEvent ) ) + { + m_toolMgr->PassEvent(); + break; + } + + else if( evt->IsMotion() ) + { + EDIT_POINT* point = editPoints.FindPoint( evt->Position() ); + + if( m_dragPoint != point ) + { + if( point ) + { + controls->ShowCursor( true ); + controls->SetAutoPan( true ); + controls->SetSnapping( true ); + } + else + { + controls->ShowCursor( false ); + controls->SetAutoPan( false ); + controls->SetSnapping( false ); + } + } + + m_dragPoint = point; + } + + else if( evt->IsDrag( BUT_LEFT ) ) + { + if( m_dragPoint ) + { + m_dragPoint->SetPosition( controls->GetCursorPosition() ); + m_dragPoint->ApplyConstraint(); + updateItem( item, editPoints ); + updatePoints( item, editPoints ); + + editPoints.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + else + { + m_toolMgr->PassEvent(); + } + } + + else if( evt->IsClick( BUT_LEFT ) ) + { + m_toolMgr->PassEvent(); + } + } + + m_toolMgr->GetView()->Remove( &editPoints ); + item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + + controls->ShowCursor( false ); + controls->SetAutoPan( false ); + controls->SetSnapping( false ); + + setTransitions(); + + return 0; +} + + +void POINT_EDITOR::setTransitions() +{ + Go( &POINT_EDITOR::OnSelected, m_selectionTool->SelectedEvent ); +} + + +void POINT_EDITOR::updateItem( EDA_ITEM* aItem, EDIT_POINTS& aPoints ) const +{ + switch( aItem->Type() ) + { + case PCB_LINE_T: + { + DRAWSEGMENT* segment = static_cast( aItem ); + switch( segment->GetShape() ) + { + case S_SEGMENT: + if( &aPoints[0] == m_dragPoint ) + segment->SetStart( wxPoint( aPoints[0].GetPosition().x, aPoints[0].GetPosition().y ) ); + else if( &aPoints[1] == m_dragPoint ) + segment->SetEnd( wxPoint( aPoints[1].GetPosition().x, aPoints[1].GetPosition().y ) ); + + break; + + case S_ARC: + { + const VECTOR2I& center = aPoints[0].GetPosition(); + const VECTOR2I& start = aPoints[1].GetPosition(); + const VECTOR2I& end = aPoints[2].GetPosition(); + + if( center != segment->GetCenter() ) + { + wxPoint moveVector = wxPoint( center.x, center.y ) - segment->GetCenter(); + segment->Move( moveVector ); + + aPoints[1].SetPosition( segment->GetArcStart() ); + aPoints[2].SetPosition( segment->GetArcEnd() ); + } + + else + { + segment->SetArcStart( wxPoint( start.x, start.y ) ); + + VECTOR2D startLine = start - center; + VECTOR2I endLine = end - center; + double newAngle = RAD2DECIDEG( endLine.Angle() - startLine.Angle() ); + + // Adjust the new angle to (counter)clockwise setting + bool clockwise = ( segment->GetAngle() > 0 ); + if( clockwise && newAngle < 0.0 ) + newAngle += 3600.0; + else if( !clockwise && newAngle > 0.0 ) + newAngle -= 3600.0; + + segment->SetAngle( newAngle ); + } + } + break; + + default: // suppress warnings + break; + } + break; + } + + default: + break; + } +} + + +void POINT_EDITOR::updatePoints( const EDA_ITEM* aItem, EDIT_POINTS& aPoints ) const +{ + switch( aItem->Type() ) + { + case PCB_LINE_T: + { + const DRAWSEGMENT* segment = static_cast( aItem ); + { + switch( segment->GetShape() ) + { + case S_SEGMENT: + aPoints[0].SetPosition( segment->GetStart() ); + aPoints[1].SetPosition( segment->GetEnd() ); + break; + + case S_ARC: + aPoints[0].SetPosition( segment->GetCenter() ); + aPoints[1].SetPosition( segment->GetArcStart() ); + aPoints[2].SetPosition( segment->GetArcEnd() ); + break; + + default: // suppress warnings + break; + } + } + break; + } + + default: + break; + } +} diff --git a/pcbnew/tools/point_editor.h b/pcbnew/tools/point_editor.h new file mode 100644 index 0000000000..a44ac07a00 --- /dev/null +++ b/pcbnew/tools/point_editor.h @@ -0,0 +1,74 @@ +/* + * 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 __POINT_EDITOR_H +#define __POINT_EDITOR_H + +#include +#include "edit_points.h" + +class SELECTION_TOOL; + +/** + * Class POINT_EDITOR + * + * Tool that displays edit points allowing to modify items by dragging the points. + */ + +class POINT_EDITOR : public TOOL_INTERACTIVE +{ +public: + POINT_EDITOR(); + + /// @copydoc TOOL_INTERACTIVE::Reset() + void Reset( RESET_REASON aReason ) {}; + + /// @copydoc TOOL_INTERACTIVE::Init() + bool Init(); + + /** + * Function OnSelected() + * + * Change selection event handler. + */ + int OnSelected( TOOL_EVENT& aEvent ); + +private: + ///> Selection tool used for obtaining selected items + SELECTION_TOOL* m_selectionTool; + + ///> Currently edited point, NULL if there is none. + EDIT_POINT* m_dragPoint; + + ///> Updates item's points with edit points. + void updateItem( EDA_ITEM* aItem, EDIT_POINTS& aPoints ) const; + + ///> Updates edit points with item's points. + void updatePoints( const EDA_ITEM* aItem, EDIT_POINTS& aPoints ) const; + + ///> Sets up handlers for various events. + void setTransitions(); +}; + +#endif From c5c83bd271bd7a9dde8099b0e14519da25a7e9cb Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 28 Feb 2014 15:46:05 +0100 Subject: [PATCH 047/134] Added TOOL_MANAGER & ACTION_MANAGER::RunAction( const TOOL_ACTION aAction ). Selection clearing is invoked using TOOL_ACTION object rather than its name. --- common/tool/action_manager.cpp | 20 ++++++++++---------- common/tool/tool_manager.cpp | 6 ++++++ include/tool/action_manager.h | 16 ++++++++-------- include/tool/tool_manager.h | 10 +++++++++- pcbnew/edit.cpp | 1 + pcbnew/tools/edit_tool.cpp | 12 ++++++------ pcbnew/tools/selection_tool.cpp | 2 +- 7 files changed, 41 insertions(+), 26 deletions(-) diff --git a/common/tool/action_manager.cpp b/common/tool/action_manager.cpp index a00d4d08cc..ce0c403e43 100644 --- a/common/tool/action_manager.cpp +++ b/common/tool/action_manager.cpp @@ -94,12 +94,20 @@ bool ACTION_MANAGER::RunAction( const std::string& aActionName ) const if( it == m_actionNameIndex.end() ) return false; // no action with given name found - runAction( it->second ); + RunAction( it->second ); return true; } +void ACTION_MANAGER::RunAction( const TOOL_ACTION* aAction ) const +{ + TOOL_EVENT event = aAction->MakeEvent(); + + m_toolMgr->ProcessEvent( event ); +} + + bool ACTION_MANAGER::RunHotKey( int aHotKey ) const { std::map::const_iterator it = m_actionHotKeys.find( aHotKey ); @@ -107,7 +115,7 @@ bool ACTION_MANAGER::RunHotKey( int aHotKey ) const if( it == m_actionHotKeys.end() ) return false; // no appropriate action found for the hotkey - runAction( it->second ); + RunAction( it->second ); return true; } @@ -117,11 +125,3 @@ void ACTION_MANAGER::ClearHotKey( int aHotKey ) { m_actionHotKeys.erase( aHotKey ); } - - -void ACTION_MANAGER::runAction( const TOOL_ACTION* aAction ) const -{ - TOOL_EVENT event = aAction->MakeEvent(); - - m_toolMgr->ProcessEvent( event ); -} diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index f36d0cb343..57a98779f6 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -196,6 +196,12 @@ bool TOOL_MANAGER::RunAction( const std::string& aActionName ) } +void TOOL_MANAGER::RunAction( const TOOL_ACTION& aAction ) +{ + m_actionMgr->RunAction( &aAction ); +} + + bool TOOL_MANAGER::invokeTool( TOOL_BASE* aTool ) { wxASSERT( aTool != NULL ); diff --git a/include/tool/action_manager.h b/include/tool/action_manager.h index fa66a23eba..b38b329abc 100644 --- a/include/tool/action_manager.h +++ b/include/tool/action_manager.h @@ -81,6 +81,14 @@ public: */ bool RunAction( const std::string& aActionName ) const; + /** + * Function RunAction() + * Prepares an appropriate event and sends it to the destination specified in a TOOL_ACTION + * object. + * @param aAction is the action to be run. + */ + void RunAction( const TOOL_ACTION* aAction ) const; + /** * Function RunHotKey() * Runs an action associated with a hotkey (if there is one available). @@ -108,14 +116,6 @@ private: ///> Map for indexing actions by their hotkeys std::map m_actionHotKeys; - - /** - * Function runAction() - * Prepares an appropriate event and sends it to the destination specified in a TOOL_ACTION - * object. - * @param aAction is the action to be run. - */ - void runAction( const TOOL_ACTION* aAction ) const; }; #endif /* ACTION_MANAGER_H_ */ diff --git a/include/tool/tool_manager.h b/include/tool/tool_manager.h index 6e9c18acb0..c07dcfe94e 100644 --- a/include/tool/tool_manager.h +++ b/include/tool/tool_manager.h @@ -101,13 +101,21 @@ public: /** * Function RunAction() - * Runs the specified action. The common format is "application.ToolName.Action". + * Runs the specified action. The common format for action names 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 RunAction() + * Runs the specified action. + * + * @param aAction is the action to be invoked. + */ + void RunAction( const TOOL_ACTION& aAction ); + /** * Function FindTool() * Searches for a tool with given ID. diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index be15d90c64..18e0d0a0bb 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -1458,6 +1458,7 @@ void PCB_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent ) if( IsGalCanvasActive() ) { std::string actionName = COMMON_ACTIONS::TranslateLegacyId( id ); + if( !actionName.empty() ) m_toolManager->RunAction( actionName ); diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index ab79ba8e84..06692910e2 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -172,7 +172,7 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) } if( unselect ) - m_toolMgr->RunAction( "pcbnew.InteractiveSelection.Clear" ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); RN_DATA* ratsnest = getModel( PCB_T )->GetRatsnest(); ratsnest->ClearSimple(); @@ -230,7 +230,7 @@ int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) getModel( PCB_T )->GetRatsnest()->Recalculate(); if( unselect ) - m_toolMgr->RunAction( "pcbnew.InteractiveSelection.Clear" ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); } setTransitions(); @@ -277,7 +277,7 @@ int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) getModel( PCB_T )->GetRatsnest()->Recalculate(); if( unselect ) - m_toolMgr->RunAction( "pcbnew.InteractiveSelection.Clear" ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); return 0; } @@ -321,7 +321,7 @@ int EDIT_TOOL::Flip( TOOL_EVENT& aEvent ) getModel( PCB_T )->GetRatsnest()->Recalculate(); if( unselect ) - m_toolMgr->RunAction( "pcbnew.InteractiveSelection.Clear" ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); return 0; } @@ -339,7 +339,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_toolMgr->RunAction( "pcbnew.InteractiveSelection.Clear" ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); // Save them for( unsigned int i = 0; i < selectedItems.GetCount(); ++i ) @@ -461,7 +461,7 @@ 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" ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionSingle ); if( aSelection.Empty() ) { diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 24d00f2439..20f88508df 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -123,7 +123,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) if( m_selection.Empty() ) selectSingle( evt->Position() ); - m_toolMgr->RunAction( "pcbnew.InteractiveEdit.properties" ); + m_toolMgr->RunAction( COMMON_ACTIONS::properties ); } // drag with LMB? Select multiple objects (or at least draw a selection box) or drag them From f87f12e222bbda86fd1009e51d61a5f499884c86 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 28 Feb 2014 16:53:28 +0100 Subject: [PATCH 048/134] Added TOOL_ACTION for updating EDIT_POINTS. EDIT_POINTs show up when there is only one item selected (now after deselection as well). --- pcbnew/tools/common_actions.cpp | 3 + pcbnew/tools/common_actions.h | 3 + pcbnew/tools/edit_points.h | 34 +++++---- pcbnew/tools/edit_tool.cpp | 20 +++-- pcbnew/tools/point_editor.cpp | 128 ++++++++++++++++---------------- pcbnew/tools/point_editor.h | 17 ++++- 6 files changed, 115 insertions(+), 90 deletions(-) diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 64dc5f760d..d5a996c284 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -99,6 +99,9 @@ TOOL_ACTION COMMON_ACTIONS::routerActivate( "pcbnew.InteractiveRouter", AS_GLOBAL, 0, "Run push & shove router", "Run push & shove router" ); +TOOL_ACTION COMMON_ACTIONS::pointEditorUpdate( "pcbnew.PointEditor.update", + AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere + std::string COMMON_ACTIONS::TranslateLegacyId( int aId ) { diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 5d4908ac59..321c372436 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -87,6 +87,9 @@ public: /// Activation of the Push and Shove router static TOOL_ACTION routerActivate; + /// Update edit points + static TOOL_ACTION pointEditorUpdate; + /** * Function TranslateLegacyId() * Translates legacy tool ids to the corresponding TOOL_ACTION name. diff --git a/pcbnew/tools/edit_points.h b/pcbnew/tools/edit_points.h index 7ddfa2fcf9..e9a444286d 100644 --- a/pcbnew/tools/edit_points.h +++ b/pcbnew/tools/edit_points.h @@ -37,13 +37,13 @@ class EDIT_POINT; class EDIT_POINT_CONSTRAINT { public: - EDIT_POINT_CONSTRAINT( EDIT_POINT* aConstrained ) : m_constrained( aConstrained ) {}; + EDIT_POINT_CONSTRAINT( EDIT_POINT& aConstrained ) : m_constrained( aConstrained ) {}; virtual ~EDIT_POINT_CONSTRAINT() {}; virtual void Apply() = 0; protected: - EDIT_POINT* m_constrained; + EDIT_POINT& m_constrained; }; @@ -53,6 +53,7 @@ class EDIT_POINT public: EDIT_POINT( const VECTOR2I& aPoint ) : m_point( aPoint ), m_constraint( NULL ) {}; + ~EDIT_POINT() { delete m_constraint; @@ -121,6 +122,11 @@ public: */ EDIT_POINT* FindPoint( const VECTOR2I& aLocation ); + EDA_ITEM* GetParent() const + { + return m_parent; + } + void Add( const EDIT_POINT& aPoint ) { m_points.push_back( aPoint ); @@ -172,7 +178,7 @@ private: class EPC_VERTICAL : public EDIT_POINT_CONSTRAINT { public: - EPC_VERTICAL( EDIT_POINT* aConstrained, EDIT_POINT& aConstrainer ) : + EPC_VERTICAL( EDIT_POINT& aConstrained, EDIT_POINT& aConstrainer ) : EDIT_POINT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) {} @@ -180,9 +186,9 @@ public: virtual void Apply() { - VECTOR2I point = m_constrained->GetPosition(); + VECTOR2I point = m_constrained.GetPosition(); point.x = m_constrainer.GetPosition().x; - m_constrained->SetPosition( point ); + m_constrained.SetPosition( point ); } virtual std::list GetConstrainers() const @@ -198,7 +204,7 @@ private: class EPC_HORIZONTAL : public EDIT_POINT_CONSTRAINT { public: - EPC_HORIZONTAL( EDIT_POINT* aConstrained, EDIT_POINT& aConstrainer ) : + EPC_HORIZONTAL( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : EDIT_POINT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) {} @@ -206,20 +212,20 @@ public: virtual void Apply() { - VECTOR2I point = m_constrained->GetPosition(); + VECTOR2I point = m_constrained.GetPosition(); point.y = m_constrainer.GetPosition().y; - m_constrained->SetPosition( point ); + m_constrained.SetPosition( point ); } private: - EDIT_POINT& m_constrainer; + const EDIT_POINT& m_constrainer; }; class EPC_CIRCLE : public EDIT_POINT_CONSTRAINT { public: - EPC_CIRCLE( EDIT_POINT* aConstrained, EDIT_POINT& aCenter, EDIT_POINT& aEnd ) : + EPC_CIRCLE( EDIT_POINT& aConstrained, const EDIT_POINT& aCenter, const EDIT_POINT& aEnd ) : EDIT_POINT_CONSTRAINT( aConstrained ), m_center( aCenter ), m_end( aEnd ) {} @@ -228,7 +234,7 @@ public: virtual void Apply() { VECTOR2I centerToEnd = m_end.GetPosition() - m_center.GetPosition(); - VECTOR2I centerToPoint = m_constrained->GetPosition() - m_center.GetPosition(); + VECTOR2I centerToPoint = m_constrained.GetPosition() - m_center.GetPosition(); int radius = centerToEnd.EuclideanNorm(); double angle = centerToPoint.Angle(); @@ -236,12 +242,12 @@ public: VECTOR2I newLine( radius, 0 ); newLine = newLine.Rotate( angle ); - m_constrained->SetPosition( m_center.GetPosition() + newLine ); + m_constrained.SetPosition( m_center.GetPosition() + newLine ); } private: - EDIT_POINT& m_center; - EDIT_POINT& m_end; + const EDIT_POINT& m_center; + const EDIT_POINT& m_end; }; #endif /* EDIT_POINTS_H_ */ diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 06692910e2..53a72f25e3 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -151,6 +151,7 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); dragPosition = controls->GetCursorPosition(); + m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate ); } else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) @@ -233,6 +234,7 @@ int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); } + m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate ); setTransitions(); return 0; @@ -268,9 +270,6 @@ int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } - setTransitions(); - updateRatsnest( true ); - if( m_dragging ) selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); else @@ -279,6 +278,11 @@ int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) if( unselect ) m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate ); + + updateRatsnest( true ); + setTransitions(); + return 0; } @@ -312,9 +316,6 @@ int EDIT_TOOL::Flip( TOOL_EVENT& aEvent ) item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS ); } - setTransitions(); - updateRatsnest( true ); - if( m_dragging ) selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); else @@ -323,6 +324,11 @@ int EDIT_TOOL::Flip( TOOL_EVENT& aEvent ) if( unselect ) m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate ); + + updateRatsnest( true ); + setTransitions(); + return 0; } @@ -359,8 +365,8 @@ int EDIT_TOOL::Remove( TOOL_EVENT& aEvent ) if( !( board->m_Status_Pcb & NET_CODES_OK ) ) board->BuildListOfNets(); + board->GetRatsnest()->Recalculate(); // TODO is it necessary? setTransitions(); - board->GetRatsnest()->Recalculate(); return 0; } diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index efd1c35094..99a64a40a8 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -22,6 +22,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#include + #include #include #include @@ -41,10 +43,10 @@ class EDIT_POINTS_FACTORY { public: - static EDIT_POINTS Make( EDA_ITEM* aItem ) + static boost::shared_ptr Make( EDA_ITEM* aItem ) { // TODO generate list of points basing on the type - EDIT_POINTS points( aItem ); + boost::shared_ptr points = boost::make_shared( aItem ); switch( aItem->Type() ) { @@ -55,19 +57,19 @@ public: switch( segment->GetShape() ) { case S_SEGMENT: - points.Add( segment->GetStart() ); - points.Add( segment->GetEnd() ); + points->Add( segment->GetStart() ); + points->Add( segment->GetEnd() ); break; case S_ARC: - points.Add( segment->GetCenter() ); // points[0] - points.Add( segment->GetArcStart() ); // points[1] - points.Add( segment->GetArcEnd() ); // points[2] + points->Add( segment->GetCenter() ); // points[0] + points->Add( segment->GetArcStart() ); // points[1] + points->Add( segment->GetArcEnd() ); // points[2] // Set constraints // Arc end has to stay at the same radius as the start - points[2].SetConstraint( new EPC_CIRCLE( &points[2], points[0], points[1] ) ); + (*points)[2].SetConstraint( new EPC_CIRCLE( (*points)[2], (*points)[0], (*points)[1] ) ); break; default: // suppress warnings @@ -111,11 +113,8 @@ bool POINT_EDITOR::Init() } -int POINT_EDITOR::OnSelected( TOOL_EVENT& aEvent ) +int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) { - std::cout << "point editor activated" << std::endl; - std::cout << aEvent.Format() << std::endl; - const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); KIGFX::VIEW_CONTROLS* controls = getViewControls(); m_dragPoint = NULL; @@ -125,24 +124,15 @@ int POINT_EDITOR::OnSelected( TOOL_EVENT& aEvent ) Activate(); EDA_ITEM* item = selection.items.GetPickedItem( 0 ); - EDIT_POINTS editPoints = EDIT_POINTS_FACTORY::Make( item ); - m_toolMgr->GetView()->Add( &editPoints ); + m_editPoints = EDIT_POINTS_FACTORY::Make( item ); + m_toolMgr->GetView()->Add( m_editPoints.get() ); // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { - if( evt->IsCancel() || - evt->Matches( m_selectionTool->ClearedEvent ) || - evt->Matches( m_selectionTool->DeselectedEvent ) || - evt->Matches( m_selectionTool->SelectedEvent ) ) + if( evt->IsMotion() ) { - m_toolMgr->PassEvent(); - break; - } - - else if( evt->IsMotion() ) - { - EDIT_POINT* point = editPoints.FindPoint( evt->Position() ); + EDIT_POINT* point = m_editPoints->FindPoint( evt->Position() ); if( m_dragPoint != point ) { @@ -163,30 +153,37 @@ int POINT_EDITOR::OnSelected( TOOL_EVENT& aEvent ) m_dragPoint = point; } - else if( evt->IsDrag( BUT_LEFT ) ) + else if( evt->IsDrag( BUT_LEFT ) && m_dragPoint ) { - if( m_dragPoint ) - { - m_dragPoint->SetPosition( controls->GetCursorPosition() ); - m_dragPoint->ApplyConstraint(); - updateItem( item, editPoints ); - updatePoints( item, editPoints ); + m_dragPoint->SetPosition( controls->GetCursorPosition() ); + m_dragPoint->ApplyConstraint(); + updateItem(); + updatePoints(); - editPoints.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - else - { - m_toolMgr->PassEvent(); - } + m_editPoints->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } - else if( evt->IsClick( BUT_LEFT ) ) + else if( evt->IsAction( &COMMON_ACTIONS::pointEditorUpdate ) ) + { + updatePoints(); + } + + else if( evt->IsCancel() || + evt->Matches( m_selectionTool->ClearedEvent ) || + evt->Matches( m_selectionTool->DeselectedEvent ) || + evt->Matches( m_selectionTool->SelectedEvent ) ) + { + break; + } + + else { m_toolMgr->PassEvent(); } } - m_toolMgr->GetView()->Remove( &editPoints ); + m_toolMgr->GetView()->Remove( m_editPoints.get() ); + m_editPoints.reset(); item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } @@ -200,42 +197,38 @@ int POINT_EDITOR::OnSelected( TOOL_EVENT& aEvent ) } -void POINT_EDITOR::setTransitions() +void POINT_EDITOR::updateItem() const { - Go( &POINT_EDITOR::OnSelected, m_selectionTool->SelectedEvent ); -} + EDA_ITEM* item = m_editPoints->GetParent(); - -void POINT_EDITOR::updateItem( EDA_ITEM* aItem, EDIT_POINTS& aPoints ) const -{ - switch( aItem->Type() ) + switch( item->Type() ) { case PCB_LINE_T: { - DRAWSEGMENT* segment = static_cast( aItem ); + DRAWSEGMENT* segment = static_cast( item ); switch( segment->GetShape() ) { case S_SEGMENT: - if( &aPoints[0] == m_dragPoint ) - segment->SetStart( wxPoint( aPoints[0].GetPosition().x, aPoints[0].GetPosition().y ) ); - else if( &aPoints[1] == m_dragPoint ) - segment->SetEnd( wxPoint( aPoints[1].GetPosition().x, aPoints[1].GetPosition().y ) ); + if( &(*m_editPoints)[0] == m_dragPoint ) + segment->SetStart( wxPoint( (*m_editPoints)[0].GetPosition().x, (*m_editPoints)[0].GetPosition().y ) ); + else if( &(*m_editPoints)[1] == m_dragPoint ) + segment->SetEnd( wxPoint( (*m_editPoints)[1].GetPosition().x, (*m_editPoints)[1].GetPosition().y ) ); break; case S_ARC: { - const VECTOR2I& center = aPoints[0].GetPosition(); - const VECTOR2I& start = aPoints[1].GetPosition(); - const VECTOR2I& end = aPoints[2].GetPosition(); + const VECTOR2I& center = (*m_editPoints)[0].GetPosition(); + const VECTOR2I& start = (*m_editPoints)[1].GetPosition(); + const VECTOR2I& end = (*m_editPoints)[2].GetPosition(); if( center != segment->GetCenter() ) { wxPoint moveVector = wxPoint( center.x, center.y ) - segment->GetCenter(); segment->Move( moveVector ); - aPoints[1].SetPosition( segment->GetArcStart() ); - aPoints[2].SetPosition( segment->GetArcEnd() ); + (*m_editPoints)[1].SetPosition( segment->GetArcStart() ); + (*m_editPoints)[2].SetPosition( segment->GetArcEnd() ); } else @@ -270,25 +263,30 @@ void POINT_EDITOR::updateItem( EDA_ITEM* aItem, EDIT_POINTS& aPoints ) const } -void POINT_EDITOR::updatePoints( const EDA_ITEM* aItem, EDIT_POINTS& aPoints ) const +void POINT_EDITOR::updatePoints() const { - switch( aItem->Type() ) + if( !m_editPoints ) + return; + + EDA_ITEM* item = m_editPoints->GetParent(); + + switch( item->Type() ) { case PCB_LINE_T: { - const DRAWSEGMENT* segment = static_cast( aItem ); + const DRAWSEGMENT* segment = static_cast( item ); { switch( segment->GetShape() ) { case S_SEGMENT: - aPoints[0].SetPosition( segment->GetStart() ); - aPoints[1].SetPosition( segment->GetEnd() ); + (*m_editPoints)[0].SetPosition( segment->GetStart() ); + (*m_editPoints)[1].SetPosition( segment->GetEnd() ); break; case S_ARC: - aPoints[0].SetPosition( segment->GetCenter() ); - aPoints[1].SetPosition( segment->GetArcStart() ); - aPoints[2].SetPosition( segment->GetArcEnd() ); + (*m_editPoints)[0].SetPosition( segment->GetCenter() ); + (*m_editPoints)[1].SetPosition( segment->GetArcStart() ); + (*m_editPoints)[2].SetPosition( segment->GetArcEnd() ); break; default: // suppress warnings diff --git a/pcbnew/tools/point_editor.h b/pcbnew/tools/point_editor.h index a44ac07a00..ca6b4abde8 100644 --- a/pcbnew/tools/point_editor.h +++ b/pcbnew/tools/point_editor.h @@ -25,6 +25,8 @@ #ifndef __POINT_EDITOR_H #define __POINT_EDITOR_H +#include + #include #include "edit_points.h" @@ -52,7 +54,7 @@ public: * * Change selection event handler. */ - int OnSelected( TOOL_EVENT& aEvent ); + int OnSelectionChange( TOOL_EVENT& aEvent ); private: ///> Selection tool used for obtaining selected items @@ -61,14 +63,21 @@ private: ///> Currently edited point, NULL if there is none. EDIT_POINT* m_dragPoint; + ///> Currently available edit points. + boost::shared_ptr m_editPoints; + ///> Updates item's points with edit points. - void updateItem( EDA_ITEM* aItem, EDIT_POINTS& aPoints ) const; + void updateItem() const; ///> Updates edit points with item's points. - void updatePoints( const EDA_ITEM* aItem, EDIT_POINTS& aPoints ) const; + void updatePoints() const; ///> Sets up handlers for various events. - void setTransitions(); + void setTransitions() + { + Go( &POINT_EDITOR::OnSelectionChange, m_selectionTool->SelectedEvent ); + Go( &POINT_EDITOR::OnSelectionChange, m_selectionTool->DeselectedEvent ); + } }; #endif From 3c656691cf304b27d359f47225a0257a1c4159f0 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 28 Feb 2014 17:20:10 +0100 Subject: [PATCH 049/134] Fixed POINT_EDITOR crash on GAL change / board reload. --- pcbnew/tools/point_editor.cpp | 34 ++++++++++++++++++++-------------- pcbnew/tools/point_editor.h | 2 +- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 99a64a40a8..0ce7035523 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -96,6 +96,12 @@ POINT_EDITOR::POINT_EDITOR() : } +void POINT_EDITOR::Reset( RESET_REASON aReason ) +{ + m_editPoints.reset(); +} + + bool POINT_EDITOR::Init() { // Find the selection tool, so they can cooperate @@ -130,6 +136,14 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { + if( !m_editPoints || evt->IsCancel() || + evt->Matches( m_selectionTool->ClearedEvent ) || + evt->Matches( m_selectionTool->DeselectedEvent ) || + evt->Matches( m_selectionTool->SelectedEvent ) ) + { + break; + } + if( evt->IsMotion() ) { EDIT_POINT* point = m_editPoints->FindPoint( evt->Position() ); @@ -168,23 +182,18 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) updatePoints(); } - else if( evt->IsCancel() || - evt->Matches( m_selectionTool->ClearedEvent ) || - evt->Matches( m_selectionTool->DeselectedEvent ) || - evt->Matches( m_selectionTool->SelectedEvent ) ) - { - break; - } - else { m_toolMgr->PassEvent(); } } - m_toolMgr->GetView()->Remove( m_editPoints.get() ); - m_editPoints.reset(); - item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + if( m_editPoints ) + { + item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + m_toolMgr->GetView()->Remove( m_editPoints.get() ); + m_editPoints.reset(); + } } controls->ShowCursor( false ); @@ -265,9 +274,6 @@ void POINT_EDITOR::updateItem() const void POINT_EDITOR::updatePoints() const { - if( !m_editPoints ) - return; - EDA_ITEM* item = m_editPoints->GetParent(); switch( item->Type() ) diff --git a/pcbnew/tools/point_editor.h b/pcbnew/tools/point_editor.h index ca6b4abde8..d43a09dda0 100644 --- a/pcbnew/tools/point_editor.h +++ b/pcbnew/tools/point_editor.h @@ -44,7 +44,7 @@ public: POINT_EDITOR(); /// @copydoc TOOL_INTERACTIVE::Reset() - void Reset( RESET_REASON aReason ) {}; + void Reset( RESET_REASON aReason ); /// @copydoc TOOL_INTERACTIVE::Init() bool Init(); From d1ffaf0deb1d9db14c0fdd9b2d6db63044c69293 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 28 Feb 2014 18:24:13 +0100 Subject: [PATCH 050/134] Circles are supported by POINT_EDITOR. --- pcbnew/tools/point_editor.cpp | 38 ++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 0ce7035523..cf464dc436 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -72,6 +72,10 @@ public: (*points)[2].SetConstraint( new EPC_CIRCLE( (*points)[2], (*points)[0], (*points)[1] ) ); break; + case S_CIRCLE: + points->Add( segment->GetCenter() ); + points->Add( segment->GetEnd() ); + default: // suppress warnings break; } @@ -219,9 +223,12 @@ void POINT_EDITOR::updateItem() const { case S_SEGMENT: if( &(*m_editPoints)[0] == m_dragPoint ) - segment->SetStart( wxPoint( (*m_editPoints)[0].GetPosition().x, (*m_editPoints)[0].GetPosition().y ) ); + segment->SetStart( wxPoint( (*m_editPoints)[0].GetPosition().x, + (*m_editPoints)[0].GetPosition().y ) ); + else if( &(*m_editPoints)[1] == m_dragPoint ) - segment->SetEnd( wxPoint( (*m_editPoints)[1].GetPosition().x, (*m_editPoints)[1].GetPosition().y ) ); + segment->SetEnd( wxPoint( (*m_editPoints)[1].GetPosition().x, + (*m_editPoints)[1].GetPosition().y ) ); break; @@ -250,6 +257,7 @@ void POINT_EDITOR::updateItem() const // Adjust the new angle to (counter)clockwise setting bool clockwise = ( segment->GetAngle() > 0 ); + if( clockwise && newAngle < 0.0 ) newAngle += 3600.0; else if( !clockwise && newAngle > 0.0 ) @@ -257,8 +265,27 @@ void POINT_EDITOR::updateItem() const segment->SetAngle( newAngle ); } + + break; + } + + case S_CIRCLE: + { + const VECTOR2I& center = (*m_editPoints)[0].GetPosition(); + const VECTOR2I& end = (*m_editPoints)[1].GetPosition(); + + if( m_dragPoint == &(*m_editPoints)[0] ) + { + wxPoint moveVector = wxPoint( center.x, center.y ) - segment->GetCenter(); + segment->Move( moveVector ); + } + else + { + segment->SetEnd( wxPoint( end.x, end.y ) ); + } + + break; } - break; default: // suppress warnings break; @@ -295,6 +322,11 @@ void POINT_EDITOR::updatePoints() const (*m_editPoints)[2].SetPosition( segment->GetArcEnd() ); break; + case S_CIRCLE: + (*m_editPoints)[0].SetPosition( segment->GetCenter() ); + (*m_editPoints)[1].SetPosition( segment->GetEnd() ); + break; + default: // suppress warnings break; } From 24c9b705a32e7764573fd9f56d06b216ab698da9 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 28 Feb 2014 18:24:29 +0100 Subject: [PATCH 051/134] Zones are supported by POINT_EDITOR. --- pcbnew/tools/point_editor.cpp | 43 +++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index cf464dc436..59e67ff732 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -33,6 +33,7 @@ #include "point_editor.h" #include +#include /** * Class POINT_EDITOR @@ -52,7 +53,7 @@ public: { case PCB_LINE_T: { - DRAWSEGMENT* segment = static_cast( aItem ); + const DRAWSEGMENT* segment = static_cast( aItem ); switch( segment->GetShape() ) { @@ -79,8 +80,19 @@ public: default: // suppress warnings break; } + + break; + } + + case PCB_ZONE_AREA_T: + { + const CPolyLine* outline = static_cast( aItem )->Outline(); + + for( int i = 0; i < outline->GetCornersCount(); ++i ) + points->Add( outline->GetPos( i ) ); + + break; } - break; default: break; @@ -290,6 +302,21 @@ void POINT_EDITOR::updateItem() const default: // suppress warnings break; } + + break; + } + + case PCB_ZONE_AREA_T: + { + ZONE_CONTAINER* zone = static_cast( item ); + CPolyLine* outline = zone->Outline(); + + for( int i = 0; i < outline->GetCornersCount(); ++i ) + { + outline->SetX( i, (*m_editPoints)[i].GetPosition().x ); + outline->SetY( i, (*m_editPoints)[i].GetPosition().y ); + } + break; } @@ -330,7 +357,19 @@ void POINT_EDITOR::updatePoints() const default: // suppress warnings break; } + + break; } + } + + case PCB_ZONE_AREA_T: + { + const ZONE_CONTAINER* zone = static_cast( item ); + const CPolyLine* outline = zone->Outline(); + + for( int i = 0; i < outline->GetCornersCount(); ++i ) + (*m_editPoints)[i].SetPosition( outline->GetPos( i ) ); + break; } From f72aec25c02784725765d716daf7ce24f323ef83 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 6 Mar 2014 11:49:08 +0100 Subject: [PATCH 052/134] Auto zone refilling after using the POINT_EDITOR. Minor code cleaning. --- pcbnew/class_zone.h | 13 ------- pcbnew/legacy_plugin.cpp | 2 +- pcbnew/tools/point_editor.cpp | 16 +++++++++ pcbnew/tools/point_editor.h | 3 ++ pcbnew/zone_filling_algorithm.cpp | 58 +++++++++++++++---------------- 5 files changed, 49 insertions(+), 43 deletions(-) diff --git a/pcbnew/class_zone.h b/pcbnew/class_zone.h index 6423d85396..016875e82c 100644 --- a/pcbnew/class_zone.h +++ b/pcbnew/class_zone.h @@ -358,19 +358,6 @@ public: */ bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const; - /** - * Function Fill_Zone - * Calculate the zone filling - * The zone outline is a frontier, and can be complex (with holes) - * The filling starts from starting points like pads, tracks. - * If exists the old filling is removed - * @param frame = reference to the main frame - * @param DC = current Device Context - * @param verbose = true to show error messages - * @return error level (0 = no error) - */ - int Fill_Zone( PCB_EDIT_FRAME* frame, wxDC* DC, bool verbose = true ); - /** * Function FillZoneAreasWithSegments * Fill sub areas in a zone with segments with m_ZoneMinThickness width diff --git a/pcbnew/legacy_plugin.cpp b/pcbnew/legacy_plugin.cpp index abed5085e7..d0a6460563 100644 --- a/pcbnew/legacy_plugin.cpp +++ b/pcbnew/legacy_plugin.cpp @@ -2339,7 +2339,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER() arcsegcount = 32; zc->SetArcSegmentCount( arcsegcount ); - zc->SetIsFilled( fillstate == 'S' ? true : false ); + zc->SetIsFilled( fillstate == 'S' ); zc->SetThermalReliefGap( thermalReliefGap ); zc->SetThermalReliefCopperBridge( thermalReliefCopperBridge ); } diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 59e67ff732..0894fedfd9 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -32,6 +32,7 @@ #include "selection_tool.h" #include "point_editor.h" +#include #include #include @@ -206,6 +207,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) if( m_editPoints ) { + finishItem(); item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); m_toolMgr->GetView()->Remove( m_editPoints.get() ); m_editPoints.reset(); @@ -326,6 +328,20 @@ void POINT_EDITOR::updateItem() const } +void POINT_EDITOR::finishItem() const +{ + EDA_ITEM* item = m_editPoints->GetParent(); + + if( item->Type() == PCB_ZONE_AREA_T ) + { + ZONE_CONTAINER* zone = static_cast( item ); + + if( zone->IsFilled() ) + getEditFrame()->Fill_Zone( zone ); + } +} + + void POINT_EDITOR::updatePoints() const { EDA_ITEM* item = m_editPoints->GetParent(); diff --git a/pcbnew/tools/point_editor.h b/pcbnew/tools/point_editor.h index d43a09dda0..81b55131ba 100644 --- a/pcbnew/tools/point_editor.h +++ b/pcbnew/tools/point_editor.h @@ -69,6 +69,9 @@ private: ///> Updates item's points with edit points. void updateItem() const; + ///> Applies the last changes to the edited item. + void finishItem() const; + ///> Updates edit points with item's points. void updatePoints() const; diff --git a/pcbnew/zone_filling_algorithm.cpp b/pcbnew/zone_filling_algorithm.cpp index 04da8e2fdc..aadcc66c2a 100644 --- a/pcbnew/zone_filling_algorithm.cpp +++ b/pcbnew/zone_filling_algorithm.cpp @@ -54,8 +54,7 @@ * to add holes for pads and tracks and other items not in net. */ -bool ZONE_CONTAINER::BuildFilledSolidAreasPolygons( BOARD* aPcb, - CPOLYGONS_LIST* aCornerBuffer ) +bool ZONE_CONTAINER::BuildFilledSolidAreasPolygons( BOARD* aPcb, CPOLYGONS_LIST* aCornerBuffer ) { if( aCornerBuffer == NULL ) m_FilledPolysList.RemoveAllContours(); @@ -80,9 +79,11 @@ bool ZONE_CONTAINER::BuildFilledSolidAreasPolygons( BOARD* aPcb, case ZONE_SETTINGS::SMOOTHING_CHAMFER: m_smoothedPoly = m_Poly->Chamfer( m_cornerRadius ); break; + case ZONE_SETTINGS::SMOOTHING_FILLET: m_smoothedPoly = m_Poly->Fillet( m_cornerRadius, m_ArcToSegmentsCount ); break; + default: m_smoothedPoly = new CPolyLine; m_smoothedPoly->Copy( m_Poly ); @@ -90,18 +91,16 @@ bool ZONE_CONTAINER::BuildFilledSolidAreasPolygons( BOARD* aPcb, } if( aCornerBuffer ) - ConvertPolysListWithHolesToOnePolygon( m_smoothedPoly->m_CornersList, - *aCornerBuffer ); + ConvertPolysListWithHolesToOnePolygon( m_smoothedPoly->m_CornersList, *aCornerBuffer ); else - ConvertPolysListWithHolesToOnePolygon( m_smoothedPoly->m_CornersList, - m_FilledPolysList ); + ConvertPolysListWithHolesToOnePolygon( m_smoothedPoly->m_CornersList, m_FilledPolysList ); /* For copper layers, we now must add holes in the Polygon list. * holes are pads and tracks with their clearance area * for non copper layers just recalculate the m_FilledPolysList * with m_ZoneMinThickness taken in account */ - if( ! aCornerBuffer ) + if( !aCornerBuffer ) { if( IsOnCopperLayer() ) AddClearanceAreasPolygonsToPolysList( aPcb ); @@ -124,16 +123,19 @@ bool ZONE_CONTAINER::BuildFilledSolidAreasPolygons( BOARD* aPcb, m_FilledPolysList.RemoveAllContours(); CopyPolygonsFromKiPolygonListToFilledPolysList( polyset_zone_solid_areas ); } - if ( m_FillMode ) // if fill mode uses segments, create them: - FillZoneAreasWithSegments( ); + + if( m_FillMode ) // if fill mode uses segments, create them: + FillZoneAreasWithSegments(); } + m_IsFilled = true; + return 1; } // Sort function to build filled zones -static bool SortByXValues( const int& a, const int &b) +static bool SortByXValues( const int& a, const int &b ) { return a < b; } @@ -141,13 +143,11 @@ static bool SortByXValues( const int& a, const int &b) int ZONE_CONTAINER::FillZoneAreasWithSegments() { - int ics, ice; + int ics, ice; int count = 0; std::vector x_coordinates; bool error = false; - - int istart, iend; // index of the starting and the endif corner of one filled area in m_FilledPolysList - + int istart, iend; // index of the starting and the endif corner of one filled area in m_FilledPolysList int margin = m_ZoneMinThickness * 2 / 10; int minwidth = Mils2iu( 2 ); margin = std::max ( minwidth, margin ); @@ -157,28 +157,25 @@ int ZONE_CONTAINER::FillZoneAreasWithSegments() // Read all filled areas in m_FilledPolysList m_FillSegmList.clear(); istart = 0; - int end_list = m_FilledPolysList.GetCornersCount()-1; + int end_list = m_FilledPolysList.GetCornersCount() - 1; for( int ic = 0; ic <= end_list; ic++ ) { CPolyPt* corner = &m_FilledPolysList[ic]; - if ( corner->end_contour || (ic == end_list) ) + if ( corner->end_contour || ( ic == end_list ) ) { iend = ic; EDA_RECT rect = CalculateSubAreaBoundaryBox( istart, iend ); // Calculate the y limits of the zone - int refy = rect.GetY(); - int endy = rect.GetBottom(); - - for( ; refy < endy; refy += step ) + for( int refy = rect.GetY(), endy = rect.GetBottom(); refy < endy; refy += step ) { // find all intersection points of an infinite line with polyline sides x_coordinates.clear(); for( ics = istart, ice = iend; ics <= iend; ice = ics, ics++ ) { - if ( m_FilledPolysList[ice].m_utility ) + if( m_FilledPolysList[ice].m_utility ) continue; int seg_startX = m_FilledPolysList[ics].x; @@ -203,7 +200,7 @@ int ZONE_CONTAINER::FillZoneAreasWithSegments() // the segment start point: seg_endX -= seg_startX; seg_endY -= seg_startY; - double newrefy = (double) (refy - seg_startY); + double newrefy = (double) ( refy - seg_startY ); double intersec_x; if ( seg_endY == 0 ) // horizontal segment on the same line: skip @@ -217,9 +214,9 @@ int ZONE_CONTAINER::FillZoneAreasWithSegments() // intersec_x = refy/slope = refy * inv_slope // Note: because horizontal segments are already tested and skipped, slope // exists (seg_end_y not O) - double inv_slope = (double)seg_endX / seg_endY; + double inv_slope = (double) seg_endX / seg_endY; intersec_x = newrefy * inv_slope; - x_coordinates.push_back((int) intersec_x + seg_startX); + x_coordinates.push_back( (int) intersec_x + seg_startX ); } // A line scan is finished: build list of segments @@ -239,12 +236,12 @@ int ZONE_CONTAINER::FillZoneAreasWithSegments() error = true; } - if ( error ) + if( error ) break; - int iimax = x_coordinates.size()-1; + int iimax = x_coordinates.size() - 1; - for (int ii = 0; ii < iimax; ii +=2 ) + for( int ii = 0; ii < iimax; ii +=2 ) { wxPoint seg_start, seg_end; count++; @@ -257,16 +254,19 @@ int ZONE_CONTAINER::FillZoneAreasWithSegments() } } //End examine segments in one area - if ( error ) + if( error ) break; istart = iend + 1; // istart points the first corner of the next area } // End find one end of outline - if ( error ) + if( error ) break; } // End examine all areas + if( !error ) + m_IsFilled = true; + return count; } From 2889a7a13ac8c053860b1257bfa3b80039f7cb14 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 6 Mar 2014 12:36:20 +0100 Subject: [PATCH 053/134] Undo/redo support for POINT_EDITOR. --- pcbnew/tools/point_editor.cpp | 39 ++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 0894fedfd9..cf78c7d89d 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -47,9 +47,9 @@ class EDIT_POINTS_FACTORY public: static boost::shared_ptr Make( EDA_ITEM* aItem ) { - // TODO generate list of points basing on the type boost::shared_ptr points = boost::make_shared( aItem ); + // Generate list of edit points basing on the item type switch( aItem->Type() ) { case PCB_LINE_T: @@ -140,20 +140,22 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) { const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); KIGFX::VIEW_CONTROLS* controls = getViewControls(); - m_dragPoint = NULL; if( selection.Size() == 1 ) { - Activate(); - + PCB_EDIT_FRAME* editFrame = getEditFrame(); EDA_ITEM* item = selection.items.GetPickedItem( 0 ); m_editPoints = EDIT_POINTS_FACTORY::Make( item ); m_toolMgr->GetView()->Add( m_editPoints.get() ); + m_dragPoint = NULL; + bool modified = false; + + Activate(); // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { - if( !m_editPoints || evt->IsCancel() || + if( !m_editPoints || evt->Matches( m_selectionTool->ClearedEvent ) || evt->Matches( m_selectionTool->DeselectedEvent ) || evt->Matches( m_selectionTool->SelectedEvent ) ) @@ -186,6 +188,14 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) else if( evt->IsDrag( BUT_LEFT ) && m_dragPoint ) { + if( !modified ) + { + // Save items, so changes can be undone + editFrame->OnModify(); + editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED ); + modified = true; + } + m_dragPoint->SetPosition( controls->GetCursorPosition() ); m_dragPoint->ApplyConstraint(); updateItem(); @@ -199,6 +209,25 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) updatePoints(); } + else if( evt->IsMouseUp( BUT_LEFT ) ) + { + modified = false; + } + + else if( evt->IsCancel() ) + { + if( modified ) // Restore the last change + { + wxCommandEvent dummy; + editFrame->GetBoardFromUndoList( dummy ); + + updatePoints(); + modified = false; + } + + break; + } + else { m_toolMgr->PassEvent(); From 8c43c216bb6b9b1bbd8b7c04a9e180960ad05a39 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 6 Mar 2014 14:41:25 +0100 Subject: [PATCH 054/134] 45 degrees mode for POINT_EDITOR. --- pcbnew/tools/edit_points.cpp | 7 +--- pcbnew/tools/edit_points.h | 79 +++++++++++++++++++++++++++++++---- pcbnew/tools/point_editor.cpp | 42 +++++++++++++++---- 3 files changed, 106 insertions(+), 22 deletions(-) diff --git a/pcbnew/tools/edit_points.cpp b/pcbnew/tools/edit_points.cpp index 5efe90bae0..5e7174e5be 100644 --- a/pcbnew/tools/edit_points.cpp +++ b/pcbnew/tools/edit_points.cpp @@ -35,11 +35,6 @@ EDIT_POINTS::EDIT_POINTS( EDA_ITEM* aParent ) : } -EDIT_POINTS::~EDIT_POINTS() -{ -} - - EDIT_POINT* EDIT_POINTS::FindPoint( const VECTOR2I& aLocation ) { float size = m_view->ToWorld( EDIT_POINT::POINT_SIZE ); @@ -59,7 +54,7 @@ EDIT_POINT* EDIT_POINTS::FindPoint( const VECTOR2I& aLocation ) void EDIT_POINTS::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const { - aGal->SetFillColor( KIGFX::COLOR4D( 1.0, 1.0, 1.0, 1.0 ) ); // TODO dynamic color depending on parent's color + aGal->SetFillColor( KIGFX::COLOR4D( 1.0, 1.0, 1.0, 1.0 ) ); aGal->SetIsFill( true ); aGal->SetIsStroke( false ); aGal->PushDepth(); diff --git a/pcbnew/tools/edit_points.h b/pcbnew/tools/edit_points.h index e9a444286d..c91bede8ec 100644 --- a/pcbnew/tools/edit_points.h +++ b/pcbnew/tools/edit_points.h @@ -80,10 +80,13 @@ public: void SetConstraint( EDIT_POINT_CONSTRAINT* aConstraint ) { + if( m_constraint ) + delete m_constraint; + m_constraint = aConstraint; } - void ClearConstraint( EDIT_POINT_CONSTRAINT* aConstraint ) + void ClearConstraint() { delete m_constraint; m_constraint = NULL; @@ -94,12 +97,22 @@ public: return m_constraint; } + bool IsConstrained() const + { + return m_constraint != NULL; + } + void ApplyConstraint() { if( m_constraint ) m_constraint->Apply(); } + bool operator==( const EDIT_POINT& aOther ) const + { + return m_point == aOther.m_point; + } + ///> Single point size in pixels static const int POINT_SIZE = 10; @@ -113,7 +126,6 @@ class EDIT_POINTS : public EDA_ITEM { public: EDIT_POINTS( EDA_ITEM* aParent ); - ~EDIT_POINTS(); /** * Function FindPoint @@ -134,7 +146,39 @@ public: void Add( const VECTOR2I& aPoint ) { - m_points.push_back( EDIT_POINT( aPoint ) ); + Add( EDIT_POINT( aPoint ) ); + } + + EDIT_POINT* Previous( const EDIT_POINT& aPoint ) + { + for( unsigned int i = 0; i < m_points.size(); ++i ) + { + if( m_points[i] == aPoint ) + { + if( i == 0 ) + return &m_points[m_points.size() - 1]; + else + return &m_points[i - 1]; + } + } + + return NULL; + } + + EDIT_POINT* Next( const EDIT_POINT& aPoint ) + { + for( unsigned int i = 0; i < m_points.size(); ++i ) + { + if( m_points[i] == aPoint ) + { + if( i == m_points.size() - 1 ) + return &m_points[0]; + else + return &m_points[i + 1]; + } + } + + return NULL; } EDIT_POINT& operator[]( unsigned int aIndex ) @@ -182,8 +226,6 @@ public: EDIT_POINT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) {} - virtual ~EPC_VERTICAL() {}; - virtual void Apply() { VECTOR2I point = m_constrained.GetPosition(); @@ -208,8 +250,6 @@ public: EDIT_POINT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) {} - virtual ~EPC_HORIZONTAL() {}; - virtual void Apply() { VECTOR2I point = m_constrained.GetPosition(); @@ -222,6 +262,31 @@ private: }; +class EPC_45DEGREE : public EDIT_POINT_CONSTRAINT +{ +public: + EPC_45DEGREE ( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : + EDIT_POINT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) + {} + + virtual void Apply() + { + // Current line vector + VECTOR2I lineVector( m_constrained.GetPosition() - m_constrainer.GetPosition() ); + double angle = lineVector.Angle(); + + // Find the closest angle, which is a multiple of 45 degrees + double newAngle = round( angle / ( M_PI / 4.0 ) ) * M_PI / 4.0; + VECTOR2I newLineVector = lineVector.Rotate( newAngle - angle ); + + m_constrained.SetPosition( m_constrainer.GetPosition() + newLineVector ); + } + +private: + const EDIT_POINT& m_constrainer; +}; + + class EPC_CIRCLE : public EDIT_POINT_CONSTRAINT { public: diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index cf78c7d89d..e00d72fe1a 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include "common_actions.h" @@ -96,6 +97,7 @@ public: } default: + points.reset(); break; } @@ -139,19 +141,27 @@ bool POINT_EDITOR::Init() int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) { const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); - KIGFX::VIEW_CONTROLS* controls = getViewControls(); if( selection.Size() == 1 ) { + Activate(); + + KIGFX::VIEW_CONTROLS* controls = getViewControls(); + KIGFX::VIEW* view = getView(); // TODO should be updated on canvas switch? PCB_EDIT_FRAME* editFrame = getEditFrame(); EDA_ITEM* item = selection.items.GetPickedItem( 0 ); + m_editPoints = EDIT_POINTS_FACTORY::Make( item ); - m_toolMgr->GetView()->Add( m_editPoints.get() ); + if( !m_editPoints ) + { + setTransitions(); + return 0; + } + + view->Add( m_editPoints.get() ); m_dragPoint = NULL; bool modified = false; - Activate(); - // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { @@ -196,6 +206,20 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) modified = true; } + if( evt->Modifier( MD_CTRL ) ) // 45 degrees mode + { + if( !m_dragPoint->IsConstrained() ) + { + // Find the previous point to be used as constrainer + EDIT_POINT* constrainer = m_editPoints->Previous( *m_dragPoint ); + m_dragPoint->SetConstraint( new EPC_45DEGREE( *m_dragPoint, *constrainer ) ); + } + } + else + { + m_dragPoint->ClearConstraint(); + } + m_dragPoint->SetPosition( controls->GetCursorPosition() ); m_dragPoint->ApplyConstraint(); updateItem(); @@ -238,14 +262,14 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) { finishItem(); item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - m_toolMgr->GetView()->Remove( m_editPoints.get() ); + view->Remove( m_editPoints.get() ); m_editPoints.reset(); } - } - controls->ShowCursor( false ); - controls->SetAutoPan( false ); - controls->SetSnapping( false ); + controls->ShowCursor( false ); + controls->SetAutoPan( false ); + controls->SetSnapping( false ); + } setTransitions(); From 88a0311afe530ae3ca1264e2eb09a17560eea3c5 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 6 Mar 2014 17:34:04 +0100 Subject: [PATCH 055/134] Added EDIT_LINEs for dragging zone outlines. --- pcbnew/tools/edit_points.cpp | 18 +++++-- pcbnew/tools/edit_points.h | 95 ++++++++++++++++++++++++++++++----- pcbnew/tools/point_editor.cpp | 63 ++++++++++++++++++----- pcbnew/tools/point_editor.h | 3 ++ 4 files changed, 151 insertions(+), 28 deletions(-) diff --git a/pcbnew/tools/edit_points.cpp b/pcbnew/tools/edit_points.cpp index 5e7174e5be..73550418f1 100644 --- a/pcbnew/tools/edit_points.cpp +++ b/pcbnew/tools/edit_points.cpp @@ -39,10 +39,19 @@ EDIT_POINT* EDIT_POINTS::FindPoint( const VECTOR2I& aLocation ) { float size = m_view->ToWorld( EDIT_POINT::POINT_SIZE ); - std::deque::iterator it, itEnd; - for( it = m_points.begin(), itEnd = m_points.end(); it != itEnd; ++it ) + std::deque::iterator pit, pitEnd; + for( pit = m_points.begin(), pitEnd = m_points.end(); pit != pitEnd; ++pit ) { - EDIT_POINT& point = *it; + EDIT_POINT& point = *pit; + + if( point.WithinPoint( aLocation, size ) ) + return &point; + } + + std::deque::iterator lit, litEnd; + for( lit = m_lines.begin(), litEnd = m_lines.end(); lit != litEnd; ++lit ) + { + EDIT_LINE& point = *lit; if( point.WithinPoint( aLocation, size ) ) return &point; @@ -65,5 +74,8 @@ void EDIT_POINTS::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const BOOST_FOREACH( const EDIT_POINT& point, m_points ) aGal->DrawRectangle( point.GetPosition() - size / 2, point.GetPosition() + size / 2 ); + BOOST_FOREACH( const EDIT_LINE& line, m_lines ) + aGal->DrawRectangle( line.GetPosition() - size / 2, line.GetPosition() + size / 2 ); + aGal->PopDepth(); } diff --git a/pcbnew/tools/edit_points.h b/pcbnew/tools/edit_points.h index c91bede8ec..3e5d8ecc9b 100644 --- a/pcbnew/tools/edit_points.h +++ b/pcbnew/tools/edit_points.h @@ -52,21 +52,21 @@ class EDIT_POINT { public: EDIT_POINT( const VECTOR2I& aPoint ) : - m_point( aPoint ), m_constraint( NULL ) {}; + m_position( aPoint ), m_constraint( NULL ) {}; - ~EDIT_POINT() + virtual ~EDIT_POINT() { delete m_constraint; } - const VECTOR2I& GetPosition() const + virtual VECTOR2I GetPosition() const { - return m_point; + return m_position; } - void SetPosition( const VECTOR2I& aPosition ) + virtual void SetPosition( const VECTOR2I& aPosition ) { - m_point = aPosition; + m_position = aPosition; } bool WithinPoint( const VECTOR2I& aPoint, unsigned int aSize ) const @@ -110,18 +110,56 @@ public: bool operator==( const EDIT_POINT& aOther ) const { - return m_point == aOther.m_point; + return m_position == aOther.m_position; } ///> Single point size in pixels static const int POINT_SIZE = 10; -private: - VECTOR2I m_point; +protected: + VECTOR2I m_position; EDIT_POINT_CONSTRAINT* m_constraint; }; +class EDIT_LINE : public EDIT_POINT +{ +public: + EDIT_LINE( EDIT_POINT& aOrigin, EDIT_POINT& aEnd ) : + EDIT_POINT( aOrigin.GetPosition() + ( aEnd.GetPosition() - aOrigin.GetPosition() ) / 2 ), + m_origin( aOrigin ), m_end( aEnd ) + { + } + + virtual VECTOR2I GetPosition() const + { + return m_origin.GetPosition() + ( m_end.GetPosition() - m_origin.GetPosition() ) / 2; + } + + virtual void SetPosition( const VECTOR2I& aPosition ) + { + VECTOR2I difference = aPosition - GetPosition(); + + m_origin.SetPosition( m_origin.GetPosition() + difference ); + m_end.SetPosition( m_end.GetPosition() + difference ); + } + + bool operator==( const EDIT_POINT& aOther ) const + { + return GetPosition() == aOther.GetPosition(); + } + + bool operator==( const EDIT_LINE& aOther ) const + { + return m_origin == aOther.m_origin && m_end == aOther.m_end; + } + +private: + EDIT_POINT& m_origin; + EDIT_POINT& m_end; +}; + + class EDIT_POINTS : public EDA_ITEM { public: @@ -139,14 +177,24 @@ public: return m_parent; } - void Add( const EDIT_POINT& aPoint ) + void AddPoint( const EDIT_POINT& aPoint ) { m_points.push_back( aPoint ); } - void Add( const VECTOR2I& aPoint ) + void AddPoint( const VECTOR2I& aPoint ) { - Add( EDIT_POINT( aPoint ) ); + AddPoint( EDIT_POINT( aPoint ) ); + } + + void AddLine( const EDIT_LINE& aLine ) + { + m_lines.push_back( aLine ); + } + + void AddLine( EDIT_POINT& aOrigin, EDIT_POINT& aEnd ) + { + m_lines.push_back( EDIT_LINE( aOrigin, aEnd ) ); } EDIT_POINT* Previous( const EDIT_POINT& aPoint ) @@ -162,6 +210,17 @@ public: } } + for( unsigned int i = 0; i < m_lines.size(); ++i ) + { + if( m_lines[i] == aPoint ) + { + if( i == 0 ) + return &m_lines[m_lines.size() - 1]; + else + return &m_lines[i - 1]; + } + } + return NULL; } @@ -178,6 +237,17 @@ public: } } + for( unsigned int i = 0; i < m_lines.size(); ++i ) + { + if( m_lines[i] == aPoint ) + { + if( i == m_lines.size() - 1 ) + return &m_lines[0]; + else + return &m_lines[i + 1]; + } + } + return NULL; } @@ -216,6 +286,7 @@ public: private: EDA_ITEM* m_parent; std::deque m_points; + std::deque m_lines; }; diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index e00d72fe1a..6a29061669 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -60,15 +60,15 @@ public: switch( segment->GetShape() ) { case S_SEGMENT: - points->Add( segment->GetStart() ); - points->Add( segment->GetEnd() ); + points->AddPoint( segment->GetStart() ); + points->AddPoint( segment->GetEnd() ); break; case S_ARC: - points->Add( segment->GetCenter() ); // points[0] - points->Add( segment->GetArcStart() ); // points[1] - points->Add( segment->GetArcEnd() ); // points[2] + points->AddPoint( segment->GetCenter() ); // points[0] + points->AddPoint( segment->GetArcStart() ); // points[1] + points->AddPoint( segment->GetArcEnd() ); // points[2] // Set constraints // Arc end has to stay at the same radius as the start @@ -76,8 +76,9 @@ public: break; case S_CIRCLE: - points->Add( segment->GetCenter() ); - points->Add( segment->GetEnd() ); + points->AddPoint( segment->GetCenter() ); + points->AddPoint( segment->GetEnd() ); + break; default: // suppress warnings break; @@ -89,9 +90,17 @@ public: case PCB_ZONE_AREA_T: { const CPolyLine* outline = static_cast( aItem )->Outline(); + int cornersCount = outline->GetCornersCount(); - for( int i = 0; i < outline->GetCornersCount(); ++i ) - points->Add( outline->GetPos( i ) ); + for( int i = 0; i < cornersCount; ++i ) + points->AddPoint( outline->GetPos( i ) ); + + // Lines have to be added after creating edit points, so they use EDIT_POINT references + for( int i = 0; i < cornersCount - 1; ++i ) + points->AddLine( (*points)[i], (*points)[i + 1] ); + + // The one missing line + points->AddLine( (*points)[cornersCount - 1], (*points)[0] ); break; } @@ -147,7 +156,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) Activate(); KIGFX::VIEW_CONTROLS* controls = getViewControls(); - KIGFX::VIEW* view = getView(); // TODO should be updated on canvas switch? + KIGFX::VIEW* view = getView(); PCB_EDIT_FRAME* editFrame = getEditFrame(); EDA_ITEM* item = selection.items.GetPickedItem( 0 ); @@ -210,9 +219,9 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) { if( !m_dragPoint->IsConstrained() ) { - // Find the previous point to be used as constrainer - EDIT_POINT* constrainer = m_editPoints->Previous( *m_dragPoint ); - m_dragPoint->SetConstraint( new EPC_45DEGREE( *m_dragPoint, *constrainer ) ); + // Find a proper constraining point for 45 degrees mode + EDIT_POINT constrainer = get45DegConstrainer(); + m_dragPoint->SetConstraint( new EPC_45DEGREE( *m_dragPoint, constrainer ) ); } } else @@ -446,3 +455,31 @@ void POINT_EDITOR::updatePoints() const break; } } + + +EDIT_POINT POINT_EDITOR::get45DegConstrainer() const +{ + EDA_ITEM* item = m_editPoints->GetParent(); + + if( item->Type() == PCB_LINE_T ) + { + const DRAWSEGMENT* segment = static_cast( item ); + { + switch( segment->GetShape() ) + { + case S_SEGMENT: + return *( m_editPoints->Next( *m_dragPoint ) ); // select the other end of line + + case S_ARC: + case S_CIRCLE: + return (*m_editPoints)[0]; // center + + default: // suppress warnings + break; + } + } + } + + // In any other case we may align item to the current cursor position. + return EDIT_POINT( getViewControls()->GetCursorPosition() ); +} diff --git a/pcbnew/tools/point_editor.h b/pcbnew/tools/point_editor.h index 81b55131ba..b465966873 100644 --- a/pcbnew/tools/point_editor.h +++ b/pcbnew/tools/point_editor.h @@ -75,6 +75,9 @@ private: ///> Updates edit points with item's points. void updatePoints() const; + ///> Returns a point that should be used as a constrainer for 45 degrees mode. + EDIT_POINT get45DegConstrainer() const; + ///> Sets up handlers for various events. void setTransitions() { From 3927c667cc5fee24912d83e9f5e142648c20b19e Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 7 Mar 2014 10:26:33 +0100 Subject: [PATCH 056/134] Added documentation. Moved some functions from .h to .cpp files. --- pcbnew/tools/edit_points.cpp | 96 ++++++++++ pcbnew/tools/edit_points.h | 334 +++++++++++++++++++++++----------- pcbnew/tools/point_editor.cpp | 3 +- pcbnew/tools/point_editor.h | 1 - 4 files changed, 321 insertions(+), 113 deletions(-) diff --git a/pcbnew/tools/edit_points.cpp b/pcbnew/tools/edit_points.cpp index 73550418f1..39102b470a 100644 --- a/pcbnew/tools/edit_points.cpp +++ b/pcbnew/tools/edit_points.cpp @@ -29,6 +29,17 @@ #include +bool EDIT_POINT::WithinPoint( const VECTOR2I& aPoint, unsigned int aSize ) const +{ + // Corners of the square + VECTOR2I topLeft = GetPosition() - aSize; + VECTOR2I bottomRight = GetPosition() + aSize; + + return ( aPoint.x > topLeft.x && aPoint.y > topLeft.y && + aPoint.x < bottomRight.x && aPoint.y < bottomRight.y ); +} + + EDIT_POINTS::EDIT_POINTS( EDA_ITEM* aParent ) : EDA_ITEM( NOT_USED ), m_parent( aParent ) { @@ -61,6 +72,62 @@ EDIT_POINT* EDIT_POINTS::FindPoint( const VECTOR2I& aLocation ) } +EDIT_POINT* EDIT_POINTS::Previous( const EDIT_POINT& aPoint ) +{ + for( unsigned int i = 0; i < m_points.size(); ++i ) + { + if( m_points[i] == aPoint ) + { + if( i == 0 ) + return &m_points[m_points.size() - 1]; + else + return &m_points[i - 1]; + } + } + + for( unsigned int i = 0; i < m_lines.size(); ++i ) + { + if( m_lines[i] == aPoint ) + { + if( i == 0 ) + return &m_lines[m_lines.size() - 1]; + else + return &m_lines[i - 1]; + } + } + + return NULL; +} + + +EDIT_POINT* EDIT_POINTS::Next( const EDIT_POINT& aPoint ) +{ + for( unsigned int i = 0; i < m_points.size(); ++i ) + { + if( m_points[i] == aPoint ) + { + if( i == m_points.size() - 1 ) + return &m_points[0]; + else + return &m_points[i + 1]; + } + } + + for( unsigned int i = 0; i < m_lines.size(); ++i ) + { + if( m_lines[i] == aPoint ) + { + if( i == m_lines.size() - 1 ) + return &m_lines[0]; + else + return &m_lines[i + 1]; + } + } + + return NULL; +} + + void EDIT_POINTS::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const { aGal->SetFillColor( KIGFX::COLOR4D( 1.0, 1.0, 1.0, 1.0 ) ); @@ -79,3 +146,32 @@ void EDIT_POINTS::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const aGal->PopDepth(); } + + +void EPC_45DEGREE::Apply() +{ + // Current line vector + VECTOR2I lineVector( m_constrained.GetPosition() - m_constrainer.GetPosition() ); + double angle = lineVector.Angle(); + + // Find the closest angle, which is a multiple of 45 degrees + double newAngle = round( angle / ( M_PI / 4.0 ) ) * M_PI / 4.0; + VECTOR2I newLineVector = lineVector.Rotate( newAngle - angle ); + + m_constrained.SetPosition( m_constrainer.GetPosition() + newLineVector ); +} + + +void EPC_CIRCLE::Apply() +{ + VECTOR2I centerToEnd = m_end.GetPosition() - m_center.GetPosition(); + VECTOR2I centerToPoint = m_constrained.GetPosition() - m_center.GetPosition(); + + int radius = centerToEnd.EuclideanNorm(); + double angle = centerToPoint.Angle(); + + VECTOR2I newLine( radius, 0 ); + newLine = newLine.Rotate( angle ); + + m_constrained.SetPosition( m_center.GetPosition() + newLine ); +} diff --git a/pcbnew/tools/edit_points.h b/pcbnew/tools/edit_points.h index 3e5d8ecc9b..5aabb41117 100644 --- a/pcbnew/tools/edit_points.h +++ b/pcbnew/tools/edit_points.h @@ -34,23 +34,50 @@ class EDIT_POINT; +/** + * Class EDIT_POINT_CONSTRAINT + * + * Allows to describe constraints between two points. After the constrained point is changed, + * Apply() has to be called to fix its coordinates according to the implemented constraint. + */ class EDIT_POINT_CONSTRAINT { public: + /** + * Constructor + * + * @param aConstrained is EDIT_POINT to which the constraint is applied. + */ EDIT_POINT_CONSTRAINT( EDIT_POINT& aConstrained ) : m_constrained( aConstrained ) {}; + virtual ~EDIT_POINT_CONSTRAINT() {}; + /** + * Function Apply() + * + * Corrects coordinates of the constrained point. + */ virtual void Apply() = 0; protected: - EDIT_POINT& m_constrained; + EDIT_POINT& m_constrained; ///< Point that is constrained by rules implemented by Apply() }; -// TODO docs +/** + * Class EDIT_POINT + * + * Represents a single point that can be used for modifying items. It is directly related to one + * of points in a graphical item (e.g. vertex of a zone or center of a circle). + */ class EDIT_POINT { public: + /** + * Constructor + * + * @param aPoint stores coordinates for EDIT_POINT. + */ EDIT_POINT( const VECTOR2I& aPoint ) : m_position( aPoint ), m_constraint( NULL ) {}; @@ -59,25 +86,44 @@ public: delete m_constraint; } + /** + * Function GetPosition() + * + * Returns coordinates of an EDIT_POINT. Note that it may be different than coordinates of + * a graphical item that is bound to the EDIT_POINT. + */ virtual VECTOR2I GetPosition() const { return m_position; } + /** + * Function SetPosition() + * + * Sets new coordinates for an EDIT_POINT. It does not change the coordinates of a graphical + * item. + * @param aPosition are new coordinates. + */ virtual void SetPosition( const VECTOR2I& aPosition ) { m_position = aPosition; } - bool WithinPoint( const VECTOR2I& aPoint, unsigned int aSize ) const - { - VECTOR2I topLeft = GetPosition() - aSize; - VECTOR2I bottomRight = GetPosition() + aSize; - - return ( aPoint.x > topLeft.x && aPoint.y > topLeft.y && - aPoint.x < bottomRight.x && aPoint.y < bottomRight.y ); - } + /** + * Function WithinPoint() + * + * Checks if given point is within a square centered in the EDIT_POINT position. + * @param aPoint is point to be checked. + * @param aSize is length of the square side. + */ + bool WithinPoint( const VECTOR2I& aPoint, unsigned int aSize ) const; + /** + * Function SetConstraint() + * + * Sets a constraint for and EDIT_POINT. + * @param aConstraint is the constraint to be set. + */ void SetConstraint( EDIT_POINT_CONSTRAINT* aConstraint ) { if( m_constraint ) @@ -86,22 +132,33 @@ public: m_constraint = aConstraint; } + /** + * Function ClearConstraint() + * + * Removes previously set constraint. + */ void ClearConstraint() { delete m_constraint; m_constraint = NULL; } - EDIT_POINT_CONSTRAINT* GetConstraint() const - { - return m_constraint; - } - + /** + * Function IsConstrained() + * + * Checks if point is constrained. + * @return True is point is constrained, false otherwise. + */ bool IsConstrained() const { return m_constraint != NULL; } + /** + * Function ApplyConstraint() + * + * Corrects coordinates of an EDIT_POINT by applying previously set constraint. + */ void ApplyConstraint() { if( m_constraint ) @@ -117,25 +174,40 @@ public: static const int POINT_SIZE = 10; protected: - VECTOR2I m_position; - EDIT_POINT_CONSTRAINT* m_constraint; + VECTOR2I m_position; ///< Position of EDIT_POINT + EDIT_POINT_CONSTRAINT* m_constraint; ///< Constraint for the point, NULL if none }; +/** + * Class EDIT_LINE + * + * Represents a line connecting two EDIT_POINTs. That allows to move them both by dragging the + * EDIT_POINT in the middle. As it uses references to EDIT_POINTs, all coordinates are + * automatically synchronized. + */ class EDIT_LINE : public EDIT_POINT { public: + /** + * Constructor + * + * @param aOrigin is the origin of EDIT_LINE. + * @param aEnd is the end of EDIT_LINE. + */ EDIT_LINE( EDIT_POINT& aOrigin, EDIT_POINT& aEnd ) : EDIT_POINT( aOrigin.GetPosition() + ( aEnd.GetPosition() - aOrigin.GetPosition() ) / 2 ), m_origin( aOrigin ), m_end( aEnd ) { } + ///> @copydoc EDIT_POINT::GetPosition() virtual VECTOR2I GetPosition() const { return m_origin.GetPosition() + ( m_end.GetPosition() - m_origin.GetPosition() ) / 2; } + ///> @copydoc EDIT_POINT::GetPosition() virtual void SetPosition( const VECTOR2I& aPosition ) { VECTOR2I difference = aPosition - GetPosition(); @@ -155,101 +227,110 @@ public: } private: - EDIT_POINT& m_origin; - EDIT_POINT& m_end; + EDIT_POINT& m_origin; ///< Origin point for a line + EDIT_POINT& m_end; ///< End point for a line }; +/** + * Class EDIT_POINTS + * + * EDIT_POINTS is a VIEW_ITEM that manages EDIT_POINTs and EDIT_LINEs and draws them. + */ class EDIT_POINTS : public EDA_ITEM { public: + /** + * Constructor. + * + * @param aParent is the item to which EDIT_POINTs are related. + */ EDIT_POINTS( EDA_ITEM* aParent ); /** - * Function FindPoint + * Function FindPoint() + * * Returns a point that is at given coordinates or NULL if there is no such point. * @param aLocation is the location for searched point. */ EDIT_POINT* FindPoint( const VECTOR2I& aLocation ); + /** + * Function GetParent() + * + * Returns parent of the EDIT_POINTS. + */ EDA_ITEM* GetParent() const { return m_parent; } + /** + * Function AddPoint() + * + * Adds an EDIT_POINT. + * @param aPoint is the new point. + */ void AddPoint( const EDIT_POINT& aPoint ) { m_points.push_back( aPoint ); } + /** + * Function AddPoint() + * + * Adds an EDIT_POINT. + * @param aPoint are coordinates of the new point. + */ void AddPoint( const VECTOR2I& aPoint ) { AddPoint( EDIT_POINT( aPoint ) ); } + /** + * Function AddLine() + * + * Adds an EDIT_LINE. + * @param aLine is the new line. + */ void AddLine( const EDIT_LINE& aLine ) { m_lines.push_back( aLine ); } + /** + * Function AddLine() + * + * Adds an EDIT_LINE. + * @param aOrigin is the origin for a new line. + * @param aEnd is the end for a new line. + */ void AddLine( EDIT_POINT& aOrigin, EDIT_POINT& aEnd ) { m_lines.push_back( EDIT_LINE( aOrigin, aEnd ) ); } - EDIT_POINT* Previous( const EDIT_POINT& aPoint ) - { - for( unsigned int i = 0; i < m_points.size(); ++i ) - { - if( m_points[i] == aPoint ) - { - if( i == 0 ) - return &m_points[m_points.size() - 1]; - else - return &m_points[i - 1]; - } - } + /** + * Function Previous() + * + * Returns the point that is after the given point in the list. + * @param aPoint is the point that is supposed to be preceding the searched point. + * @return The point following aPoint in the list. If aPoint is the first in + * the list, the last from the list will be returned. If there are no points at all, NULL + * is returned. + */ + EDIT_POINT* Previous( const EDIT_POINT& aPoint ); - for( unsigned int i = 0; i < m_lines.size(); ++i ) - { - if( m_lines[i] == aPoint ) - { - if( i == 0 ) - return &m_lines[m_lines.size() - 1]; - else - return &m_lines[i - 1]; - } - } - - return NULL; - } - - EDIT_POINT* Next( const EDIT_POINT& aPoint ) - { - for( unsigned int i = 0; i < m_points.size(); ++i ) - { - if( m_points[i] == aPoint ) - { - if( i == m_points.size() - 1 ) - return &m_points[0]; - else - return &m_points[i + 1]; - } - } - - for( unsigned int i = 0; i < m_lines.size(); ++i ) - { - if( m_lines[i] == aPoint ) - { - if( i == m_lines.size() - 1 ) - return &m_lines[0]; - else - return &m_lines[i + 1]; - } - } - - return NULL; - } + /** + * Function Next() + * + * Returns the point that is before the given point in the list. + * @param aPoint is the point that is supposed to be following the searched point. + * @return The point preceding aPoint in the list. If aPoint is the last in + * the list, the first point from the list will be returned. If there are no points at all, + * NULL is returned. + */ + EDIT_POINT* Next( const EDIT_POINT& aPoint ); EDIT_POINT& operator[]( unsigned int aIndex ) { @@ -261,18 +342,26 @@ public: return m_points[aIndex]; } + /** + * Function Size() + * + * Returns number of stored points. + */ unsigned int Size() const { return m_points.size(); } + ///> @copydoc VIEW_ITEM::ViewBBox() virtual const BOX2I ViewBBox() const { return m_parent->ViewBBox(); } + ///> @copydoc VIEW_ITEM::ViewDraw() virtual void ViewDraw( int aLayer, KIGFX::GAL* aGal ) const; + ///> @copydoc VIEW_ITEM::ViewGetLayers() virtual void ViewGetLayers( int aLayers[], int& aCount ) const { aCount = 1; @@ -284,19 +373,31 @@ public: } private: - EDA_ITEM* m_parent; - std::deque m_points; - std::deque m_lines; + EDA_ITEM* m_parent; ///< Parent of the EDIT_POINTs + std::deque m_points; ///< EDIT_POINTs for modifying m_parent + std::deque m_lines; ///< EDIT_LINEs for modifying m_parent }; +/** + * Class EPC_VERTICAL. + * + * EDIT_POINT_CONSTRAINT that imposes a constraint that two points have to have the same X coordinate. + */ class EPC_VERTICAL : public EDIT_POINT_CONSTRAINT { public: - EPC_VERTICAL( EDIT_POINT& aConstrained, EDIT_POINT& aConstrainer ) : + /** + * Constructor. + * + * @param aConstrained is the point that is put under constrain. + * @param aConstrainer is the point that is the source of the constrain. + */ + EPC_VERTICAL( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : EDIT_POINT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) {} + ///> @copydoc EDIT_POINT_CONSTRAINT::Apply() virtual void Apply() { VECTOR2I point = m_constrained.GetPosition(); @@ -304,23 +405,30 @@ public: m_constrained.SetPosition( point ); } - virtual std::list GetConstrainers() const - { - return std::list( 1, &m_constrainer ); - } - private: - EDIT_POINT& m_constrainer; + const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint. }; +/** + * Class EPC_HORIZONTAL. + * + * EDIT_POINT_CONSTRAINT that imposes a constraint that two points have to have the same Y coordinate. + */ class EPC_HORIZONTAL : public EDIT_POINT_CONSTRAINT { public: + /** + * Constructor. + * + * @param aConstrained is the point that is put under constrain. + * @param aConstrainer is the point that is the source of the constrain. + */ EPC_HORIZONTAL( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : EDIT_POINT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) {} + ///> @copydoc EDIT_POINT_CONSTRAINT::Apply() virtual void Apply() { VECTOR2I point = m_constrained.GetPosition(); @@ -329,60 +437,64 @@ public: } private: - const EDIT_POINT& m_constrainer; + const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint. }; +/** + * Class EPC_45DEGREE + * + * EDIT_POINT_CONSTRAINT that imposes a constraint that two to be located at angle of 45 degree + * multiplicity. + */ class EPC_45DEGREE : public EDIT_POINT_CONSTRAINT { public: + /** + * Constructor. + * + * @param aConstrained is the point that is put under constrain. + * @param aConstrainer is the point that is the source of the constrain. + */ EPC_45DEGREE ( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : EDIT_POINT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) {} - virtual void Apply() - { - // Current line vector - VECTOR2I lineVector( m_constrained.GetPosition() - m_constrainer.GetPosition() ); - double angle = lineVector.Angle(); - - // Find the closest angle, which is a multiple of 45 degrees - double newAngle = round( angle / ( M_PI / 4.0 ) ) * M_PI / 4.0; - VECTOR2I newLineVector = lineVector.Rotate( newAngle - angle ); - - m_constrained.SetPosition( m_constrainer.GetPosition() + newLineVector ); - } + ///> @copydoc EDIT_POINT_CONSTRAINT::Apply() + virtual void Apply(); private: - const EDIT_POINT& m_constrainer; + const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint. }; +/** + * Class EPC_CIRCLE. + * + * EDIT_POINT_CONSTRAINT that imposes a constraint that a point has to lie on a circle. + */ class EPC_CIRCLE : public EDIT_POINT_CONSTRAINT { public: + /** + * Constructor. + * + * @param aConstrained is the point that is put under constrain. + * @parama aCenter is the point that is the center of the circle. + * @parama aEnd is the point that decides on the radius of the circle. + */ EPC_CIRCLE( EDIT_POINT& aConstrained, const EDIT_POINT& aCenter, const EDIT_POINT& aEnd ) : EDIT_POINT_CONSTRAINT( aConstrained ), m_center( aCenter ), m_end( aEnd ) {} - virtual ~EPC_CIRCLE() {}; - - virtual void Apply() - { - VECTOR2I centerToEnd = m_end.GetPosition() - m_center.GetPosition(); - VECTOR2I centerToPoint = m_constrained.GetPosition() - m_center.GetPosition(); - - int radius = centerToEnd.EuclideanNorm(); - double angle = centerToPoint.Angle(); - - VECTOR2I newLine( radius, 0 ); - newLine = newLine.Rotate( angle ); - - m_constrained.SetPosition( m_center.GetPosition() + newLine ); - } + ///> @copydoc EDIT_POINT_CONSTRAINT::Apply() + virtual void Apply(); private: + ///> Point that imposes the constraint (center of the circle). const EDIT_POINT& m_center; + + ///> Point that imposes the constraint (decides on the radius of the circle). const EDIT_POINT& m_end; }; diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 6a29061669..2e87717411 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -159,6 +159,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) KIGFX::VIEW* view = getView(); PCB_EDIT_FRAME* editFrame = getEditFrame(); EDA_ITEM* item = selection.items.GetPickedItem( 0 ); + EDIT_POINT constrainer( VECTOR2I( 0, 0 ) ); m_editPoints = EDIT_POINTS_FACTORY::Make( item ); if( !m_editPoints ) @@ -220,7 +221,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) if( !m_dragPoint->IsConstrained() ) { // Find a proper constraining point for 45 degrees mode - EDIT_POINT constrainer = get45DegConstrainer(); + constrainer = get45DegConstrainer(); m_dragPoint->SetConstraint( new EPC_45DEGREE( *m_dragPoint, constrainer ) ); } } diff --git a/pcbnew/tools/point_editor.h b/pcbnew/tools/point_editor.h index b465966873..f0a9405e01 100644 --- a/pcbnew/tools/point_editor.h +++ b/pcbnew/tools/point_editor.h @@ -37,7 +37,6 @@ class SELECTION_TOOL; * * Tool that displays edit points allowing to modify items by dragging the points. */ - class POINT_EDITOR : public TOOL_INTERACTIVE { public: From c4dbdbf9d3a838ebbcc1ff1c3dfa5473749c7051 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 10 Mar 2014 10:18:48 +0100 Subject: [PATCH 057/134] Removed unnecessary casting. --- common/worksheet_viewitem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/worksheet_viewitem.cpp b/common/worksheet_viewitem.cpp index ba4185f8af..e261b3eff9 100644 --- a/common/worksheet_viewitem.cpp +++ b/common/worksheet_viewitem.cpp @@ -189,7 +189,7 @@ void WORKSHEET_VIEWITEM::draw( const WS_DRAW_ITEM_TEXT* aItem, GAL* aGal ) const aGal->SetStrokeColor( COLOR4D( aItem->GetColor() ) ); aGal->SetLineWidth( aItem->GetThickness() ); aGal->SetTextAttributes( aItem ); - aGal->StrokeText( std::wstring( aItem->GetText().wc_str() ), position, 0.0 ); + aGal->StrokeText( aItem->GetText(), position, 0.0 ); } From ecb3aebce366100c3f5c0007cb132810d122cc1e Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 10 Mar 2014 16:01:15 +0100 Subject: [PATCH 058/134] Fixed a bug caused by removed VIEW_ITEMs that were marked for updating. --- common/view/view.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/common/view/view.cpp b/common/view/view.cpp index 1baa2599fc..14792fae0e 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -114,6 +114,14 @@ void VIEW::Remove( VIEW_ITEM* aItem ) if( m_dynamic ) aItem->m_view = NULL; + if( aItem->viewRequiredUpdate() != VIEW_ITEM::NONE ) // prevent from updating a removed item + { + std::vector::iterator item = std::find( m_needsUpdate.begin(), m_needsUpdate.end(), aItem ); + + if( item != m_needsUpdate.end() ) + m_needsUpdate.erase( item ); + } + int layers[VIEW::VIEW_MAX_LAYERS], layers_count; aItem->getLayers( layers, layers_count ); From 5ac6579a87f92faf89283dc55a60ee2a414061a6 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 10 Mar 2014 16:25:40 +0100 Subject: [PATCH 059/134] Cursor snaps to EDIT_POINTs. Added POINT_EDITOR::isModified(). --- pcbnew/tools/edit_points.h | 2 +- pcbnew/tools/point_editor.cpp | 10 ++++++---- pcbnew/tools/point_editor.h | 6 ++++++ 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/pcbnew/tools/edit_points.h b/pcbnew/tools/edit_points.h index 5aabb41117..bdcf5ec55a 100644 --- a/pcbnew/tools/edit_points.h +++ b/pcbnew/tools/edit_points.h @@ -456,7 +456,7 @@ public: * @param aConstrained is the point that is put under constrain. * @param aConstrainer is the point that is the source of the constrain. */ - EPC_45DEGREE ( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : + EPC_45DEGREE( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : EDIT_POINT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) {} diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 2e87717411..4415aae5a0 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -62,7 +62,6 @@ public: case S_SEGMENT: points->AddPoint( segment->GetStart() ); points->AddPoint( segment->GetEnd() ); - break; case S_ARC: @@ -194,12 +193,14 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) controls->ShowCursor( true ); controls->SetAutoPan( true ); controls->SetSnapping( true ); + controls->ForceCursorPosition( true, point->GetPosition() ); } else { controls->ShowCursor( false ); controls->SetAutoPan( false ); controls->SetSnapping( false ); + controls->ForceCursorPosition( false ); } } @@ -213,6 +214,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) // Save items, so changes can be undone editFrame->OnModify(); editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED ); + controls->ForceCursorPosition( false ); modified = true; } @@ -299,11 +301,11 @@ void POINT_EDITOR::updateItem() const switch( segment->GetShape() ) { case S_SEGMENT: - if( &(*m_editPoints)[0] == m_dragPoint ) + if( isModified( (*m_editPoints)[0] ) ) segment->SetStart( wxPoint( (*m_editPoints)[0].GetPosition().x, (*m_editPoints)[0].GetPosition().y ) ); - else if( &(*m_editPoints)[1] == m_dragPoint ) + else if( isModified( (*m_editPoints)[1] ) ) segment->SetEnd( wxPoint( (*m_editPoints)[1].GetPosition().x, (*m_editPoints)[1].GetPosition().y ) ); @@ -351,7 +353,7 @@ void POINT_EDITOR::updateItem() const const VECTOR2I& center = (*m_editPoints)[0].GetPosition(); const VECTOR2I& end = (*m_editPoints)[1].GetPosition(); - if( m_dragPoint == &(*m_editPoints)[0] ) + if( isModified( (*m_editPoints)[0] ) ) { wxPoint moveVector = wxPoint( center.x, center.y ) - segment->GetCenter(); segment->Move( moveVector ); diff --git a/pcbnew/tools/point_editor.h b/pcbnew/tools/point_editor.h index f0a9405e01..054d6b444e 100644 --- a/pcbnew/tools/point_editor.h +++ b/pcbnew/tools/point_editor.h @@ -74,6 +74,12 @@ private: ///> Updates edit points with item's points. void updatePoints() const; + ///> Returns true if aPoint is the currently modified point. + inline bool isModified( const EDIT_POINT& aPoint ) const + { + return m_dragPoint == &aPoint; + } + ///> Returns a point that should be used as a constrainer for 45 degrees mode. EDIT_POINT get45DegConstrainer() const; From 54bf21768cf40748126db24cc076de4135e661e6 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 11 Mar 2014 10:58:58 +0100 Subject: [PATCH 060/134] Added a few settings to make the layer settings more similar to KiCad defaults (moved vias to VIA_THROUGH_VISIBLE, added a few rules for required layers). --- common/view/view.cpp | 13 ++++++++++++- pcbnew/basepcbframe.cpp | 7 +++++-- pcbnew/class_track.cpp | 2 +- pcbnew/pcb_painter.cpp | 12 ++++++------ pcbnew/pcbframe.cpp | 4 ++-- pcbnew/tools/drawing_tool.cpp | 4 ++-- 6 files changed, 28 insertions(+), 14 deletions(-) diff --git a/common/view/view.cpp b/common/view/view.cpp index 14792fae0e..3cf57a210b 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -765,6 +765,11 @@ void VIEW::ClearTargets() void VIEW::Redraw() { +#ifdef PROFILE + prof_counter totalRealTime; + prof_start( &totalRealTime ); +#endif /* PROFILE */ + VECTOR2D screenSize = m_gal->GetScreenPixelSize(); BOX2I rect( ToWorld( VECTOR2D( 0, 0 ) ), ToWorld( screenSize ) - ToWorld( VECTOR2D( 0, 0 ) ) ); @@ -776,6 +781,12 @@ void VIEW::Redraw() markTargetClean( TARGET_CACHED ); markTargetClean( TARGET_NONCACHED ); markTargetClean( TARGET_OVERLAY ); + +#ifdef PROFILE + prof_end( &totalRealTime ); + + wxLogDebug( wxT( "Redraw: %.1f ms" ), totalRealTime.msecs() ); +#endif /* PROFILE */ } @@ -971,7 +982,7 @@ bool VIEW::areRequiredLayersEnabled( int aLayerId ) const it_end = m_layers.at( aLayerId ).requiredLayers.end(); it != it_end; ++it ) { // That is enough if just one layer is not enabled - if( !m_layers.at( *it ).visible ) + if( !m_layers.at( *it ).visible || !areRequiredLayersEnabled( *it ) ) return false; } diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index 957ac978ab..7adc4ca473 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -83,7 +83,7 @@ const LAYER_NUM PCB_BASE_FRAME::GAL_LAYER_ORDER[] = ITEM_GAL_LAYER( RATSNEST_VISIBLE ), ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), - ITEM_GAL_LAYER( VIAS_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ), + ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ), NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE ), ITEM_GAL_LAYER( PAD_FR_VISIBLE ), SOLDERMASK_N_FRONT, NETNAMES_GAL_LAYER( LAYER_16_NETNAMES_VISIBLE ), LAYER_N_FRONT, @@ -798,7 +798,7 @@ void PCB_BASE_FRAME::LoadSettings() } // Some more required layers settings - view->SetRequired( ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( VIAS_VISIBLE ) ); + view->SetRequired( ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ) ); view->SetRequired( ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ) ); view->SetRequired( NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ) ); @@ -812,6 +812,9 @@ void PCB_BASE_FRAME::LoadSettings() view->SetRequired( SOLDERPASTE_N_BACK, ITEM_GAL_LAYER( PAD_BK_VISIBLE ) ); view->SetRequired( SOLDERMASK_N_BACK, ITEM_GAL_LAYER( PAD_BK_VISIBLE ) ); + view->SetRequired( ITEM_GAL_LAYER( PAD_FR_VISIBLE ), ITEM_GAL_LAYER( MOD_FR_VISIBLE ) ); + view->SetRequired( ITEM_GAL_LAYER( PAD_BK_VISIBLE ), ITEM_GAL_LAYER( MOD_BK_VISIBLE ) ); + view->SetLayerTarget( ITEM_GAL_LAYER( GP_OVERLAY ), KIGFX::TARGET_OVERLAY ); view->SetLayerTarget( ITEM_GAL_LAYER( RATSNEST_VISIBLE ), KIGFX::TARGET_OVERLAY ); diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index 6221756253..93288465c2 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -981,7 +981,7 @@ void SEGVIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, void SEGVIA::ViewGetLayers( int aLayers[], int& aCount ) const { // Just show it on common via & via holes layers - aLayers[0] = ITEM_GAL_LAYER( VIAS_VISIBLE ); + aLayers[0] = ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ); aLayers[1] = ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ); aCount = 2; } diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 2587f7f65e..40576eba42 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -69,7 +69,7 @@ void PCB_RENDER_SETTINGS::ImportLegacyColors( COLORS_DESIGN_SETTINGS* aSettings // Default colors for specific layers m_layerColors[ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE )] = COLOR4D( 0.5, 0.4, 0.0, 1.0 ); m_layerColors[ITEM_GAL_LAYER( PADS_HOLES_VISIBLE )] = COLOR4D( 0.0, 0.5, 0.5, 1.0 ); - m_layerColors[ITEM_GAL_LAYER( VIAS_VISIBLE )] = COLOR4D( 0.7, 0.7, 0.7, 1.0 ); + m_layerColors[ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE )] = COLOR4D( 0.7, 0.7, 0.7, 1.0 ); m_layerColors[ITEM_GAL_LAYER( PADS_VISIBLE )] = COLOR4D( 0.7, 0.7, 0.7, 1.0 ); m_layerColors[NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE )] = COLOR4D( 0.8, 0.8, 0.8, 0.7 ); m_layerColors[NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE )] = COLOR4D( 0.8, 0.8, 0.8, 0.7 ); @@ -94,9 +94,9 @@ void PCB_RENDER_SETTINGS::LoadDisplayOptions( const DISPLAY_OPTIONS& aOptions ) m_padNumbers = aOptions.DisplayPadNum; // Whether to draw tracks, vias & pads filled or as outlines - m_sketchModeSelect[PADS_VISIBLE] = !aOptions.DisplayPadFill; - m_sketchModeSelect[VIAS_VISIBLE] = !aOptions.DisplayViaFill; - m_sketchModeSelect[TRACKS_VISIBLE] = !aOptions.DisplayPcbTrackFill; + m_sketchModeSelect[PADS_VISIBLE] = !aOptions.DisplayPadFill; + m_sketchModeSelect[VIA_THROUGH_VISIBLE] = !aOptions.DisplayViaFill; + m_sketchModeSelect[TRACKS_VISIBLE] = !aOptions.DisplayPcbTrackFill; switch( aOptions.DisplayNetNamesMode ) { @@ -328,7 +328,7 @@ void PCB_PAINTER::draw( const SEGVIA* aVia, int aLayer ) double radius; // Choose drawing settings depending on if we are drawing via's pad or hole - if( aLayer == ITEM_GAL_LAYER( VIAS_VISIBLE ) ) + if( aLayer == ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ) ) { radius = aVia->GetWidth() / 2.0; } @@ -341,7 +341,7 @@ void PCB_PAINTER::draw( const SEGVIA* aVia, int aLayer ) const COLOR4D& color = m_pcbSettings->GetColor( aVia, aLayer ); - if( m_pcbSettings->m_sketchModeSelect[VIAS_VISIBLE] ) + if( m_pcbSettings->m_sketchModeSelect[VIA_THROUGH_VISIBLE] ) { // Outline mode m_gal->SetIsFill( false ); diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 9758f82f6f..0d56f1a634 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -879,7 +879,7 @@ void PCB_EDIT_FRAME::setHighContrastLayer( LAYER_NUM aLayer ) // fixme do not like the idea of storing the list of layers here, // should be done in some other way I guess.. LAYER_NUM layers[] = { - GetNetnameLayer( aLayer ), ITEM_GAL_LAYER( VIAS_VISIBLE ), + GetNetnameLayer( aLayer ), ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ), ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ), ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ), ITEM_GAL_LAYER( GP_OVERLAY ), ITEM_GAL_LAYER( RATSNEST_VISIBLE ) @@ -919,7 +919,7 @@ void PCB_EDIT_FRAME::SetTopLayer( LAYER_NUM aLayer ) // fixme do not like the idea of storing the list of layers here, // should be done in some other way I guess.. LAYER_NUM layers[] = { - GetNetnameLayer( aLayer ), ITEM_GAL_LAYER( VIAS_VISIBLE ), + GetNetnameLayer( aLayer ), ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ), ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ), ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ), ITEM_GAL_LAYER( GP_OVERLAY ), ITEM_GAL_LAYER( RATSNEST_VISIBLE ), DRAW_N diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index a1eddfca16..41bb93340a 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -80,8 +80,8 @@ int DRAWING_TOOL::DrawCircle( TOOL_EVENT& aEvent ) int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) { - bool clockwise = true; // drawing direction of the arc - double startAngle; // angle of the first arc line + bool clockwise = true; // drawing direction of the arc + double startAngle = 0.0f; // angle of the first arc line VECTOR2I cursorPos = m_controls->GetCursorPosition(); DRAWSEGMENT* arc = NULL; From d2ed2efc85f7b48c459670ecd32a4b32f331edf5 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 11 Mar 2014 14:50:53 +0100 Subject: [PATCH 061/134] Workarounded SWIG problems (does not support nested C++ classes, more on the subject: http://www.swig.org/Doc1.3/SWIGPlus.html#SWIGPlus_nested_classes). --- pcbnew/class_board.h | 2 ++ pcbnew/class_netinfo.h | 15 ++++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h index cac0f66ffd..92058d0af6 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -871,6 +871,7 @@ public: m_NetInfo.AppendNet( aNewNet ); } +#ifndef SWIG /** * Function BeginNets * @return iterator to the first element of the NETINFO_ITEMs list @@ -888,6 +889,7 @@ public: { return m_NetInfo.end(); } +#endif /** * Function GetNetCount diff --git a/pcbnew/class_netinfo.h b/pcbnew/class_netinfo.h index f566926fcc..64e6e9f8b8 100644 --- a/pcbnew/class_netinfo.h +++ b/pcbnew/class_netinfo.h @@ -145,6 +145,7 @@ public: */ int Translate( int aNetCode ) const; +#ifndef SWIG ///> Wrapper class, so you can iterate through NETINFO_ITEM*s, not ///> std::pair class iterator @@ -212,6 +213,7 @@ public: { return iterator( m_netMapping.end(), this ); } +#endif /** * Function GetSize @@ -329,6 +331,7 @@ public: typedef boost::unordered_map NETNAMES_MAP; typedef boost::unordered_map NETCODES_MAP; +#ifndef SWIG ///> Wrapper class, so you can iterate through NETINFO_ITEM*s, not ///> std::pair class iterator @@ -388,6 +391,7 @@ public: { return iterator( m_netNames.end() ); } +#endif private: /** @@ -438,25 +442,22 @@ class NETINFO_ITEM friend class NETINFO_LIST; private: - const int m_NetCode; ///< A number equivalent to the net name. + int m_NetCode; ///< A number equivalent to the net name. ///< Used for fast comparisons in ratsnest and DRC computations. - const wxString m_Netname; ///< Full net name like /mysheet/mysubsheet/vout - ///< used by Eeschema + wxString m_Netname; ///< Full net name like /mysheet/mysubsheet/vout used by Eeschema - const wxString m_ShortNetname; // short net name, like vout from - // /mysheet/mysubsheet/vout + 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 // item of the net classes list - NETCLASS* m_NetClass; BOARD_ITEM* m_parent; ///< The parent board item object the net belongs to. public: - std::vector m_PadInNetList; // List of pads connected to this net + std::vector m_PadInNetList; ///< List of pads connected to this net unsigned m_RatsnestStartIdx; /* Starting point of ratsnests of this * net (included) in a general buffer of From 66fcb84f9240fa6e26054cb5877d51ccac16565d Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 12 Mar 2014 10:05:09 +0100 Subject: [PATCH 062/134] Minor fix to SEG class. --- include/geometry/seg.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/include/geometry/seg.h b/include/geometry/seg.h index b400930ef2..7e789f9d21 100644 --- a/include/geometry/seg.h +++ b/include/geometry/seg.h @@ -46,7 +46,8 @@ public: * to an object the segment belongs to (e.g. a line chain) or references to locally stored * points (m_a, m_b). */ - VECTOR2I& A, B; + VECTOR2I& A; + VECTOR2I& B; /** Default constructor * Creates an empty (0, 0) segment, locally-referenced @@ -203,6 +204,8 @@ public: bool Collide( const SEG& aSeg, int aClearance ) const; + ecoord SquaredDistance( const SEG& aSeg ) const; + /** * Function Distance() * @@ -210,14 +213,16 @@ public: * @param aSeg other segment * @return minimum distance */ - - ecoord SquaredDistance( const SEG& aSeg ) const; - int Distance( const SEG& aSeg ) const { return sqrt( SquaredDistance( aSeg ) ); } + ecoord SquaredDistance( const VECTOR2I& aP ) const + { + return ( NearestPoint( aP ) - aP ).SquaredEuclideanNorm(); + } + /** * Function Distance() * @@ -225,11 +230,6 @@ public: * @param aP the point * @return minimum distance */ - ecoord SquaredDistance( const VECTOR2I& aP ) const - { - return ( NearestPoint( aP ) - aP ).SquaredEuclideanNorm(); - } - int Distance( const VECTOR2I& aP ) const { return sqrt( SquaredDistance( aP ) ); From e6571f686204086584be1a37afb0f75c0995128f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 12 Mar 2014 10:46:11 +0100 Subject: [PATCH 063/134] Added new constraint for EDIT_POINTs (EPC_LINE). Dimensions have EDIT_POINTs. Different handling of 45 degree mode in POINT_EDITOR. --- pcbnew/class_dimension.cpp | 40 +++++++------ pcbnew/class_dimension.h | 34 +++++++---- pcbnew/pcb_parser.cpp | 3 + pcbnew/tools/edit_points.cpp | 38 ++++++++++++- pcbnew/tools/edit_points.h | 57 +++++++++++++++++++ pcbnew/tools/point_editor.cpp | 103 ++++++++++++++++++++++++++++++---- 6 files changed, 235 insertions(+), 40 deletions(-) diff --git a/pcbnew/class_dimension.cpp b/pcbnew/class_dimension.cpp index 3a56797468..47cb98b4e4 100644 --- a/pcbnew/class_dimension.cpp +++ b/pcbnew/class_dimension.cpp @@ -47,13 +47,9 @@ DIMENSION::DIMENSION( BOARD_ITEM* aParent ) : BOARD_ITEM( aParent, PCB_DIMENSION_T ), - m_Text( this ) + m_Width( Millimeter2iu( 0.2 ) ), m_Unit( INCHES ), m_Value( 0 ), m_Height( 0 ), m_Text( this ) { m_Layer = DRAW_N; - m_Width = Millimeter2iu( 0.2 ); - m_Value = 0; - m_Shape = 0; - m_Unit = INCHES; } @@ -99,6 +95,7 @@ void DIMENSION::Copy( DIMENSION* source ) SetLayer( source->GetLayer() ); m_Width = source->m_Width; m_Shape = source->m_Shape; + m_Height = source->m_Height; m_Unit = source->m_Unit; SetTimeStamp( GetNewTimeStamp() ); m_Text.Copy( &source->m_Text ); @@ -195,7 +192,6 @@ void DIMENSION::Mirror( const wxPoint& axis_pos ) void DIMENSION::SetOrigin( const wxPoint& aOrigin ) { - m_crossBarO = aOrigin; m_featureLineGO = aOrigin; AdjustDimensionDetails(); @@ -204,29 +200,32 @@ void DIMENSION::SetOrigin( const wxPoint& aOrigin ) void DIMENSION::SetEnd( const wxPoint& aEnd ) { - m_crossBarF = aEnd; m_featureLineDO = aEnd; AdjustDimensionDetails(); } -void DIMENSION::SetHeight( double aHeight ) +void DIMENSION::SetHeight( int aHeight ) { - /* Calculating the direction of travel perpendicular to the selected axis. */ - double angle = GetAngle() + ( M_PI / 2 ); - - int dx = KiROUND( aHeight * cos( angle ) ); - int dy = KiROUND( aHeight * sin( angle ) ); - m_crossBarO.x = m_featureLineGO.x + dx; - m_crossBarO.y = m_featureLineGO.y + dy; - m_crossBarF.x = m_featureLineDO.x + dx; - m_crossBarF.y = m_featureLineDO.y + dy; + m_Height = aHeight; AdjustDimensionDetails(); } +void DIMENSION::UpdateHeight() +{ + VECTOR2D featureLine( m_crossBarO - m_featureLineGO ); + VECTOR2D crossBar( m_featureLineDO - m_featureLineGO ); + + if( featureLine.Cross( crossBar ) > 0 ) + m_Height = -featureLine.EuclideanNorm(); + else + m_Height = featureLine.EuclideanNorm(); +} + + void DIMENSION::AdjustDimensionDetails( bool aDoNotChangeText ) { const int arrowz = DMils2iu( 500 ); // size of arrows @@ -281,6 +280,13 @@ void DIMENSION::AdjustDimensionDetails( bool aDoNotChangeText ) arrow_dw_Y = wxRound( arrowz * sin( angle_f ) ); } + int dx = KiROUND( m_Height * cos( angle + M_PI / 2 ) ); + int dy = KiROUND( m_Height * sin( angle + M_PI / 2 ) ); + m_crossBarO.x = m_featureLineGO.x + dx; + m_crossBarO.y = m_featureLineGO.y + dy; + m_crossBarF.x = m_featureLineDO.x + dx; + m_crossBarF.y = m_featureLineDO.y + dy; + m_arrowG1F.x = m_crossBarO.x + arrow_up_X; m_arrowG1F.y = m_crossBarO.y + arrow_up_Y; diff --git a/pcbnew/class_dimension.h b/pcbnew/class_dimension.h index 2992991505..956c7e4480 100644 --- a/pcbnew/class_dimension.h +++ b/pcbnew/class_dimension.h @@ -61,14 +61,13 @@ class MSG_PANEL_ITEM; */ class DIMENSION : public BOARD_ITEM { - int m_Width; - int m_Shape; // / Currently always 0. - int m_Unit; // / 0 = inches, 1 = mm - int m_Value; // / value of PCB dimensions. - + int m_Width; ///< Line width + int m_Shape; ///< Currently always 0. + EDA_UNITS_T m_Unit; ///< 0 = inches, 1 = mm + int m_Value; ///< value of PCB dimensions. + int m_Height; ///< length of feature lines TEXTE_PCB m_Text; - public: // TODO private: These member should be private. they are public only due to legacy code wxPoint m_crossBarO, m_crossBarF; @@ -117,7 +116,7 @@ public: */ const wxPoint& GetOrigin() const { - return m_crossBarO; + return m_featureLineGO; } /** @@ -133,7 +132,7 @@ public: */ const wxPoint& GetEnd() { - return m_crossBarF; + return m_featureLineDO; } /** @@ -141,12 +140,27 @@ public: * Sets the length of feature lines. * @param aHeight is the new height. */ - void SetHeight( double aHeight ); + void SetHeight( int aHeight ); + + /** + * Function GetHeight + * Returns the length of feature lines. + */ + int GetHeight() const + { + return m_Height; + } + + /** + * Function UpdateHeight + * Updates stored height basing on points coordinates. + */ + void UpdateHeight(); /** * Function GetAngle * Returns angle of the crossbar. - * @return Angle of the crossbar line. + * @return Angle of the crossbar line expressed in radians. */ double GetAngle() const { diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index f82814311e..70e3295f17 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -1438,6 +1438,7 @@ DIMENSION* PCB_PARSER::parseDIMENSION() throw( IO_ERROR, PARSE_ERROR ) parseXY( &dimension->m_featureLineDO.x, &dimension->m_featureLineDO.y ); parseXY( &dimension->m_featureLineDF.x, &dimension->m_featureLineDF.y ); + dimension->UpdateHeight(); NeedRIGHT(); NeedRIGHT(); break; @@ -1451,6 +1452,7 @@ DIMENSION* PCB_PARSER::parseDIMENSION() throw( IO_ERROR, PARSE_ERROR ) parseXY( &dimension->m_featureLineGO.x, &dimension->m_featureLineGO.y ); parseXY( &dimension->m_featureLineGF.x, &dimension->m_featureLineGF.y ); + dimension->UpdateHeight(); NeedRIGHT(); NeedRIGHT(); break; @@ -1465,6 +1467,7 @@ DIMENSION* PCB_PARSER::parseDIMENSION() throw( IO_ERROR, PARSE_ERROR ) parseXY( &dimension->m_crossBarO.x, &dimension->m_crossBarO.y ); parseXY( &dimension->m_crossBarF.x, &dimension->m_crossBarF.y ); + dimension->UpdateHeight(); NeedRIGHT(); NeedRIGHT(); break; diff --git a/pcbnew/tools/edit_points.cpp b/pcbnew/tools/edit_points.cpp index 39102b470a..000da9cb83 100644 --- a/pcbnew/tools/edit_points.cpp +++ b/pcbnew/tools/edit_points.cpp @@ -31,7 +31,7 @@ bool EDIT_POINT::WithinPoint( const VECTOR2I& aPoint, unsigned int aSize ) const { - // Corners of the square + // Corners of the EDIT_POINT square VECTOR2I topLeft = GetPosition() - aSize; VECTOR2I bottomRight = GetPosition() + aSize; @@ -162,6 +162,42 @@ void EPC_45DEGREE::Apply() } +EPC_LINE::EPC_LINE( EDIT_POINT& aConstrained, EDIT_POINT& aConstrainer ) : + EDIT_POINT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) +{ + Update(); +} + + +void EPC_LINE::Apply() +{ + VECTOR2I position = m_constrained.GetPosition(); + + if( std::isfinite( m_coefA ) ) + { + if( abs( m_coefA ) < 1 ) + position.y = m_coefA * position.x + m_coefB; + else + position.x = ( position.y - m_coefB ) / m_coefA; + } + else // vertical line + { + position.x = m_constrainer.GetX(); + } + + m_constrained.SetPosition( position ); +} + + +void EPC_LINE::Update() +{ + // Compute line coefficients + VECTOR2D delta = m_constrainer.GetPosition() - m_constrained.GetPosition(); + m_coefA = delta.y / delta.x; + m_coefB = m_constrainer.GetY() - m_coefA * m_constrainer.GetX(); +} + + void EPC_CIRCLE::Apply() { VECTOR2I centerToEnd = m_end.GetPosition() - m_center.GetPosition(); diff --git a/pcbnew/tools/edit_points.h b/pcbnew/tools/edit_points.h index bdcf5ec55a..1dd0f17014 100644 --- a/pcbnew/tools/edit_points.h +++ b/pcbnew/tools/edit_points.h @@ -97,6 +97,26 @@ public: return m_position; } + /** + * Function GetX() + * + * Returns X coordinate of an EDIT_POINT. + */ + int GetX() const + { + return GetPosition().x; + } + + /** + * Function GetX() + * + * Returns Y coordinate of an EDIT_POINT. + */ + int GetY() const + { + return GetPosition().y; + } + /** * Function SetPosition() * @@ -132,6 +152,17 @@ public: m_constraint = aConstraint; } + /** + * Function GetConstraint() + * + * Returns the constraint imposed on an EDIT_POINT. If there are no constraints, NULL is + * returned. + */ + EDIT_POINT_CONSTRAINT* GetConstraint() const + { + return m_constraint; + } + /** * Function ClearConstraint() * @@ -468,6 +499,32 @@ private: }; +/** + * Class EPC_LINE + * + * EDIT_POINT_CONSTRAINT that imposes a constraint that a point has to lie on a line (determined + * by 2 points). + */ +class EPC_LINE : public EDIT_POINT_CONSTRAINT +{ +public: + EPC_LINE( EDIT_POINT& aConstrained, EDIT_POINT& aConstrainer ); + + ///> @copydoc EDIT_POINT_CONSTRAINT::Apply() + virtual void Apply(); + + /** + * Function Update() + * Updates line coefficients that make the constraining line. + */ + void Update(); + +private: + EDIT_POINT& m_constrainer; ///< Point that imposes the constraint. + double m_coefA, m_coefB; +}; + + /** * Class EPC_CIRCLE. * diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 4415aae5a0..bd06e2306c 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -35,6 +35,7 @@ #include #include +#include #include /** @@ -60,8 +61,8 @@ public: switch( segment->GetShape() ) { case S_SEGMENT: - points->AddPoint( segment->GetStart() ); - points->AddPoint( segment->GetEnd() ); + points->AddPoint( segment->GetStart() ); // points[0] + points->AddPoint( segment->GetEnd() ); // points[1] break; case S_ARC: @@ -75,8 +76,8 @@ public: break; case S_CIRCLE: - points->AddPoint( segment->GetCenter() ); - points->AddPoint( segment->GetEnd() ); + points->AddPoint( segment->GetCenter() ); // points[0] + points->AddPoint( segment->GetEnd() ); // points[1] break; default: // suppress warnings @@ -98,8 +99,23 @@ public: for( int i = 0; i < cornersCount - 1; ++i ) points->AddLine( (*points)[i], (*points)[i + 1] ); - // The one missing line + // The last missing line, connecting the last and the first polygon point points->AddLine( (*points)[cornersCount - 1], (*points)[0] ); + break; + } + + case PCB_DIMENSION_T: + { + const DIMENSION* dimension = static_cast( aItem ); + + points->AddPoint( dimension->m_featureLineGO ); + points->AddPoint( dimension->m_featureLineDO ); + points->AddPoint( dimension->m_crossBarO ); + points->AddPoint( dimension->m_crossBarF ); + + // Dimension height setting - edit points should move only along the feature lines + (*points)[2].SetConstraint( new EPC_LINE( (*points)[2], (*points)[0] ) ); + (*points)[3].SetConstraint( new EPC_LINE( (*points)[3], (*points)[1] ) ); break; } @@ -118,7 +134,7 @@ private: POINT_EDITOR::POINT_EDITOR() : - TOOL_INTERACTIVE( "pcbnew.PointEditor" ), m_selectionTool( NULL ) + TOOL_INTERACTIVE( "pcbnew.PointEditor" ), m_selectionTool( NULL ), m_dragPoint( NULL ) { } @@ -159,6 +175,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) PCB_EDIT_FRAME* editFrame = getEditFrame(); EDA_ITEM* item = selection.items.GetPickedItem( 0 ); EDIT_POINT constrainer( VECTOR2I( 0, 0 ) ); + bool degree45 = false; // 45 degree mode m_editPoints = EDIT_POINTS_FACTORY::Make( item ); if( !m_editPoints ) @@ -218,18 +235,20 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) modified = true; } - if( evt->Modifier( MD_CTRL ) ) // 45 degrees mode + if( evt->Modifier( MD_CTRL ) != degree45 ) // 45 degrees mode { - if( !m_dragPoint->IsConstrained() ) + degree45 = evt->Modifier( MD_CTRL ); + + if( degree45 ) { // Find a proper constraining point for 45 degrees mode constrainer = get45DegConstrainer(); m_dragPoint->SetConstraint( new EPC_45DEGREE( *m_dragPoint, constrainer ) ); } - } - else - { - m_dragPoint->ClearConstraint(); + else + { + m_dragPoint->ClearConstraint(); + } } m_dragPoint->SetPosition( controls->GetCursorPosition() ); @@ -387,6 +406,47 @@ void POINT_EDITOR::updateItem() const break; } + case PCB_DIMENSION_T: + { + DIMENSION* dimension = static_cast( item ); + + // Check which point is currently modified and updated dimension's points respectively + if( isModified( (*m_editPoints)[0] ) ) + { + dimension->SetOrigin( wxPoint( m_dragPoint->GetPosition().x, m_dragPoint->GetPosition().y ) ); + static_cast( (*m_editPoints)[2].GetConstraint() )->Update(); + static_cast( (*m_editPoints)[3].GetConstraint() )->Update(); + } + else if( isModified( (*m_editPoints)[1] ) ) + { + dimension->SetEnd( wxPoint( m_dragPoint->GetPosition().x, m_dragPoint->GetPosition().y ) ); + static_cast( (*m_editPoints)[2].GetConstraint() )->Update(); + static_cast( (*m_editPoints)[3].GetConstraint() )->Update(); + } + else if( isModified( (*m_editPoints)[2] ) ) + { + VECTOR2D featureLine( m_dragPoint->GetPosition() - dimension->GetOrigin() ); + VECTOR2D crossBar( dimension->GetEnd() - dimension->GetOrigin() ); + + if( featureLine.Cross( crossBar ) > 0 ) + dimension->SetHeight( -featureLine.EuclideanNorm() ); + else + dimension->SetHeight( featureLine.EuclideanNorm() ); + } + else if( isModified( (*m_editPoints)[3] ) ) + { + VECTOR2D featureLine( m_dragPoint->GetPosition() - dimension->GetEnd() ); + VECTOR2D crossBar( dimension->GetEnd() - dimension->GetOrigin() ); + + if( featureLine.Cross( crossBar ) > 0 ) + dimension->SetHeight( -featureLine.EuclideanNorm() ); + else + dimension->SetHeight( featureLine.EuclideanNorm() ); + } + + break; + } + default: break; } @@ -454,6 +514,17 @@ void POINT_EDITOR::updatePoints() const break; } + case PCB_DIMENSION_T: + { + const DIMENSION* dimension = static_cast( item ); + + (*m_editPoints)[0].SetPosition( dimension->m_featureLineGO ); + (*m_editPoints)[1].SetPosition( dimension->m_featureLineDO ); + (*m_editPoints)[2].SetPosition( dimension->m_crossBarO ); + (*m_editPoints)[3].SetPosition( dimension->m_crossBarF ); + break; + } + default: break; } @@ -482,6 +553,14 @@ EDIT_POINT POINT_EDITOR::get45DegConstrainer() const } } } + else if( item->Type() == PCB_DIMENSION_T ) + { + // Constraint for crossbar + if( isModified( (*m_editPoints)[0] ) ) + return (*m_editPoints)[1]; + else if( isModified( (*m_editPoints)[1] ) ) + return (*m_editPoints)[0]; + } // In any other case we may align item to the current cursor position. return EDIT_POINT( getViewControls()->GetCursorPosition() ); From e5b0c720ed087f6d7cc74d4e4b981d3065daf006 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 12 Mar 2014 10:53:42 +0100 Subject: [PATCH 064/134] Switched order of EDIT_POINTs for DIMENSION, so in case when feature lines are of 0 length, then still can be stretched. --- pcbnew/tools/point_editor.cpp | 54 +++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index bd06e2306c..f0bb4f5496 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -108,14 +108,14 @@ public: { const DIMENSION* dimension = static_cast( aItem ); - points->AddPoint( dimension->m_featureLineGO ); - points->AddPoint( dimension->m_featureLineDO ); points->AddPoint( dimension->m_crossBarO ); points->AddPoint( dimension->m_crossBarF ); + points->AddPoint( dimension->m_featureLineGO ); + points->AddPoint( dimension->m_featureLineDO ); // Dimension height setting - edit points should move only along the feature lines - (*points)[2].SetConstraint( new EPC_LINE( (*points)[2], (*points)[0] ) ); - (*points)[3].SetConstraint( new EPC_LINE( (*points)[3], (*points)[1] ) ); + (*points)[0].SetConstraint( new EPC_LINE( (*points)[0], (*points)[2] ) ); + (*points)[1].SetConstraint( new EPC_LINE( (*points)[1], (*points)[3] ) ); break; } @@ -412,18 +412,6 @@ void POINT_EDITOR::updateItem() const // Check which point is currently modified and updated dimension's points respectively if( isModified( (*m_editPoints)[0] ) ) - { - dimension->SetOrigin( wxPoint( m_dragPoint->GetPosition().x, m_dragPoint->GetPosition().y ) ); - static_cast( (*m_editPoints)[2].GetConstraint() )->Update(); - static_cast( (*m_editPoints)[3].GetConstraint() )->Update(); - } - else if( isModified( (*m_editPoints)[1] ) ) - { - dimension->SetEnd( wxPoint( m_dragPoint->GetPosition().x, m_dragPoint->GetPosition().y ) ); - static_cast( (*m_editPoints)[2].GetConstraint() )->Update(); - static_cast( (*m_editPoints)[3].GetConstraint() )->Update(); - } - else if( isModified( (*m_editPoints)[2] ) ) { VECTOR2D featureLine( m_dragPoint->GetPosition() - dimension->GetOrigin() ); VECTOR2D crossBar( dimension->GetEnd() - dimension->GetOrigin() ); @@ -433,7 +421,8 @@ void POINT_EDITOR::updateItem() const else dimension->SetHeight( featureLine.EuclideanNorm() ); } - else if( isModified( (*m_editPoints)[3] ) ) + + else if( isModified( (*m_editPoints)[1] ) ) { VECTOR2D featureLine( m_dragPoint->GetPosition() - dimension->GetEnd() ); VECTOR2D crossBar( dimension->GetEnd() - dimension->GetOrigin() ); @@ -444,6 +433,20 @@ void POINT_EDITOR::updateItem() const dimension->SetHeight( featureLine.EuclideanNorm() ); } + else if( isModified( (*m_editPoints)[2] ) ) + { + dimension->SetOrigin( wxPoint( m_dragPoint->GetPosition().x, m_dragPoint->GetPosition().y ) ); + static_cast( (*m_editPoints)[0].GetConstraint() )->Update(); + static_cast( (*m_editPoints)[1].GetConstraint() )->Update(); + } + + else if( isModified( (*m_editPoints)[3] ) ) + { + dimension->SetEnd( wxPoint( m_dragPoint->GetPosition().x, m_dragPoint->GetPosition().y ) ); + static_cast( (*m_editPoints)[0].GetConstraint() )->Update(); + static_cast( (*m_editPoints)[1].GetConstraint() )->Update(); + } + break; } @@ -518,10 +521,10 @@ void POINT_EDITOR::updatePoints() const { const DIMENSION* dimension = static_cast( item ); - (*m_editPoints)[0].SetPosition( dimension->m_featureLineGO ); - (*m_editPoints)[1].SetPosition( dimension->m_featureLineDO ); - (*m_editPoints)[2].SetPosition( dimension->m_crossBarO ); - (*m_editPoints)[3].SetPosition( dimension->m_crossBarF ); + (*m_editPoints)[0].SetPosition( dimension->m_crossBarO ); + (*m_editPoints)[1].SetPosition( dimension->m_crossBarF ); + (*m_editPoints)[2].SetPosition( dimension->m_featureLineGO ); + (*m_editPoints)[3].SetPosition( dimension->m_featureLineDO ); break; } @@ -556,10 +559,11 @@ EDIT_POINT POINT_EDITOR::get45DegConstrainer() const else if( item->Type() == PCB_DIMENSION_T ) { // Constraint for crossbar - if( isModified( (*m_editPoints)[0] ) ) - return (*m_editPoints)[1]; - else if( isModified( (*m_editPoints)[1] ) ) - return (*m_editPoints)[0]; + if( isModified( (*m_editPoints)[2] ) ) + return (*m_editPoints)[3]; + + else if( isModified( (*m_editPoints)[3] ) ) + return (*m_editPoints)[2]; } // In any other case we may align item to the current cursor position. From 1e04f3b948bef7da3241ff8c966bd59d6e2bc87f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 12 Mar 2014 15:53:20 +0100 Subject: [PATCH 065/134] Removed excessive variable (m_Corners) from MARKER_BASE. --- common/class_marker_base.cpp | 11 +++++------ include/class_marker_base.h | 1 - 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/common/class_marker_base.cpp b/common/class_marker_base.cpp index b8aa30a058..6e54012fd4 100644 --- a/common/class_marker_base.cpp +++ b/common/class_marker_base.cpp @@ -19,8 +19,8 @@ // Default marquer shape: -#define M_SHAPE_SCALE 6 // default scaling factor for MarkerShapeCorners coordinates -#define CORNERS_COUNT 8 +const int M_SHAPE_SCALE = 6; // default scaling factor for MarkerShapeCorners coordinates +const int CORNERS_COUNT = 8; /* corners of the default shape * actual coordinates are these values * .m_ScalingFactor */ @@ -46,10 +46,10 @@ void MARKER_BASE::init() m_Color = RED; wxPoint start = MarkerShapeCorners[0]; wxPoint end = MarkerShapeCorners[0]; + for( unsigned ii = 0; ii < CORNERS_COUNT; ii++ ) { wxPoint corner = MarkerShapeCorners[ii]; - m_Corners.push_back( corner ); start.x = std::min( start.x, corner.x); start.y = std::min( start.y, corner.y); end.x = std::max( end.x, corner.x); @@ -64,7 +64,6 @@ void MARKER_BASE::init() MARKER_BASE::MARKER_BASE( const MARKER_BASE& aMarker ) { m_Pos = aMarker.m_Pos; - m_Corners = aMarker.m_Corners; m_MarkerType = aMarker.m_MarkerType; m_Color = aMarker.m_Color; m_ShapeBoundingBox = aMarker.m_ShapeBoundingBox; @@ -154,9 +153,9 @@ void MARKER_BASE::DrawMarker( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDr GRSetDrawMode( aDC, aDrawMode ); - for( unsigned ii = 0; ii < m_Corners.size(); ii++ ) + for( unsigned ii = 0; ii < CORNERS_COUNT; ii++ ) { - corners[ii] = m_Corners[ii]; + corners[ii] = MarkerShapeCorners[ii]; corners[ii].x *= m_ScalingFactor; corners[ii].y *= m_ScalingFactor; corners[ii] += m_Pos + aOffset; diff --git a/include/class_marker_base.h b/include/class_marker_base.h index bcc1d66337..d76b114b03 100644 --- a/include/class_marker_base.h +++ b/include/class_marker_base.h @@ -13,7 +13,6 @@ class MARKER_BASE public: wxPoint m_Pos; ///< position of the marker protected: - std::vector m_Corners; ///< Corner list for shape definition (a polygon) int m_MarkerType; ///< Can be used as a flag EDA_COLOR_T m_Color; ///< color EDA_RECT m_ShapeBoundingBox; ///< Bounding box of the graphic symbol, relative From c7fa57faf616023f4079dbb790adcf59aa14082b Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 12 Mar 2014 17:09:37 +0100 Subject: [PATCH 066/134] Changed the way of handling BOX2 traits (used std::numeric_limits). --- include/math/box2.h | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/include/math/box2.h b/include/math/box2.h index 8ed1621935..467558e676 100644 --- a/include/math/box2.h +++ b/include/math/box2.h @@ -28,24 +28,9 @@ #define __BOX2_H #include +#include -template -class BOX2_TRAITS -{ -}; - -template <> -class BOX2_TRAITS -{ -public: - enum - { - c_max_size = INT_MAX - 1, - c_min_coord_value = INT_MIN / 2 + 1 - }; -}; - /** * Class BOX2 * handles a 2-D bounding box, built on top of an origin point @@ -59,8 +44,9 @@ private: Vec m_Size; // Rectangle Size public: - typedef typename Vec::coord_type coord_type; - typedef typename Vec::extended_type ecoord_type; + typedef typename Vec::coord_type coord_type; + typedef typename Vec::extended_type ecoord_type; + typedef typename std::numeric_limits coord_limits; BOX2() {}; @@ -73,8 +59,8 @@ public: void SetMaximum() { - m_Pos.x = m_Pos.y = BOX2_TRAITS().c_min_coord_value; - m_Size.x = m_Size.y = BOX2_TRAITS().c_max_size; + m_Pos.x = m_Pos.y = coord_limits::min() / 2 + coord_limits::epsilon(); + m_Size.x = m_Size.y = coord_limits::max() - coord_limits::epsilon(); } Vec Centre() const From afc56d3f6f121f049ceffe611d3b97246636fe14 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 12 Mar 2014 17:09:53 +0100 Subject: [PATCH 067/134] Moved panning boundaries and scale limits from VIEW to VIEW_CONTROL. --- common/view/view.cpp | 22 +------------- common/view/wx_view_controls.cpp | 44 +++++++++++++++++++++++++--- include/view/view.h | 29 ------------------ include/view/view_controls.h | 50 ++++++++++++++++++++++++++++---- pcbnew/pcbframe.cpp | 3 +- 5 files changed, 87 insertions(+), 61 deletions(-) diff --git a/common/view/view.cpp b/common/view/view.cpp index 3cf57a210b..b28b0a1c32 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -45,10 +45,8 @@ VIEW::VIEW( bool aIsDynamic ) : m_scale( 1.0 ), m_painter( NULL ), m_gal( NULL ), - m_dynamic( aIsDynamic ), - m_scaleLimits( 15000.0, 1.0 ) + m_dynamic( aIsDynamic ) { - m_panBoundary.SetMaximum(); m_needsUpdate.reserve( 32768 ); // Redraw everything at the beginning @@ -295,11 +293,6 @@ void VIEW::SetMirror( bool aMirrorX, bool aMirrorY ) void VIEW::SetScale( double aScale, const VECTOR2D& aAnchor ) { - if( aScale > m_scaleLimits.x ) - aScale = m_scaleLimits.x; - else if( aScale < m_scaleLimits.y ) - aScale = m_scaleLimits.y; - VECTOR2D a = ToScreen( aAnchor ); m_gal->SetZoomFactor( aScale ); @@ -319,19 +312,6 @@ void VIEW::SetCenter( const VECTOR2D& aCenter ) { m_center = aCenter; - if( !m_panBoundary.Contains( aCenter ) ) - { - if( aCenter.x < m_panBoundary.GetLeft() ) - m_center.x = m_panBoundary.GetLeft(); - else if( aCenter.x > m_panBoundary.GetRight() ) - m_center.x = m_panBoundary.GetRight(); - - if( aCenter.y < m_panBoundary.GetTop() ) - m_center.y = m_panBoundary.GetTop(); - else if( aCenter.y > m_panBoundary.GetBottom() ) - m_center.y = m_panBoundary.GetBottom(); - } - m_gal->SetLookAtPoint( m_center ); m_gal->ComputeWorldScreenMatrix(); diff --git a/common/view/wx_view_controls.cpp b/common/view/wx_view_controls.cpp index 4ecfa953fd..22eb3ee47e 100644 --- a/common/view/wx_view_controls.cpp +++ b/common/view/wx_view_controls.cpp @@ -66,6 +66,42 @@ void VIEW_CONTROLS::ShowCursor( bool aEnabled ) } +void VIEW_CONTROLS::setCenter( const VECTOR2D& aCenter ) +{ + if( !m_panBoundary.Contains( aCenter ) ) + { + VECTOR2D newCenter( aCenter ); + + if( aCenter.x < m_panBoundary.GetLeft() ) + newCenter.x = m_panBoundary.GetLeft(); + else if( aCenter.x > m_panBoundary.GetRight() ) + newCenter.x = m_panBoundary.GetRight(); + + if( aCenter.y < m_panBoundary.GetTop() ) + newCenter.y = m_panBoundary.GetTop(); + else if( aCenter.y > m_panBoundary.GetBottom() ) + newCenter.y = m_panBoundary.GetBottom(); + + m_view->SetCenter( newCenter ); + } + else + { + m_view->SetCenter( aCenter ); + } +} + + +void VIEW_CONTROLS::setScale( double aScale, const VECTOR2D& aAnchor ) +{ + if( aScale < m_minScale ) + aScale = m_minScale; + else if( aScale > m_maxScale ) + aScale = m_maxScale; + + m_view->SetScale( aScale, aAnchor ); +} + + void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent ) { bool isAutoPanning = false; @@ -80,7 +116,7 @@ void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent ) VECTOR2D d = m_dragStartPoint - VECTOR2D( aEvent.GetX(), aEvent.GetY() ); VECTOR2D delta = m_view->ToWorld( d, false ); - m_view->SetCenter( m_lookStartPoint + delta ); + setCenter( m_lookStartPoint + delta ); aEvent.StopPropagation(); } else @@ -110,7 +146,7 @@ void WX_VIEW_CONTROLS::onWheel( wxMouseEvent& aEvent ) VECTOR2D delta( aEvent.ControlDown() ? -scrollSpeed : 0.0, aEvent.ShiftDown() ? -scrollSpeed : 0.0 ); - m_view->SetCenter( m_view->GetCenter() + delta ); + setCenter( m_view->GetCenter() + delta ); } else { @@ -133,7 +169,7 @@ void WX_VIEW_CONTROLS::onWheel( wxMouseEvent& aEvent ) } VECTOR2D anchor = m_view->ToWorld( VECTOR2D( aEvent.GetX(), aEvent.GetY() ) ); - m_view->SetScale( m_view->GetScale() * zoomScale, anchor ); + setScale( m_view->GetScale() * zoomScale, anchor ); } aEvent.Skip(); @@ -190,7 +226,7 @@ void WX_VIEW_CONTROLS::onTimer( wxTimerEvent& aEvent ) dir = dir.Resize( borderSize ); dir = m_view->ToWorld( dir, false ); - m_view->SetCenter( m_view->GetCenter() + dir * m_autoPanSpeed ); + setCenter( m_view->GetCenter() + dir * m_autoPanSpeed ); // Notify tools that the cursor position has changed in the world coordinates wxMouseEvent moveEvent( EVT_REFRESH_MOUSE ); diff --git a/include/view/view.h b/include/view/view.h index 63d6769254..e103089ae0 100644 --- a/include/view/view.h +++ b/include/view/view.h @@ -507,29 +507,6 @@ public: */ void UpdateItems(); - /** - * Function SetPanBoundary() - * Sets limits for panning area. - * @param aBoundary is the box that limits panning area. - */ - void SetPanBoundary( const BOX2I& aBoundary ) - { - m_panBoundary = aBoundary; - } - - /** - * Function SetScaleLimits() - * Sets minimum and maximum values for scale. - * @param aMaximum is the maximum value for scale.. - * @param aMinimum is the minimum value for scale. - */ - void SetScaleLimits( double aMaximum, double aMinimum ) - { - wxASSERT_MSG( aMaximum > aMinimum, wxT( "I guess you passed parameters in wrong order" ) ); - - m_scaleLimits = VECTOR2D( aMaximum, aMinimum ); - } - static const int VIEW_MAX_LAYERS = 128; ///< maximum number of layers that may be shown private: @@ -670,12 +647,6 @@ private: /// Rendering order modifier for layers that are marked as top layers static const int TOP_LAYER_MODIFIER = -VIEW_MAX_LAYERS; - /// Panning boundaries - BOX2I m_panBoundary; - - /// Zoom limits - VECTOR2D m_scaleLimits; - /// Items to be updated std::vector m_needsUpdate; }; diff --git a/include/view/view_controls.h b/include/view/view_controls.h index 35e6709f18..90fecd9ef9 100644 --- a/include/view/view_controls.h +++ b/include/view/view_controls.h @@ -46,14 +46,40 @@ class VIEW; class VIEW_CONTROLS { public: - VIEW_CONTROLS( VIEW* aView ) : m_view( aView ), m_forceCursorPosition( false ), - m_snappingEnabled( false ), m_grabMouse( false ), m_autoPanEnabled( false ), - m_autoPanMargin( 0.1 ), m_autoPanSpeed( 0.15 ) - {} + VIEW_CONTROLS( VIEW* aView ) : m_view( aView ), m_minScale( 4.0 ), m_maxScale( 15000 ), + m_forceCursorPosition( false ), m_snappingEnabled( false ), m_grabMouse( false ), + m_autoPanEnabled( false ), m_autoPanMargin( 0.1 ), m_autoPanSpeed( 0.15 ) + { + m_panBoundary.SetMaximum(); + } virtual ~VIEW_CONTROLS() {} + /** + * Function SetPanBoundary() + * Sets limits for panning area. + * @param aBoundary is the box that limits panning area. + */ + void SetPanBoundary( const BOX2I& aBoundary ) + { + m_panBoundary = aBoundary; + } + + /** + * Function SetScaleLimits() + * Sets minimum and maximum values for scale. + * @param aMaximum is the maximum value for scale. + * @param aMinimum is the minimum value for scale. + */ + void SetScaleLimits( double aMaximum, double aMinimum ) + { + wxASSERT_MSG( aMaximum > aMinimum, wxT( "I guess you passed parameters in wrong order" ) ); + + m_minScale = aMinimum; + m_maxScale = aMaximum; + } + /** * Function SetSnapping() * Enables/disables snapping cursor to grid. @@ -146,11 +172,23 @@ public: virtual void ShowCursor( bool aEnabled ); protected: + /// Sets center for VIEW, takes into account panning boundaries. + void setCenter( const VECTOR2D& aCenter ); + + /// Sets scale for VIEW, takes into account scale limits. + void setScale( double aScale, const VECTOR2D& aAnchor ); + /// Pointer to controlled VIEW. VIEW* m_view; - /// Current mouse position - VECTOR2D m_mousePosition; + /// Panning boundaries. + BOX2I m_panBoundary; + + /// Scale lower limit. + double m_minScale; + + /// Scale upper limit. + double m_maxScale; /// Current cursor position VECTOR2D m_cursorPosition; diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 0d56f1a634..1b5c4c5c20 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -56,6 +56,7 @@ #include #include #include +#include #include #include @@ -583,7 +584,7 @@ void PCB_EDIT_FRAME::ViewReloadBoard( const BOARD* aBoard ) const view->Add( aBoard->GetRatsnestViewItem() ); // Limit panning to the size of worksheet frame - view->SetPanBoundary( aBoard->GetWorksheetViewItem()->ViewBBox() ); + GetGalCanvas()->GetViewControls()->SetPanBoundary( aBoard->GetWorksheetViewItem()->ViewBBox() ); view->RecacheAllItems( true ); if( IsGalCanvasActive() ) From a377c9c1bc2f15dfaec5955272c9c7e03f380353 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 12 Mar 2014 17:11:52 +0100 Subject: [PATCH 068/134] Fixed erroneous hit testing for polygons in ratsnest for GAL. --- pcbnew/ratsnest_data.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index 9bf0e837da..ec618c7e9d 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -356,8 +356,8 @@ bool RN_POLY::HitTest( const RN_NODE_PTR& aNode ) const x2 = xOld; y2 = yOld; } - if( ( xNew < xt ) == ( xt <= xOld ) /* edge "open" at left end */ - && ( yt - y1 ) * ( x2 - x1 ) < ( y2 - y1 ) * ( xt - x1 ) ) + if( ( xNew < xt ) == ( xt <= xOld ) && /* edge "open" at left end */ + (float)( yt - y1 ) * (float)( x2 - x1 ) < (float)( y2 - y1 ) * (float)( xt - x1 ) ) { inside = !inside; } From f9d5f584cb41b9b0b944d21b576a4e1a546888be Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 12 Mar 2014 17:50:24 +0100 Subject: [PATCH 069/134] Fixed 45 degree mode toggle. --- pcbnew/tools/point_editor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index f0bb4f5496..eb07c71ec3 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -235,7 +235,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) modified = true; } - if( evt->Modifier( MD_CTRL ) != degree45 ) // 45 degrees mode + if( !!evt->Modifier( MD_CTRL ) != degree45 ) // 45 degrees mode { degree45 = evt->Modifier( MD_CTRL ); From 85e8b8bd87dfabcc4d39a79e8d2a45b063640608 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 13 Mar 2014 11:48:19 +0100 Subject: [PATCH 070/134] Yet another approach to 45 degree constraints. --- pcbnew/tools/edit_points.h | 9 ++++++ pcbnew/tools/point_editor.cpp | 53 ++++++++++++++++++++++++----------- pcbnew/tools/point_editor.h | 3 ++ 3 files changed, 48 insertions(+), 17 deletions(-) diff --git a/pcbnew/tools/edit_points.h b/pcbnew/tools/edit_points.h index 1dd0f17014..ecc84a8df6 100644 --- a/pcbnew/tools/edit_points.h +++ b/pcbnew/tools/edit_points.h @@ -59,6 +59,15 @@ public: */ virtual void Apply() = 0; + /** + * Function Update() + * + * Updates contraint's traits. + */ + virtual void Update() + { + } + protected: EDIT_POINT& m_constrained; ///< Point that is constrained by rules implemented by Apply() }; diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index eb07c71ec3..0d95d4b294 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -134,7 +134,8 @@ private: POINT_EDITOR::POINT_EDITOR() : - TOOL_INTERACTIVE( "pcbnew.PointEditor" ), m_selectionTool( NULL ), m_dragPoint( NULL ) + TOOL_INTERACTIVE( "pcbnew.PointEditor" ), m_selectionTool( NULL ), m_dragPoint( NULL ), + m_original( VECTOR2I( 0, 0 ) ) { } @@ -175,7 +176,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) PCB_EDIT_FRAME* editFrame = getEditFrame(); EDA_ITEM* item = selection.items.GetPickedItem( 0 ); EDIT_POINT constrainer( VECTOR2I( 0, 0 ) ); - bool degree45 = false; // 45 degree mode + boost::shared_ptr degree45Constraint; m_editPoints = EDIT_POINTS_FACTORY::Make( item ); if( !m_editPoints ) @@ -232,27 +233,31 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) editFrame->OnModify(); editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED ); controls->ForceCursorPosition( false ); + m_original = *m_dragPoint; // Save the original position modified = true; } - if( !!evt->Modifier( MD_CTRL ) != degree45 ) // 45 degrees mode + if( !!evt->Modifier( MD_CTRL ) != (bool) degree45Constraint ) // 45 degrees mode { - degree45 = evt->Modifier( MD_CTRL ); - - if( degree45 ) + if( !degree45Constraint ) { // Find a proper constraining point for 45 degrees mode constrainer = get45DegConstrainer(); - m_dragPoint->SetConstraint( new EPC_45DEGREE( *m_dragPoint, constrainer ) ); + degree45Constraint.reset( new EPC_45DEGREE( *m_dragPoint, constrainer ) ); } else { - m_dragPoint->ClearConstraint(); + degree45Constraint.reset(); } } m_dragPoint->SetPosition( controls->GetCursorPosition() ); - m_dragPoint->ApplyConstraint(); + + if( degree45Constraint ) + degree45Constraint->Apply(); + else + m_dragPoint->ApplyConstraint(); + updateItem(); updatePoints(); @@ -436,15 +441,15 @@ void POINT_EDITOR::updateItem() const else if( isModified( (*m_editPoints)[2] ) ) { dimension->SetOrigin( wxPoint( m_dragPoint->GetPosition().x, m_dragPoint->GetPosition().y ) ); - static_cast( (*m_editPoints)[0].GetConstraint() )->Update(); - static_cast( (*m_editPoints)[1].GetConstraint() )->Update(); + (*m_editPoints)[0].GetConstraint()->Update(); + (*m_editPoints)[1].GetConstraint()->Update(); } else if( isModified( (*m_editPoints)[3] ) ) { dimension->SetEnd( wxPoint( m_dragPoint->GetPosition().x, m_dragPoint->GetPosition().y ) ); - static_cast( (*m_editPoints)[0].GetConstraint() )->Update(); - static_cast( (*m_editPoints)[1].GetConstraint() )->Update(); + (*m_editPoints)[0].GetConstraint()->Update(); + (*m_editPoints)[1].GetConstraint()->Update(); } break; @@ -538,7 +543,9 @@ EDIT_POINT POINT_EDITOR::get45DegConstrainer() const { EDA_ITEM* item = m_editPoints->GetParent(); - if( item->Type() == PCB_LINE_T ) + switch( item->Type() ) + { + case PCB_LINE_T: { const DRAWSEGMENT* segment = static_cast( item ); { @@ -555,8 +562,11 @@ EDIT_POINT POINT_EDITOR::get45DegConstrainer() const break; } } + + break; } - else if( item->Type() == PCB_DIMENSION_T ) + + case PCB_DIMENSION_T: { // Constraint for crossbar if( isModified( (*m_editPoints)[2] ) ) @@ -564,8 +574,17 @@ EDIT_POINT POINT_EDITOR::get45DegConstrainer() const else if( isModified( (*m_editPoints)[3] ) ) return (*m_editPoints)[2]; + + else + return EDIT_POINT( m_dragPoint->GetPosition() ); // no constraint + + break; } - // In any other case we may align item to the current cursor position. - return EDIT_POINT( getViewControls()->GetCursorPosition() ); + default: + break; + } + + // In any other case we may align item to the current cursor position. TODO wrong desc + return m_original; } diff --git a/pcbnew/tools/point_editor.h b/pcbnew/tools/point_editor.h index 054d6b444e..8e37a142cd 100644 --- a/pcbnew/tools/point_editor.h +++ b/pcbnew/tools/point_editor.h @@ -62,6 +62,9 @@ private: ///> Currently edited point, NULL if there is none. EDIT_POINT* m_dragPoint; + ///> Original position for the current drag point. + EDIT_POINT m_original; + ///> Currently available edit points. boost::shared_ptr m_editPoints; From d6c1670cd78d8f13c5b3c8b5e015e63920aad56c Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 14 Mar 2014 15:15:38 +0100 Subject: [PATCH 071/134] Templated EDIT_POINT_CONSTRAINT. Removed EDIT_CONSTRAINT::Update() - replaced with resetting constraints. EDIT_CONSTRAINT is stored in EDIT_POIN using boost::shared_ptr instead of pointer. Added EDIT_LINE::GetEnd() & GetOrigin(). Overridden ApplyConstraint() for EDIT_LINE. Side EDIT_POINTS for zones are drawn as circles. --- pcbnew/tools/edit_points.cpp | 26 +++--- pcbnew/tools/edit_points.h | 153 +++++++++++++++++++--------------- pcbnew/tools/point_editor.cpp | 21 ++--- 3 files changed, 105 insertions(+), 95 deletions(-) diff --git a/pcbnew/tools/edit_points.cpp b/pcbnew/tools/edit_points.cpp index 000da9cb83..00fdb101ae 100644 --- a/pcbnew/tools/edit_points.cpp +++ b/pcbnew/tools/edit_points.cpp @@ -142,13 +142,13 @@ void EDIT_POINTS::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const aGal->DrawRectangle( point.GetPosition() - size / 2, point.GetPosition() + size / 2 ); BOOST_FOREACH( const EDIT_LINE& line, m_lines ) - aGal->DrawRectangle( line.GetPosition() - size / 2, line.GetPosition() + size / 2 ); + aGal->DrawCircle( line.GetPosition(), size / 2 ); aGal->PopDepth(); } -void EPC_45DEGREE::Apply() +void EC_45DEGREE::Apply() { // Current line vector VECTOR2I lineVector( m_constrained.GetPosition() - m_constrainer.GetPosition() ); @@ -162,14 +162,17 @@ void EPC_45DEGREE::Apply() } -EPC_LINE::EPC_LINE( EDIT_POINT& aConstrained, EDIT_POINT& aConstrainer ) : - EDIT_POINT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) +EC_LINE::EC_LINE( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : + EDIT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) { - Update(); + // Compute line coefficients + VECTOR2D delta = m_constrainer.GetPosition() - m_constrained.GetPosition(); + m_coefA = delta.y / delta.x; + m_coefB = m_constrainer.GetY() - m_coefA * m_constrainer.GetX(); } -void EPC_LINE::Apply() +void EC_LINE::Apply() { VECTOR2I position = m_constrained.GetPosition(); @@ -189,16 +192,7 @@ void EPC_LINE::Apply() } -void EPC_LINE::Update() -{ - // Compute line coefficients - VECTOR2D delta = m_constrainer.GetPosition() - m_constrained.GetPosition(); - m_coefA = delta.y / delta.x; - m_coefB = m_constrainer.GetY() - m_coefA * m_constrainer.GetX(); -} - - -void EPC_CIRCLE::Apply() +void EC_CIRCLE::Apply() { VECTOR2I centerToEnd = m_end.GetPosition() - m_center.GetPosition(); VECTOR2I centerToPoint = m_constrained.GetPosition() - m_center.GetPosition(); diff --git a/pcbnew/tools/edit_points.h b/pcbnew/tools/edit_points.h index ecc84a8df6..1d10e21a45 100644 --- a/pcbnew/tools/edit_points.h +++ b/pcbnew/tools/edit_points.h @@ -27,6 +27,8 @@ #include #include +#include + #include #include @@ -35,12 +37,13 @@ class EDIT_POINT; /** - * Class EDIT_POINT_CONSTRAINT + * Class EDIT_CONSTRAINT * - * Allows to describe constraints between two points. After the constrained point is changed, + * Allows to describe constraints between two edit handles. After the constrained handle is changed, * Apply() has to be called to fix its coordinates according to the implemented constraint. */ -class EDIT_POINT_CONSTRAINT +template +class EDIT_CONSTRAINT { public: /** @@ -48,9 +51,9 @@ public: * * @param aConstrained is EDIT_POINT to which the constraint is applied. */ - EDIT_POINT_CONSTRAINT( EDIT_POINT& aConstrained ) : m_constrained( aConstrained ) {}; + EDIT_CONSTRAINT( EDIT_TYPE& aConstrained ) : m_constrained( aConstrained ) {}; - virtual ~EDIT_POINT_CONSTRAINT() {}; + virtual ~EDIT_CONSTRAINT() {}; /** * Function Apply() @@ -59,17 +62,8 @@ public: */ virtual void Apply() = 0; - /** - * Function Update() - * - * Updates contraint's traits. - */ - virtual void Update() - { - } - protected: - EDIT_POINT& m_constrained; ///< Point that is constrained by rules implemented by Apply() + EDIT_TYPE& m_constrained; ///< Point that is constrained by rules implemented by Apply() }; @@ -88,12 +82,9 @@ public: * @param aPoint stores coordinates for EDIT_POINT. */ EDIT_POINT( const VECTOR2I& aPoint ) : - m_position( aPoint ), m_constraint( NULL ) {}; + m_position( aPoint ) {}; - virtual ~EDIT_POINT() - { - delete m_constraint; - } + virtual ~EDIT_POINT() {} /** * Function GetPosition() @@ -153,12 +144,9 @@ public: * Sets a constraint for and EDIT_POINT. * @param aConstraint is the constraint to be set. */ - void SetConstraint( EDIT_POINT_CONSTRAINT* aConstraint ) + void SetConstraint( EDIT_CONSTRAINT* aConstraint ) { - if( m_constraint ) - delete m_constraint; - - m_constraint = aConstraint; + m_constraint.reset( aConstraint ); } /** @@ -167,9 +155,9 @@ public: * Returns the constraint imposed on an EDIT_POINT. If there are no constraints, NULL is * returned. */ - EDIT_POINT_CONSTRAINT* GetConstraint() const + EDIT_CONSTRAINT* GetConstraint() const { - return m_constraint; + return m_constraint.get(); } /** @@ -179,8 +167,7 @@ public: */ void ClearConstraint() { - delete m_constraint; - m_constraint = NULL; + m_constraint.reset(); } /** @@ -199,7 +186,7 @@ public: * * Corrects coordinates of an EDIT_POINT by applying previously set constraint. */ - void ApplyConstraint() + virtual void ApplyConstraint() { if( m_constraint ) m_constraint->Apply(); @@ -214,8 +201,11 @@ public: static const int POINT_SIZE = 10; protected: - VECTOR2I m_position; ///< Position of EDIT_POINT - EDIT_POINT_CONSTRAINT* m_constraint; ///< Constraint for the point, NULL if none + ///> Position of EDIT_POINT + VECTOR2I m_position; + + ///> Constraint for the point, NULL if none + boost::shared_ptr > m_constraint; }; @@ -256,6 +246,36 @@ public: m_end.SetPosition( m_end.GetPosition() + difference ); } + ///> @copydoc EDIT_POINT::ApplyConstraint() + virtual void ApplyConstraint() + { + m_origin.ApplyConstraint(); + m_end.ApplyConstraint(); + + if( m_constraint ) + m_constraint->Apply(); + } + + /** + * Function GetOrigin() + * + * Returns the origin EDIT_POINT. + */ + EDIT_POINT& GetOrigin() + { + return m_origin; + } + + /** + * Function GetEnd() + * + * Returns the end EDIT_POINT. + */ + EDIT_POINT& GetEnd() + { + return m_end; + } + bool operator==( const EDIT_POINT& aOther ) const { return GetPosition() == aOther.GetPosition(); @@ -420,11 +440,11 @@ private: /** - * Class EPC_VERTICAL. + * Class EC_VERTICAL. * - * EDIT_POINT_CONSTRAINT that imposes a constraint that two points have to have the same X coordinate. + * EDIT_CONSTRAINT that imposes a constraint that two points have to have the same X coordinate. */ -class EPC_VERTICAL : public EDIT_POINT_CONSTRAINT +class EC_VERTICAL : public EDIT_CONSTRAINT { public: /** @@ -433,11 +453,11 @@ public: * @param aConstrained is the point that is put under constrain. * @param aConstrainer is the point that is the source of the constrain. */ - EPC_VERTICAL( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : - EDIT_POINT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) + EC_VERTICAL( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : + EDIT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) {} - ///> @copydoc EDIT_POINT_CONSTRAINT::Apply() + ///> @copydoc EDIT_CONSTRAINT::Apply() virtual void Apply() { VECTOR2I point = m_constrained.GetPosition(); @@ -451,11 +471,11 @@ private: /** - * Class EPC_HORIZONTAL. + * Class EC_HORIZONTAL. * - * EDIT_POINT_CONSTRAINT that imposes a constraint that two points have to have the same Y coordinate. + * EDIT_CONSTRAINT that imposes a constraint that two points have to have the same Y coordinate. */ -class EPC_HORIZONTAL : public EDIT_POINT_CONSTRAINT +class EC_HORIZONTAL : public EDIT_CONSTRAINT { public: /** @@ -464,11 +484,11 @@ public: * @param aConstrained is the point that is put under constrain. * @param aConstrainer is the point that is the source of the constrain. */ - EPC_HORIZONTAL( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : - EDIT_POINT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) + EC_HORIZONTAL( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : + EDIT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) {} - ///> @copydoc EDIT_POINT_CONSTRAINT::Apply() + ///> @copydoc EDIT_CONSTRAINT::Apply() virtual void Apply() { VECTOR2I point = m_constrained.GetPosition(); @@ -482,12 +502,12 @@ private: /** - * Class EPC_45DEGREE + * Class EC_45DEGREE * - * EDIT_POINT_CONSTRAINT that imposes a constraint that two to be located at angle of 45 degree + * EDIT_CONSTRAINT that imposes a constraint that two to be located at angle of 45 degree * multiplicity. */ -class EPC_45DEGREE : public EDIT_POINT_CONSTRAINT +class EC_45DEGREE : public EDIT_CONSTRAINT { public: /** @@ -496,11 +516,11 @@ public: * @param aConstrained is the point that is put under constrain. * @param aConstrainer is the point that is the source of the constrain. */ - EPC_45DEGREE( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : - EDIT_POINT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) + EC_45DEGREE( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : + EDIT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) {} - ///> @copydoc EDIT_POINT_CONSTRAINT::Apply() + ///> @copydoc EDIT_CONSTRAINT::Apply() virtual void Apply(); private: @@ -509,37 +529,32 @@ private: /** - * Class EPC_LINE + * Class EC_LINE * - * EDIT_POINT_CONSTRAINT that imposes a constraint that a point has to lie on a line (determined + * EDIT_CONSTRAINT that imposes a constraint that a point has to lie on a line (determined * by 2 points). */ -class EPC_LINE : public EDIT_POINT_CONSTRAINT +class EC_LINE : public EDIT_CONSTRAINT { public: - EPC_LINE( EDIT_POINT& aConstrained, EDIT_POINT& aConstrainer ); + EC_LINE( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ); - ///> @copydoc EDIT_POINT_CONSTRAINT::Apply() + ///> @copydoc EDIT_CONSTRAINT::Apply() virtual void Apply(); - /** - * Function Update() - * Updates line coefficients that make the constraining line. - */ - void Update(); - private: - EDIT_POINT& m_constrainer; ///< Point that imposes the constraint. - double m_coefA, m_coefB; + EDIT_POINT m_constrainer; ///< Point that imposes the constraint. + double m_coefA; ///< Line A coefficient (y = Ax + B) + double m_coefB; ///< Line B coefficient (y = Ax + B) }; /** - * Class EPC_CIRCLE. + * Class EC_CIRCLE. * - * EDIT_POINT_CONSTRAINT that imposes a constraint that a point has to lie on a circle. + * EDIT_CONSTRAINT that imposes a constraint that a point has to lie on a circle. */ -class EPC_CIRCLE : public EDIT_POINT_CONSTRAINT +class EC_CIRCLE : public EDIT_CONSTRAINT { public: /** @@ -549,11 +564,11 @@ public: * @parama aCenter is the point that is the center of the circle. * @parama aEnd is the point that decides on the radius of the circle. */ - EPC_CIRCLE( EDIT_POINT& aConstrained, const EDIT_POINT& aCenter, const EDIT_POINT& aEnd ) : - EDIT_POINT_CONSTRAINT( aConstrained ), m_center( aCenter ), m_end( aEnd ) + EC_CIRCLE( EDIT_POINT& aConstrained, const EDIT_POINT& aCenter, const EDIT_POINT& aEnd ) : + EDIT_CONSTRAINT( aConstrained ), m_center( aCenter ), m_end( aEnd ) {} - ///> @copydoc EDIT_POINT_CONSTRAINT::Apply() + ///> @copydoc EDIT_CONSTRAINT::Apply() virtual void Apply(); private: diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 0d95d4b294..3caec5eb5e 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -72,7 +72,7 @@ public: // Set constraints // Arc end has to stay at the same radius as the start - (*points)[2].SetConstraint( new EPC_CIRCLE( (*points)[2], (*points)[0], (*points)[1] ) ); + (*points)[2].SetConstraint( new EC_CIRCLE( (*points)[2], (*points)[0], (*points)[1] ) ); break; case S_CIRCLE: @@ -114,8 +114,8 @@ public: points->AddPoint( dimension->m_featureLineDO ); // Dimension height setting - edit points should move only along the feature lines - (*points)[0].SetConstraint( new EPC_LINE( (*points)[0], (*points)[2] ) ); - (*points)[1].SetConstraint( new EPC_LINE( (*points)[1], (*points)[3] ) ); + (*points)[0].SetConstraint( new EC_LINE( (*points)[0], (*points)[2] ) ); + (*points)[1].SetConstraint( new EC_LINE( (*points)[1], (*points)[3] ) ); break; } @@ -176,7 +176,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) PCB_EDIT_FRAME* editFrame = getEditFrame(); EDA_ITEM* item = selection.items.GetPickedItem( 0 ); EDIT_POINT constrainer( VECTOR2I( 0, 0 ) ); - boost::shared_ptr degree45Constraint; + boost::shared_ptr > degree45Constraint; m_editPoints = EDIT_POINTS_FACTORY::Make( item ); if( !m_editPoints ) @@ -243,7 +243,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) { // Find a proper constraining point for 45 degrees mode constrainer = get45DegConstrainer(); - degree45Constraint.reset( new EPC_45DEGREE( *m_dragPoint, constrainer ) ); + degree45Constraint.reset( new EC_45DEGREE( *m_dragPoint, constrainer ) ); } else { @@ -271,6 +271,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) else if( evt->IsMouseUp( BUT_LEFT ) ) { + degree45Constraint.reset(); modified = false; } @@ -441,15 +442,15 @@ void POINT_EDITOR::updateItem() const else if( isModified( (*m_editPoints)[2] ) ) { dimension->SetOrigin( wxPoint( m_dragPoint->GetPosition().x, m_dragPoint->GetPosition().y ) ); - (*m_editPoints)[0].GetConstraint()->Update(); - (*m_editPoints)[1].GetConstraint()->Update(); + (*m_editPoints)[0].SetConstraint( new EC_LINE( (*m_editPoints)[0], (*m_editPoints)[2] ) ); + (*m_editPoints)[1].SetConstraint( new EC_LINE( (*m_editPoints)[1], (*m_editPoints)[3] ) ); } else if( isModified( (*m_editPoints)[3] ) ) { dimension->SetEnd( wxPoint( m_dragPoint->GetPosition().x, m_dragPoint->GetPosition().y ) ); - (*m_editPoints)[0].GetConstraint()->Update(); - (*m_editPoints)[1].GetConstraint()->Update(); + (*m_editPoints)[0].SetConstraint( new EC_LINE( (*m_editPoints)[0], (*m_editPoints)[2] ) ); + (*m_editPoints)[1].SetConstraint( new EC_LINE( (*m_editPoints)[1], (*m_editPoints)[3] ) ); } break; @@ -585,6 +586,6 @@ EDIT_POINT POINT_EDITOR::get45DegConstrainer() const break; } - // In any other case we may align item to the current cursor position. TODO wrong desc + // In any other case we may align item to its original position return m_original; } From 19a87ac7804e14a8b1a69f46deb5b9e5e0495b9f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 14 Mar 2014 15:37:55 +0100 Subject: [PATCH 072/134] Added EC_CONVERGING for zone areas modification. --- pcbnew/tools/edit_points.cpp | 89 ++++++++++++++++++++++++++++++++++- pcbnew/tools/edit_points.h | 25 ++++++++++ pcbnew/tools/point_editor.cpp | 53 +++++++++++++-------- pcbnew/tools/point_editor.h | 9 ++++ 4 files changed, 155 insertions(+), 21 deletions(-) diff --git a/pcbnew/tools/edit_points.cpp b/pcbnew/tools/edit_points.cpp index 00fdb101ae..e98a8dee6b 100644 --- a/pcbnew/tools/edit_points.cpp +++ b/pcbnew/tools/edit_points.cpp @@ -26,8 +26,7 @@ #include "edit_points.h" #include - -#include +#include bool EDIT_POINT::WithinPoint( const VECTOR2I& aPoint, unsigned int aSize ) const { @@ -205,3 +204,89 @@ void EC_CIRCLE::Apply() m_constrained.SetPosition( m_center.GetPosition() + newLine ); } + + +EC_CONVERGING::EC_CONVERGING( EDIT_LINE& aLine, EDIT_POINTS& aPoints ) : + EDIT_CONSTRAINT( aLine.GetEnd() ), + /*m_end( aLine.GetEnd() ), m_origin( aLine.GetOrigin() ),*/ m_line( aLine ), + m_editPoints( aPoints ) +{ + // Dragged segment endings + EDIT_POINT& origin = aLine.GetOrigin(); + EDIT_POINT& end = aLine.GetEnd(); + + // Add constraint to the line origin, so it moves only along it current line + EDIT_POINT& prevOrigin = *aPoints.Previous( origin ); + EDIT_POINT& nextEnd = *aPoints.Next( end ); + + // Constraints for segments adjacent to the dragged one + m_originSideConstraint = new EC_LINE( origin, prevOrigin ); + m_endSideConstraint = new EC_LINE( end, nextEnd ); + + // Compute dragged segment slope + VECTOR2D delta = m_line.GetPosition() - end.GetPosition(); + m_coefA = delta.y / delta.x; +} + + +EC_CONVERGING::~EC_CONVERGING() +{ + delete m_originSideConstraint; + delete m_endSideConstraint; +} + + +void EC_CONVERGING::Apply() +{ + EDIT_POINT& origin = m_line.GetOrigin(); + EDIT_POINT& end = m_line.GetEnd(); + + // Do not allow points on the adjacent segments move freely + m_originSideConstraint->Apply(); + m_endSideConstraint->Apply(); + + // Find points that make adjacent segments + EDIT_POINT& prevOrigin = *m_editPoints.Previous( origin ); // point previous to origin + EDIT_POINT& nextEnd = *m_editPoints.Next( end ); // point next to end + + // Two segments adjacent to the dragged segment + SEG originSide( origin.GetPosition(), prevOrigin.GetPosition() ); + SEG endSide( end.GetPosition(), nextEnd.GetPosition() ); + + VECTOR2I draggedCenter; // center point of the dragged segment + + // Check if adjacent segments intersect (did we dragged the line to the point that it may + // create a selfintersecting polygon?) + if( OPT_VECTOR2I originEndIntersect = endSide.Intersect( originSide ) ) + draggedCenter = *originEndIntersect; + else + draggedCenter = m_line.GetPosition(); + + // Line B coefficient (y=Ax+B) for the dragged segment (A coefficient is computed up on the + // the construction of EC_CONVERGING + double coefB = draggedCenter.y - m_coefA * draggedCenter.x; + VECTOR2D draggedEnd = draggedCenter + 10000; + + if( std::isfinite( m_coefA ) ) + { + if( std::abs( m_coefA ) < 1 ) + draggedEnd.y = m_coefA * draggedEnd.x + coefB; + else + draggedEnd.x = ( draggedEnd.y - coefB ) / m_coefA; + } + else // vertical line + { + draggedEnd.x = draggedCenter.x; + draggedEnd.y = draggedEnd.x + coefB; + } + + SEG dragged( draggedCenter, draggedEnd ); // the dragged segment + + // First intersection point (dragged segment against origin side) + if( OPT_VECTOR2I originIntersect = dragged.IntersectLines( originSide ) ) + origin.SetPosition( *originIntersect ); + + // Second intersection point (dragged segment against end side) + if( OPT_VECTOR2I endIntersect = dragged.IntersectLines( endSide ) ) + end.SetPosition( *endIntersect ); +} diff --git a/pcbnew/tools/edit_points.h b/pcbnew/tools/edit_points.h index 1d10e21a45..49aa2b9383 100644 --- a/pcbnew/tools/edit_points.h +++ b/pcbnew/tools/edit_points.h @@ -579,4 +579,29 @@ private: const EDIT_POINT& m_end; }; + +/** + * Class EC_CONVERGING + * + * EDIT_CONSTRAINT for 3 segment: dragged and two adjacent ones, enforcing to keep their slopes + * and allows only to change ending points. Applied to zones. + */ +class EC_CONVERGING : public EDIT_CONSTRAINT +{ +public: + EC_CONVERGING( EDIT_LINE& aLine, EDIT_POINTS& aPoints ); + + virtual ~EC_CONVERGING(); + + ///> @copydoc EDIT_CONSTRAINT::Apply() + virtual void Apply(); + +private: + EC_LINE* m_originSideConstraint; ///< Constraint for origin side segment + EC_LINE* m_endSideConstraint; ///< Constraint for end side segment + EDIT_LINE& m_line; ///< Dragged segment + EDIT_POINTS& m_editPoints; ///< EDIT_POINT instance storing modified lines + double m_coefA; ///< Original dragged segment A coefficient (y = Ax + B) +}; + #endif /* EDIT_POINTS_H_ */ diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 3caec5eb5e..f48f0583dc 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -135,7 +135,7 @@ private: POINT_EDITOR::POINT_EDITOR() : TOOL_INTERACTIVE( "pcbnew.PointEditor" ), m_selectionTool( NULL ), m_dragPoint( NULL ), - m_original( VECTOR2I( 0, 0 ) ) + m_original( VECTOR2I( 0, 0 ) ), m_altConstrainer( VECTOR2I( 0, 0 ) ) { } @@ -143,6 +143,7 @@ POINT_EDITOR::POINT_EDITOR() : void POINT_EDITOR::Reset( RESET_REASON aReason ) { m_editPoints.reset(); + m_altConstraint.reset(); } @@ -175,8 +176,6 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) KIGFX::VIEW* view = getView(); PCB_EDIT_FRAME* editFrame = getEditFrame(); EDA_ITEM* item = selection.items.GetPickedItem( 0 ); - EDIT_POINT constrainer( VECTOR2I( 0, 0 ) ); - boost::shared_ptr > degree45Constraint; m_editPoints = EDIT_POINTS_FACTORY::Make( item ); if( !m_editPoints ) @@ -237,24 +236,14 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) modified = true; } - if( !!evt->Modifier( MD_CTRL ) != (bool) degree45Constraint ) // 45 degrees mode - { - if( !degree45Constraint ) - { - // Find a proper constraining point for 45 degrees mode - constrainer = get45DegConstrainer(); - degree45Constraint.reset( new EC_45DEGREE( *m_dragPoint, constrainer ) ); - } - else - { - degree45Constraint.reset(); - } - } + bool enableAltConstraint = !!evt->Modifier( MD_CTRL ); + if( enableAltConstraint != (bool) m_altConstraint ) // alternative constraint + setAltConstraint( enableAltConstraint ); m_dragPoint->SetPosition( controls->GetCursorPosition() ); - if( degree45Constraint ) - degree45Constraint->Apply(); + if( m_altConstraint ) + m_altConstraint->Apply(); else m_dragPoint->ApplyConstraint(); @@ -271,7 +260,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) else if( evt->IsMouseUp( BUT_LEFT ) ) { - degree45Constraint.reset(); + setAltConstraint( false ); modified = false; } @@ -540,6 +529,32 @@ void POINT_EDITOR::updatePoints() const } +void POINT_EDITOR::setAltConstraint( bool aEnabled ) +{ + if( aEnabled ) + { + EDIT_LINE* line = dynamic_cast( m_dragPoint ); + if( line ) + { + if( m_editPoints->GetParent()->Type() == PCB_ZONE_AREA_T ) + { + m_altConstraint.reset( new EC_CONVERGING( *line, *m_editPoints ) ); + } + } + else + { + // Find a proper constraining point for 45 degrees mode + m_altConstrainer = get45DegConstrainer(); + m_altConstraint.reset( new EC_45DEGREE( *m_dragPoint, m_altConstrainer ) ); + } + } + else + { + m_altConstraint.reset(); + } +} + + EDIT_POINT POINT_EDITOR::get45DegConstrainer() const { EDA_ITEM* item = m_editPoints->GetParent(); diff --git a/pcbnew/tools/point_editor.h b/pcbnew/tools/point_editor.h index 8e37a142cd..fe77760c3d 100644 --- a/pcbnew/tools/point_editor.h +++ b/pcbnew/tools/point_editor.h @@ -68,6 +68,12 @@ private: ///> Currently available edit points. boost::shared_ptr m_editPoints; + // Alternative constraint, enabled while a modifier key is held + boost::shared_ptr > m_altConstraint; + + // EDIT_POINT for alternative constraint mode + EDIT_POINT m_altConstrainer; + ///> Updates item's points with edit points. void updateItem() const; @@ -83,6 +89,9 @@ private: return m_dragPoint == &aPoint; } + ///> Sets up an alternative constraint (typically enabled upon a modifier key being pressed). + void setAltConstraint( bool aEnabled ); + ///> Returns a point that should be used as a constrainer for 45 degrees mode. EDIT_POINT get45DegConstrainer() const; From 40ee66f8c51a32cb47deb4de5f20abde5b9a29e0 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 14 Mar 2014 16:05:30 +0100 Subject: [PATCH 073/134] ZONE_CONTAINERs are drawn as outlines while being edited using the POINT_EDITOR. --- pcbnew/tools/point_editor.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index f48f0583dc..4ae508288c 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -390,6 +390,7 @@ void POINT_EDITOR::updateItem() const case PCB_ZONE_AREA_T: { ZONE_CONTAINER* zone = static_cast( item ); + zone->ClearFilledPolysList(); CPolyLine* outline = zone->Outline(); for( int i = 0; i < outline->GetCornersCount(); ++i ) From f6959c039c92cc57204d0700ce2ec2290436bd39 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 18 Mar 2014 11:04:52 +0100 Subject: [PATCH 074/134] Comments. --- common/view/view.cpp | 3 ++- pcbnew/tools/selection_tool.h | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/common/view/view.cpp b/common/view/view.cpp index b28b0a1c32..ba070b2786 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -114,7 +114,8 @@ void VIEW::Remove( VIEW_ITEM* aItem ) if( aItem->viewRequiredUpdate() != VIEW_ITEM::NONE ) // prevent from updating a removed item { - std::vector::iterator item = std::find( m_needsUpdate.begin(), m_needsUpdate.end(), aItem ); + std::vector::iterator item = std::find( m_needsUpdate.begin(), + m_needsUpdate.end(), aItem ); if( item != m_needsUpdate.end() ) m_needsUpdate.erase( item ); diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h index 9ef61fbd4b..7072c89655 100644 --- a/pcbnew/tools/selection_tool.h +++ b/pcbnew/tools/selection_tool.h @@ -114,9 +114,13 @@ public: */ void AddMenuItem( const TOOL_ACTION& aAction ); - // TODO comments + ///> Event sent after an item is selected. const TOOL_EVENT SelectedEvent; + + ///> Event sent after an item is deselected. const TOOL_EVENT DeselectedEvent; + + ///> Event sent after selection is cleared. const TOOL_EVENT ClearedEvent; private: From 48161dcc4a1b1e53288355bbf741aa01bacef7d6 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 18 Mar 2014 11:05:24 +0100 Subject: [PATCH 075/134] Yet another approach to EC_LINE and EC_CONVERGING edit constraints. --- pcbnew/tools/edit_points.cpp | 103 ++++++++++++----------------------- pcbnew/tools/edit_points.h | 68 ++++++++++++++++------- 2 files changed, 84 insertions(+), 87 deletions(-) diff --git a/pcbnew/tools/edit_points.cpp b/pcbnew/tools/edit_points.cpp index e98a8dee6b..23c8f1dbf4 100644 --- a/pcbnew/tools/edit_points.cpp +++ b/pcbnew/tools/edit_points.cpp @@ -147,54 +147,41 @@ void EDIT_POINTS::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const } -void EC_45DEGREE::Apply() +void EC_45DEGREE::Apply( EDIT_POINT& aHandle ) { // Current line vector - VECTOR2I lineVector( m_constrained.GetPosition() - m_constrainer.GetPosition() ); + VECTOR2I lineVector( aHandle.GetPosition() - m_constrainer.GetPosition() ); double angle = lineVector.Angle(); // Find the closest angle, which is a multiple of 45 degrees double newAngle = round( angle / ( M_PI / 4.0 ) ) * M_PI / 4.0; VECTOR2I newLineVector = lineVector.Rotate( newAngle - angle ); - m_constrained.SetPosition( m_constrainer.GetPosition() + newLineVector ); + aHandle.SetPosition( m_constrainer.GetPosition() + newLineVector ); } EC_LINE::EC_LINE( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : EDIT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) { - // Compute line coefficients - VECTOR2D delta = m_constrainer.GetPosition() - m_constrained.GetPosition(); - m_coefA = delta.y / delta.x; - m_coefB = m_constrainer.GetY() - m_coefA * m_constrainer.GetX(); + m_line = m_constrained.GetPosition() - m_constrainer.GetPosition(); } -void EC_LINE::Apply() +void EC_LINE::Apply( EDIT_POINT& aHandle ) { - VECTOR2I position = m_constrained.GetPosition(); + SEG main( m_constrainer.GetPosition(), m_constrainer.GetPosition() + m_line ); + SEG projection( aHandle.GetPosition(), aHandle.GetPosition() + m_line.Perpendicular() ); - if( std::isfinite( m_coefA ) ) - { - if( abs( m_coefA ) < 1 ) - position.y = m_coefA * position.x + m_coefB; - else - position.x = ( position.y - m_coefB ) / m_coefA; - } - else // vertical line - { - position.x = m_constrainer.GetX(); - } - - m_constrained.SetPosition( position ); + if( OPT_VECTOR2I intersect = projection.IntersectLines( main ) ) + aHandle.SetPosition( *intersect ); } -void EC_CIRCLE::Apply() +void EC_CIRCLE::Apply( EDIT_POINT& aHandle ) { VECTOR2I centerToEnd = m_end.GetPosition() - m_center.GetPosition(); - VECTOR2I centerToPoint = m_constrained.GetPosition() - m_center.GetPosition(); + VECTOR2I centerToPoint = aHandle.GetPosition() - m_center.GetPosition(); int radius = centerToEnd.EuclideanNorm(); double angle = centerToPoint.Angle(); @@ -202,20 +189,18 @@ void EC_CIRCLE::Apply() VECTOR2I newLine( radius, 0 ); newLine = newLine.Rotate( angle ); - m_constrained.SetPosition( m_center.GetPosition() + newLine ); + aHandle.SetPosition( m_center.GetPosition() + newLine ); } EC_CONVERGING::EC_CONVERGING( EDIT_LINE& aLine, EDIT_POINTS& aPoints ) : - EDIT_CONSTRAINT( aLine.GetEnd() ), - /*m_end( aLine.GetEnd() ), m_origin( aLine.GetOrigin() ),*/ m_line( aLine ), - m_editPoints( aPoints ) + EDIT_CONSTRAINT( aLine.GetOrigin() ), m_line( aLine ), m_editPoints( aPoints ) { // Dragged segment endings EDIT_POINT& origin = aLine.GetOrigin(); EDIT_POINT& end = aLine.GetEnd(); - // Add constraint to the line origin, so it moves only along it current line + // Previous and next points, to make constraining lines (adjacent to the dragged line) EDIT_POINT& prevOrigin = *aPoints.Previous( origin ); EDIT_POINT& nextEnd = *aPoints.Next( end ); @@ -223,9 +208,8 @@ EC_CONVERGING::EC_CONVERGING( EDIT_LINE& aLine, EDIT_POINTS& aPoints ) : m_originSideConstraint = new EC_LINE( origin, prevOrigin ); m_endSideConstraint = new EC_LINE( end, nextEnd ); - // Compute dragged segment slope - VECTOR2D delta = m_line.GetPosition() - end.GetPosition(); - m_coefA = delta.y / delta.x; + // Store the current vector of the line + m_draggedVector = end.GetPosition() - origin.GetPosition() ; } @@ -236,8 +220,12 @@ EC_CONVERGING::~EC_CONVERGING() } -void EC_CONVERGING::Apply() +void EC_CONVERGING::Apply( EDIT_POINT& aHandle ) { + // The dragged segment + SEG dragged( m_line.GetPosition(), m_line.GetPosition() + m_draggedVector ); + + // The dragged segment endpoints EDIT_POINT& origin = m_line.GetOrigin(); EDIT_POINT& end = m_line.GetEnd(); @@ -245,42 +233,12 @@ void EC_CONVERGING::Apply() m_originSideConstraint->Apply(); m_endSideConstraint->Apply(); - // Find points that make adjacent segments - EDIT_POINT& prevOrigin = *m_editPoints.Previous( origin ); // point previous to origin - EDIT_POINT& nextEnd = *m_editPoints.Next( end ); // point next to end + EDIT_POINT& prevOrigin = *m_editPoints.Previous( origin ); + EDIT_POINT& nextEnd = *m_editPoints.Next( end ); // Two segments adjacent to the dragged segment - SEG originSide( origin.GetPosition(), prevOrigin.GetPosition() ); - SEG endSide( end.GetPosition(), nextEnd.GetPosition() ); - - VECTOR2I draggedCenter; // center point of the dragged segment - - // Check if adjacent segments intersect (did we dragged the line to the point that it may - // create a selfintersecting polygon?) - if( OPT_VECTOR2I originEndIntersect = endSide.Intersect( originSide ) ) - draggedCenter = *originEndIntersect; - else - draggedCenter = m_line.GetPosition(); - - // Line B coefficient (y=Ax+B) for the dragged segment (A coefficient is computed up on the - // the construction of EC_CONVERGING - double coefB = draggedCenter.y - m_coefA * draggedCenter.x; - VECTOR2D draggedEnd = draggedCenter + 10000; - - if( std::isfinite( m_coefA ) ) - { - if( std::abs( m_coefA ) < 1 ) - draggedEnd.y = m_coefA * draggedEnd.x + coefB; - else - draggedEnd.x = ( draggedEnd.y - coefB ) / m_coefA; - } - else // vertical line - { - draggedEnd.x = draggedCenter.x; - draggedEnd.y = draggedEnd.x + coefB; - } - - SEG dragged( draggedCenter, draggedEnd ); // the dragged segment + SEG originSide = SEG( origin.GetPosition(), prevOrigin.GetPosition() ); + SEG endSide = SEG( end.GetPosition(), nextEnd.GetPosition() ); // First intersection point (dragged segment against origin side) if( OPT_VECTOR2I originIntersect = dragged.IntersectLines( originSide ) ) @@ -289,4 +247,15 @@ void EC_CONVERGING::Apply() // Second intersection point (dragged segment against end side) if( OPT_VECTOR2I endIntersect = dragged.IntersectLines( endSide ) ) end.SetPosition( *endIntersect ); + + // Check if adjacent segments intersect (did we dragged the line to the point that it may + // create a selfintersecting polygon?) + originSide = SEG( origin.GetPosition(), prevOrigin.GetPosition() ); + endSide = SEG( end.GetPosition(), nextEnd.GetPosition() ); + + if( OPT_VECTOR2I originEndIntersect = endSide.Intersect( originSide ) ) + { + origin.SetPosition( *originEndIntersect ); + end.SetPosition( *originEndIntersect ); + } } diff --git a/pcbnew/tools/edit_points.h b/pcbnew/tools/edit_points.h index 49aa2b9383..0c1dd343c2 100644 --- a/pcbnew/tools/edit_points.h +++ b/pcbnew/tools/edit_points.h @@ -58,9 +58,19 @@ public: /** * Function Apply() * - * Corrects coordinates of the constrained point. + * Corrects coordinates of the constrained edit handle. */ - virtual void Apply() = 0; + virtual void Apply( EDIT_TYPE& aHandle ) = 0; + + /** + * Function Apply() + * + * Corrects coordinates of the constrained edit handle. + */ + void Apply() + { + Apply( m_constrained ); + } protected: EDIT_TYPE& m_constrained; ///< Point that is constrained by rules implemented by Apply() @@ -234,7 +244,7 @@ public: ///> @copydoc EDIT_POINT::GetPosition() virtual VECTOR2I GetPosition() const { - return m_origin.GetPosition() + ( m_end.GetPosition() - m_origin.GetPosition() ) / 2; + return ( m_origin.GetPosition() + m_end.GetPosition() ) / 2; } ///> @copydoc EDIT_POINT::GetPosition() @@ -266,6 +276,11 @@ public: return m_origin; } + const EDIT_POINT& GetOrigin() const + { + return m_origin; + } + /** * Function GetEnd() * @@ -276,6 +291,11 @@ public: return m_end; } + const EDIT_POINT& GetEnd() const + { + return m_end; + } + bool operator==( const EDIT_POINT& aOther ) const { return GetPosition() == aOther.GetPosition(); @@ -458,11 +478,11 @@ public: {} ///> @copydoc EDIT_CONSTRAINT::Apply() - virtual void Apply() + virtual void Apply( EDIT_POINT& aHandle ) { - VECTOR2I point = m_constrained.GetPosition(); + VECTOR2I point = aHandle.GetPosition(); point.x = m_constrainer.GetPosition().x; - m_constrained.SetPosition( point ); + aHandle.SetPosition( point ); } private: @@ -489,11 +509,11 @@ public: {} ///> @copydoc EDIT_CONSTRAINT::Apply() - virtual void Apply() + virtual void Apply( EDIT_POINT& aHandle ) { - VECTOR2I point = m_constrained.GetPosition(); + VECTOR2I point = aHandle.GetPosition(); point.y = m_constrainer.GetPosition().y; - m_constrained.SetPosition( point ); + aHandle.SetPosition( point ); } private: @@ -521,7 +541,7 @@ public: {} ///> @copydoc EDIT_CONSTRAINT::Apply() - virtual void Apply(); + virtual void Apply( EDIT_POINT& aHandle ); private: const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint. @@ -540,12 +560,11 @@ public: EC_LINE( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ); ///> @copydoc EDIT_CONSTRAINT::Apply() - virtual void Apply(); + virtual void Apply( EDIT_POINT& aHandle ); private: EDIT_POINT m_constrainer; ///< Point that imposes the constraint. - double m_coefA; ///< Line A coefficient (y = Ax + B) - double m_coefB; ///< Line B coefficient (y = Ax + B) + VECTOR2I m_line; ///< Vector representing the constraining line. }; @@ -569,7 +588,7 @@ public: {} ///> @copydoc EDIT_CONSTRAINT::Apply() - virtual void Apply(); + virtual void Apply( EDIT_POINT& aHandle ); private: ///> Point that imposes the constraint (center of the circle). @@ -594,14 +613,23 @@ public: virtual ~EC_CONVERGING(); ///> @copydoc EDIT_CONSTRAINT::Apply() - virtual void Apply(); + virtual void Apply( EDIT_POINT& aHandle ); private: - EC_LINE* m_originSideConstraint; ///< Constraint for origin side segment - EC_LINE* m_endSideConstraint; ///< Constraint for end side segment - EDIT_LINE& m_line; ///< Dragged segment - EDIT_POINTS& m_editPoints; ///< EDIT_POINT instance storing modified lines - double m_coefA; ///< Original dragged segment A coefficient (y = Ax + B) + ///> Constraint for origin side segment. + EDIT_CONSTRAINT* m_originSideConstraint; + + ///> Constraint for end side segment. + EDIT_CONSTRAINT* m_endSideConstraint; + + ///> Dragged segment. + EDIT_LINE& m_line; + + ///> EDIT_POINTS instance that stores currently modified lines. + EDIT_POINTS& m_editPoints; + + ///> Vector that represents the initial direction of the dragged segment. + VECTOR2I m_draggedVector; }; #endif /* EDIT_POINTS_H_ */ From 1ff99b47c8ad5d32e97cef6fee60d98f1ab84953 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 18 Mar 2014 11:09:43 +0100 Subject: [PATCH 076/134] Fixed triple click bug while drawing zones with DRAWING_TOOL. --- pcbnew/tools/drawing_tool.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 41bb93340a..03be29686b 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -1006,6 +1006,8 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) m_frame->OnModify(); m_frame->SaveCopyInUndoList( zone, UR_NEW ); + + zone = NULL; } else delete zone; From 4d6f628a1fcf10656539bfc1a56fdd60d6ea277d Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 18 Mar 2014 11:33:49 +0100 Subject: [PATCH 077/134] Minor fixes to zone drawing tool. --- pcbnew/tools/drawing_tool.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 03be29686b..67b2b607b1 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -970,10 +970,15 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) if( numPoints > 0 ) // cancel the current zone { delete zone; + zone = NULL; m_controls->SetAutoPan( false ); if( direction45 ) + { preview.Remove( &line45 ); + direction45 = false; + } + preview.FreeItems(); updatePreview = true; @@ -1010,10 +1015,20 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) zone = NULL; } else + { delete zone; + zone = NULL; + } numPoints = 0; m_controls->SetAutoPan( false ); + + if( direction45 ) + { + preview.Remove( &line45 ); + direction45 = false; + } + preview.FreeItems(); updatePreview = true; } From 342fd6e19eaf9a941b15df0696f7ecbe35206de1 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 18 Mar 2014 13:57:10 +0100 Subject: [PATCH 078/134] EC_CONVERGING handles colinear lines properly. --- include/geometry/seg.h | 14 +++++++------- pcbnew/tools/edit_points.cpp | 28 +++++++++++++++++++++++----- pcbnew/tools/edit_points.h | 4 ++++ 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/include/geometry/seg.h b/include/geometry/seg.h index 7e789f9d21..cf5b8d50c9 100644 --- a/include/geometry/seg.h +++ b/include/geometry/seg.h @@ -244,14 +244,14 @@ public: */ bool Collinear( const SEG& aSeg ) const { - ecoord qa1 = A.y - B.y; - ecoord qb1 = B.x - A.x; - ecoord qc1 = -qa1 * A.x - qb1 * A.y; - ecoord qa2 = aSeg.A.y - aSeg.B.y; - ecoord qb2 = aSeg.B.x - aSeg.A.x; - ecoord qc2 = -qa2 * aSeg.A.x - qb2 * aSeg.A.y; + ecoord qa = A.y - B.y; + ecoord qb = B.x - A.x; + ecoord qc = -qa * A.x - qb * A.y; - return ( qa1 == qa2 ) && ( qb1 == qb2 ) && ( qc1 == qc2 ); + ecoord d1 = std::abs( aSeg.A.x * qa + aSeg.A.y * qb + qc ); + ecoord d2 = std::abs( aSeg.B.x * qa + aSeg.B.y * qb + qc ); + + return ( d1 <= 1 && d2 <= 1 ); } /** diff --git a/pcbnew/tools/edit_points.cpp b/pcbnew/tools/edit_points.cpp index 23c8f1dbf4..291caae818 100644 --- a/pcbnew/tools/edit_points.cpp +++ b/pcbnew/tools/edit_points.cpp @@ -194,7 +194,8 @@ void EC_CIRCLE::Apply( EDIT_POINT& aHandle ) EC_CONVERGING::EC_CONVERGING( EDIT_LINE& aLine, EDIT_POINTS& aPoints ) : - EDIT_CONSTRAINT( aLine.GetOrigin() ), m_line( aLine ), m_editPoints( aPoints ) + EDIT_CONSTRAINT( aLine.GetOrigin() ), + m_colinearConstraint( NULL ), m_line( aLine ), m_editPoints( aPoints ) { // Dragged segment endings EDIT_POINT& origin = aLine.GetOrigin(); @@ -209,7 +210,17 @@ EC_CONVERGING::EC_CONVERGING( EDIT_LINE& aLine, EDIT_POINTS& aPoints ) : m_endSideConstraint = new EC_LINE( end, nextEnd ); // Store the current vector of the line - m_draggedVector = end.GetPosition() - origin.GetPosition() ; + m_draggedVector = end.GetPosition() - origin.GetPosition(); + + // Check for colinearity + SEG originSide( origin.GetPosition(), prevOrigin.GetPosition() ); + SEG endSide( end.GetPosition(), nextEnd.GetPosition() ); + SEG dragged( origin.GetPosition(), end.GetPosition() ); + + if( dragged.Collinear( originSide ) ) + m_colinearConstraint = m_originSideConstraint; + else if( dragged.Collinear( endSide ) ) + m_colinearConstraint = m_endSideConstraint; } @@ -217,18 +228,25 @@ EC_CONVERGING::~EC_CONVERGING() { delete m_originSideConstraint; delete m_endSideConstraint; + // m_colinearConstraint should not be freed, it is a pointer to one of the above } void EC_CONVERGING::Apply( EDIT_POINT& aHandle ) { - // The dragged segment - SEG dragged( m_line.GetPosition(), m_line.GetPosition() + m_draggedVector ); - // The dragged segment endpoints EDIT_POINT& origin = m_line.GetOrigin(); EDIT_POINT& end = m_line.GetEnd(); + if( m_colinearConstraint ) + { + m_colinearConstraint->Apply( origin ); + m_colinearConstraint->Apply( end ); + } + + // The dragged segment + SEG dragged( origin.GetPosition(), origin.GetPosition() + m_draggedVector ); + // Do not allow points on the adjacent segments move freely m_originSideConstraint->Apply(); m_endSideConstraint->Apply(); diff --git a/pcbnew/tools/edit_points.h b/pcbnew/tools/edit_points.h index 0c1dd343c2..b2e99988e6 100644 --- a/pcbnew/tools/edit_points.h +++ b/pcbnew/tools/edit_points.h @@ -622,6 +622,10 @@ private: ///> Constraint for end side segment. EDIT_CONSTRAINT* m_endSideConstraint; + ///> Additional constriant, applied when at least two points are collinear. It is a pointer to + ///> m_[origin/end]SideConstraint, so it should not be freed. + EDIT_CONSTRAINT* m_colinearConstraint; + ///> Dragged segment. EDIT_LINE& m_line; From dbcc18ab31e9bd8ef9abc1911e08d40c7e09cba0 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 18 Mar 2014 14:01:09 +0100 Subject: [PATCH 079/134] Enabled autopanning while drawing zones. --- pcbnew/tools/drawing_tool.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 67b2b607b1..e35956f213 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -1040,6 +1040,8 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) ZONE_SETTINGS zoneInfo = m_frame->GetZoneSettings(); zoneInfo.m_CurrentZone_Layer = m_frame->GetScreen()->m_Active_Layer; + m_controls->SetAutoPan( true ); + // Show options dialog ZONE_EDIT_T dialogResult; if( aKeepout ) @@ -1053,7 +1055,10 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) } if( dialogResult == ZONE_ABORT ) + { + m_controls->SetAutoPan( false ); continue; + } // Apply the selected settings zone = new ZONE_CONTAINER( m_board ); From 17ec7ace4c14cb0e637c352cd7a661885697d563 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 18 Mar 2014 14:52:22 +0100 Subject: [PATCH 080/134] Breaking outlines for zones using POINT_EDITOR. --- pcbnew/tools/point_editor.cpp | 49 +++++++++++++++++++++++++++++++++++ pcbnew/tools/point_editor.h | 3 +++ 2 files changed, 52 insertions(+) diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 4ae508288c..295c90cdd5 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "common_actions.h" @@ -224,6 +225,11 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) m_dragPoint = point; } + else if( evt->IsDblClick( BUT_LEFT ) ) + { + breakOutline( controls->GetCursorPosition() ); + } + else if( evt->IsDrag( BUT_LEFT ) && m_dragPoint ) { if( !modified ) @@ -605,3 +611,46 @@ EDIT_POINT POINT_EDITOR::get45DegConstrainer() const // In any other case we may align item to its original position return m_original; } + + + +void POINT_EDITOR::breakOutline( const VECTOR2I& aBreakPoint ) +{ + EDA_ITEM* item = m_editPoints->GetParent(); + const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + + if( item->Type() == PCB_ZONE_AREA_T ) + { + getEditFrame()->OnModify(); + getEditFrame()->SaveCopyInUndoList( selection.items, UR_CHANGED ); + + ZONE_CONTAINER* zone = static_cast( item ); + CPolyLine* outline = zone->Outline(); + + // Handle the last segment, so other segments can be easily handled in a loop + unsigned int nearestIdx = outline->GetCornersCount() - 1, nextNearestIdx = 0; + SEG side( VECTOR2I( outline->GetPos( nearestIdx ) ), + VECTOR2I( outline->GetPos( nextNearestIdx ) ) ); + unsigned int nearestDist = side.Distance( aBreakPoint ); + + for( int i = 0; i < outline->GetCornersCount() - 2; ++i ) + { + SEG side( VECTOR2I( outline->GetPos( i ) ), VECTOR2I( outline->GetPos( i + 1 ) ) ); + + unsigned int distance = side.Distance( aBreakPoint ); + if( distance < nearestDist ) + { + nearestDist = distance; + nearestIdx = i; + nextNearestIdx = i + 1; + } + } + + // Find the point on the closest segment + SEG nearestSide( VECTOR2I( outline->GetPos( nearestIdx ) ), + VECTOR2I( outline->GetPos( nextNearestIdx ) ) ); + VECTOR2I nearestPoint = nearestSide.NearestPoint( aBreakPoint ); + + outline->InsertCorner( nearestIdx, nearestPoint.x, nearestPoint.y ); + } +} diff --git a/pcbnew/tools/point_editor.h b/pcbnew/tools/point_editor.h index fe77760c3d..7fdf655809 100644 --- a/pcbnew/tools/point_editor.h +++ b/pcbnew/tools/point_editor.h @@ -95,6 +95,9 @@ private: ///> Returns a point that should be used as a constrainer for 45 degrees mode. EDIT_POINT get45DegConstrainer() const; + // TODO docs + void breakOutline( const VECTOR2I& aBreakPoint ); + ///> Sets up handlers for various events. void setTransitions() { From 9783aaf3e66c4dad7c221ddcb6da5d6d77cce726 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 18 Mar 2014 15:46:38 +0100 Subject: [PATCH 081/134] Splitting DRAWSEGMENTs with POINT_EDITOR. --- pcbnew/tools/point_editor.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 295c90cdd5..666b385d15 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -38,6 +38,7 @@ #include #include #include +#include /** * Class POINT_EDITOR @@ -653,4 +654,30 @@ void POINT_EDITOR::breakOutline( const VECTOR2I& aBreakPoint ) outline->InsertCorner( nearestIdx, nearestPoint.x, nearestPoint.y ); } + + else if( item->Type() == PCB_LINE_T ) + { + getEditFrame()->OnModify(); + getEditFrame()->SaveCopyInUndoList( selection.items, UR_CHANGED ); + + DRAWSEGMENT* segment = static_cast( item ); + + if( segment->GetShape() == S_SEGMENT ) + { + SEG seg( segment->GetStart(), segment->GetEnd() ); + VECTOR2I nearestPoint = seg.NearestPoint( aBreakPoint ); + + // Move the end of the line to the break point.. + segment->SetEnd( wxPoint( nearestPoint.x, nearestPoint.y ) ); + + // and add another one starting from the break point + DRAWSEGMENT* newSegment = new DRAWSEGMENT( *segment ); + newSegment->ClearSelected(); + newSegment->SetStart( wxPoint( nearestPoint.x, nearestPoint.y ) ); + newSegment->SetEnd( wxPoint( seg.B.x, seg.B.y ) ); + + getModel( PCB_T )->Add( newSegment ); + getView()->Add( newSegment ); + } + } } From 6a1d3445419d1bbb0449b1421343c8c64d6bc091 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 18 Mar 2014 16:25:46 +0100 Subject: [PATCH 082/134] Instant dragging (without prior selection). --- pcbnew/tools/selection_tool.cpp | 34 +++++++++++++++++++++++++-------- pcbnew/tools/selection_tool.h | 5 ++++- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index de1624ad74..14f430fcca 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -141,10 +141,18 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) { if( m_selection.Empty() || m_additive ) { - // If nothings has been selected or user wants to select more - // draw the selection box - selectMultiple(); + if( !selectSingle( getView()->ToWorld( getViewControls()->GetMousePosition() ), false ) ) + { + // If nothings has been selected or user wants to select more + // draw the selection box + selectMultiple(); + } + else + { + m_toolMgr->InvokeTool( "pcbnew.InteractiveEdit" ); + } } + else { // Check if dragging has started within any of selected items bounding box @@ -205,7 +213,7 @@ void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem ) } -void SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere ) +bool SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere, bool aAllowDisambiguation ) { BOARD* pcb = getModel( PCB_T ); BOARD_ITEM* item; @@ -220,11 +228,13 @@ void SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere ) case 0: if( !m_additive ) clearSelection(); - break; + + return false; case 1: toggleSelection( collector[0] ); - break; + + return true; default: // Remove unselectable items @@ -238,17 +248,25 @@ void SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere ) if( collector.GetCount() == 1 ) { toggleSelection( collector[0] ); + + return true; } - else if( collector.GetCount() > 1 ) + + else if( aAllowDisambiguation && collector.GetCount() > 1 ) { item = disambiguationMenu( &collector ); if( item ) + { toggleSelection( item ); - } + return true; + } + } break; } + + return false; } diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h index 7072c89655..ca46f8bbdd 100644 --- a/pcbnew/tools/selection_tool.h +++ b/pcbnew/tools/selection_tool.h @@ -130,8 +130,11 @@ private: * place, there is a menu displayed that allows to choose the item. * * @param aWhere is the place where the item should be selected. + * @param aAllowDisambiguation decides what to do in case of disambiguation. If true, then + * a menu is shown, otherise function finishes without selecting anything. + * @return True if an item was selected, false otherwise. */ - void selectSingle( const VECTOR2I& aWhere ); + bool selectSingle( const VECTOR2I& aWhere, bool aAllowDisambiguation = true ); /** * Function selectMultiple() From e6a7ff3c34cecaf76cd61b83f2688264a6213fca Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 18 Mar 2014 16:55:06 +0100 Subject: [PATCH 083/134] Isolated EDIT_CONSTRAINTs to different .cpp/.h files. --- pcbnew/CMakeLists.txt | 1 + pcbnew/tools/edit_constraints.cpp | 175 +++++++++++++++++++++ pcbnew/tools/edit_constraints.h | 242 ++++++++++++++++++++++++++++++ pcbnew/tools/edit_points.cpp | 135 +---------------- pcbnew/tools/edit_points.h | 225 +-------------------------- 5 files changed, 420 insertions(+), 358 deletions(-) create mode 100644 pcbnew/tools/edit_constraints.cpp create mode 100644 pcbnew/tools/edit_constraints.h diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 60deda1c4f..dee4a0af07 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -256,6 +256,7 @@ set( PCBNEW_CLASS_SRCS tools/selection_area.cpp tools/bright_box.cpp tools/edit_points.cpp + tools/edit_constraints.cpp tools/point_editor.cpp tools/drawing_tool.cpp tools/edit_tool.cpp diff --git a/pcbnew/tools/edit_constraints.cpp b/pcbnew/tools/edit_constraints.cpp new file mode 100644 index 0000000000..91e14ea82d --- /dev/null +++ b/pcbnew/tools/edit_constraints.cpp @@ -0,0 +1,175 @@ +/* + * This program source code file is part of KICAD, a free EDA CAD application. + * + * Copyright (C) 2014 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 "edit_constraints.h" +#include "edit_points.h" + +#include + +void EC_VERTICAL::Apply( EDIT_POINT& aHandle ) +{ + VECTOR2I point = aHandle.GetPosition(); + point.x = m_constrainer.GetPosition().x; + aHandle.SetPosition( point ); +} + + +void EC_HORIZONTAL::Apply( EDIT_POINT& aHandle ) +{ + VECTOR2I point = aHandle.GetPosition(); + point.y = m_constrainer.GetPosition().y; + aHandle.SetPosition( point ); +} + + +void EC_45DEGREE::Apply( EDIT_POINT& aHandle ) +{ + // Current line vector + VECTOR2I lineVector( aHandle.GetPosition() - m_constrainer.GetPosition() ); + double angle = lineVector.Angle(); + + // Find the closest angle, which is a multiple of 45 degrees + double newAngle = round( angle / ( M_PI / 4.0 ) ) * M_PI / 4.0; + VECTOR2I newLineVector = lineVector.Rotate( newAngle - angle ); + + aHandle.SetPosition( m_constrainer.GetPosition() + newLineVector ); +} + + +EC_LINE::EC_LINE( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : + EDIT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) +{ + m_line = m_constrained.GetPosition() - m_constrainer.GetPosition(); +} + + +void EC_LINE::Apply( EDIT_POINT& aHandle ) +{ + SEG main( m_constrainer.GetPosition(), m_constrainer.GetPosition() + m_line ); + SEG projection( aHandle.GetPosition(), aHandle.GetPosition() + m_line.Perpendicular() ); + + if( OPT_VECTOR2I intersect = projection.IntersectLines( main ) ) + aHandle.SetPosition( *intersect ); +} + + +void EC_CIRCLE::Apply( EDIT_POINT& aHandle ) +{ + VECTOR2I centerToEnd = m_end.GetPosition() - m_center.GetPosition(); + VECTOR2I centerToPoint = aHandle.GetPosition() - m_center.GetPosition(); + + int radius = centerToEnd.EuclideanNorm(); + double angle = centerToPoint.Angle(); + + VECTOR2I newLine( radius, 0 ); + newLine = newLine.Rotate( angle ); + + aHandle.SetPosition( m_center.GetPosition() + newLine ); +} + + +EC_CONVERGING::EC_CONVERGING( EDIT_LINE& aLine, EDIT_POINTS& aPoints ) : + EDIT_CONSTRAINT( aLine.GetOrigin() ), + m_colinearConstraint( NULL ), m_line( aLine ), m_editPoints( aPoints ) +{ + // Dragged segment endings + EDIT_POINT& origin = aLine.GetOrigin(); + EDIT_POINT& end = aLine.GetEnd(); + + // Previous and next points, to make constraining lines (adjacent to the dragged line) + EDIT_POINT& prevOrigin = *aPoints.Previous( origin ); + EDIT_POINT& nextEnd = *aPoints.Next( end ); + + // Constraints for segments adjacent to the dragged one + m_originSideConstraint = new EC_LINE( origin, prevOrigin ); + m_endSideConstraint = new EC_LINE( end, nextEnd ); + + // Store the current vector of the line + m_draggedVector = end.GetPosition() - origin.GetPosition(); + + // Check for colinearity + SEG originSide( origin.GetPosition(), prevOrigin.GetPosition() ); + SEG endSide( end.GetPosition(), nextEnd.GetPosition() ); + SEG dragged( origin.GetPosition(), end.GetPosition() ); + + if( dragged.Collinear( originSide ) ) + m_colinearConstraint = m_originSideConstraint; + else if( dragged.Collinear( endSide ) ) + m_colinearConstraint = m_endSideConstraint; +} + + +EC_CONVERGING::~EC_CONVERGING() +{ + delete m_originSideConstraint; + delete m_endSideConstraint; + // m_colinearConstraint should not be freed, it is a pointer to one of the above +} + + +void EC_CONVERGING::Apply( EDIT_POINT& aHandle ) +{ + // The dragged segment endpoints + EDIT_POINT& origin = m_line.GetOrigin(); + EDIT_POINT& end = m_line.GetEnd(); + + if( m_colinearConstraint ) + { + m_colinearConstraint->Apply( origin ); + m_colinearConstraint->Apply( end ); + } + + // The dragged segment + SEG dragged( origin.GetPosition(), origin.GetPosition() + m_draggedVector ); + + // Do not allow points on the adjacent segments move freely + m_originSideConstraint->Apply(); + m_endSideConstraint->Apply(); + + EDIT_POINT& prevOrigin = *m_editPoints.Previous( origin ); + EDIT_POINT& nextEnd = *m_editPoints.Next( end ); + + // Two segments adjacent to the dragged segment + SEG originSide = SEG( origin.GetPosition(), prevOrigin.GetPosition() ); + SEG endSide = SEG( end.GetPosition(), nextEnd.GetPosition() ); + + // First intersection point (dragged segment against origin side) + if( OPT_VECTOR2I originIntersect = dragged.IntersectLines( originSide ) ) + origin.SetPosition( *originIntersect ); + + // Second intersection point (dragged segment against end side) + if( OPT_VECTOR2I endIntersect = dragged.IntersectLines( endSide ) ) + end.SetPosition( *endIntersect ); + + // Check if adjacent segments intersect (did we dragged the line to the point that it may + // create a selfintersecting polygon?) + originSide = SEG( origin.GetPosition(), prevOrigin.GetPosition() ); + endSide = SEG( end.GetPosition(), nextEnd.GetPosition() ); + + if( OPT_VECTOR2I originEndIntersect = endSide.Intersect( originSide ) ) + { + origin.SetPosition( *originEndIntersect ); + end.SetPosition( *originEndIntersect ); + } +} diff --git a/pcbnew/tools/edit_constraints.h b/pcbnew/tools/edit_constraints.h new file mode 100644 index 0000000000..b26c4f69f7 --- /dev/null +++ b/pcbnew/tools/edit_constraints.h @@ -0,0 +1,242 @@ +/* + * This program source code file is part of KICAD, a free EDA CAD application. + * + * Copyright (C) 2014 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_CONSTRAINTS_H_ +#define EDIT_CONSTRAINTS_H_ + +#include + +class EDIT_POINT; +class EDIT_LINE; +class EDIT_POINTS; + +/** + * Class EDIT_CONSTRAINT + * + * Allows to describe constraints between two edit handles. After the constrained handle is changed, + * Apply() has to be called to fix its coordinates according to the implemented constraint. + */ +template +class EDIT_CONSTRAINT +{ +public: + /** + * Constructor + * + * @param aConstrained is EDIT_POINT to which the constraint is applied. + */ + EDIT_CONSTRAINT( EDIT_TYPE& aConstrained ) : m_constrained( aConstrained ) {}; + + virtual ~EDIT_CONSTRAINT() {}; + + /** + * Function Apply() + * + * Corrects coordinates of the constrained edit handle. + */ + virtual void Apply( EDIT_TYPE& aHandle ) = 0; + + /** + * Function Apply() + * + * Corrects coordinates of the constrained edit handle. + */ + void Apply() + { + Apply( m_constrained ); + } + +protected: + EDIT_TYPE& m_constrained; ///< Point that is constrained by rules implemented by Apply() +}; + + +/** + * Class EC_VERTICAL. + * + * EDIT_CONSTRAINT that imposes a constraint that two points have to have the same X coordinate. + */ +class EC_VERTICAL : public EDIT_CONSTRAINT +{ +public: + /** + * Constructor. + * + * @param aConstrained is the point that is put under constrain. + * @param aConstrainer is the point that is the source of the constrain. + */ + EC_VERTICAL( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : + EDIT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) + {} + + ///> @copydoc EDIT_CONSTRAINT::Apply() + virtual void Apply( EDIT_POINT& aHandle ); + +private: + const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint. +}; + + +/** + * Class EC_HORIZONTAL. + * + * EDIT_CONSTRAINT that imposes a constraint that two points have to have the same Y coordinate. + */ +class EC_HORIZONTAL : public EDIT_CONSTRAINT +{ +public: + /** + * Constructor. + * + * @param aConstrained is the point that is put under constrain. + * @param aConstrainer is the point that is the source of the constrain. + */ + EC_HORIZONTAL( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : + EDIT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) + {} + + ///> @copydoc EDIT_CONSTRAINT::Apply() + virtual void Apply( EDIT_POINT& aHandle ); + +private: + const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint. +}; + + +/** + * Class EC_45DEGREE + * + * EDIT_CONSTRAINT that imposes a constraint that two to be located at angle of 45 degree + * multiplicity. + */ +class EC_45DEGREE : public EDIT_CONSTRAINT +{ +public: + /** + * Constructor. + * + * @param aConstrained is the point that is put under constrain. + * @param aConstrainer is the point that is the source of the constrain. + */ + EC_45DEGREE( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : + EDIT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) + {} + + ///> @copydoc EDIT_CONSTRAINT::Apply() + virtual void Apply( EDIT_POINT& aHandle ); + +private: + const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint. +}; + + +/** + * Class EC_LINE + * + * EDIT_CONSTRAINT that imposes a constraint that a point has to lie on a line (determined + * by 2 points). + */ +class EC_LINE : public EDIT_CONSTRAINT +{ +public: + EC_LINE( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ); + + ///> @copydoc EDIT_CONSTRAINT::Apply() + virtual void Apply( EDIT_POINT& aHandle ); + +private: + const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint. + VECTOR2I m_line; ///< Vector representing the constraining line. +}; + + +/** + * Class EC_CIRCLE. + * + * EDIT_CONSTRAINT that imposes a constraint that a point has to lie on a circle. + */ +class EC_CIRCLE : public EDIT_CONSTRAINT +{ +public: + /** + * Constructor. + * + * @param aConstrained is the point that is put under constrain. + * @parama aCenter is the point that is the center of the circle. + * @parama aEnd is the point that decides on the radius of the circle. + */ + EC_CIRCLE( EDIT_POINT& aConstrained, const EDIT_POINT& aCenter, const EDIT_POINT& aEnd ) : + EDIT_CONSTRAINT( aConstrained ), m_center( aCenter ), m_end( aEnd ) + {} + + ///> @copydoc EDIT_CONSTRAINT::Apply() + virtual void Apply( EDIT_POINT& aHandle ); + +private: + ///> Point that imposes the constraint (center of the circle). + const EDIT_POINT& m_center; + + ///> Point that imposes the constraint (decides on the radius of the circle). + const EDIT_POINT& m_end; +}; + + +/** + * Class EC_CONVERGING + * + * EDIT_CONSTRAINT for 3 segment: dragged and two adjacent ones, enforcing to keep their slopes + * and allows only to change ending points. Applied to zones. + */ +class EC_CONVERGING : public EDIT_CONSTRAINT +{ +public: + EC_CONVERGING( EDIT_LINE& aLine, EDIT_POINTS& aPoints ); + + virtual ~EC_CONVERGING(); + + ///> @copydoc EDIT_CONSTRAINT::Apply() + virtual void Apply( EDIT_POINT& aHandle ); + +private: + ///> Constraint for origin side segment. + EDIT_CONSTRAINT* m_originSideConstraint; + + ///> Constraint for end side segment. + EDIT_CONSTRAINT* m_endSideConstraint; + + ///> Additional constriant, applied when at least two points are collinear. It is a pointer to + ///> m_[origin/end]SideConstraint, so it should not be freed. + EDIT_CONSTRAINT* m_colinearConstraint; + + ///> Dragged segment. + EDIT_LINE& m_line; + + ///> EDIT_POINTS instance that stores currently modified lines. + EDIT_POINTS& m_editPoints; + + ///> Vector that represents the initial direction of the dragged segment. + VECTOR2I m_draggedVector; +}; + +#endif /* EDIT_CONSTRAINTS_H_ */ diff --git a/pcbnew/tools/edit_points.cpp b/pcbnew/tools/edit_points.cpp index 291caae818..9f6069d551 100644 --- a/pcbnew/tools/edit_points.cpp +++ b/pcbnew/tools/edit_points.cpp @@ -24,9 +24,8 @@ #include -#include "edit_points.h" #include -#include +#include "edit_points.h" bool EDIT_POINT::WithinPoint( const VECTOR2I& aPoint, unsigned int aSize ) const { @@ -145,135 +144,3 @@ void EDIT_POINTS::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const aGal->PopDepth(); } - - -void EC_45DEGREE::Apply( EDIT_POINT& aHandle ) -{ - // Current line vector - VECTOR2I lineVector( aHandle.GetPosition() - m_constrainer.GetPosition() ); - double angle = lineVector.Angle(); - - // Find the closest angle, which is a multiple of 45 degrees - double newAngle = round( angle / ( M_PI / 4.0 ) ) * M_PI / 4.0; - VECTOR2I newLineVector = lineVector.Rotate( newAngle - angle ); - - aHandle.SetPosition( m_constrainer.GetPosition() + newLineVector ); -} - - -EC_LINE::EC_LINE( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : - EDIT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) -{ - m_line = m_constrained.GetPosition() - m_constrainer.GetPosition(); -} - - -void EC_LINE::Apply( EDIT_POINT& aHandle ) -{ - SEG main( m_constrainer.GetPosition(), m_constrainer.GetPosition() + m_line ); - SEG projection( aHandle.GetPosition(), aHandle.GetPosition() + m_line.Perpendicular() ); - - if( OPT_VECTOR2I intersect = projection.IntersectLines( main ) ) - aHandle.SetPosition( *intersect ); -} - - -void EC_CIRCLE::Apply( EDIT_POINT& aHandle ) -{ - VECTOR2I centerToEnd = m_end.GetPosition() - m_center.GetPosition(); - VECTOR2I centerToPoint = aHandle.GetPosition() - m_center.GetPosition(); - - int radius = centerToEnd.EuclideanNorm(); - double angle = centerToPoint.Angle(); - - VECTOR2I newLine( radius, 0 ); - newLine = newLine.Rotate( angle ); - - aHandle.SetPosition( m_center.GetPosition() + newLine ); -} - - -EC_CONVERGING::EC_CONVERGING( EDIT_LINE& aLine, EDIT_POINTS& aPoints ) : - EDIT_CONSTRAINT( aLine.GetOrigin() ), - m_colinearConstraint( NULL ), m_line( aLine ), m_editPoints( aPoints ) -{ - // Dragged segment endings - EDIT_POINT& origin = aLine.GetOrigin(); - EDIT_POINT& end = aLine.GetEnd(); - - // Previous and next points, to make constraining lines (adjacent to the dragged line) - EDIT_POINT& prevOrigin = *aPoints.Previous( origin ); - EDIT_POINT& nextEnd = *aPoints.Next( end ); - - // Constraints for segments adjacent to the dragged one - m_originSideConstraint = new EC_LINE( origin, prevOrigin ); - m_endSideConstraint = new EC_LINE( end, nextEnd ); - - // Store the current vector of the line - m_draggedVector = end.GetPosition() - origin.GetPosition(); - - // Check for colinearity - SEG originSide( origin.GetPosition(), prevOrigin.GetPosition() ); - SEG endSide( end.GetPosition(), nextEnd.GetPosition() ); - SEG dragged( origin.GetPosition(), end.GetPosition() ); - - if( dragged.Collinear( originSide ) ) - m_colinearConstraint = m_originSideConstraint; - else if( dragged.Collinear( endSide ) ) - m_colinearConstraint = m_endSideConstraint; -} - - -EC_CONVERGING::~EC_CONVERGING() -{ - delete m_originSideConstraint; - delete m_endSideConstraint; - // m_colinearConstraint should not be freed, it is a pointer to one of the above -} - - -void EC_CONVERGING::Apply( EDIT_POINT& aHandle ) -{ - // The dragged segment endpoints - EDIT_POINT& origin = m_line.GetOrigin(); - EDIT_POINT& end = m_line.GetEnd(); - - if( m_colinearConstraint ) - { - m_colinearConstraint->Apply( origin ); - m_colinearConstraint->Apply( end ); - } - - // The dragged segment - SEG dragged( origin.GetPosition(), origin.GetPosition() + m_draggedVector ); - - // Do not allow points on the adjacent segments move freely - m_originSideConstraint->Apply(); - m_endSideConstraint->Apply(); - - EDIT_POINT& prevOrigin = *m_editPoints.Previous( origin ); - EDIT_POINT& nextEnd = *m_editPoints.Next( end ); - - // Two segments adjacent to the dragged segment - SEG originSide = SEG( origin.GetPosition(), prevOrigin.GetPosition() ); - SEG endSide = SEG( end.GetPosition(), nextEnd.GetPosition() ); - - // First intersection point (dragged segment against origin side) - if( OPT_VECTOR2I originIntersect = dragged.IntersectLines( originSide ) ) - origin.SetPosition( *originIntersect ); - - // Second intersection point (dragged segment against end side) - if( OPT_VECTOR2I endIntersect = dragged.IntersectLines( endSide ) ) - end.SetPosition( *endIntersect ); - - // Check if adjacent segments intersect (did we dragged the line to the point that it may - // create a selfintersecting polygon?) - originSide = SEG( origin.GetPosition(), prevOrigin.GetPosition() ); - endSide = SEG( end.GetPosition(), nextEnd.GetPosition() ); - - if( OPT_VECTOR2I originEndIntersect = endSide.Intersect( originSide ) ) - { - origin.SetPosition( *originEndIntersect ); - end.SetPosition( *originEndIntersect ); - } -} diff --git a/pcbnew/tools/edit_points.h b/pcbnew/tools/edit_points.h index b2e99988e6..7177bd5241 100644 --- a/pcbnew/tools/edit_points.h +++ b/pcbnew/tools/edit_points.h @@ -25,57 +25,12 @@ #ifndef EDIT_POINTS_H_ #define EDIT_POINTS_H_ -#include -#include #include -#include - #include #include -class EDIT_POINT; - -/** - * Class EDIT_CONSTRAINT - * - * Allows to describe constraints between two edit handles. After the constrained handle is changed, - * Apply() has to be called to fix its coordinates according to the implemented constraint. - */ -template -class EDIT_CONSTRAINT -{ -public: - /** - * Constructor - * - * @param aConstrained is EDIT_POINT to which the constraint is applied. - */ - EDIT_CONSTRAINT( EDIT_TYPE& aConstrained ) : m_constrained( aConstrained ) {}; - - virtual ~EDIT_CONSTRAINT() {}; - - /** - * Function Apply() - * - * Corrects coordinates of the constrained edit handle. - */ - virtual void Apply( EDIT_TYPE& aHandle ) = 0; - - /** - * Function Apply() - * - * Corrects coordinates of the constrained edit handle. - */ - void Apply() - { - Apply( m_constrained ); - } - -protected: - EDIT_TYPE& m_constrained; ///< Point that is constrained by rules implemented by Apply() -}; - +#include "edit_constraints.h" /** * Class EDIT_POINT @@ -458,182 +413,4 @@ private: std::deque m_lines; ///< EDIT_LINEs for modifying m_parent }; - -/** - * Class EC_VERTICAL. - * - * EDIT_CONSTRAINT that imposes a constraint that two points have to have the same X coordinate. - */ -class EC_VERTICAL : public EDIT_CONSTRAINT -{ -public: - /** - * Constructor. - * - * @param aConstrained is the point that is put under constrain. - * @param aConstrainer is the point that is the source of the constrain. - */ - EC_VERTICAL( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : - EDIT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) - {} - - ///> @copydoc EDIT_CONSTRAINT::Apply() - virtual void Apply( EDIT_POINT& aHandle ) - { - VECTOR2I point = aHandle.GetPosition(); - point.x = m_constrainer.GetPosition().x; - aHandle.SetPosition( point ); - } - -private: - const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint. -}; - - -/** - * Class EC_HORIZONTAL. - * - * EDIT_CONSTRAINT that imposes a constraint that two points have to have the same Y coordinate. - */ -class EC_HORIZONTAL : public EDIT_CONSTRAINT -{ -public: - /** - * Constructor. - * - * @param aConstrained is the point that is put under constrain. - * @param aConstrainer is the point that is the source of the constrain. - */ - EC_HORIZONTAL( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : - EDIT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) - {} - - ///> @copydoc EDIT_CONSTRAINT::Apply() - virtual void Apply( EDIT_POINT& aHandle ) - { - VECTOR2I point = aHandle.GetPosition(); - point.y = m_constrainer.GetPosition().y; - aHandle.SetPosition( point ); - } - -private: - const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint. -}; - - -/** - * Class EC_45DEGREE - * - * EDIT_CONSTRAINT that imposes a constraint that two to be located at angle of 45 degree - * multiplicity. - */ -class EC_45DEGREE : public EDIT_CONSTRAINT -{ -public: - /** - * Constructor. - * - * @param aConstrained is the point that is put under constrain. - * @param aConstrainer is the point that is the source of the constrain. - */ - EC_45DEGREE( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) : - EDIT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer ) - {} - - ///> @copydoc EDIT_CONSTRAINT::Apply() - virtual void Apply( EDIT_POINT& aHandle ); - -private: - const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint. -}; - - -/** - * Class EC_LINE - * - * EDIT_CONSTRAINT that imposes a constraint that a point has to lie on a line (determined - * by 2 points). - */ -class EC_LINE : public EDIT_CONSTRAINT -{ -public: - EC_LINE( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ); - - ///> @copydoc EDIT_CONSTRAINT::Apply() - virtual void Apply( EDIT_POINT& aHandle ); - -private: - EDIT_POINT m_constrainer; ///< Point that imposes the constraint. - VECTOR2I m_line; ///< Vector representing the constraining line. -}; - - -/** - * Class EC_CIRCLE. - * - * EDIT_CONSTRAINT that imposes a constraint that a point has to lie on a circle. - */ -class EC_CIRCLE : public EDIT_CONSTRAINT -{ -public: - /** - * Constructor. - * - * @param aConstrained is the point that is put under constrain. - * @parama aCenter is the point that is the center of the circle. - * @parama aEnd is the point that decides on the radius of the circle. - */ - EC_CIRCLE( EDIT_POINT& aConstrained, const EDIT_POINT& aCenter, const EDIT_POINT& aEnd ) : - EDIT_CONSTRAINT( aConstrained ), m_center( aCenter ), m_end( aEnd ) - {} - - ///> @copydoc EDIT_CONSTRAINT::Apply() - virtual void Apply( EDIT_POINT& aHandle ); - -private: - ///> Point that imposes the constraint (center of the circle). - const EDIT_POINT& m_center; - - ///> Point that imposes the constraint (decides on the radius of the circle). - const EDIT_POINT& m_end; -}; - - -/** - * Class EC_CONVERGING - * - * EDIT_CONSTRAINT for 3 segment: dragged and two adjacent ones, enforcing to keep their slopes - * and allows only to change ending points. Applied to zones. - */ -class EC_CONVERGING : public EDIT_CONSTRAINT -{ -public: - EC_CONVERGING( EDIT_LINE& aLine, EDIT_POINTS& aPoints ); - - virtual ~EC_CONVERGING(); - - ///> @copydoc EDIT_CONSTRAINT::Apply() - virtual void Apply( EDIT_POINT& aHandle ); - -private: - ///> Constraint for origin side segment. - EDIT_CONSTRAINT* m_originSideConstraint; - - ///> Constraint for end side segment. - EDIT_CONSTRAINT* m_endSideConstraint; - - ///> Additional constriant, applied when at least two points are collinear. It is a pointer to - ///> m_[origin/end]SideConstraint, so it should not be freed. - EDIT_CONSTRAINT* m_colinearConstraint; - - ///> Dragged segment. - EDIT_LINE& m_line; - - ///> EDIT_POINTS instance that stores currently modified lines. - EDIT_POINTS& m_editPoints; - - ///> Vector that represents the initial direction of the dragged segment. - VECTOR2I m_draggedVector; -}; - #endif /* EDIT_POINTS_H_ */ From c11b0bc8a615428d558afc00294039d38e8a546f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 18 Mar 2014 17:02:10 +0100 Subject: [PATCH 084/134] Break points for zones are not added in the same place as existing points. --- pcbnew/tools/point_editor.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 666b385d15..1cfdb0a001 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -648,10 +648,16 @@ void POINT_EDITOR::breakOutline( const VECTOR2I& aBreakPoint ) } // Find the point on the closest segment - SEG nearestSide( VECTOR2I( outline->GetPos( nearestIdx ) ), - VECTOR2I( outline->GetPos( nextNearestIdx ) ) ); + VECTOR2I sideOrigin( outline->GetPos( nearestIdx ) ); + VECTOR2I sideEnd( outline->GetPos( nextNearestIdx ) ); + SEG nearestSide( sideOrigin, sideEnd ); VECTOR2I nearestPoint = nearestSide.NearestPoint( aBreakPoint ); + // Do not add points that have the same coordinates as ones that already belong to polygon + // instead, add a point in the middle of the side + if( nearestPoint == sideOrigin || nearestPoint == sideEnd ) + nearestPoint = ( sideOrigin + sideEnd ) / 2; + outline->InsertCorner( nearestIdx, nearestPoint.x, nearestPoint.y ); } From 696a8a89fe57c1c45bd990a989f6cf16c4ca947d Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 19 Mar 2014 11:16:01 +0100 Subject: [PATCH 085/134] Changed cast from float to double in RN_POLY::HitTest. --- 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 ec618c7e9d..5bff81fe4f 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -357,7 +357,7 @@ bool RN_POLY::HitTest( const RN_NODE_PTR& aNode ) const } if( ( xNew < xt ) == ( xt <= xOld ) && /* edge "open" at left end */ - (float)( yt - y1 ) * (float)( x2 - x1 ) < (float)( y2 - y1 ) * (float)( xt - x1 ) ) + (double)( yt - y1 ) * (double)( x2 - x1 ) < (double)( y2 - y1 ) * (double)( xt - x1 ) ) { inside = !inside; } From e1ce30d89d97f1a8506532feef160b3466965725 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 19 Mar 2014 11:57:59 +0100 Subject: [PATCH 086/134] Fixed mouse wheel handling for GAL canvases with wx3.0. --- common/gal/cairo/cairo_gal.cpp | 1 + common/gal/opengl/opengl_gal.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/common/gal/cairo/cairo_gal.cpp b/common/gal/cairo/cairo_gal.cpp index 790fb06049..393e851235 100644 --- a/common/gal/cairo/cairo_gal.cpp +++ b/common/gal/cairo/cairo_gal.cpp @@ -64,6 +64,7 @@ CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); Connect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); + Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); #if defined _WIN32 || defined _WIN64 Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); #endif diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index 5eb63c31c4..81028d6eea 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -80,6 +80,7 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); Connect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); + Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); #if defined _WIN32 || defined _WIN64 Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); #endif From ef1ed9646ab7a7f06b88bee5b8102af9e644e92a Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 19 Mar 2014 13:42:46 +0100 Subject: [PATCH 087/134] DRC markers are drawn in GAL canvases. --- include/layers_id_colors_and_visibility.h | 1 + pcbnew/basepcbframe.cpp | 2 ++ pcbnew/class_marker_pcb.cpp | 14 ++++++++---- pcbnew/class_marker_pcb.h | 23 ++++++++++++++++++++ pcbnew/drc.cpp | 13 ++++++++++++ pcbnew/drc_marker_functions.cpp | 20 +++++++++++++++++ pcbnew/pcb_painter.cpp | 26 +++++++++++++++++++++-- pcbnew/pcb_painter.h | 2 ++ pcbnew/pcbframe.cpp | 3 ++- 9 files changed, 97 insertions(+), 7 deletions(-) diff --git a/include/layers_id_colors_and_visibility.h b/include/layers_id_colors_and_visibility.h index 5df67215be..50aa5fa832 100644 --- a/include/layers_id_colors_and_visibility.h +++ b/include/layers_id_colors_and_visibility.h @@ -239,6 +239,7 @@ enum PCB_VISIBLE PADS_HOLES_VISIBLE, VIAS_HOLES_VISIBLE, + DRC_VISIBLE, ///< drc markers WORKSHEET, ///< worksheet frame GP_OVERLAY, ///< general purpose overlay diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index 7adc4ca473..d89094a6fd 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -75,6 +75,7 @@ static const wxString FastGrid2Entry( wxT( "FastGrid2" ) ); const LAYER_NUM PCB_BASE_FRAME::GAL_LAYER_ORDER[] = { ITEM_GAL_LAYER( GP_OVERLAY ), + ITEM_GAL_LAYER( DRC_VISIBLE ), NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ), DRAW_N, COMMENT_N, ECO1_N, ECO2_N, EDGE_N, UNUSED_LAYER_29, UNUSED_LAYER_30, UNUSED_LAYER_31, @@ -817,6 +818,7 @@ void PCB_BASE_FRAME::LoadSettings() view->SetLayerTarget( ITEM_GAL_LAYER( GP_OVERLAY ), KIGFX::TARGET_OVERLAY ); view->SetLayerTarget( ITEM_GAL_LAYER( RATSNEST_VISIBLE ), KIGFX::TARGET_OVERLAY ); + view->SetLayerTarget( ITEM_GAL_LAYER( DRC_VISIBLE ), KIGFX::TARGET_NONCACHED ); // Apply layer coloring scheme & display options if( view->GetPainter() ) diff --git a/pcbnew/class_marker_pcb.cpp b/pcbnew/class_marker_pcb.cpp index 4e947e07cd..9222698696 100644 --- a/pcbnew/class_marker_pcb.cpp +++ b/pcbnew/class_marker_pcb.cpp @@ -46,7 +46,7 @@ MARKER_PCB::MARKER_PCB( BOARD_ITEM* aParent ) : BOARD_ITEM( aParent, PCB_MARKER_T ), - MARKER_BASE( ) + MARKER_BASE(), m_item( NULL ) { m_Color = WHITE; m_ScalingFactor = SCALING_FACTOR; @@ -57,8 +57,7 @@ MARKER_PCB::MARKER_PCB( int aErrorCode, const wxPoint& aMarkerPos, const wxString& aText, const wxPoint& aPos, const wxString& bText, const wxPoint& bPos ) : BOARD_ITEM( NULL, PCB_MARKER_T ), // parent set during BOARD::Add() - MARKER_BASE( aErrorCode, aMarkerPos, aText, aPos, bText, bPos ) - + MARKER_BASE( aErrorCode, aMarkerPos, aText, aPos, bText, bPos ), m_item( NULL ) { m_Color = WHITE; m_ScalingFactor = SCALING_FACTOR; @@ -67,7 +66,7 @@ MARKER_PCB::MARKER_PCB( int aErrorCode, const wxPoint& aMarkerPos, MARKER_PCB::MARKER_PCB( int aErrorCode, const wxPoint& aMarkerPos, const wxString& aText, const wxPoint& aPos ) : BOARD_ITEM( NULL, PCB_MARKER_T ), // parent set during BOARD::Add() - MARKER_BASE( aErrorCode, aMarkerPos, aText, aPos ) + MARKER_BASE( aErrorCode, aMarkerPos, aText, aPos ), m_item( NULL ) { m_Color = WHITE; m_ScalingFactor = SCALING_FACTOR; @@ -136,3 +135,10 @@ wxString MARKER_PCB::GetSelectMenuText() const return text; } + + +void MARKER_PCB::ViewGetLayers( int aLayers[], int& aCount ) const +{ + aCount = 1; + aLayers[0] = ITEM_GAL_LAYER( DRC_VISIBLE ); +} diff --git a/pcbnew/class_marker_pcb.h b/pcbnew/class_marker_pcb.h index 7728b152c0..1e2c0931cd 100644 --- a/pcbnew/class_marker_pcb.h +++ b/pcbnew/class_marker_pcb.h @@ -64,6 +64,16 @@ public: const wxPoint& GetPosition() const { return m_Pos; } void SetPosition( const wxPoint& aPos ) { m_Pos = aPos; } + void SetItem( const BOARD_ITEM* aItem ) + { + m_item = aItem; + } + + const BOARD_ITEM* GetItem() const + { + return m_item; + } + bool HitTest( const wxPoint& aPosition ) { return HitTestMarker( aPosition ); @@ -77,9 +87,22 @@ public: BITMAP_DEF GetMenuImage() const { return drc_xpm; } + ///> @copydoc VIEW_ITEM::ViewBBox() + virtual const BOX2I ViewBBox() const + { + return GetParent()->ViewBBox(); + } + + ///> @copydoc VIEW_ITEM::ViewGetLayers() + virtual void ViewGetLayers( int aLayers[], int& aCount ) const; + #if defined(DEBUG) void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override #endif + +protected: + ///> Pointer to BOARD_ITEM that causes DRC error. + const BOARD_ITEM* m_item; }; #endif // CLASS_MARKER_PCB_H diff --git a/pcbnew/drc.cpp b/pcbnew/drc.cpp index c10f0537b0..1039fc3492 100644 --- a/pcbnew/drc.cpp +++ b/pcbnew/drc.cpp @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include #include @@ -312,6 +314,7 @@ bool DRC::doNetClass( NETCLASS* nc, wxString& msg ) m_currentMarker = fillMarker( DRCE_NETCLASS_CLEARANCE, msg, m_currentMarker ); m_pcb->Add( m_currentMarker ); + m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker ); m_currentMarker = 0; ret = false; } @@ -327,6 +330,7 @@ bool DRC::doNetClass( NETCLASS* nc, wxString& msg ) m_currentMarker = fillMarker( DRCE_NETCLASS_TRACKWIDTH, msg, m_currentMarker ); m_pcb->Add( m_currentMarker ); + m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker ); m_currentMarker = 0; ret = false; } @@ -341,6 +345,7 @@ bool DRC::doNetClass( NETCLASS* nc, wxString& msg ) m_currentMarker = fillMarker( DRCE_NETCLASS_VIASIZE, msg, m_currentMarker ); m_pcb->Add( m_currentMarker ); + m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker ); m_currentMarker = 0; ret = false; } @@ -355,6 +360,7 @@ bool DRC::doNetClass( NETCLASS* nc, wxString& msg ) m_currentMarker = fillMarker( DRCE_NETCLASS_VIADRILLSIZE, msg, m_currentMarker ); m_pcb->Add( m_currentMarker ); + m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker ); m_currentMarker = 0; ret = false; } @@ -369,6 +375,7 @@ bool DRC::doNetClass( NETCLASS* nc, wxString& msg ) m_currentMarker = fillMarker( DRCE_NETCLASS_uVIASIZE, msg, m_currentMarker ); m_pcb->Add( m_currentMarker ); + m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker ); m_currentMarker = 0; ret = false; } @@ -383,6 +390,7 @@ bool DRC::doNetClass( NETCLASS* nc, wxString& msg ) m_currentMarker = fillMarker( DRCE_NETCLASS_uVIADRILLSIZE, msg, m_currentMarker ); m_pcb->Add( m_currentMarker ); + m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker ); m_currentMarker = 0; ret = false; } @@ -447,6 +455,7 @@ void DRC::testPad2Pad() { wxASSERT( m_currentMarker ); m_pcb->Add( m_currentMarker ); + m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker ); m_currentMarker = 0; } } @@ -493,6 +502,7 @@ void DRC::testTracks( bool aShowProgressBar ) { wxASSERT( m_currentMarker ); m_pcb->Add( m_currentMarker ); + m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker ); m_currentMarker = 0; } } @@ -554,6 +564,7 @@ void DRC::testZones() m_currentMarker = fillMarker( test_area, DRCE_NON_EXISTANT_NET_FOR_ZONE_OUTLINE, m_currentMarker ); m_pcb->Add( m_currentMarker ); + m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker ); m_currentMarker = 0; } } @@ -589,6 +600,7 @@ void DRC::testKeepoutAreas() m_currentMarker = fillMarker( segm, NULL, DRCE_TRACK_INSIDE_KEEPOUT, m_currentMarker ); m_pcb->Add( m_currentMarker ); + m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker ); m_currentMarker = 0; } } @@ -605,6 +617,7 @@ void DRC::testKeepoutAreas() m_currentMarker = fillMarker( segm, NULL, DRCE_VIA_INSIDE_KEEPOUT, m_currentMarker ); m_pcb->Add( m_currentMarker ); + m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker ); m_currentMarker = 0; } } diff --git a/pcbnew/drc_marker_functions.cpp b/pcbnew/drc_marker_functions.cpp index 817d7e17d9..a069acaaa4 100644 --- a/pcbnew/drc_marker_functions.cpp +++ b/pcbnew/drc_marker_functions.cpp @@ -100,12 +100,17 @@ MARKER_PCB* DRC::fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, M else { if( aItem ) + { fillMe = new MARKER_PCB( aErrorCode, position, textA, aTrack->GetPosition(), textB, posB ); + fillMe->SetItem( aItem ); + } else + { fillMe = new MARKER_PCB( aErrorCode, position, textA, aTrack->GetPosition() ); + } } return fillMe; @@ -121,9 +126,14 @@ MARKER_PCB* DRC::fillMarker( D_PAD* aPad, D_PAD* bPad, int aErrorCode, MARKER_PC wxPoint posB = bPad->GetPosition(); if( fillMe ) + { fillMe->SetData( aErrorCode, posA, textA, posA, textB, posB ); + } else + { fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA, textB, posB ); + fillMe->SetItem( aPad ); // TODO it has to be checked + } return fillMe; } @@ -136,9 +146,14 @@ MARKER_PCB* DRC::fillMarker( ZONE_CONTAINER* aArea, int aErrorCode, MARKER_PCB* wxPoint posA = aArea->GetPosition(); if( fillMe ) + { fillMe->SetData( aErrorCode, posA, textA, posA ); + } else + { fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA ); + fillMe->SetItem( aArea ); + } return fillMe; } @@ -154,9 +169,14 @@ MARKER_PCB* DRC::fillMarker( const ZONE_CONTAINER* aArea, wxPoint posA = aPos; if( fillMe ) + { fillMe->SetData( aErrorCode, posA, textA, posA ); + } else + { fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA ); + fillMe->SetItem( aArea ); + } return fillMe; } diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 40576eba42..6aa9e54929 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -34,9 +34,8 @@ #include #include #include -#include +#include -#include #include #include @@ -76,6 +75,7 @@ void PCB_RENDER_SETTINGS::ImportLegacyColors( COLORS_DESIGN_SETTINGS* aSettings m_layerColors[NETNAMES_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 ); + m_layerColors[ITEM_GAL_LAYER( DRC_VISIBLE )] = COLOR4D( 1.0, 0.0, 0.0, 1.0 ); // Netnames for copper layers for( LAYER_NUM layer = FIRST_COPPER_LAYER; layer <= LAST_COPPER_LAYER; ++layer ) @@ -246,6 +246,9 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer ) draw( (PCB_TARGET*) aItem ); break; + case PCB_MARKER_T: + draw( (MARKER_PCB*) aItem ); + default: // Painter does not know how to draw the object return false; @@ -863,4 +866,23 @@ void PCB_PAINTER::draw( const PCB_TARGET* aTarget ) } +void PCB_PAINTER::draw( const MARKER_PCB* aMarker ) +{ + const BOARD_ITEM* item = aMarker->GetItem(); + + if( item ) // By default draw an item in a different color + { + Draw( item, ITEM_GAL_LAYER( DRC_VISIBLE ) ); + } + else // If there is no item associated - draw a circle marking the DRC error + { + m_gal->SetStrokeColor( COLOR4D( 1.0, 0.0, 0.0, 1.0 ) ); + m_gal->SetIsFill( false ); + m_gal->SetIsStroke( true ); + m_gal->SetLineWidth( 10000 ); + m_gal->DrawCircle( VECTOR2D( aMarker->GetPosition() ), 200000 ); + } +} + + const double PCB_RENDER_SETTINGS::MAX_FONT_SIZE = Millimeter2iu( 10.0 ); diff --git a/pcbnew/pcb_painter.h b/pcbnew/pcb_painter.h index 10819affdb..efa9cc061b 100644 --- a/pcbnew/pcb_painter.h +++ b/pcbnew/pcb_painter.h @@ -48,6 +48,7 @@ class TEXTE_PCB; class TEXTE_MODULE; class DIMENSION; class PCB_TARGET; +class MARKER_PCB; namespace KIGFX { @@ -169,6 +170,7 @@ protected: void draw( const ZONE_CONTAINER* aZone ); void draw( const DIMENSION* aDimension, int aLayer ); void draw( const PCB_TARGET* aTarget ); + void draw( const MARKER_PCB* aMarker ); }; } // namespace KIGFX diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 1b5c4c5c20..be5896b50e 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -923,7 +923,8 @@ void PCB_EDIT_FRAME::SetTopLayer( LAYER_NUM aLayer ) GetNetnameLayer( aLayer ), ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ), ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ), ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ), - ITEM_GAL_LAYER( GP_OVERLAY ), ITEM_GAL_LAYER( RATSNEST_VISIBLE ), DRAW_N + ITEM_GAL_LAYER( GP_OVERLAY ), ITEM_GAL_LAYER( RATSNEST_VISIBLE ), DRAW_N, + ITEM_GAL_LAYER( DRC_VISIBLE ) }; for( unsigned int i = 0; i < sizeof( layers ) / sizeof( LAYER_NUM ); ++i ) From 2d8dc04693a59c204e9ee4ef531549774253b9aa Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 19 Mar 2014 13:46:52 +0100 Subject: [PATCH 088/134] Fixed undo for MARKER_PCBs. --- pcbnew/basepcbframe.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index d89094a6fd..1467773da6 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -818,7 +818,6 @@ void PCB_BASE_FRAME::LoadSettings() view->SetLayerTarget( ITEM_GAL_LAYER( GP_OVERLAY ), KIGFX::TARGET_OVERLAY ); view->SetLayerTarget( ITEM_GAL_LAYER( RATSNEST_VISIBLE ), KIGFX::TARGET_OVERLAY ); - view->SetLayerTarget( ITEM_GAL_LAYER( DRC_VISIBLE ), KIGFX::TARGET_NONCACHED ); // Apply layer coloring scheme & display options if( view->GetPainter() ) From bf418eb1eeee317b7155247941e426f260d477f3 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 19 Mar 2014 14:26:02 +0100 Subject: [PATCH 089/134] Cursor coordinates are updated in GAL canvases. --- common/drawframe.cpp | 14 ++++++++++++-- common/tool/tool_dispatcher.cpp | 1 + 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/common/drawframe.cpp b/common/drawframe.cpp index 5820bed89b..152152fe1a 100644 --- a/common/drawframe.cpp +++ b/common/drawframe.cpp @@ -47,6 +47,7 @@ #include #include +#include #include /** @@ -1019,9 +1020,18 @@ void EDA_DRAW_FRAME::UseGalCanvas( bool aEnable ) wxPoint EDA_DRAW_FRAME::GetCrossHairPosition( bool aInvertY ) const { // subject to change, borrow from old BASE_SCREEN for now. + if( IsGalCanvasActive() ) + { + VECTOR2I cursor = GetGalCanvas()->GetViewControls()->GetCursorPosition(); + cursor = GetGalCanvas()->GetGAL()->GetGridPoint( cursor ); - BASE_SCREEN* screen = GetScreen(); // virtual call - return screen->getCrossHairPosition( aInvertY ); + return wxPoint( cursor.x, cursor.y ); + } + else + { + BASE_SCREEN* screen = GetScreen(); // virtual call + return screen->getCrossHairPosition( aInvertY ); + } } diff --git a/common/tool/tool_dispatcher.cpp b/common/tool/tool_dispatcher.cpp index b19da891e2..1085534eec 100644 --- a/common/tool/tool_dispatcher.cpp +++ b/common/tool/tool_dispatcher.cpp @@ -229,6 +229,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) { motion = true; m_lastMousePos = pos; + m_editFrame->UpdateStatusBar(); } for( unsigned int i = 0; i < m_buttons.size(); i++ ) From 093e311a8d7914819d6821ac6cbe5660caa8edfc Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 19 Mar 2014 15:33:13 +0100 Subject: [PATCH 090/134] Fixed a few ratsnest glitches in GAL. --- pcbnew/tools/edit_tool.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 53a72f25e3..6965042775 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -270,6 +270,8 @@ int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } + updateRatsnest( m_dragging ); + if( m_dragging ) selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); else @@ -279,8 +281,6 @@ int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate ); - - updateRatsnest( true ); setTransitions(); return 0; @@ -316,6 +316,8 @@ int EDIT_TOOL::Flip( TOOL_EVENT& aEvent ) item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS ); } + updateRatsnest( m_dragging ); + if( m_dragging ) selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); else @@ -325,8 +327,6 @@ int EDIT_TOOL::Flip( TOOL_EVENT& aEvent ) m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate ); - - updateRatsnest( true ); setTransitions(); return 0; @@ -365,7 +365,6 @@ int EDIT_TOOL::Remove( TOOL_EVENT& aEvent ) if( !( board->m_Status_Pcb & NET_CODES_OK ) ) board->BuildListOfNets(); - board->GetRatsnest()->Recalculate(); // TODO is it necessary? setTransitions(); return 0; From dbc4a8f29261ce2739a64455447609b692989b2c Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 20 Mar 2014 08:47:31 +0100 Subject: [PATCH 091/134] GAL zooms in and out using the default hot keys (F1/F2). Screen size is saved in VECTOR2I instead of VECTOR2D. --- common/gal/cairo/cairo_gal.cpp | 6 +++--- common/gal/graphics_abstraction_layer.cpp | 4 ++-- common/gal/opengl/opengl_gal.cpp | 4 ++-- common/view/view.cpp | 2 +- common/zoom.cpp | 5 +++-- include/gal/graphics_abstraction_layer.h | 4 ++-- include/view/view.h | 2 +- pcbnew/menubar_pcbframe.cpp | 20 ++++++++++---------- 8 files changed, 24 insertions(+), 23 deletions(-) diff --git a/common/gal/cairo/cairo_gal.cpp b/common/gal/cairo/cairo_gal.cpp index 393e851235..13055c7aed 100644 --- a/common/gal/cairo/cairo_gal.cpp +++ b/common/gal/cairo/cairo_gal.cpp @@ -70,7 +70,7 @@ CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, #endif SetSize( aParent->GetSize() ); - screenSize = VECTOR2D( aParent->GetSize() ); + screenSize = VECTOR2I( aParent->GetSize() ); initCursor(); // Grid color settings are different in Cairo and OpenGL @@ -138,7 +138,7 @@ void CAIRO_GAL::EndDrawing() *wxOutputPtr++ = value & 0xff; // Blue pixel } - wxImage img( (int) screenSize.x, (int) screenSize.y, (unsigned char*) wxOutput, true ); + wxImage img( screenSize.x, screenSize.y, (unsigned char*) wxOutput, true ); wxBitmap bmp( img ); wxClientDC client_dc( this ); wxBufferedDC dc; @@ -283,7 +283,7 @@ void CAIRO_GAL::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aControl void CAIRO_GAL::ResizeScreen( int aWidth, int aHeight ) { - screenSize = VECTOR2D( aWidth, aHeight ); + screenSize = VECTOR2I( aWidth, aHeight ); // Recreate the bitmaps deleteBitmaps(); diff --git a/common/gal/graphics_abstraction_layer.cpp b/common/gal/graphics_abstraction_layer.cpp index 7f57d652c4..724d14ac9e 100644 --- a/common/gal/graphics_abstraction_layer.cpp +++ b/common/gal/graphics_abstraction_layer.cpp @@ -88,7 +88,7 @@ void GAL::ComputeWorldScreenMatrix() MATRIX3x3D translation; translation.SetIdentity(); - translation.SetTranslation( 0.5 * screenSize ); + translation.SetTranslation( 0.5 * VECTOR2D( screenSize ) ); MATRIX3x3D scale; scale.SetIdentity(); @@ -131,7 +131,7 @@ void GAL::DrawGrid() // For the drawing the start points, end points and increments have // to be calculated in world coordinates VECTOR2D worldStartPoint = screenWorldMatrix * VECTOR2D( 0.0, 0.0 ); - VECTOR2D worldEndPoint = screenWorldMatrix * screenSize; + VECTOR2D worldEndPoint = screenWorldMatrix * VECTOR2D( screenSize ); int gridScreenSizeDense = round( gridSize.x * worldScale ); int gridScreenSizeCoarse = round( gridSize.x * static_cast( gridTick ) * worldScale ); diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index 81028d6eea..fb8a0fcf4d 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -86,7 +86,7 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, #endif SetSize( aParent->GetSize() ); - screenSize = VECTOR2D( aParent->GetSize() ); + screenSize = VECTOR2I( aParent->GetSize() ); // Grid color settings are different in Cairo and OpenGL SetGridColor( COLOR4D( 0.8, 0.8, 0.8, 0.1 ) ); @@ -562,7 +562,7 @@ void OPENGL_GAL::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aContro void OPENGL_GAL::ResizeScreen( int aWidth, int aHeight ) { - screenSize = VECTOR2D( aWidth, aHeight ); + screenSize = VECTOR2I( aWidth, aHeight ); // Resize framebuffers compositor.Resize( aWidth, aHeight ); diff --git a/common/view/view.cpp b/common/view/view.cpp index ba070b2786..5cfe071d9f 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -771,7 +771,7 @@ void VIEW::Redraw() } -const VECTOR2D& VIEW::GetScreenPixelSize() const +const VECTOR2I& VIEW::GetScreenPixelSize() const { return m_gal->GetScreenPixelSize(); } diff --git a/common/zoom.cpp b/common/zoom.cpp index 6add6bc2f6..859d5a4872 100644 --- a/common/zoom.cpp +++ b/common/zoom.cpp @@ -203,8 +203,9 @@ void EDA_DRAW_FRAME::OnZoom( wxCommandEvent& event ) double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor(); double zoom = 1.0 / ( zoomFactor * GetZoom() ); - view->SetScale( zoom ); - view->SetCenter( VECTOR2D( center ) ); + VECTOR2D cursorWorld( GetCrossHairPosition() ); + view->SetScale( zoom, cursorWorld ); + GetGalCanvas()->Refresh(); } diff --git a/include/gal/graphics_abstraction_layer.h b/include/gal/graphics_abstraction_layer.h index d49e5e2fad..50b5c355c7 100644 --- a/include/gal/graphics_abstraction_layer.h +++ b/include/gal/graphics_abstraction_layer.h @@ -160,7 +160,7 @@ public: virtual bool Show( bool aShow ) = 0; /// @brief Returns GAL canvas size in pixels - const VECTOR2D& GetScreenPixelSize() const + const VECTOR2I& GetScreenPixelSize() const { return screenSize; } @@ -831,7 +831,7 @@ public: protected: std::stack depthStack; ///< Stored depth values - VECTOR2D screenSize; ///< Screen size in screen coordinates + VECTOR2I screenSize; ///< Screen size in screen coordinates double worldUnitLength; ///< The unit length of the world coordinates [inch] double screenDPI; ///< The dots per inch of the screen diff --git a/include/view/view.h b/include/view/view.h index e103089ae0..694042724f 100644 --- a/include/view/view.h +++ b/include/view/view.h @@ -261,7 +261,7 @@ public: * Returns the size of the our rendering area, in pixels. * @return viewport screen size */ - const VECTOR2D& GetScreenPixelSize() const; + const VECTOR2I& GetScreenPixelSize() const; /** * Function AddLayer() diff --git a/pcbnew/menubar_pcbframe.cpp b/pcbnew/menubar_pcbframe.cpp index 3a340b0c47..f75bd16aaf 100644 --- a/pcbnew/menubar_pcbframe.cpp +++ b/pcbnew/menubar_pcbframe.cpp @@ -328,12 +328,12 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() */ // Zoom In text = AddHotkeyName( _( "Zoom &In" ), g_Pcbnew_Editor_Hokeys_Descr, - HK_ZOOM_IN, IS_ACCELERATOR ); + HK_ZOOM_IN ); AddMenuItem( viewMenu, ID_ZOOM_IN, text, HELP_ZOOM_IN, KiBitmap( zoom_in_xpm ) ); // Zoom Out text = AddHotkeyName( _( "Zoom &Out" ), g_Pcbnew_Editor_Hokeys_Descr, - HK_ZOOM_OUT, IS_ACCELERATOR ); + HK_ZOOM_OUT ); AddMenuItem( viewMenu, ID_ZOOM_OUT, text, HELP_ZOOM_OUT, KiBitmap( zoom_out_xpm ) ); // Fit on Screen @@ -366,38 +366,38 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() viewMenu->AppendSeparator(); text = AddHotkeyName( _( "&Switch canvas to default" ), g_Pcbnew_Editor_Hokeys_Descr, - HK_CANVAS_DEFAULT, IS_ACCELERATOR ); + HK_CANVAS_DEFAULT ); AddMenuItem( viewMenu, ID_MENU_CANVAS_DEFAULT, text, _( "Switch the canvas implementation to default" ), - KiBitmap( tools_xpm ) ); + KiBitmap( tools_xpm ) ); text = AddHotkeyName( _( "&Switch canvas to OpenGL" ), g_Pcbnew_Editor_Hokeys_Descr, - HK_CANVAS_OPENGL, IS_ACCELERATOR ); + HK_CANVAS_OPENGL ); AddMenuItem( viewMenu, ID_MENU_CANVAS_OPENGL, text, _( "Switch the canvas implementation to OpenGL" ), - KiBitmap( tools_xpm ) ); + KiBitmap( tools_xpm ) ); text = AddHotkeyName( _( "&Switch canvas to Cairo" ), g_Pcbnew_Editor_Hokeys_Descr, - HK_CANVAS_CAIRO, IS_ACCELERATOR ); + HK_CANVAS_CAIRO ); AddMenuItem( viewMenu, ID_MENU_CANVAS_CAIRO, text, _( "Switch the canvas implementation to Cairo" ), - KiBitmap( tools_xpm ) ); + KiBitmap( tools_xpm ) ); /** Create Place Menu **/ wxMenu* placeMenu = new wxMenu; // Module text = AddHotkeyName( _( "&Module" ), g_Pcbnew_Editor_Hokeys_Descr, - HK_ADD_MODULE, IS_ACCELERATOR ); + HK_ADD_MODULE ); AddMenuItem( placeMenu, ID_PCB_MODULE_BUTT, text, _( "Add modules" ), KiBitmap( module_xpm ) ); // Track text = AddHotkeyName( _( "&Track" ), g_Pcbnew_Editor_Hokeys_Descr, - HK_ADD_NEW_TRACK, IS_ACCELERATOR ); + HK_ADD_NEW_TRACK ); AddMenuItem( placeMenu, ID_TRACK_BUTT, text, _( "Add tracks and vias" ), KiBitmap( add_tracks_xpm ) ); From 426844896e9415160b669d41eeb38c8ab5f97729 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 20 Mar 2014 11:31:32 +0100 Subject: [PATCH 092/134] Minor fixes (check for net codes size for ratsnest, cursor coordinates are not always shown as if the cursor was snapped). --- common/drawframe.cpp | 1 - include/wxPcbStruct.h | 2 -- pcbnew/ratsnest_data.cpp | 2 +- 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/common/drawframe.cpp b/common/drawframe.cpp index 152152fe1a..31048df82f 100644 --- a/common/drawframe.cpp +++ b/common/drawframe.cpp @@ -1023,7 +1023,6 @@ wxPoint EDA_DRAW_FRAME::GetCrossHairPosition( bool aInvertY ) const if( IsGalCanvasActive() ) { VECTOR2I cursor = GetGalCanvas()->GetViewControls()->GetCursorPosition(); - cursor = GetGalCanvas()->GetGAL()->GetGridPoint( cursor ); return wxPoint( cursor.x, cursor.y ); } diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index be47c3bd22..1298f96e1f 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -216,8 +216,6 @@ public: bool m_show_microwave_tools; bool m_show_layer_manager_tools; - -public: PCB_EDIT_FRAME( wxWindow* father, const wxString& title, const wxPoint& pos, const wxSize& size, long style = KICAD_DEFAULT_DRAWFRAME_STYLE ); diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index 5bff81fe4f..4242ea6bf1 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -1024,7 +1024,7 @@ void RN_DATA::updateNet( int aNetCode ) { assert( aNetCode < (int) m_nets.size() ); - if( aNetCode < 1 ) + if( aNetCode < 1 || aNetCode > m_nets.size() ) return; m_nets[aNetCode].ClearSimple(); From 0694f2fa1cc5783853e0ffe644c7f924cb9cd217 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 21 Mar 2014 10:40:50 +0100 Subject: [PATCH 093/134] TOOL_EVENTs autoregister themselves in ACTION_MANAGER. ROUTER_TOOL events have temporarily changed their hotkeys assignment. --- common/tool/action_manager.cpp | 3 --- include/tool/tool_action.h | 17 ++++---------- include/tool/tool_manager.h | 10 +++++++- include/wxBasePcbFrame.h | 2 +- pcbnew/basepcbframe.cpp | 4 ++-- pcbnew/board_undo_redo.cpp | 4 ++-- pcbnew/edit.cpp | 2 +- pcbnew/pcbframe.cpp | 13 ++++------- pcbnew/router/router_tool.cpp | 6 ++--- pcbnew/tools/pcb_tools.cpp | 42 ++++++++++------------------------ 10 files changed, 39 insertions(+), 64 deletions(-) diff --git a/common/tool/action_manager.cpp b/common/tool/action_manager.cpp index ce0c403e43..bc1a8be368 100644 --- a/common/tool/action_manager.cpp +++ b/common/tool/action_manager.cpp @@ -60,8 +60,6 @@ void ACTION_MANAGER::RegisterAction( TOOL_ACTION* aAction ) m_actionHotKeys[aAction->m_currentHotKey] = aAction; } - - aAction->setActionMgr( this ); } @@ -71,7 +69,6 @@ void ACTION_MANAGER::UnregisterAction( TOOL_ACTION* aAction ) m_actionIdIndex.erase( aAction->m_id ); // Indicate that the ACTION_MANAGER no longer care about the object - aAction->setActionMgr( NULL ); aAction->setId( -1 ); if( aAction->HasHotKey() ) diff --git a/include/tool/tool_action.h b/include/tool/tool_action.h index 8a3e7c4111..4d91ea982f 100644 --- a/include/tool/tool_action.h +++ b/include/tool/tool_action.h @@ -30,7 +30,7 @@ #include #include -#include +#include /** * Class TOOL_ACTION @@ -50,14 +50,14 @@ public: const std::string& aMenuDesc = std::string( "" ) ) : m_name( aName ), m_scope( aScope ), m_defaultHotKey( aDefaultHotKey ), m_currentHotKey( aDefaultHotKey ), m_menuItem( aMenuItem ), - m_menuDescription( aMenuDesc ), m_id( -1 ), m_actionMgr( NULL ) + m_menuDescription( aMenuDesc ), m_id( -1 ) { + TOOL_MANAGER::Instance().RegisterAction( this ); } ~TOOL_ACTION() { - if( m_actionMgr ) - m_actionMgr->UnregisterAction( this ); + TOOL_MANAGER::Instance().UnregisterAction( this ); } bool operator==( const TOOL_ACTION& aRhs ) const @@ -180,12 +180,6 @@ private: m_id = aId; } - /// Assigns ACTION_MANAGER object that handles the TOOL_ACTION. - void setActionMgr( ACTION_MANAGER* aManager ) - { - m_actionMgr = aManager; - } - /// Name of the action (convention is: app.[tool.]action.name) std::string m_name; @@ -210,9 +204,6 @@ private: /// Unique ID for fast matching. Assigned by ACTION_MANAGER. int m_id; - /// Action manager that handles this TOOL_ACTION. - ACTION_MANAGER* m_actionMgr; - /// Origin of the action // const TOOL_BASE* m_origin; diff --git a/include/tool/tool_manager.h b/include/tool/tool_manager.h index c07dcfe94e..04afea3483 100644 --- a/include/tool/tool_manager.h +++ b/include/tool/tool_manager.h @@ -48,7 +48,13 @@ class wxWindow; class TOOL_MANAGER { public: - TOOL_MANAGER(); + static TOOL_MANAGER& Instance() + { + static TOOL_MANAGER manager; + + return manager; + } + ~TOOL_MANAGER(); /** @@ -211,6 +217,8 @@ public: } private: + TOOL_MANAGER(); + struct TOOL_STATE; typedef std::pair TRANSITION; diff --git a/include/wxBasePcbFrame.h b/include/wxBasePcbFrame.h index 139b6f4d3f..4306d67977 100644 --- a/include/wxBasePcbFrame.h +++ b/include/wxBasePcbFrame.h @@ -95,7 +95,7 @@ protected: /// main window. wxAuiToolBar* m_auxiliaryToolBar; - TOOL_MANAGER* m_toolManager; + TOOL_MANAGER& m_toolManager; TOOL_DISPATCHER* m_toolDispatcher; void updateGridSelectBox(); diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index 1467773da6..0464d04683 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -131,10 +131,10 @@ PCB_BASE_FRAME::PCB_BASE_FRAME( wxWindow* aParent, ID_DRAWFRAME_TYPE aFrameType, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, long aStyle, const wxString & aFrameName) : - EDA_DRAW_FRAME( aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName ) + EDA_DRAW_FRAME( aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName ), + m_toolManager( TOOL_MANAGER::Instance() ) { m_Pcb = NULL; - m_toolManager = NULL; m_toolDispatcher = NULL; m_DisplayPadFill = true; // How to draw pads diff --git a/pcbnew/board_undo_redo.cpp b/pcbnew/board_undo_redo.cpp index a5a3ad314e..5912380180 100644 --- a/pcbnew/board_undo_redo.cpp +++ b/pcbnew/board_undo_redo.cpp @@ -629,7 +629,7 @@ void PCB_EDIT_FRAME::GetBoardFromUndoList( wxCommandEvent& aEvent ) // Inform tools that undo command was issued TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL ); - m_toolManager->ProcessEvent( event ); + m_toolManager.ProcessEvent( event ); /* Get the old list */ PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList(); @@ -652,7 +652,7 @@ void PCB_EDIT_FRAME::GetBoardFromRedoList( wxCommandEvent& aEvent ) // Inform tools that redo command was issued TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL ); - m_toolManager->ProcessEvent( event ); + m_toolManager.ProcessEvent( event ); /* Get the old list */ PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromRedoList(); diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index 91bd9ee4ad..453572ddc5 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -1466,7 +1466,7 @@ void PCB_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent ) std::string actionName = COMMON_ACTIONS::TranslateLegacyId( id ); if( !actionName.empty() ) - m_toolManager->RunAction( actionName ); + m_toolManager.RunAction( actionName ); return; } diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index be5896b50e..dee3308be0 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -528,12 +528,9 @@ void PCB_EDIT_FRAME::SetBoard( BOARD* aBoard ) ViewReloadBoard( 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 ); - } + m_toolManager.SetEnvironment( aBoard, GetGalCanvas()->GetView(), + GetGalCanvas()->GetViewControls(), this ); + m_toolManager.ResetTools( TOOL_BASE::MODEL_RELOAD ); } } @@ -714,9 +711,9 @@ void PCB_EDIT_FRAME::UseGalCanvas( bool aEnable ) // Update potential changes in the ratsnest m_Pcb->GetRatsnest()->Recalculate(); - m_toolManager->SetEnvironment( m_Pcb, GetGalCanvas()->GetView(), + m_toolManager.SetEnvironment( m_Pcb, GetGalCanvas()->GetView(), GetGalCanvas()->GetViewControls(), this ); - m_toolManager->ResetTools( TOOL_BASE::GAL_SWITCH ); + m_toolManager.ResetTools( TOOL_BASE::GAL_SWITCH ); } } diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index adb3490de3..88e797b92b 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -44,11 +44,11 @@ using namespace KIGFX; using boost::optional; -static TOOL_ACTION ACT_AutoEndRoute( "AutoEndRoute", AS_CONTEXT, 'F' ); +static TOOL_ACTION ACT_AutoEndRoute( "AutoEndRoute", AS_CONTEXT, 'G' ); static TOOL_ACTION ACT_PlaceVia( "PlaceVia", AS_CONTEXT, 'V' ); -static TOOL_ACTION ACT_OpenRouteOptions( "OpenRouterOptions", AS_CONTEXT, 'E' ); +static TOOL_ACTION ACT_OpenRouteOptions( "OpenRouterOptions", AS_CONTEXT, 'Y' ); static TOOL_ACTION ACT_SwitchPosture( "SwitchPosture", AS_CONTEXT, '/' ); -static TOOL_ACTION ACT_EndTrack( "SwitchPosture", AS_CONTEXT, WXK_END ); +static TOOL_ACTION ACT_EndTrack( "EndTrack", AS_CONTEXT, WXK_END ); ROUTER_TOOL::ROUTER_TOOL() : TOOL_INTERACTIVE( "pcbnew.InteractiveRouter" ) diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index 53683e1a55..28a1b424a3 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -38,54 +38,36 @@ #include "edit_tool.h" #include "drawing_tool.h" #include "point_editor.h" +#include "settings_tool.h" #include "common_actions.h" #include void PCB_EDIT_FRAME::setupTools() { // Create the manager and dispatcher & route draw panel events to the dispatcher - m_toolManager = new TOOL_MANAGER; - m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager, this ); + m_toolManager = TOOL_MANAGER::Instance(); + m_toolDispatcher = new TOOL_DISPATCHER( &m_toolManager, this ); 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 ); - m_toolManager->RegisterAction( &COMMON_ACTIONS::remove ); - m_toolManager->RegisterAction( &COMMON_ACTIONS::properties ); - m_toolManager->RegisterAction( &COMMON_ACTIONS::drawLine ); - m_toolManager->RegisterAction( &COMMON_ACTIONS::drawCircle ); - m_toolManager->RegisterAction( &COMMON_ACTIONS::drawArc ); - m_toolManager->RegisterAction( &COMMON_ACTIONS::drawText ); - m_toolManager->RegisterAction( &COMMON_ACTIONS::drawDimension ); - m_toolManager->RegisterAction( &COMMON_ACTIONS::drawZone ); - m_toolManager->RegisterAction( &COMMON_ACTIONS::drawKeepout ); - m_toolManager->RegisterAction( &COMMON_ACTIONS::placeTarget ); - m_toolManager->RegisterAction( &COMMON_ACTIONS::placeModule ); - m_toolManager->RegisterAction( &COMMON_ACTIONS::routerActivate ); - // Register tools - m_toolManager->RegisterTool( new SELECTION_TOOL ); - m_toolManager->RegisterTool( new ROUTER_TOOL ); - m_toolManager->RegisterTool( new EDIT_TOOL ); - m_toolManager->RegisterTool( new DRAWING_TOOL ); - m_toolManager->RegisterTool( new POINT_EDITOR ); + m_toolManager.RegisterTool( new SELECTION_TOOL ); + m_toolManager.RegisterTool( new ROUTER_TOOL ); + m_toolManager.RegisterTool( new EDIT_TOOL ); + m_toolManager.RegisterTool( new DRAWING_TOOL ); + m_toolManager.RegisterTool( new POINT_EDITOR ); + m_toolManager.RegisterTool( new SETTINGS_TOOL ); - m_toolManager->SetEnvironment( NULL, GetGalCanvas()->GetView(), + m_toolManager.SetEnvironment( NULL, GetGalCanvas()->GetView(), GetGalCanvas()->GetViewControls(), this ); - m_toolManager->ResetTools( TOOL_BASE::RUN ); + m_toolManager.ResetTools( TOOL_BASE::RUN ); // Run the selection tool, it is supposed to be always active - m_toolManager->InvokeTool( "pcbnew.InteractiveSelection" ); + m_toolManager.InvokeTool( "pcbnew.InteractiveSelection" ); } void PCB_EDIT_FRAME::destroyTools() { - delete m_toolManager; delete m_toolDispatcher; } From 87c9423f0feb2a08e288643b892f6362b9a1f87b Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 21 Mar 2014 11:17:47 +0100 Subject: [PATCH 094/134] PCB_EDIT_FRAME::SetActiveLayer() & GetActiveLayer() made public. --- include/wxPcbStruct.h | 34 +++++++++++------------ pcbnew/class_pcb_layer_widget.cpp | 4 +-- pcbnew/deltrack.cpp | 4 +-- pcbnew/dialogs/dialog_general_options.cpp | 2 +- pcbnew/dialogs/dialog_global_deletion.cpp | 2 +- pcbnew/dialogs/dialog_layers_setup.cpp | 10 +++---- pcbnew/dimension.cpp | 2 +- pcbnew/edit.cpp | 28 +++++++++---------- pcbnew/editedge.cpp | 4 +-- pcbnew/editrack-part2.cpp | 12 ++++---- pcbnew/hotkeys_board_editor.cpp | 10 +++---- pcbnew/onleftclick.cpp | 8 +++--- pcbnew/pcbframe.cpp | 6 ++-- pcbnew/tool_pcb.cpp | 2 +- pcbnew/toolbars_update_user_interface.cpp | 2 +- pcbnew/zones_by_polygon.cpp | 8 +++--- 16 files changed, 69 insertions(+), 69 deletions(-) diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index 1298f96e1f..03038aece4 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -134,22 +134,6 @@ protected: void createPopUpBlockMenu( wxMenu* menu ); void createPopUpMenuForMarkers( MARKER_PCB* aMarker, wxMenu* aPopMenu ); - /** - * Function setActiveLayer - * will change the currently active layer to \a aLayer and also - * update the PCB_LAYER_WIDGET. - */ - void setActiveLayer( LAYER_NUM aLayer, bool doLayerWidgetUpdate = true ); - - /** - * Function getActiveLayer - * returns the active layer - */ - LAYER_NUM getActiveLayer() - { - return ( (PCB_SCREEN*) GetScreen() )->m_Active_Layer; - } - /** * Function setHighContrastLayer * takes care of display settings for the given layer to be displayed in high contrast mode. @@ -159,7 +143,7 @@ protected: /** * Function syncLayerWidgetLayer * updates the currently layer "selection" within the PCB_LAYER_WIDGET. - * The currently selected layer is defined by the return value of getActiveLayer(). + * The currently selected layer is defined by the return value of GetActiveLayer(). *

* This function cannot be inline without including layer_widget.h in * here and we do not want to do that. @@ -577,6 +561,22 @@ public: */ void SetTopLayer( LAYER_NUM aLayer ); + /** + * Function SetActiveLayer + * will change the currently active layer to \a aLayer and also + * update the PCB_LAYER_WIDGET. + */ + void SetActiveLayer( LAYER_NUM aLayer, bool doLayerWidgetUpdate = true ); + + /** + * Function GetActiveLayer + * returns the active layer + */ + LAYER_NUM GetActiveLayer() + { + return ( (PCB_SCREEN*) GetScreen() )->m_Active_Layer; + } + /** * Function IsElementVisible * tests whether a given element category is visible. Keep this as an diff --git a/pcbnew/class_pcb_layer_widget.cpp b/pcbnew/class_pcb_layer_widget.cpp index 6dc983babf..cd80e35b75 100644 --- a/pcbnew/class_pcb_layer_widget.cpp +++ b/pcbnew/class_pcb_layer_widget.cpp @@ -183,7 +183,7 @@ void PCB_LAYER_WIDGET::onPopupSelection( wxCommandEvent& event ) if( IsCopperLayer( layer ) ) { bool loc_visible = visible; - if( force_active_layer_visible && (layer == myframe->getActiveLayer() ) ) + if( force_active_layer_visible && (layer == myframe->GetActiveLayer() ) ) loc_visible = true; cb->SetValue( loc_visible ); @@ -354,7 +354,7 @@ bool PCB_LAYER_WIDGET::OnLayerSelect( LAYER_NUM aLayer ) { // the layer change from the PCB_LAYER_WIDGET can be denied by returning // false from this function. - myframe->setActiveLayer( aLayer, false ); + myframe->SetActiveLayer( aLayer, false ); if( m_alwaysShowActiveCopperLayer ) OnLayerSelected(); diff --git a/pcbnew/deltrack.cpp b/pcbnew/deltrack.cpp index 331fbd22ab..a4012d76fc 100644 --- a/pcbnew/deltrack.cpp +++ b/pcbnew/deltrack.cpp @@ -53,7 +53,7 @@ TRACK* PCB_EDIT_FRAME::Delete_Segment( wxDC* DC, TRACK* aTrack ) { if( g_CurrentTrackList.GetCount() > 0 ) { - LAYER_NUM previous_layer = getActiveLayer(); + LAYER_NUM previous_layer = GetActiveLayer(); DBG( g_CurrentTrackList.VerifyListIntegrity(); ) @@ -86,7 +86,7 @@ TRACK* PCB_EDIT_FRAME::Delete_Segment( wxDC* DC, TRACK* aTrack ) // Correct active layer which could change if a via // has been erased - setActiveLayer( previous_layer ); + SetActiveLayer( previous_layer ); UpdateStatusBar(); diff --git a/pcbnew/dialogs/dialog_general_options.cpp b/pcbnew/dialogs/dialog_general_options.cpp index 9f3ea26914..fd7b1aa847 100644 --- a/pcbnew/dialogs/dialog_general_options.cpp +++ b/pcbnew/dialogs/dialog_general_options.cpp @@ -228,7 +228,7 @@ void PCB_EDIT_FRAME::OnSelectOptionToolbar( wxCommandEvent& event ) // Apply new display options to the GAL canvas (this is faster than recaching) settings->LoadDisplayOptions( DisplayOpt ); - setHighContrastLayer( getActiveLayer() ); + setHighContrastLayer( GetActiveLayer() ); m_canvas->Refresh(); break; diff --git a/pcbnew/dialogs/dialog_global_deletion.cpp b/pcbnew/dialogs/dialog_global_deletion.cpp index 69eec16422..99ff3f3e92 100644 --- a/pcbnew/dialogs/dialog_global_deletion.cpp +++ b/pcbnew/dialogs/dialog_global_deletion.cpp @@ -39,7 +39,7 @@ DIALOG_GLOBAL_DELETION::DIALOG_GLOBAL_DELETION( PCB_EDIT_FRAME* parent ) void PCB_EDIT_FRAME::InstallPcbGlobalDeleteFrame( const wxPoint& pos ) { DIALOG_GLOBAL_DELETION dlg( this ); - dlg.SetCurrentLayer( getActiveLayer() ); + dlg.SetCurrentLayer( GetActiveLayer() ); dlg.ShowModal(); } diff --git a/pcbnew/dialogs/dialog_layers_setup.cpp b/pcbnew/dialogs/dialog_layers_setup.cpp index fc26fe399e..2c3756af5a 100644 --- a/pcbnew/dialogs/dialog_layers_setup.cpp +++ b/pcbnew/dialogs/dialog_layers_setup.cpp @@ -670,11 +670,11 @@ void PCB_EDIT_FRAME::InstallDialogLayerSetup() if( dlg.ShowModal() == wxID_CANCEL ) return; - wxLogDebug( wxT( "Current layer selected %d." ), getActiveLayer() ); + wxLogDebug( wxT( "Current layer selected %d." ), GetActiveLayer() ); // If the current active layer was removed, find the next avaiable layer to set as the // active layer. - if( !( GetLayerMask( getActiveLayer() ) & GetBoard()->GetEnabledLayers() ) ) + if( !( GetLayerMask( GetActiveLayer() ) & GetBoard()->GetEnabledLayers() ) ) { for( LAYER_NUM i = FIRST_LAYER; i < NB_LAYERS; ++i ) { @@ -685,14 +685,14 @@ void PCB_EDIT_FRAME::InstallDialogLayerSetup() if( GetLayerMask( tmp ) & GetBoard()->GetEnabledLayers() ) { - wxLogDebug( wxT( "Setting current layer to %d." ), getActiveLayer() ); - setActiveLayer( tmp, true ); + wxLogDebug( wxT( "Setting current layer to %d." ), GetActiveLayer() ); + SetActiveLayer( tmp, true ); break; } } } else { - setActiveLayer( getActiveLayer(), true ); + SetActiveLayer( GetActiveLayer(), true ); } } diff --git a/pcbnew/dimension.cpp b/pcbnew/dimension.cpp index 71c1a14393..db02e08ae4 100644 --- a/pcbnew/dimension.cpp +++ b/pcbnew/dimension.cpp @@ -251,7 +251,7 @@ DIMENSION* PCB_EDIT_FRAME::EditDimension( DIMENSION* aDimension, wxDC* aDC ) aDimension = new DIMENSION( GetBoard() ); aDimension->SetFlags( IS_NEW ); - aDimension->SetLayer( getActiveLayer() ); + aDimension->SetLayer( GetActiveLayer() ); aDimension->SetOrigin( pos ); aDimension->SetEnd( pos ); diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index 453572ddc5..cf1c9242e2 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -406,14 +406,14 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) m_canvas->SetIgnoreMouseEvents( true ); wxPoint dlgPosition; wxGetMousePosition( &dlgPosition.x, &dlgPosition.y ); - LAYER_NUM layer = SelectLayer( getActiveLayer(), ALL_NO_CU_LAYERS, + LAYER_NUM layer = SelectLayer( GetActiveLayer(), ALL_NO_CU_LAYERS, dlgPosition ); m_canvas->SetIgnoreMouseEvents( false ); m_canvas->MoveCursorToCrossHair(); - if( getActiveLayer() != layer ) + if( GetActiveLayer() != layer ) { - GetScreen()->m_Route_Layer_TOP = getActiveLayer(); + GetScreen()->m_Route_Layer_TOP = GetActiveLayer(); GetScreen()->m_Route_Layer_BOTTOM = layer; Other_Layer_Route( (TRACK*) GetCurItem(), &dc ); } @@ -942,17 +942,17 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) break; case ID_POPUP_PCB_SELECT_LAYER: - itmp = SelectLayer( getActiveLayer() ); + itmp = SelectLayer( GetActiveLayer() ); if( itmp >= 0 ) { // if user changed colors and we are in high contrast mode, then redraw // because the PAD_SMD pads may change color. - if( DisplayOpt.ContrastModeDisplay && getActiveLayer() != itmp ) + if( DisplayOpt.ContrastModeDisplay && GetActiveLayer() != itmp ) { m_canvas->Refresh(); } - setActiveLayer( itmp ); + SetActiveLayer( itmp ); } m_canvas->MoveCursorToCrossHair(); @@ -963,19 +963,19 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) break; case ID_POPUP_PCB_SELECT_NO_CU_LAYER: - itmp = SelectLayer( getActiveLayer(), ALL_CU_LAYERS ); + itmp = SelectLayer( GetActiveLayer(), ALL_CU_LAYERS ); if( itmp >= 0 ) - setActiveLayer( itmp ); + SetActiveLayer( itmp ); m_canvas->MoveCursorToCrossHair(); break; case ID_POPUP_PCB_SELECT_CU_LAYER: - itmp = SelectLayer( getActiveLayer(), ALL_NO_CU_LAYERS ); + itmp = SelectLayer( GetActiveLayer(), ALL_NO_CU_LAYERS ); if( itmp >= 0 ) - setActiveLayer( itmp ); + SetActiveLayer( itmp ); break; @@ -985,7 +985,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) break; case ID_TOOLBARH_PCB_SELECT_LAYER: - setActiveLayer( m_SelLayerBox->GetLayerSelection() ); + SetActiveLayer( m_SelLayerBox->GetLayerSelection() ); if( DisplayOpt.ContrastModeDisplay ) m_canvas->Refresh( true ); @@ -1288,7 +1288,7 @@ void PCB_EDIT_FRAME::RemoveStruct( BOARD_ITEM* Item, wxDC* DC ) void PCB_EDIT_FRAME::SwitchLayer( wxDC* DC, LAYER_NUM layer ) { - LAYER_NUM curLayer = getActiveLayer(); + LAYER_NUM curLayer = GetActiveLayer(); // Check if the specified layer matches the present layer if( layer == curLayer ) @@ -1330,7 +1330,7 @@ void PCB_EDIT_FRAME::SwitchLayer( wxDC* DC, LAYER_NUM layer ) GetScreen()->m_Route_Layer_TOP = curLayer; GetScreen()->m_Route_Layer_BOTTOM = layer; - setActiveLayer( curLayer ); + SetActiveLayer( curLayer ); if( Other_Layer_Route( (TRACK*) GetScreen()->GetCurItem(), DC ) ) { @@ -1351,7 +1351,7 @@ void PCB_EDIT_FRAME::SwitchLayer( wxDC* DC, LAYER_NUM layer ) // and a non-copper layer, or vice-versa? // ... - setActiveLayer( layer ); + SetActiveLayer( layer ); if( DisplayOpt.ContrastModeDisplay ) m_canvas->Refresh(); diff --git a/pcbnew/editedge.cpp b/pcbnew/editedge.cpp index a85a0bf26e..207b515e66 100644 --- a/pcbnew/editedge.cpp +++ b/pcbnew/editedge.cpp @@ -246,7 +246,7 @@ DRAWSEGMENT* PCB_EDIT_FRAME::Begin_DrawSegment( DRAWSEGMENT* Segment, STROKE_T s s_large = GetDesignSettings().m_DrawSegmentWidth; - if( getActiveLayer() == EDGE_N ) + if( GetActiveLayer() == EDGE_N ) { s_large = GetDesignSettings().m_EdgeSegmentWidth; } @@ -255,7 +255,7 @@ DRAWSEGMENT* PCB_EDIT_FRAME::Begin_DrawSegment( DRAWSEGMENT* Segment, STROKE_T s { SetCurItem( Segment = new DRAWSEGMENT( GetBoard() ) ); Segment->SetFlags( IS_NEW ); - Segment->SetLayer( getActiveLayer() ); + Segment->SetLayer( GetActiveLayer() ); Segment->SetWidth( s_large ); Segment->SetShape( shape ); Segment->SetAngle( 900 ); diff --git a/pcbnew/editrack-part2.cpp b/pcbnew/editrack-part2.cpp index e394ad1ca3..528d96988a 100644 --- a/pcbnew/editrack-part2.cpp +++ b/pcbnew/editrack-part2.cpp @@ -51,10 +51,10 @@ bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC ) if( aTrack == NULL ) { - if( getActiveLayer() != ((PCB_SCREEN*)GetScreen())->m_Route_Layer_TOP ) - setActiveLayer( ((PCB_SCREEN*)GetScreen())->m_Route_Layer_TOP ); + if( GetActiveLayer() != ((PCB_SCREEN*)GetScreen())->m_Route_Layer_TOP ) + SetActiveLayer( ((PCB_SCREEN*)GetScreen())->m_Route_Layer_TOP ); else - setActiveLayer(((PCB_SCREEN*)GetScreen())->m_Route_Layer_BOTTOM ); + SetActiveLayer(((PCB_SCREEN*)GetScreen())->m_Route_Layer_BOTTOM ); UpdateStatusBar(); return true; @@ -108,7 +108,7 @@ bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC ) via->SetLayerPair( LAYER_N_BACK, LAYER_N_FRONT ); via->SetDrill( GetBoard()->GetCurrentViaDrill() ); - LAYER_NUM first_layer = getActiveLayer(); + LAYER_NUM first_layer = GetActiveLayer(); LAYER_NUM last_layer; // prepare switch to new active layer: @@ -171,7 +171,7 @@ bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC ) return false; } - setActiveLayer( last_layer ); + SetActiveLayer( last_layer ); TRACK* lastNonVia = g_CurrentTrackSegment; @@ -193,7 +193,7 @@ bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC ) */ // set the layer to the new value - track->SetLayer( getActiveLayer() ); + track->SetLayer( GetActiveLayer() ); /* the start point is the via position and the end point is the cursor * which also is on the via (will change when moving mouse) diff --git a/pcbnew/hotkeys_board_editor.cpp b/pcbnew/hotkeys_board_editor.cpp index b42f2ddb04..6364d69ba6 100644 --- a/pcbnew/hotkeys_board_editor.cpp +++ b/pcbnew/hotkeys_board_editor.cpp @@ -263,7 +263,7 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit break; case HK_SWITCH_LAYER_TO_PREVIOUS: - ll = getActiveLayer(); + ll = GetActiveLayer(); if( (ll <= LAYER_N_BACK) || (ll > LAYER_N_FRONT) ) break; @@ -279,7 +279,7 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit break; case HK_SWITCH_LAYER_TO_NEXT: - ll = getActiveLayer(); + ll = GetActiveLayer(); if( (ll < LAYER_N_BACK) || (ll >= LAYER_N_FRONT) ) break; @@ -397,7 +397,7 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit break; case HK_BACK_SPACE: - if( IsCopperLayer( getActiveLayer() ) ) + if( IsCopperLayer( GetActiveLayer() ) ) { if( !itemCurrentlyEdited ) { @@ -622,7 +622,7 @@ bool PCB_EDIT_FRAME::OnHotkeyDeleteItem( wxDC* aDC ) switch( GetToolId() ) { case ID_TRACK_BUTT: - if( getActiveLayer() > LAYER_N_FRONT ) + if( GetActiveLayer() > LAYER_N_FRONT ) return false; if( ItemFree ) @@ -983,7 +983,7 @@ bool PCB_EDIT_FRAME::OnHotkeyPlaceItem( wxDC* aDC ) TRACK * PCB_EDIT_FRAME::OnHotkeyBeginRoute( wxDC* aDC ) { - if( getActiveLayer() > LAYER_N_FRONT ) + if( GetActiveLayer() > LAYER_N_FRONT ) return NULL; bool itemCurrentlyEdited = (GetCurItem() && GetCurItem()->GetFlags()); diff --git a/pcbnew/onleftclick.cpp b/pcbnew/onleftclick.cpp index 00b313d784..43f0486fe1 100644 --- a/pcbnew/onleftclick.cpp +++ b/pcbnew/onleftclick.cpp @@ -243,7 +243,7 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) if( GetToolId() == ID_PCB_ARC_BUTT ) shape = S_ARC; - if( IsCopperLayer( getActiveLayer() ) ) + if( IsCopperLayer( GetActiveLayer() ) ) { DisplayError( this, _( "Graphic not allowed on Copper layers" ) ); break; @@ -267,7 +267,7 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) break; case ID_TRACK_BUTT: - if( !IsCopperLayer( getActiveLayer() ) ) + if( !IsCopperLayer( GetActiveLayer() ) ) { DisplayError( this, _( "Tracks on Copper layers only " ) ); break; @@ -325,7 +325,7 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) break; case ID_PCB_ADD_TEXT_BUTT: - if( IsLayerInList( EDGE_LAYER, getActiveLayer() ) ) + if( IsLayerInList( EDGE_LAYER, GetActiveLayer() ) ) { DisplayError( this, _( "Texts not allowed on Edge Cut layer" ) ); @@ -374,7 +374,7 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) break; case ID_PCB_DIMENSION_BUTT: - if( IsLayerInList( EDGE_LAYER|ALL_CU_LAYERS, getActiveLayer() ) ) + if( IsLayerInList( EDGE_LAYER|ALL_CU_LAYERS, GetActiveLayer() ) ) { DisplayError( this, _( "Dimension not allowed on Copper or Edge Cut layers" ) ); diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index dee3308be0..8c39655d8b 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -842,7 +842,7 @@ void PCB_EDIT_FRAME::SetGridColor(EDA_COLOR_T aColor) bool PCB_EDIT_FRAME::IsMicroViaAcceptable( void ) { int copperlayercnt = GetBoard()->GetCopperLayerCount( ); - LAYER_NUM currLayer = getActiveLayer(); + LAYER_NUM currLayer = GetActiveLayer(); if( !GetDesignSettings().m_MicroViasAllowed ) return false; // Obvious.. @@ -946,7 +946,7 @@ void PCB_EDIT_FRAME::SetTopLayer( LAYER_NUM aLayer ) } -void PCB_EDIT_FRAME::setActiveLayer( LAYER_NUM aLayer, bool doLayerWidgetUpdate ) +void PCB_EDIT_FRAME::SetActiveLayer( LAYER_NUM aLayer, bool doLayerWidgetUpdate ) { ( (PCB_SCREEN*) GetScreen() )->m_Active_Layer = aLayer; @@ -962,7 +962,7 @@ void PCB_EDIT_FRAME::setActiveLayer( LAYER_NUM aLayer, bool doLayerWidgetUpdate void PCB_EDIT_FRAME::syncLayerWidgetLayer() { - m_Layers->SelectLayer( getActiveLayer() ); + m_Layers->SelectLayer( GetActiveLayer() ); m_Layers->OnLayerSelected(); } diff --git a/pcbnew/tool_pcb.cpp b/pcbnew/tool_pcb.cpp index 6038bf41ff..ec4d07df7d 100644 --- a/pcbnew/tool_pcb.cpp +++ b/pcbnew/tool_pcb.cpp @@ -105,7 +105,7 @@ void PCB_EDIT_FRAME::PrepareLayerIndicator() previous_Route_Layer_BOTTOM_color, previous_via_color; /* get colors, and redraw bitmap button only on changes */ - active_layer_color = GetBoard()->GetLayerColor(getActiveLayer()); + active_layer_color = GetBoard()->GetLayerColor(GetActiveLayer()); if( previous_active_layer_color != active_layer_color ) { diff --git a/pcbnew/toolbars_update_user_interface.cpp b/pcbnew/toolbars_update_user_interface.cpp index 6e8ceaac2c..b65328dcf5 100644 --- a/pcbnew/toolbars_update_user_interface.cpp +++ b/pcbnew/toolbars_update_user_interface.cpp @@ -96,7 +96,7 @@ void PCB_EDIT_FRAME::OnUpdateSelectViaSize( wxUpdateUIEvent& aEvent ) void PCB_EDIT_FRAME::OnUpdateLayerSelectBox( wxUpdateUIEvent& aEvent ) { - m_SelLayerBox->SetLayerSelection( getActiveLayer() ); + m_SelLayerBox->SetLayerSelection( GetActiveLayer() ); } diff --git a/pcbnew/zones_by_polygon.cpp b/pcbnew/zones_by_polygon.cpp index 838bf67bb7..81719711f6 100644 --- a/pcbnew/zones_by_polygon.cpp +++ b/pcbnew/zones_by_polygon.cpp @@ -515,7 +515,7 @@ int PCB_EDIT_FRAME::Begin_Zone( wxDC* DC ) if( !GetBoard()->m_CurrentZoneContour ) { if( GetToolId() == ID_PCB_KEEPOUT_AREA_BUTT && - getActiveLayer() >= FIRST_NON_COPPER_LAYER ) + GetActiveLayer() >= FIRST_NON_COPPER_LAYER ) { DisplayError( this, _( "Error: a keepout area is allowed only on copper layers" ) ); @@ -534,7 +534,7 @@ int PCB_EDIT_FRAME::Begin_Zone( wxDC* DC ) ZONE_EDIT_T edited; // Init zone params to reasonable values - zone->SetLayer( getActiveLayer() ); + zone->SetLayer( GetActiveLayer() ); // Prompt user for parameters: m_canvas->SetIgnoreMouseEvents( true ); @@ -597,7 +597,7 @@ int PCB_EDIT_FRAME::Begin_Zone( wxDC* DC ) return 0; // Switch active layer to the selected zone layer - setActiveLayer( zoneInfo.m_CurrentZone_Layer ); + SetActiveLayer( zoneInfo.m_CurrentZone_Layer ); SetZoneSettings( zoneInfo ); } @@ -607,7 +607,7 @@ int PCB_EDIT_FRAME::Begin_Zone( wxDC* DC ) // zone (add cutout or similar zone) zoneInfo.m_CurrentZone_Layer = s_CurrentZone->GetLayer(); - setActiveLayer( s_CurrentZone->GetLayer() ); + SetActiveLayer( s_CurrentZone->GetLayer() ); zoneInfo << *s_CurrentZone; From c7116e9d0316704da2a04ebc4ca35aaa91f96efe Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 21 Mar 2014 17:55:46 +0100 Subject: [PATCH 095/134] FIxed too late deletion of TOOLs. --- common/tool/tool_manager.cpp | 10 +++++++++- include/tool/tool_manager.h | 5 +++++ pcbnew/tools/pcb_tools.cpp | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index 57a98779f6..0d25c88434 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -103,6 +103,14 @@ TOOL_MANAGER::TOOL_MANAGER() : TOOL_MANAGER::~TOOL_MANAGER() +{ + DeleteAll(); + + delete m_actionMgr; +} + + +void TOOL_MANAGER::DeleteAll() { std::map::iterator it, it_end; @@ -113,7 +121,7 @@ TOOL_MANAGER::~TOOL_MANAGER() delete it->first; // delete the tool itself } - delete m_actionMgr; + m_toolState.clear(); } diff --git a/include/tool/tool_manager.h b/include/tool/tool_manager.h index 04afea3483..1103a7f890 100644 --- a/include/tool/tool_manager.h +++ b/include/tool/tool_manager.h @@ -57,6 +57,11 @@ public: ~TOOL_MANAGER(); + /** + * Deletes all the tools that were registered in the TOOL_MANAGER. + */ + void DeleteAll(); + /** * Generates an unique ID from for a tool with given name. */ diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index 28a1b424a3..437ad4fba8 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -68,6 +68,7 @@ void PCB_EDIT_FRAME::setupTools() void PCB_EDIT_FRAME::destroyTools() { + m_toolManager.DeleteAll(); delete m_toolDispatcher; } From 3a43f0527f300ece3c33a7b5bd3ec69ed8a8b8e1 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 21 Mar 2014 18:00:11 +0100 Subject: [PATCH 096/134] Changed void BASE_SCREEN::GetGrids( GRIDS& aList ) to const GRIDS& BASE_SCREEN::GetGrids(). Refactored: - EDA_DRAW_FRAME::SetNextGrid() & SetPrevGrid() - PCB_BASE_FRAME::SetFastGrid1() & SetFastGrid2() Removed a warning from RN_DATA::updateNet(int). --- common/base_screen.cpp | 7 ------ common/drawframe.cpp | 34 +++++++++++++++++++++++++++- eeschema/eeschema_config.cpp | 4 +--- include/class_base_screen.h | 11 +++++----- include/wxBasePcbFrame.h | 21 +++++++++++++----- include/wxstruct.h | 12 ++++++++++ pcbnew/basepcbframe.cpp | 27 +++++++++++++++++++++++ pcbnew/class_board.h | 14 +++++------- pcbnew/hotkeys_board_editor.cpp | 39 ++++----------------------------- pcbnew/ratsnest_data.cpp | 2 +- 10 files changed, 106 insertions(+), 65 deletions(-) diff --git a/common/base_screen.cpp b/common/base_screen.cpp index a441a418d5..01a798df4a 100644 --- a/common/base_screen.cpp +++ b/common/base_screen.cpp @@ -175,13 +175,6 @@ void BASE_SCREEN::SetGridList( GRIDS& gridlist ) } -void BASE_SCREEN::GetGrids( GRIDS& aList ) -{ - for( size_t i = 0; i < m_grids.size(); i++ ) - aList.push_back( m_grids[ i ] ); -} - - int BASE_SCREEN::SetGrid( const wxRealPoint& size ) { wxASSERT( !m_grids.empty() ); diff --git a/common/drawframe.cpp b/common/drawframe.cpp index 31048df82f..45913b5171 100644 --- a/common/drawframe.cpp +++ b/common/drawframe.cpp @@ -395,7 +395,7 @@ void EDA_DRAW_FRAME::OnSelectGrid( wxCommandEvent& event ) if( IsGalCanvasActive() ) { GetGalCanvas()->GetGAL()->SetGridSize( VECTOR2D( screen->GetGrid().m_Size.x, - screen->GetGrid().m_Size.y ) ); + screen->GetGrid().m_Size.y ) ); GetGalCanvas()->GetView()->MarkTargetDirty( KIGFX::TARGET_NONCACHED ); } @@ -532,6 +532,38 @@ wxPoint EDA_DRAW_FRAME::GetGridPosition( const wxPoint& aPosition ) const } +void EDA_DRAW_FRAME::SetNextGrid() +{ + if( m_gridSelectBox ) + { + m_gridSelectBox->SetSelection( ( m_gridSelectBox->GetSelection() + 1 ) % + m_gridSelectBox->GetCount() ); + + wxCommandEvent cmd( wxEVT_COMMAND_COMBOBOX_SELECTED ); + // cmd.SetEventObject( this ); + OnSelectGrid( cmd ); + } +} + + +void EDA_DRAW_FRAME::SetPrevGrid() +{ + if( m_gridSelectBox ) + { + int cnt = m_gridSelectBox->GetSelection(); + + if( --cnt < 0 ) + cnt = m_gridSelectBox->GetCount() - 1; + + m_gridSelectBox->SetSelection( cnt ); + + wxCommandEvent cmd( wxEVT_COMMAND_COMBOBOX_SELECTED ); + // cmd.SetEventObject( this ); + OnSelectGrid( cmd ); + } +} + + int EDA_DRAW_FRAME::ReturnBlockCommand( int key ) { return 0; diff --git a/eeschema/eeschema_config.cpp b/eeschema/eeschema_config.cpp index 43e5ec21e3..4449957e0b 100644 --- a/eeschema/eeschema_config.cpp +++ b/eeschema/eeschema_config.cpp @@ -255,9 +255,7 @@ void SCH_EDIT_FRAME::Process_Config( wxCommandEvent& event ) void SCH_EDIT_FRAME::OnSetOptions( wxCommandEvent& event ) { wxArrayString units; - GRIDS grid_list; - - GetScreen()->GetGrids( grid_list ); + GRIDS grid_list = GetScreen()->GetGrids(); DIALOG_EESCHEMA_OPTIONS dlg( this ); diff --git a/include/class_base_screen.h b/include/class_base_screen.h index eed5987e39..502ab9a9e6 100644 --- a/include/class_base_screen.h +++ b/include/class_base_screen.h @@ -65,7 +65,7 @@ public: }; -typedef std::vector< GRID_TYPE > GRIDS; +typedef std::vector GRIDS; /** @@ -445,11 +445,12 @@ public: /** * Function GetGrids(). - * Copy the grid list to \a aList. - * - * @param aList - List to copy to. + * Returns the current list of grids. */ - void GetGrids( GRIDS& aList ); + const GRIDS& GetGrids() const + { + return m_grids; + } /** * Function GetClass diff --git a/include/wxBasePcbFrame.h b/include/wxBasePcbFrame.h index 4306d67977..6f8c226e90 100644 --- a/include/wxBasePcbFrame.h +++ b/include/wxBasePcbFrame.h @@ -76,8 +76,8 @@ public: EDA_UNITS_T m_UserGridUnit; wxRealPoint m_UserGridSize; - int m_FastGrid1; - int m_FastGrid2; + int m_FastGrid1; // 1st fast grid setting (index in EDA_DRAW_FRAME::m_gridSelectBox) + int m_FastGrid2; // 2nd fast grid setting (index in EDA_DRAW_FRAME::m_gridSelectBox) EDA_3D_FRAME* m_Draw3DFrame; @@ -220,13 +220,10 @@ public: * Function BestZoom * @return the "best" zoom to show the entire board or footprint on the screen. */ - virtual double BestZoom(); virtual void Show3D_Frame( wxCommandEvent& event ); -public: - // Read/write functions: EDA_ITEM* ReadDrawSegmentDescr( LINE_READER* aReader ); int ReadListeSegmentDescr( LINE_READER* aReader, @@ -680,6 +677,20 @@ public: void OnUpdateSelectGrid( wxUpdateUIEvent& aEvent ); void OnUpdateSelectZoom( wxUpdateUIEvent& aEvent ); + /** + * Function SetFastGrid1() + * + * Switches grid settings to the 1st "fast" setting predefined by user. + */ + void SetFastGrid1(); + + /** + * Function SetFastGrid2() + * + * Switches grid settings to the 1st "fast" setting predefined by user. + */ + void SetFastGrid2(); + DECLARE_EVENT_TABLE() }; diff --git a/include/wxstruct.h b/include/wxstruct.h index 69a24fa7a0..5564fe6050 100644 --- a/include/wxstruct.h +++ b/include/wxstruct.h @@ -727,6 +727,18 @@ public: */ wxPoint GetGridPosition( const wxPoint& aPosition ) const; + /** + * Function SetNextGrid() + * changes the grid size settings to the next one available. + */ + virtual void SetNextGrid(); + + /** + * Function SetPrevGrid() + * changes the grid size settings to the previous one available. + */ + virtual void SetPrevGrid(); + /** * Command event handler for selecting grid sizes. * diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index 0464d04683..1bccc1894a 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -914,6 +914,7 @@ void PCB_BASE_FRAME::updateGridSelectBox() } } + void PCB_BASE_FRAME::updateZoomSelectBox() { if( m_zoomSelectBox == NULL ) @@ -943,3 +944,29 @@ void PCB_BASE_FRAME::updateZoomSelectBox() m_zoomSelectBox->SetSelection( i + 1 ); } } + + +void PCB_BASE_FRAME::SetFastGrid1() +{ + if( m_gridSelectBox ) + { + m_gridSelectBox->SetSelection( m_FastGrid1 ); + + wxCommandEvent cmd( wxEVT_COMMAND_COMBOBOX_SELECTED ); + cmd.SetEventObject( this ); + OnSelectGrid( cmd ); + } +} + + +void PCB_BASE_FRAME::SetFastGrid2() +{ + if( m_gridSelectBox ) + { + m_gridSelectBox->SetSelection( m_FastGrid2 ); + + wxCommandEvent cmd( wxEVT_COMMAND_COMBOBOX_SELECTED ); + cmd.SetEventObject( this ); + OnSelectGrid( cmd ); + } +} diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h index 92058d0af6..0d394297b2 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -68,8 +68,6 @@ namespace KIGFX // non-owning container of item candidates when searching for items on the same track. typedef std::vector< TRACK* > TRACK_PTRS; -#define HISTORY_MAX_COUNT 8 - /** * Enum LAYER_T @@ -305,13 +303,13 @@ public: // the first value is always the value of the current NetClass // The others values are extra values - /// Vias size and drill list(max count = HISTORY_MAX_COUNT) - std::vector m_ViasDimensionsList; + // The first value is the current netclass via size // TODO verify + /// Vias size and drill list + std::vector m_ViasDimensionsList; - // The first value is the current netclass via size - // tracks widths (max count = HISTORY_MAX_COUNT) - // The first value is the current netclass track width - std::vector m_TrackWidthList; + // The first value is the current netclass track width // TODO verify + /// Track width list + std::vector m_TrackWidthList; BOARD(); diff --git a/pcbnew/hotkeys_board_editor.cpp b/pcbnew/hotkeys_board_editor.cpp index 6364d69ba6..42ab76ac75 100644 --- a/pcbnew/hotkeys_board_editor.cpp +++ b/pcbnew/hotkeys_board_editor.cpp @@ -216,50 +216,19 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit break; case HK_SWITCH_GRID_TO_FASTGRID1: - if( m_gridSelectBox ) - { - m_gridSelectBox->SetSelection( m_FastGrid1 ); - cmd.SetEventType( wxEVT_COMMAND_COMBOBOX_SELECTED ); - OnSelectGrid( cmd ); - } - + SetFastGrid1(); break; case HK_SWITCH_GRID_TO_FASTGRID2: - if( m_gridSelectBox ) - { - m_gridSelectBox->SetSelection( m_FastGrid2 ); - cmd.SetEventType( wxEVT_COMMAND_COMBOBOX_SELECTED ); - OnSelectGrid( cmd ); - } - + SetFastGrid2(); break; case HK_SWITCH_GRID_TO_NEXT: - if( m_gridSelectBox ) - { - m_gridSelectBox->SetSelection( ( m_gridSelectBox->GetSelection() + 1 ) % - m_gridSelectBox->GetCount() ); - cmd.SetEventType( wxEVT_COMMAND_COMBOBOX_SELECTED ); - OnSelectGrid( cmd ); - } + SetNextGrid(); break; case HK_SWITCH_GRID_TO_PREVIOUS: - if( m_gridSelectBox ) - { - cnt = m_gridSelectBox->GetSelection(); - - if ( cnt == 0 ) - cnt = m_gridSelectBox->GetCount() - 1; - else - cnt--; - - m_gridSelectBox->SetSelection( cnt ); - cmd.SetEventType( wxEVT_COMMAND_COMBOBOX_SELECTED ); - OnSelectGrid( cmd ); - } - + SetPrevGrid(); break; case HK_SWITCH_LAYER_TO_PREVIOUS: diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index 4242ea6bf1..b2bc4d5899 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -1024,7 +1024,7 @@ void RN_DATA::updateNet( int aNetCode ) { assert( aNetCode < (int) m_nets.size() ); - if( aNetCode < 1 || aNetCode > m_nets.size() ) + if( aNetCode < 1 || aNetCode > (int) m_nets.size() ) return; m_nets[aNetCode].ClearSimple(); From dc9298730d65a3dc1f840eb1255bb627b85168e7 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 24 Mar 2014 08:45:05 +0100 Subject: [PATCH 097/134] Added PCBNEW_CONTROLS for handling miscellaneous hot keys (trying to be compatible with the default hot key settings). Currently there are a lot of stubs to be filled out (in pcbnew_controls.cpp). Handled actions: - switching layers - switching grids - changing track width & via size --- pcbnew/CMakeLists.txt | 1 + pcbnew/tools/common_actions.cpp | 147 +++++++++- pcbnew/tools/common_actions.h | 50 ++++ pcbnew/tools/pcb_tools.cpp | 4 +- pcbnew/tools/pcbnew_control.cpp | 458 ++++++++++++++++++++++++++++++++ pcbnew/tools/pcbnew_control.h | 97 +++++++ 6 files changed, 753 insertions(+), 4 deletions(-) create mode 100644 pcbnew/tools/pcbnew_control.cpp create mode 100644 pcbnew/tools/pcbnew_control.h diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index dee4a0af07..b68f93e05b 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -260,6 +260,7 @@ set( PCBNEW_CLASS_SRCS tools/point_editor.cpp tools/drawing_tool.cpp tools/edit_tool.cpp + tools/pcbnew_control.cpp tools/pcb_tools.cpp tools/common_actions.cpp ) diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index d5a996c284..f409cc610d 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -92,17 +92,160 @@ TOOL_ACTION COMMON_ACTIONS::placeTarget( "pcbnew.InteractiveDrawing.placeTarget" "Add layer alignment target", "Add layer alignment target" ); TOOL_ACTION COMMON_ACTIONS::placeModule( "pcbnew.InteractiveDrawing.placeModule", - AS_GLOBAL, 0, + AS_GLOBAL, 'O', "Add modules", "Add modules" ); TOOL_ACTION COMMON_ACTIONS::routerActivate( "pcbnew.InteractiveRouter", - AS_GLOBAL, 0, + AS_GLOBAL, 'X', "Run push & shove router", "Run push & shove router" ); TOOL_ACTION COMMON_ACTIONS::pointEditorUpdate( "pcbnew.PointEditor.update", AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere +// View Controls +TOOL_ACTION COMMON_ACTIONS::zoomIn( "pcbnew.zoomIn", + AS_GLOBAL, WXK_F1, + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::zoomOut( "pcbnew.zoomOut", + AS_GLOBAL, WXK_F2, + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::zoomCenter( "pcbnew.zoomCenter", + AS_GLOBAL, WXK_F4, + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::zoomFitScreen( "pcbnew.zoomFitScreen", + AS_GLOBAL, WXK_HOME, + "", "" ); + +// Display modes +TOOL_ACTION COMMON_ACTIONS::trackDisplayMode( "pcbnew.trackDisplayMode", + AS_GLOBAL, 'K', + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::padDisplayMode( "pcbnew.padDisplayMode", + AS_GLOBAL, 'J', // TODO temporarily, find a better hot key + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::viaDisplayMode( "pcbnew.viaDisplayMode", + AS_GLOBAL, 'L', // TODO temporarily, find a better hot key + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::highContrastMode( "pcbnew.highContrastMode", + AS_GLOBAL, 'H', + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::highContrastInc( "pcbnew.highContrastInc", + AS_GLOBAL, MD_SHIFT + '.', // shift+. == > + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::highContrastDec( "pcbnew.highContrastDec", + AS_GLOBAL, MD_SHIFT + 60, // shift+, == < + "", "" ); + + +// Layer control +TOOL_ACTION COMMON_ACTIONS::layerTop( "pcbnew.layerTop", + AS_GLOBAL, WXK_PAGEUP, + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::layerInner1( "pcbnew.layerInner1", + AS_GLOBAL, WXK_F5, + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::layerInner2( "pcbnew.layerInner2", + AS_GLOBAL, WXK_F6, + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::layerInner3( "pcbnew.layerInner3", + AS_GLOBAL, WXK_F7, + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::layerInner4( "pcbnew.layerInner4", + AS_GLOBAL, WXK_F8, + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::layerInner5( "pcbnew.layerInner5", + AS_GLOBAL, WXK_F9, + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::layerInner6( "pcbnew.layerInner6", + AS_GLOBAL, WXK_F10, + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::layerBottom( "pcbnew.layerBottom", + AS_GLOBAL, WXK_PAGEDOWN, + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::layerNext( "pcbnew.layerNext", + AS_GLOBAL, '=', + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::layerPrev( "pcbnew.layerPrev", + AS_GLOBAL, '-', + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::layerAlphaInc( "pcbnew.layerAlphaInc", + AS_GLOBAL, MD_SHIFT + '[', // shift+[ == { + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::layerAlphaDec( "pcbnew.layerAlphaDec", + AS_GLOBAL, MD_SHIFT + ']', // shift+] == } + "", "" ); + + +// Grid control +TOOL_ACTION COMMON_ACTIONS::gridFast1( "pcbnew.gridFast1", + AS_GLOBAL, MD_ALT + '1', + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::gridFast2( "pcbnew.gridFast2", + AS_GLOBAL, MD_ALT + '2', + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::gridNext( "pcbnew.gridNext", + AS_GLOBAL, '`', + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::gridPrev( "pcbnew.gridPrev", + AS_GLOBAL, MD_CTRL + '`', + "", "" ); + + +// Track & via size control +TOOL_ACTION COMMON_ACTIONS::trackWidthInc( "pcbnew.trackWidthInc", + AS_GLOBAL, '[', + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::trackWidthDec( "pcbnew.trackWidthDec", + AS_GLOBAL, ']', + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::viaSizeInc( "pcbnew.viaSizeInc", + AS_GLOBAL, '\'', + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::viaSizeDec( "pcbnew.viaSizeDec", + AS_GLOBAL, '\\', + "", "" ); + + +// Miscellaneous +TOOL_ACTION COMMON_ACTIONS::resetCoords( "pcbnew.resetCoords", + AS_GLOBAL, ' ', + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::switchUnits( "pcbnew.switchUnits", + AS_GLOBAL, MD_CTRL + 'U', + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::showHelp( "pcbnew.showHelp", + AS_GLOBAL, MD_SHIFT + '/', // shift+/ == ? + "", "" ); + + std::string COMMON_ACTIONS::TranslateLegacyId( int aId ) { switch( aId ) diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 321c372436..c97fa154cf 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -33,6 +33,7 @@ class COMMON_ACTIONS { public: + // Selection Tool /// Activation of the selection tool static TOOL_ACTION selectionActivate; @@ -42,6 +43,7 @@ public: /// Clears the current selection static TOOL_ACTION selectionClear; + // Edit Tool /// Activation of the edit tool static TOOL_ACTION editActivate; @@ -57,6 +59,7 @@ public: /// Deleting a BOARD_ITEM static TOOL_ACTION remove; + // Drawing Tool /// Activation of the drawing tool (line) static TOOL_ACTION drawLine; @@ -84,12 +87,59 @@ public: /// Activation of the drawing tool (placing a MODULE) static TOOL_ACTION placeModule; + // Push and Shove Router Tool /// Activation of the Push and Shove router static TOOL_ACTION routerActivate; + // Point Editor /// Update edit points static TOOL_ACTION pointEditorUpdate; + // View controls + static TOOL_ACTION zoomIn; + static TOOL_ACTION zoomOut; + static TOOL_ACTION zoomCenter; + static TOOL_ACTION zoomFitScreen; + + // Display modes + static TOOL_ACTION trackDisplayMode; + static TOOL_ACTION padDisplayMode; + static TOOL_ACTION viaDisplayMode; + static TOOL_ACTION highContrastMode; + static TOOL_ACTION highContrastInc; + static TOOL_ACTION highContrastDec; + + // Layer control + static TOOL_ACTION layerTop; + static TOOL_ACTION layerInner1; + static TOOL_ACTION layerInner2; + static TOOL_ACTION layerInner3; + static TOOL_ACTION layerInner4; + static TOOL_ACTION layerInner5; + static TOOL_ACTION layerInner6; + static TOOL_ACTION layerBottom; + static TOOL_ACTION layerNext; + static TOOL_ACTION layerPrev; + static TOOL_ACTION layerAlphaInc; + static TOOL_ACTION layerAlphaDec; + + // Grid control + static TOOL_ACTION gridFast1; + static TOOL_ACTION gridFast2; + static TOOL_ACTION gridNext; + static TOOL_ACTION gridPrev; + + // Track & via size control + static TOOL_ACTION trackWidthInc; + static TOOL_ACTION trackWidthDec; + static TOOL_ACTION viaSizeInc; + static TOOL_ACTION viaSizeDec; + + // Miscellaneous + static TOOL_ACTION resetCoords; + static TOOL_ACTION switchUnits; + static TOOL_ACTION showHelp; + /** * Function TranslateLegacyId() * Translates legacy tool ids to the corresponding TOOL_ACTION name. diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index 437ad4fba8..45a46a9cdd 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -38,7 +38,7 @@ #include "edit_tool.h" #include "drawing_tool.h" #include "point_editor.h" -#include "settings_tool.h" +#include "pcbnew_control.h" #include "common_actions.h" #include @@ -55,7 +55,7 @@ void PCB_EDIT_FRAME::setupTools() m_toolManager.RegisterTool( new EDIT_TOOL ); m_toolManager.RegisterTool( new DRAWING_TOOL ); m_toolManager.RegisterTool( new POINT_EDITOR ); - m_toolManager.RegisterTool( new SETTINGS_TOOL ); + m_toolManager.RegisterTool( new PCBNEW_CONTROL ); m_toolManager.SetEnvironment( NULL, GetGalCanvas()->GetView(), GetGalCanvas()->GetViewControls(), this ); diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp new file mode 100644 index 0000000000..c3ffab9c9c --- /dev/null +++ b/pcbnew/tools/pcbnew_control.cpp @@ -0,0 +1,458 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 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 "pcbnew_control.h" +#include "common_actions.h" + +#include +#include +#include +#include +#include +#include + +using namespace KIGFX; +using boost::optional; + +PCBNEW_CONTROL::PCBNEW_CONTROL() : + TOOL_INTERACTIVE( "pcbnew.Settings" ) +{ +} + + +bool PCBNEW_CONTROL::Init() +{ + setTransitions(); + + return true; +} + + +int PCBNEW_CONTROL::ZoomIn( TOOL_EVENT& aEvent ) +{ + std::cout << __PRETTY_FUNCTION__ << std::endl; + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::ZoomOut( TOOL_EVENT& aEvent ) +{ + std::cout << __PRETTY_FUNCTION__ << std::endl; + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::ZoomCenter( TOOL_EVENT& aEvent ) +{ + std::cout << __PRETTY_FUNCTION__ << std::endl; + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::ZoomFitScreen( TOOL_EVENT& aEvent ) +{ + std::cout << __PRETTY_FUNCTION__ << std::endl; + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::TrackDisplayMode( TOOL_EVENT& aEvent ) +{ + std::cout << __PRETTY_FUNCTION__ << std::endl; + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::PadDisplayMode( TOOL_EVENT& aEvent ) +{ + wxCommandEvent dummy; + getEditFrame()->OnTogglePadDrawMode( dummy ); + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::ViaDisplayMode( TOOL_EVENT& aEvent ) +{ + std::cout << __PRETTY_FUNCTION__ << std::endl; + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::HighContrastMode( TOOL_EVENT& aEvent ) +{ + std::cout << __PRETTY_FUNCTION__ << std::endl; + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::HighContrastInc( TOOL_EVENT& aEvent ) +{ + std::cout << __PRETTY_FUNCTION__ << std::endl; + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::HighContrastDec( TOOL_EVENT& aEvent ) +{ + std::cout << __PRETTY_FUNCTION__ << std::endl; + setTransitions(); + + return 0; +} + + +// Layer control +int PCBNEW_CONTROL::LayerTop( TOOL_EVENT& aEvent ) +{ + getEditFrame()->SwitchLayer( NULL, LAYER_N_FRONT ); + getEditFrame()->GetGalCanvas()->SetFocus(); + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::LayerInner1( TOOL_EVENT& aEvent ) +{ + getEditFrame()->SwitchLayer( NULL, LAYER_N_2 ); + getEditFrame()->GetGalCanvas()->SetFocus(); + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::LayerInner2( TOOL_EVENT& aEvent ) +{ + getEditFrame()->SwitchLayer( NULL, LAYER_N_3 ); + getEditFrame()->GetGalCanvas()->SetFocus(); + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::LayerInner3( TOOL_EVENT& aEvent ) +{ + getEditFrame()->SwitchLayer( NULL, LAYER_N_4 ); + getEditFrame()->GetGalCanvas()->SetFocus(); + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::LayerInner4( TOOL_EVENT& aEvent ) +{ + getEditFrame()->SwitchLayer( NULL, LAYER_N_5 ); + getEditFrame()->GetGalCanvas()->SetFocus(); + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::LayerInner5( TOOL_EVENT& aEvent ) +{ + getEditFrame()->SwitchLayer( NULL, LAYER_N_6 ); + getEditFrame()->GetGalCanvas()->SetFocus(); + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::LayerInner6( TOOL_EVENT& aEvent ) +{ + getEditFrame()->SwitchLayer( NULL, LAYER_N_7 ); + getEditFrame()->GetGalCanvas()->SetFocus(); + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::LayerBottom( TOOL_EVENT& aEvent ) +{ + getEditFrame()->SetActiveLayer( LAYER_N_BACK, true ); + getEditFrame()->GetGalCanvas()->SetFocus(); + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::LayerNext( TOOL_EVENT& aEvent ) +{ + PCB_EDIT_FRAME* editFrame = getEditFrame(); + LAYER_NUM layer = editFrame->GetActiveLayer(); + layer = ( layer + 1 ) % ( LAST_COPPER_LAYER + 1 ); + assert( IsCopperLayer( layer ) ); + + editFrame->SwitchLayer( NULL, layer ); + editFrame->GetGalCanvas()->SetFocus(); + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::LayerPrev( TOOL_EVENT& aEvent ) +{ + PCB_EDIT_FRAME* editFrame = getEditFrame(); + LAYER_NUM layer = editFrame->GetActiveLayer(); + + if( --layer < 0 ) + layer = LAST_COPPER_LAYER; + + assert( IsCopperLayer( layer ) ); + editFrame->SwitchLayer( NULL, layer ); + editFrame->GetGalCanvas()->SetFocus(); + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::LayerAlphaInc( TOOL_EVENT& aEvent ) +{ + std::cout << __PRETTY_FUNCTION__ << std::endl; + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::LayerAlphaDec( TOOL_EVENT& aEvent ) +{ + std::cout << __PRETTY_FUNCTION__ << std::endl; + setTransitions(); + + return 0; +} + + +// Grid control +int PCBNEW_CONTROL::GridFast1( TOOL_EVENT& aEvent ) +{ + getEditFrame()->SetFastGrid1(); + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::GridFast2( TOOL_EVENT& aEvent ) +{ + getEditFrame()->SetFastGrid2(); + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::GridNext( TOOL_EVENT& aEvent ) +{ + getEditFrame()->SetNextGrid(); + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::GridPrev( TOOL_EVENT& aEvent ) +{ + getEditFrame()->SetPrevGrid(); + setTransitions(); + + return 0; +} + + +// Track & via size control +int PCBNEW_CONTROL::TrackWidthInc( TOOL_EVENT& aEvent ) +{ + BOARD* board = getModel( PCB_T ); + int widthIndex = board->GetTrackWidthIndex() + 1; + + if( widthIndex >= (int) board->m_TrackWidthList.size() ) + widthIndex = board->m_TrackWidthList.size() - 1; + + board->SetTrackWidthIndex( widthIndex ); + + wxUpdateUIEvent dummy; + getEditFrame()->OnUpdateSelectTrackWidth( dummy ); + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::TrackWidthDec( TOOL_EVENT& aEvent ) +{ + BOARD* board = getModel( PCB_T ); + int widthIndex = board->GetTrackWidthIndex() - 1; + + if( widthIndex < 0 ) + widthIndex = 0; + + board->SetTrackWidthIndex( widthIndex ); + + wxUpdateUIEvent dummy; + getEditFrame()->OnUpdateSelectTrackWidth( dummy ); + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::ViaSizeInc( TOOL_EVENT& aEvent ) +{ + BOARD* board = getModel( PCB_T ); + int sizeIndex = board->GetViaSizeIndex() + 1; + + if( sizeIndex >= (int) board->m_ViasDimensionsList.size() ) + sizeIndex = board->m_ViasDimensionsList.size() - 1; + + board->SetViaSizeIndex( sizeIndex ); + + wxUpdateUIEvent dummy; + getEditFrame()->OnUpdateSelectViaSize( dummy ); + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::ViaSizeDec( TOOL_EVENT& aEvent ) +{ + BOARD* board = getModel( PCB_T ); + int sizeIndex = board->GetViaSizeIndex() - 1; + + if( sizeIndex < 0 ) + sizeIndex = 0; + + board->SetViaSizeIndex( sizeIndex ); + + wxUpdateUIEvent dummy; + getEditFrame()->OnUpdateSelectViaSize( dummy ); + setTransitions(); + + return 0; +} + + +// Miscellaneous +int PCBNEW_CONTROL::ResetCoords( TOOL_EVENT& aEvent ) +{ + std::cout << __PRETTY_FUNCTION__ << std::endl; + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::SwitchUnits( TOOL_EVENT& aEvent ) +{ + std::cout << __PRETTY_FUNCTION__ << std::endl; + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::ShowHelp( TOOL_EVENT& aEvent ) +{ + std::cout << __PRETTY_FUNCTION__ << std::endl; + setTransitions(); + + return 0; +} + + +void PCBNEW_CONTROL::setTransitions() +{ + // View controls + Go( &PCBNEW_CONTROL::ZoomIn, COMMON_ACTIONS::zoomIn.MakeEvent() ); + Go( &PCBNEW_CONTROL::ZoomOut, COMMON_ACTIONS::zoomOut.MakeEvent() ); + Go( &PCBNEW_CONTROL::ZoomCenter, COMMON_ACTIONS::zoomCenter.MakeEvent() ); + Go( &PCBNEW_CONTROL::ZoomFitScreen, COMMON_ACTIONS::zoomFitScreen.MakeEvent() ); + + // Display modes + Go( &PCBNEW_CONTROL::TrackDisplayMode, COMMON_ACTIONS::trackDisplayMode.MakeEvent() ); + Go( &PCBNEW_CONTROL::PadDisplayMode, COMMON_ACTIONS::padDisplayMode.MakeEvent() ); + Go( &PCBNEW_CONTROL::ViaDisplayMode, COMMON_ACTIONS::viaDisplayMode.MakeEvent() ); + Go( &PCBNEW_CONTROL::HighContrastMode, COMMON_ACTIONS::highContrastMode.MakeEvent() ); + Go( &PCBNEW_CONTROL::HighContrastInc, COMMON_ACTIONS::highContrastInc.MakeEvent() ); + Go( &PCBNEW_CONTROL::HighContrastDec, COMMON_ACTIONS::highContrastDec.MakeEvent() ); + + // Layer control + Go( &PCBNEW_CONTROL::LayerTop, COMMON_ACTIONS::layerTop.MakeEvent() ); + Go( &PCBNEW_CONTROL::LayerInner1, COMMON_ACTIONS::layerInner1.MakeEvent() ); + Go( &PCBNEW_CONTROL::LayerInner2, COMMON_ACTIONS::layerInner2.MakeEvent() ); + Go( &PCBNEW_CONTROL::LayerInner3, COMMON_ACTIONS::layerInner3.MakeEvent() ); + Go( &PCBNEW_CONTROL::LayerInner4, COMMON_ACTIONS::layerInner4.MakeEvent() ); + Go( &PCBNEW_CONTROL::LayerInner5, COMMON_ACTIONS::layerInner5.MakeEvent() ); + Go( &PCBNEW_CONTROL::LayerInner6, COMMON_ACTIONS::layerInner6.MakeEvent() ); + Go( &PCBNEW_CONTROL::LayerBottom, COMMON_ACTIONS::layerBottom.MakeEvent() ); + Go( &PCBNEW_CONTROL::LayerNext, COMMON_ACTIONS::layerNext.MakeEvent() ); + Go( &PCBNEW_CONTROL::LayerPrev, COMMON_ACTIONS::layerPrev.MakeEvent() ); + Go( &PCBNEW_CONTROL::LayerAlphaInc, COMMON_ACTIONS::layerAlphaInc.MakeEvent() ); + Go( &PCBNEW_CONTROL::LayerAlphaDec , COMMON_ACTIONS::layerAlphaDec.MakeEvent() ); + + // Grid control + Go( &PCBNEW_CONTROL::GridFast1, COMMON_ACTIONS::gridFast1.MakeEvent() ); + Go( &PCBNEW_CONTROL::GridFast2, COMMON_ACTIONS::gridFast2.MakeEvent() ); + Go( &PCBNEW_CONTROL::GridNext, COMMON_ACTIONS::gridNext.MakeEvent() ); + Go( &PCBNEW_CONTROL::GridPrev, COMMON_ACTIONS::gridPrev.MakeEvent() ); + + // Track & via size control + Go( &PCBNEW_CONTROL::TrackWidthInc, COMMON_ACTIONS::trackWidthInc.MakeEvent() ); + Go( &PCBNEW_CONTROL::TrackWidthDec, COMMON_ACTIONS::trackWidthDec.MakeEvent() ); + Go( &PCBNEW_CONTROL::ViaSizeInc, COMMON_ACTIONS::viaSizeInc.MakeEvent() ); + Go( &PCBNEW_CONTROL::ViaSizeDec, COMMON_ACTIONS::viaSizeDec.MakeEvent() ); + + // Miscellaneous + Go( &PCBNEW_CONTROL::ResetCoords, COMMON_ACTIONS::resetCoords.MakeEvent() ); + Go( &PCBNEW_CONTROL::SwitchUnits, COMMON_ACTIONS::switchUnits.MakeEvent() ); + Go( &PCBNEW_CONTROL::ShowHelp, COMMON_ACTIONS::showHelp.MakeEvent() ); +} diff --git a/pcbnew/tools/pcbnew_control.h b/pcbnew/tools/pcbnew_control.h new file mode 100644 index 0000000000..41861cd3c0 --- /dev/null +++ b/pcbnew/tools/pcbnew_control.h @@ -0,0 +1,97 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 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 PCBNEW_CONTROL_H +#define PCBNEW_CONTROL_H + +#include + +/** + * Class PCBNEW_CONTROL + * + * TODO + */ + +class PCBNEW_CONTROL : public TOOL_INTERACTIVE +{ +public: + PCBNEW_CONTROL(); + + /// @copydoc TOOL_INTERACTIVE::Reset() + void Reset( RESET_REASON aReason ) {}; + + /// @copydoc TOOL_INTERACTIVE::Init() + bool Init(); + + // View controls + int ZoomIn( TOOL_EVENT& aEvent ); + int ZoomOut( TOOL_EVENT& aEvent ); + int ZoomCenter( TOOL_EVENT& aEvent ); + int ZoomFitScreen( TOOL_EVENT& aEvent ); + + // Display modes + int TrackDisplayMode( TOOL_EVENT& aEvent ); + int PadDisplayMode( TOOL_EVENT& aEvent ); + int ViaDisplayMode( TOOL_EVENT& aEvent ); + int HighContrastMode( TOOL_EVENT& aEvent ); + int HighContrastInc( TOOL_EVENT& aEvent ); + int HighContrastDec( TOOL_EVENT& aEvent ); + + // Layer control + int LayerTop( TOOL_EVENT& aEvent ); + int LayerInner1( TOOL_EVENT& aEvent ); + int LayerInner2( TOOL_EVENT& aEvent ); + int LayerInner3( TOOL_EVENT& aEvent ); + int LayerInner4( TOOL_EVENT& aEvent ); + int LayerInner5( TOOL_EVENT& aEvent ); + int LayerInner6( TOOL_EVENT& aEvent ); + int LayerBottom( TOOL_EVENT& aEvent ); + int LayerNext( TOOL_EVENT& aEvent ); + int LayerPrev( TOOL_EVENT& aEvent ); + int LayerAlphaInc( TOOL_EVENT& aEvent ); + int LayerAlphaDec( TOOL_EVENT& aEvent ); + + // Grid control + int GridFast1( TOOL_EVENT& aEvent ); + int GridFast2( TOOL_EVENT& aEvent ); + int GridNext( TOOL_EVENT& aEvent ); + int GridPrev( TOOL_EVENT& aEvent ); + + // Track & via size control + int TrackWidthInc( TOOL_EVENT& aEvent ); + int TrackWidthDec( TOOL_EVENT& aEvent ); + int ViaSizeInc( TOOL_EVENT& aEvent ); + int ViaSizeDec( TOOL_EVENT& aEvent ); + + // Miscellaneous + int ResetCoords( TOOL_EVENT& aEvent ); + int SwitchUnits( TOOL_EVENT& aEvent ); + int ShowHelp( TOOL_EVENT& aEvent ); + +private: + ///> Sets up handlers for various events. + void setTransitions(); +}; + +#endif From 60e9546b627ad5d5f0b0ead3c4cdf5d728bd8856 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 24 Mar 2014 17:20:23 +0100 Subject: [PATCH 098/134] PCB_EDIT_FRAME::SetHighContrastLayer() went public. Refactored code that handled zooming events. Added PCB_RENDER_SETTINGS::Get/SetSketchMode(). PCBNEW_CONTROL reacts to hot keys changing display modes (sketch via/tracks, high contrast). --- common/tool/tool_dispatcher.cpp | 34 +++++-- common/zoom.cpp | 27 +++-- include/tool/tool_dispatcher.h | 2 +- include/wxPcbStruct.h | 14 +-- include/wxstruct.h | 12 +++ pcbnew/dialogs/dialog_general_options.cpp | 2 +- pcbnew/hotkeys_board_editor.cpp | 4 +- pcbnew/initpcb.cpp | 2 +- pcbnew/menubar_pcbframe.cpp | 4 +- pcbnew/pcb_painter.cpp | 21 ++-- pcbnew/pcb_painter.h | 30 +++++- pcbnew/pcbframe.cpp | 4 +- pcbnew/tools/common_actions.cpp | 9 ++ pcbnew/tools/common_actions.h | 2 + pcbnew/tools/pcb_tools.cpp | 15 ++- pcbnew/tools/pcbnew_control.cpp | 115 +++++++++++++++++++--- pcbnew/tools/pcbnew_control.h | 13 ++- 17 files changed, 242 insertions(+), 68 deletions(-) diff --git a/common/tool/tool_dispatcher.cpp b/common/tool/tool_dispatcher.cpp index 1085534eec..8f36386766 100644 --- a/common/tool/tool_dispatcher.cpp +++ b/common/tool/tool_dispatcher.cpp @@ -27,16 +27,16 @@ #include #include +#include #include #include #include +#include #include #include -using boost::optional; - ///> Stores information about a mouse button state struct TOOL_DISPATCHER::BUTTON_STATE { @@ -126,7 +126,7 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti { BUTTON_STATE* st = m_buttons[aIndex]; wxEventType type = aEvent.GetEventType(); - optional evt; + boost::optional evt; bool isClick = false; bool up = type == st->upEvent; @@ -205,7 +205,7 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) { bool motion = false, buttonEvents = false; - optional evt; + boost::optional evt; int type = aEvent.GetEventType(); @@ -270,7 +270,29 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) } -void TOOL_DISPATCHER::DispatchWxCommand( const wxCommandEvent& aEvent ) +void TOOL_DISPATCHER::DispatchWxCommand( wxCommandEvent& aEvent ) { - // no events to dispatch currently + boost::optional evt; + + switch( aEvent.GetId() ) + { + case ID_ZOOM_IN: // toolbar button "Zoom In" + evt = COMMON_ACTIONS::zoomInCenter.MakeEvent(); + break; + + case ID_ZOOM_OUT: // toolbar button "Zoom In" + evt = COMMON_ACTIONS::zoomOutCenter.MakeEvent(); + break; + + case ID_ZOOM_PAGE: // toolbar button "Fit on Screen" + evt = COMMON_ACTIONS::zoomFitScreen.MakeEvent(); + break; + + default: + aEvent.Skip(); + break; + } + + if( evt ) + m_toolMgr->ProcessEvent( *evt ); } diff --git a/common/zoom.cpp b/common/zoom.cpp index 859d5a4872..b85cc0cc2a 100644 --- a/common/zoom.cpp +++ b/common/zoom.cpp @@ -194,25 +194,22 @@ void EDA_DRAW_FRAME::OnZoom( wxCommandEvent& event ) RedrawScreen( center, true ); } - if( IsGalCanvasActive() ) - { - // Apply computed view settings to GAL - KIGFX::VIEW* view = GetGalCanvas()->GetView(); - KIGFX::GAL* gal = GetGalCanvas()->GetGAL(); - - double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor(); - double zoom = 1.0 / ( zoomFactor * GetZoom() ); - - VECTOR2D cursorWorld( GetCrossHairPosition() ); - view->SetScale( zoom, cursorWorld ); - - GetGalCanvas()->Refresh(); - } - UpdateStatusBar(); } +void EDA_DRAW_FRAME::SetNextZoom() +{ + GetScreen()->SetNextZoom(); +} + + +void EDA_DRAW_FRAME::SetPrevZoom() +{ + GetScreen()->SetPreviousZoom(); +} + + /* add the zoom list menu the the MasterMenu. * used in OnRightClick(wxMouseEvent& event) */ diff --git a/include/tool/tool_dispatcher.h b/include/tool/tool_dispatcher.h index 3a9be1ac64..8ecd893db1 100644 --- a/include/tool/tool_dispatcher.h +++ b/include/tool/tool_dispatcher.h @@ -79,7 +79,7 @@ public: * specified tool). * @param aEvent is the wxCommandEvent to be processed. */ - virtual void DispatchWxCommand( const wxCommandEvent& aEvent ); + virtual void DispatchWxCommand( wxCommandEvent& aEvent ); private: ///> Number of mouse buttons that is handled in events. diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index 03038aece4..022a591930 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -134,12 +134,6 @@ protected: void createPopUpBlockMenu( wxMenu* menu ); void createPopUpMenuForMarkers( MARKER_PCB* aMarker, wxMenu* aPopMenu ); - /** - * Function setHighContrastLayer - * takes care of display settings for the given layer to be displayed in high contrast mode. - */ - void setHighContrastLayer( LAYER_NUM aLayer ); - /** * Function syncLayerWidgetLayer * updates the currently layer "selection" within the PCB_LAYER_WIDGET. @@ -555,6 +549,12 @@ public: */ virtual void OnModify(); + /** + * Function SetHighContrastLayer + * takes care of display settings for the given layer to be displayed in high contrast mode. + */ + void SetHighContrastLayer( LAYER_NUM aLayer ); + /** * Function SetTopLayer * moves the selected layer to the top, so it is displayed above all others. @@ -572,7 +572,7 @@ public: * Function GetActiveLayer * returns the active layer */ - LAYER_NUM GetActiveLayer() + LAYER_NUM GetActiveLayer() const { return ( (PCB_SCREEN*) GetScreen() )->m_Active_Layer; } diff --git a/include/wxstruct.h b/include/wxstruct.h index 5564fe6050..1047a04302 100644 --- a/include/wxstruct.h +++ b/include/wxstruct.h @@ -796,6 +796,18 @@ public: virtual void OnZoom( wxCommandEvent& event ); + /** + * Function SetNextZoom() + * changes the zoom to the next one available. + */ + void SetNextZoom(); + + /** + * Function SetPrevZoom() + * changes the zoom to the previous one available. + */ + void SetPrevZoom(); + /** * Function RedrawScreen * redraws the entire screen area by updating the scroll bars and mouse pointer in diff --git a/pcbnew/dialogs/dialog_general_options.cpp b/pcbnew/dialogs/dialog_general_options.cpp index fd7b1aa847..af29d9796a 100644 --- a/pcbnew/dialogs/dialog_general_options.cpp +++ b/pcbnew/dialogs/dialog_general_options.cpp @@ -228,7 +228,7 @@ void PCB_EDIT_FRAME::OnSelectOptionToolbar( wxCommandEvent& event ) // Apply new display options to the GAL canvas (this is faster than recaching) settings->LoadDisplayOptions( DisplayOpt ); - setHighContrastLayer( GetActiveLayer() ); + SetHighContrastLayer( GetActiveLayer() ); m_canvas->Refresh(); break; diff --git a/pcbnew/hotkeys_board_editor.cpp b/pcbnew/hotkeys_board_editor.cpp index 42ab76ac75..a1dae36662 100644 --- a/pcbnew/hotkeys_board_editor.cpp +++ b/pcbnew/hotkeys_board_editor.cpp @@ -152,7 +152,6 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit cmd.SetEventObject( this ); LAYER_NUM ll; - unsigned int cnt; switch( hk_id ) { @@ -355,8 +354,7 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit break; case HK_SWITCH_TRACK_DISPLAY_MODE: - DisplayOpt.DisplayPcbTrackFill ^= 1; - DisplayOpt.DisplayPcbTrackFill &= 1; + DisplayOpt.DisplayPcbTrackFill = !DisplayOpt.DisplayPcbTrackFill; m_DisplayPcbTrackFill = DisplayOpt.DisplayPcbTrackFill; m_canvas->Refresh(); break; diff --git a/pcbnew/initpcb.cpp b/pcbnew/initpcb.cpp index 8b3b398995..0cb84ac8fb 100644 --- a/pcbnew/initpcb.cpp +++ b/pcbnew/initpcb.cpp @@ -74,7 +74,7 @@ bool PCB_EDIT_FRAME::Clear_Pcb( bool aQuery ) GetBoard()->SetVisibleLayers( ALL_LAYERS ); // Set currently selected layer to be shown in high contrast mode, when enabled` - setHighContrastLayer( GetScreen()->m_Active_Layer ); + SetHighContrastLayer( GetScreen()->m_Active_Layer ); ReFillLayerWidget(); diff --git a/pcbnew/menubar_pcbframe.cpp b/pcbnew/menubar_pcbframe.cpp index f75bd16aaf..780d876ee6 100644 --- a/pcbnew/menubar_pcbframe.cpp +++ b/pcbnew/menubar_pcbframe.cpp @@ -328,12 +328,12 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() */ // Zoom In text = AddHotkeyName( _( "Zoom &In" ), g_Pcbnew_Editor_Hokeys_Descr, - HK_ZOOM_IN ); + HK_ZOOM_IN, IS_ACCELERATOR ); AddMenuItem( viewMenu, ID_ZOOM_IN, text, HELP_ZOOM_IN, KiBitmap( zoom_in_xpm ) ); // Zoom Out text = AddHotkeyName( _( "Zoom &Out" ), g_Pcbnew_Editor_Hokeys_Descr, - HK_ZOOM_OUT ); + HK_ZOOM_OUT, IS_ACCELERATOR ); AddMenuItem( viewMenu, ID_ZOOM_OUT, text, HELP_ZOOM_OUT, KiBitmap( zoom_out_xpm ) ); // Fit on Screen diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 6aa9e54929..e47e2b3686 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -46,7 +46,7 @@ PCB_RENDER_SETTINGS::PCB_RENDER_SETTINGS() // By default everything should be displayed as filled for( unsigned int i = 0; i < END_PCB_VISIBLE_LIST; ++i ) { - m_sketchModeSelect[i] = false; + m_sketchMode[i] = false; } update(); @@ -94,9 +94,9 @@ void PCB_RENDER_SETTINGS::LoadDisplayOptions( const DISPLAY_OPTIONS& aOptions ) m_padNumbers = aOptions.DisplayPadNum; // Whether to draw tracks, vias & pads filled or as outlines - m_sketchModeSelect[PADS_VISIBLE] = !aOptions.DisplayPadFill; - m_sketchModeSelect[VIA_THROUGH_VISIBLE] = !aOptions.DisplayViaFill; - m_sketchModeSelect[TRACKS_VISIBLE] = !aOptions.DisplayPcbTrackFill; + m_sketchMode[PADS_VISIBLE] = !aOptions.DisplayPadFill; + m_sketchMode[VIA_THROUGH_VISIBLE] = !aOptions.DisplayViaFill; + m_sketchMode[TRACKS_VISIBLE] = !aOptions.DisplayPcbTrackFill; switch( aOptions.DisplayNetNamesMode ) { @@ -248,6 +248,7 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer ) case PCB_MARKER_T: draw( (MARKER_PCB*) aItem ); + break; default: // Painter does not know how to draw the object @@ -308,7 +309,7 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer ) m_gal->SetStrokeColor( color ); m_gal->SetIsStroke( true ); - if( m_pcbSettings->m_sketchModeSelect[TRACKS_VISIBLE] ) + if( m_pcbSettings->m_sketchMode[TRACKS_VISIBLE] ) { // Outline mode m_gal->SetLineWidth( m_pcbSettings->m_outlineWidth ); @@ -344,7 +345,7 @@ void PCB_PAINTER::draw( const SEGVIA* aVia, int aLayer ) const COLOR4D& color = m_pcbSettings->GetColor( aVia, aLayer ); - if( m_pcbSettings->m_sketchModeSelect[VIA_THROUGH_VISIBLE] ) + if( m_pcbSettings->m_sketchMode[VIA_THROUGH_VISIBLE] ) { // Outline mode m_gal->SetIsFill( false ); @@ -475,7 +476,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer ) // Pad drawing const COLOR4D& color = m_pcbSettings->GetColor( aPad, aLayer ); - if( m_pcbSettings->m_sketchModeSelect[PADS_VISIBLE] ) + if( m_pcbSettings->m_sketchMode[PADS_VISIBLE] ) { // Outline mode m_gal->SetIsFill( false ); @@ -538,7 +539,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer ) m = ( size.y - size.x ); n = size.x; - if( m_pcbSettings->m_sketchModeSelect[PADS_VISIBLE] ) + if( m_pcbSettings->m_sketchMode[PADS_VISIBLE] ) { // Outline mode m_gal->DrawArc( VECTOR2D( 0, -m ), n, -M_PI, 0 ); @@ -559,7 +560,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer ) m = ( size.x - size.y ); n = size.y; - if( m_pcbSettings->m_sketchModeSelect[PADS_VISIBLE] ) + if( m_pcbSettings->m_sketchMode[PADS_VISIBLE] ) { // Outline mode m_gal->DrawArc( VECTOR2D( -m, 0 ), n, M_PI / 2, 3 * M_PI / 2 ); @@ -595,7 +596,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer ) pointList.push_back( VECTOR2D( corners[2] ) ); pointList.push_back( VECTOR2D( corners[3] ) ); - if( m_pcbSettings->m_sketchModeSelect[PADS_VISIBLE] ) + if( m_pcbSettings->m_sketchMode[PADS_VISIBLE] ) { // Add the beginning point to close the outline pointList.push_back( pointList.front() ); diff --git a/pcbnew/pcb_painter.h b/pcbnew/pcb_painter.h index efa9cc061b..820c4077a5 100644 --- a/pcbnew/pcb_painter.h +++ b/pcbnew/pcb_painter.h @@ -99,6 +99,34 @@ public: */ const COLOR4D& GetLayerColor( int aLayer ) const; + /** + * Function SetSketchMode + * Turns on/off sketch mode for given item layer. + * @param aItemLayer is the item layer that is changed. + * @param aEnabled decides if it is drawn in sketch mode (true for sketched mode, + * false for filled mode). + */ + void SetSketchMode( int aItemLayer, bool aEnabled ) + { + // It is supposed to work only with item layers + assert( aItemLayer >= ITEM_GAL_LAYER( 0 ) ); + + m_sketchMode[aItemLayer] = aEnabled; + } + + /** + * Function GetSketchMode + * Returns sketch mode setting for a given item layer. + * @param aItemLayer is the item layer that is changed. + */ + bool GetSketchMode( int aItemLayer ) const + { + // It is supposed to work only with item layers + assert( aItemLayer >= ITEM_GAL_LAYER( 0 ) ); + + return m_sketchMode[aItemLayer]; + } + protected: ///> @copydoc RENDER_SETTINGS::Update() void update(); @@ -116,7 +144,7 @@ protected: COLOR4D m_layerColorsDark[TOTAL_LAYER_COUNT]; ///> Flag determining if items on a given layer should be drawn as an outline or a filled item - bool m_sketchModeSelect[TOTAL_LAYER_COUNT]; + bool m_sketchMode[TOTAL_LAYER_COUNT]; ///> Flag determining if pad numbers should be visible bool m_padNumbers; diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 8c39655d8b..b168e54300 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -860,7 +860,7 @@ bool PCB_EDIT_FRAME::IsMicroViaAcceptable( void ) } -void PCB_EDIT_FRAME::setHighContrastLayer( LAYER_NUM aLayer ) +void PCB_EDIT_FRAME::SetHighContrastLayer( LAYER_NUM aLayer ) { // Set display settings for high contrast mode KIGFX::VIEW* view = GetGalCanvas()->GetView(); @@ -950,7 +950,7 @@ void PCB_EDIT_FRAME::SetActiveLayer( LAYER_NUM aLayer, bool doLayerWidgetUpdate { ( (PCB_SCREEN*) GetScreen() )->m_Active_Layer = aLayer; - setHighContrastLayer( aLayer ); + SetHighContrastLayer( aLayer ); if( doLayerWidgetUpdate ) syncLayerWidgetLayer(); diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index f409cc610d..11e527d552 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -112,6 +112,14 @@ TOOL_ACTION COMMON_ACTIONS::zoomOut( "pcbnew.zoomOut", AS_GLOBAL, WXK_F2, "", "" ); +TOOL_ACTION COMMON_ACTIONS::zoomInCenter( "pcbnew.zoomInCenter", + AS_GLOBAL, 0, + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::zoomOutCenter( "pcbnew.zoomOutCenter", + AS_GLOBAL, 0, + "", "" ); + TOOL_ACTION COMMON_ACTIONS::zoomCenter( "pcbnew.zoomCenter", AS_GLOBAL, WXK_F4, "", "" ); @@ -120,6 +128,7 @@ TOOL_ACTION COMMON_ACTIONS::zoomFitScreen( "pcbnew.zoomFitScreen", AS_GLOBAL, WXK_HOME, "", "" ); + // Display modes TOOL_ACTION COMMON_ACTIONS::trackDisplayMode( "pcbnew.trackDisplayMode", AS_GLOBAL, 'K', diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index c97fa154cf..097400b9c7 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -98,6 +98,8 @@ public: // View controls static TOOL_ACTION zoomIn; static TOOL_ACTION zoomOut; + static TOOL_ACTION zoomInCenter; + static TOOL_ACTION zoomOutCenter; static TOOL_ACTION zoomCenter; static TOOL_ACTION zoomFitScreen; diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index 45a46a9cdd..4d618615dc 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -49,6 +49,16 @@ void PCB_EDIT_FRAME::setupTools() m_toolDispatcher = new TOOL_DISPATCHER( &m_toolManager, this ); GetGalCanvas()->SetEventDispatcher( m_toolDispatcher ); + // Connect handlers to toolbar buttons +#if wxCHECK_VERSION( 3, 0, 0 ) + Connect( wxEVT_TOOL, wxCommandEventHandler( PCB_EDIT_FRAME::onGenericCommand ), NULL, this ); +#else + Connect( wxEVT_COMMAND_MENU_SELECTED, + wxCommandEventHandler( PCB_EDIT_FRAME::onGenericCommand ), NULL, this ); + Connect( wxEVT_COMMAND_TOOL_CLICKED, + wxCommandEventHandler( PCB_EDIT_FRAME::onGenericCommand ), NULL, this ); +#endif + // Register tools m_toolManager.RegisterTool( new SELECTION_TOOL ); m_toolManager.RegisterTool( new ROUTER_TOOL ); @@ -75,5 +85,8 @@ void PCB_EDIT_FRAME::destroyTools() void PCB_EDIT_FRAME::onGenericCommand( wxCommandEvent& aEvent ) { - m_toolDispatcher->DispatchWxCommand( aEvent ); + if( IsGalCanvasActive() ) + m_toolDispatcher->DispatchWxCommand( aEvent ); + else + aEvent.Skip(); } diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp index c3ffab9c9c..92e29f2ee7 100644 --- a/pcbnew/tools/pcbnew_control.cpp +++ b/pcbnew/tools/pcbnew_control.cpp @@ -28,12 +28,14 @@ #include #include #include +#include #include #include -#include +#include -using namespace KIGFX; -using boost::optional; +#include +#include +#include PCBNEW_CONTROL::PCBNEW_CONTROL() : TOOL_INTERACTIVE( "pcbnew.Settings" ) @@ -41,6 +43,12 @@ PCBNEW_CONTROL::PCBNEW_CONTROL() : } +void PCBNEW_CONTROL::Reset( RESET_REASON aReason ) +{ + m_frame = getEditFrame(); +} + + bool PCBNEW_CONTROL::Init() { setTransitions(); @@ -49,18 +57,40 @@ bool PCBNEW_CONTROL::Init() } -int PCBNEW_CONTROL::ZoomIn( TOOL_EVENT& aEvent ) +int PCBNEW_CONTROL::ZoomInOut( TOOL_EVENT& aEvent ) { - std::cout << __PRETTY_FUNCTION__ << std::endl; + KIGFX::VIEW* view = m_frame->GetGalCanvas()->GetView(); + KIGFX::GAL* gal = m_frame->GetGalCanvas()->GetGAL(); + + if( aEvent.IsAction( &COMMON_ACTIONS::zoomIn ) ) + m_frame->SetPrevZoom(); + else if( aEvent.IsAction( &COMMON_ACTIONS::zoomOut ) ) + m_frame->SetNextZoom(); + + double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor(); + double zoom = 1.0 / ( zoomFactor * m_frame->GetZoom() ); + + view->SetScale( zoom, getViewControls()->GetCursorPosition() ); setTransitions(); return 0; } -int PCBNEW_CONTROL::ZoomOut( TOOL_EVENT& aEvent ) +int PCBNEW_CONTROL::ZoomInOutCenter( TOOL_EVENT& aEvent ) { - std::cout << __PRETTY_FUNCTION__ << std::endl; + KIGFX::VIEW* view = m_frame->GetGalCanvas()->GetView(); + KIGFX::GAL* gal = m_frame->GetGalCanvas()->GetGAL(); + + if( aEvent.IsAction( &COMMON_ACTIONS::zoomInCenter ) ) + m_frame->SetPrevZoom(); + else if( aEvent.IsAction( &COMMON_ACTIONS::zoomOutCenter ) ) + m_frame->SetNextZoom(); + + double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor(); + double zoom = 1.0 / ( zoomFactor * m_frame->GetZoom() ); + + view->SetScale( zoom ); setTransitions(); return 0; @@ -69,7 +99,8 @@ int PCBNEW_CONTROL::ZoomOut( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::ZoomCenter( TOOL_EVENT& aEvent ) { - std::cout << __PRETTY_FUNCTION__ << std::endl; + KIGFX::VIEW* view = m_frame->GetGalCanvas()->GetView(); + view->SetCenter( getViewControls()->GetCursorPosition() ); setTransitions(); return 0; @@ -78,7 +109,24 @@ int PCBNEW_CONTROL::ZoomCenter( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::ZoomFitScreen( TOOL_EVENT& aEvent ) { - std::cout << __PRETTY_FUNCTION__ << std::endl; + KIGFX::VIEW* view = m_frame->GetGalCanvas()->GetView(); + KIGFX::GAL* gal = m_frame->GetGalCanvas()->GetGAL(); + BOX2I boardBBox = getModel( PCB_T )->ViewBBox(); + VECTOR2I screenSize = gal->GetScreenPixelSize(); + + double iuPerX = screenSize.x ? boardBBox.GetWidth() / screenSize.x : 1.0; + double iuPerY = screenSize.y ? boardBBox.GetHeight() / screenSize.y : 1.0; + + double bestZoom = std::max( iuPerX, iuPerY ); + // This is needed to avoid "jumpy" zooms if first hot key was used and then mouse scroll + // (or other way round). + m_frame->GetScreen()->SetZoom( bestZoom ); + + double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor(); + double zoom = 1.0 / ( zoomFactor * bestZoom ); + + view->SetScale( zoom ); + view->SetCenter( boardBBox.Centre() ); setTransitions(); return 0; @@ -87,7 +135,20 @@ int PCBNEW_CONTROL::ZoomFitScreen( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::TrackDisplayMode( TOOL_EVENT& aEvent ) { - std::cout << __PRETTY_FUNCTION__ << std::endl; + KIGFX::PCB_PAINTER* painter = + static_cast( m_frame->GetGalCanvas()->GetView()->GetPainter() ); + KIGFX::PCB_RENDER_SETTINGS* settings = + static_cast ( painter->GetSettings() ); + + // Apply new display options to the GAL canvas + DisplayOpt.DisplayPcbTrackFill = !DisplayOpt.DisplayPcbTrackFill; + m_frame->m_DisplayPcbTrackFill = DisplayOpt.DisplayPcbTrackFill; + settings->LoadDisplayOptions( DisplayOpt ); + + BOARD* board = getModel( PCB_T ); + for( TRACK* track = board->m_Track; track; track = track->Next() ) + track->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + setTransitions(); return 0; @@ -106,7 +167,23 @@ int PCBNEW_CONTROL::PadDisplayMode( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::ViaDisplayMode( TOOL_EVENT& aEvent ) { - std::cout << __PRETTY_FUNCTION__ << std::endl; + KIGFX::PCB_PAINTER* painter = + static_cast( m_frame->GetGalCanvas()->GetView()->GetPainter() ); + KIGFX::PCB_RENDER_SETTINGS* settings = + static_cast ( painter->GetSettings() ); + + // Apply new display options to the GAL canvas + DisplayOpt.DisplayViaFill = !DisplayOpt.DisplayViaFill; + m_frame->m_DisplayViaFill = DisplayOpt.DisplayViaFill; + settings->LoadDisplayOptions( DisplayOpt ); + + BOARD* board = getModel( PCB_T ); + for( TRACK* track = board->m_Track; track; track = track->Next() ) + { + if( track->Type() == PCB_VIA_T ) + track->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + setTransitions(); return 0; @@ -115,7 +192,15 @@ int PCBNEW_CONTROL::ViaDisplayMode( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::HighContrastMode( TOOL_EVENT& aEvent ) { - std::cout << __PRETTY_FUNCTION__ << std::endl; + KIGFX::PCB_PAINTER* painter = + static_cast( m_frame->GetGalCanvas()->GetView()->GetPainter() ); + KIGFX::PCB_RENDER_SETTINGS* settings = + static_cast ( painter->GetSettings() ); + + DisplayOpt.ContrastModeDisplay = !DisplayOpt.ContrastModeDisplay; + settings->LoadDisplayOptions( DisplayOpt ); + m_frame->SetHighContrastLayer( m_frame->GetActiveLayer() ); + setTransitions(); return 0; @@ -412,8 +497,10 @@ int PCBNEW_CONTROL::ShowHelp( TOOL_EVENT& aEvent ) void PCBNEW_CONTROL::setTransitions() { // View controls - Go( &PCBNEW_CONTROL::ZoomIn, COMMON_ACTIONS::zoomIn.MakeEvent() ); - Go( &PCBNEW_CONTROL::ZoomOut, COMMON_ACTIONS::zoomOut.MakeEvent() ); + Go( &PCBNEW_CONTROL::ZoomInOut, COMMON_ACTIONS::zoomIn.MakeEvent() ); + Go( &PCBNEW_CONTROL::ZoomInOut, COMMON_ACTIONS::zoomOut.MakeEvent() ); + Go( &PCBNEW_CONTROL::ZoomInOutCenter, COMMON_ACTIONS::zoomInCenter.MakeEvent() ); + Go( &PCBNEW_CONTROL::ZoomInOutCenter, COMMON_ACTIONS::zoomOutCenter.MakeEvent() ); Go( &PCBNEW_CONTROL::ZoomCenter, COMMON_ACTIONS::zoomCenter.MakeEvent() ); Go( &PCBNEW_CONTROL::ZoomFitScreen, COMMON_ACTIONS::zoomFitScreen.MakeEvent() ); diff --git a/pcbnew/tools/pcbnew_control.h b/pcbnew/tools/pcbnew_control.h index 41861cd3c0..8acc0fba8c 100644 --- a/pcbnew/tools/pcbnew_control.h +++ b/pcbnew/tools/pcbnew_control.h @@ -27,10 +27,12 @@ #include +class PCB_EDIT_FRAME; + /** * Class PCBNEW_CONTROL * - * TODO + * Handles hot keys that are not accepted by any other tool. */ class PCBNEW_CONTROL : public TOOL_INTERACTIVE @@ -39,14 +41,14 @@ public: PCBNEW_CONTROL(); /// @copydoc TOOL_INTERACTIVE::Reset() - void Reset( RESET_REASON aReason ) {}; + void Reset( RESET_REASON aReason ); /// @copydoc TOOL_INTERACTIVE::Init() bool Init(); // View controls - int ZoomIn( TOOL_EVENT& aEvent ); - int ZoomOut( TOOL_EVENT& aEvent ); + int ZoomInOut( TOOL_EVENT& aEvent ); + int ZoomInOutCenter( TOOL_EVENT& aEvent ); int ZoomCenter( TOOL_EVENT& aEvent ); int ZoomFitScreen( TOOL_EVENT& aEvent ); @@ -92,6 +94,9 @@ public: private: ///> Sets up handlers for various events. void setTransitions(); + + ///> Pointerto the currently used edit frame. + PCB_EDIT_FRAME* m_frame; }; #endif From 39bca76df7bcf0d723a219714257988b6b06bd2f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 24 Mar 2014 18:28:21 +0100 Subject: [PATCH 099/134] >Added handled hotkeys: - resetting relative coordinates - switching units - not official: changing transparency for layers (works only for main layers, does not work on vias/pads/etc.) --- common/view/view.cpp | 2 ++ pcbnew/pcb_painter.cpp | 32 ++++++++------------ pcbnew/pcb_painter.h | 18 ++++++++++- pcbnew/tools/common_actions.cpp | 4 +-- pcbnew/tools/pcbnew_control.cpp | 53 +++++++++++++++++++++++++++++---- 5 files changed, 80 insertions(+), 29 deletions(-) diff --git a/common/view/view.cpp b/common/view/view.cpp index 5cfe071d9f..08de942811 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -400,6 +400,7 @@ void VIEW::UpdateLayerColor( int aLayer ) updateItemsColor visitor( aLayer, m_painter, m_gal ); m_layers[aLayer].items->Query( r, visitor ); + MarkTargetDirty( m_layers[aLayer].target ); } @@ -459,6 +460,7 @@ void VIEW::ChangeLayerDepth( int aLayer, int aDepth ) changeItemsDepth visitor( aLayer, aDepth, m_gal ); m_layers[aLayer].items->Query( r, visitor ); + MarkTargetDirty( m_layers[aLayer].target ); } diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index e47e2b3686..33f44f2dd9 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -66,16 +66,16 @@ void PCB_RENDER_SETTINGS::ImportLegacyColors( COLORS_DESIGN_SETTINGS* aSettings } // Default colors for specific layers - m_layerColors[ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE )] = COLOR4D( 0.5, 0.4, 0.0, 1.0 ); - m_layerColors[ITEM_GAL_LAYER( PADS_HOLES_VISIBLE )] = COLOR4D( 0.0, 0.5, 0.5, 1.0 ); - m_layerColors[ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE )] = COLOR4D( 0.7, 0.7, 0.7, 1.0 ); - m_layerColors[ITEM_GAL_LAYER( PADS_VISIBLE )] = COLOR4D( 0.7, 0.7, 0.7, 1.0 ); - m_layerColors[NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE )] = COLOR4D( 0.8, 0.8, 0.8, 0.7 ); - m_layerColors[NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE )] = COLOR4D( 0.8, 0.8, 0.8, 0.7 ); - m_layerColors[NETNAMES_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 ); - m_layerColors[ITEM_GAL_LAYER( DRC_VISIBLE )] = COLOR4D( 1.0, 0.0, 0.0, 1.0 ); + m_layerColors[ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE )] = COLOR4D( 0.5, 0.4, 0.0, 0.8 ); + m_layerColors[ITEM_GAL_LAYER( PADS_HOLES_VISIBLE )] = COLOR4D( 0.0, 0.5, 0.5, 0.8 ); + m_layerColors[ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE )] = COLOR4D( 0.7, 0.7, 0.7, 0.8 ); + m_layerColors[ITEM_GAL_LAYER( PADS_VISIBLE )] = COLOR4D( 0.7, 0.7, 0.7, 0.8 ); + m_layerColors[NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE )] = COLOR4D( 0.8, 0.8, 0.8, 0.8 ); + m_layerColors[NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE )] = COLOR4D( 0.8, 0.8, 0.8, 0.8 ); + m_layerColors[NETNAMES_GAL_LAYER( PAD_BK_NETNAMES_VISIBLE )] = COLOR4D( 0.8, 0.8, 0.8, 0.8 ); + m_layerColors[ITEM_GAL_LAYER( RATSNEST_VISIBLE )] = COLOR4D( 0.4, 0.4, 0.4, 0.8 ); + m_layerColors[ITEM_GAL_LAYER( WORKSHEET )] = COLOR4D( 0.5, 0.0, 0.0, 0.8 ); + m_layerColors[ITEM_GAL_LAYER( DRC_VISIBLE )] = COLOR4D( 1.0, 0.0, 0.0, 0.8 ); // Netnames for copper layers for( LAYER_NUM layer = FIRST_COPPER_LAYER; layer <= LAST_COPPER_LAYER; ++layer ) @@ -175,23 +175,15 @@ const COLOR4D& PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer void PCB_RENDER_SETTINGS::update() { + RENDER_SETTINGS::update(); + // Calculate darkened/highlighted variants of layer colors for( int i = 0; i < TOTAL_LAYER_COUNT; i++ ) { - m_layerColors[i].a = m_layerOpacity; m_layerColorsHi[i] = m_layerColors[i].Brightened( m_highlightFactor ); m_layerColorsDark[i] = m_layerColors[i].Darkened( 1.0 - m_highlightFactor ); m_layerColorsSel[i] = m_layerColors[i].Brightened( m_selectFactor ); } - - m_hiContrastColor = COLOR4D( m_hiContrastFactor, m_hiContrastFactor, m_hiContrastFactor, - m_layerOpacity ); -} - - -const COLOR4D& PCB_RENDER_SETTINGS::GetLayerColor( int aLayer ) const -{ - return m_layerColors[aLayer]; } diff --git a/pcbnew/pcb_painter.h b/pcbnew/pcb_painter.h index 820c4077a5..cdcedb1db7 100644 --- a/pcbnew/pcb_painter.h +++ b/pcbnew/pcb_painter.h @@ -97,7 +97,23 @@ public: * Returns the color used to draw a layer. * @param aLayer is the layer number. */ - const COLOR4D& GetLayerColor( int aLayer ) const; + const COLOR4D& GetLayerColor( int aLayer ) const + { + return m_layerColors[aLayer]; + } + + /** + * Function SetLayerColor + * Changes the color used to draw a layer. + * @param aLayer is the layer number. + * @param aColor is the new color. + */ + void SetLayerColor( int aLayer, const COLOR4D& aColor ) + { + m_layerColors[aLayer] = aColor; + + update(); // recompute other shades of the color + } /** * Function SetSketchMode diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 11e527d552..0e998de43a 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -197,11 +197,11 @@ TOOL_ACTION COMMON_ACTIONS::layerPrev( "pcbnew.layerPrev", "", "" ); TOOL_ACTION COMMON_ACTIONS::layerAlphaInc( "pcbnew.layerAlphaInc", - AS_GLOBAL, MD_SHIFT + '[', // shift+[ == { + AS_GLOBAL, MD_SHIFT + ']', // shift+] == } "", "" ); TOOL_ACTION COMMON_ACTIONS::layerAlphaDec( "pcbnew.layerAlphaDec", - AS_GLOBAL, MD_SHIFT + ']', // shift+] == } + AS_GLOBAL, MD_SHIFT + '[', // shift+[ == { "", "" ); diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp index 92e29f2ee7..0a04fc0f88 100644 --- a/pcbnew/tools/pcbnew_control.cpp +++ b/pcbnew/tools/pcbnew_control.cpp @@ -32,13 +32,14 @@ #include #include #include +#include #include #include #include PCBNEW_CONTROL::PCBNEW_CONTROL() : - TOOL_INTERACTIVE( "pcbnew.Settings" ) + TOOL_INTERACTIVE( "pcbnew.Control" ) { } @@ -340,7 +341,21 @@ int PCBNEW_CONTROL::LayerPrev( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::LayerAlphaInc( TOOL_EVENT& aEvent ) { - std::cout << __PRETTY_FUNCTION__ << std::endl; + KIGFX::PCB_PAINTER* painter = + static_cast( m_frame->GetGalCanvas()->GetView()->GetPainter() ); + KIGFX::PCB_RENDER_SETTINGS* settings = + static_cast ( painter->GetSettings() ); + + LAYER_NUM currentLayer = m_frame->GetActiveLayer(); + KIGFX::COLOR4D currentColor = settings->GetLayerColor( currentLayer ); + + if( currentColor.a <= 0.95 ) + { + currentColor.a += 0.05; + settings->SetLayerColor( currentLayer, currentColor ); + m_frame->GetGalCanvas()->GetView()->UpdateLayerColor( currentLayer ); + } + setTransitions(); return 0; @@ -349,7 +364,21 @@ int PCBNEW_CONTROL::LayerAlphaInc( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::LayerAlphaDec( TOOL_EVENT& aEvent ) { - std::cout << __PRETTY_FUNCTION__ << std::endl; + KIGFX::PCB_PAINTER* painter = + static_cast( m_frame->GetGalCanvas()->GetView()->GetPainter() ); + KIGFX::PCB_RENDER_SETTINGS* settings = + static_cast ( painter->GetSettings() ); + + LAYER_NUM currentLayer = m_frame->GetActiveLayer(); + KIGFX::COLOR4D currentColor = settings->GetLayerColor( currentLayer ); + + if( currentColor.a >= 0.05 ) + { + currentColor.a -= 0.05; + settings->SetLayerColor( currentLayer, currentColor ); + m_frame->GetGalCanvas()->GetView()->UpdateLayerColor( currentLayer ); + } + setTransitions(); return 0; @@ -469,7 +498,10 @@ int PCBNEW_CONTROL::ViaSizeDec( TOOL_EVENT& aEvent ) // Miscellaneous int PCBNEW_CONTROL::ResetCoords( TOOL_EVENT& aEvent ) { - std::cout << __PRETTY_FUNCTION__ << std::endl; + VECTOR2I cursorPos = getViewControls()->GetCursorPosition(); + + m_frame->GetScreen()->m_O_Curseur = wxPoint( cursorPos.x, cursorPos.y ); + m_frame->UpdateStatusBar(); setTransitions(); return 0; @@ -478,7 +510,15 @@ int PCBNEW_CONTROL::ResetCoords( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::SwitchUnits( TOOL_EVENT& aEvent ) { - std::cout << __PRETTY_FUNCTION__ << std::endl; + // TODO should not it be refactored to pcb_frame member function? + wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED ); + + if( g_UserUnit == INCHES ) + evt.SetId( ID_TB_OPTIONS_SELECT_UNIT_MM ); + else + evt.SetId( ID_TB_OPTIONS_SELECT_UNIT_INCH ); + + m_frame->ProcessEvent( evt ); setTransitions(); return 0; @@ -487,7 +527,8 @@ int PCBNEW_CONTROL::SwitchUnits( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::ShowHelp( TOOL_EVENT& aEvent ) { - std::cout << __PRETTY_FUNCTION__ << std::endl; + // TODO + DisplayInfoMessage( m_frame, _( "Not implemented yet." ) ); setTransitions(); return 0; From 1fa49ce7f06190cd54c3a488dbdd57c3eeb423b7 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 1 Apr 2014 13:30:31 +0200 Subject: [PATCH 100/134] Fixed drifting for items dragged using EDIT_TOOL. --- pcbnew/tools/edit_tool.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 6965042775..3f912e42e5 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -81,13 +81,15 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) if( !makeSelection( selection ) ) return 0; - VECTOR2I dragPosition; // The last position of the cursor while dragging 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 m_updateFlag = KIGFX::VIEW_ITEM::GEOMETRY; + // Offset from the dragged item's center (anchor) + wxPoint offset; + VIEW_CONTROLS* controls = getViewControls(); PCB_EDIT_FRAME* editFrame = static_cast( m_toolMgr->GetEditFrame() ); controls->ShowCursor( true ); @@ -128,29 +130,34 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) else if( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) { + VECTOR2I cursor( controls->GetCursorPosition() ); + if( m_dragging ) { + wxPoint movement = wxPoint( cursor.x, cursor.y ) - + static_cast( selection.items.GetPickedItem( 0 ) )->GetPosition(); + // Drag items to the current cursor position - VECTOR2I movement = ( 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 ) ); + item->Move( movement + offset ); } updateRatsnest( true ); } - else + else // Prepare to start dragging { - // Prepare to drag - save items, so changes can be undone + // Save items, so changes can be undone editFrame->OnModify(); editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED ); + offset = static_cast( selection.items.GetPickedItem( 0 ) )->GetPosition() - + wxPoint( cursor.x, cursor.y ); m_dragging = true; } selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); - dragPosition = controls->GetCursorPosition(); m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate ); } @@ -350,6 +357,7 @@ int EDIT_TOOL::Remove( TOOL_EVENT& aEvent ) // Save them for( unsigned int i = 0; i < selectedItems.GetCount(); ++i ) selectedItems.SetPickedItemStatus( UR_DELETED, i ); + editFrame->OnModify(); editFrame->SaveCopyInUndoList( selectedItems, UR_DELETED ); From a55d25803ef5911900769496e9aebaf1b81f75c2 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 1 Apr 2014 14:06:19 +0200 Subject: [PATCH 101/134] Activation of any drawing/placement tool clears current selection. --- pcbnew/tools/common_actions.cpp | 4 ++-- pcbnew/tools/common_actions.h | 2 +- pcbnew/tools/drawing_tool.cpp | 30 +++++++++++++++++++----------- pcbnew/tools/drawing_tool.h | 2 +- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 0e998de43a..63f4f91712 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -71,7 +71,7 @@ TOOL_ACTION COMMON_ACTIONS::drawArc( "pcbnew.InteractiveDrawing.arc", AS_GLOBAL, 0, "Draw an arc", "Draw an arc" ); -TOOL_ACTION COMMON_ACTIONS::drawText( "pcbnew.InteractiveDrawing.text", +TOOL_ACTION COMMON_ACTIONS::placeText( "pcbnew.InteractiveDrawing.text", AS_GLOBAL, 0, "Add a text", "Add a text" ); @@ -281,7 +281,7 @@ std::string COMMON_ACTIONS::TranslateLegacyId( int aId ) return COMMON_ACTIONS::drawArc.GetName(); case ID_PCB_ADD_TEXT_BUTT: - return COMMON_ACTIONS::drawText.GetName(); + return COMMON_ACTIONS::placeText.GetName(); case ID_PCB_DIMENSION_BUTT: return COMMON_ACTIONS::drawDimension.GetName(); diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 097400b9c7..38569af29a 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -70,7 +70,7 @@ public: static TOOL_ACTION drawArc; /// Activation of the drawing tool (text) - static TOOL_ACTION drawText; + static TOOL_ACTION placeText; /// Activation of the drawing tool (dimension) static TOOL_ACTION drawDimension; diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index e35956f213..30283cca17 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -94,6 +94,7 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); @@ -270,7 +271,7 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) } -int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) +int DRAWING_TOOL::PlaceText( TOOL_EVENT& aEvent ) { TEXTE_PCB* text = NULL; @@ -278,6 +279,7 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); m_controls->SetAutoPan( true ); @@ -325,6 +327,7 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) { // Init the new item attributes text = m_frame->CreateTextePcb( NULL ); + if( text == NULL ) continue; @@ -381,6 +384,7 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); @@ -571,6 +575,7 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) m_view->Add( &preview ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_controls->SetSnapping( true ); m_controls->SetAutoPan( true ); @@ -644,6 +649,7 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); m_controls->SetAutoPan( true ); @@ -659,7 +665,7 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) { if( module ) { - m_board->Delete( module ); // it was added by LoadModuleFromLibrary + m_board->Delete( module ); // it was added by LoadModuleFromLibrary() module = NULL; preview.Clear(); @@ -755,6 +761,7 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); @@ -930,6 +937,7 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); @@ -1149,13 +1157,13 @@ void DRAWING_TOOL::make45DegLine( DRAWSEGMENT* aSegment, DRAWSEGMENT* aHelper ) void DRAWING_TOOL::setTransitions() { - Go( &DRAWING_TOOL::DrawLine, COMMON_ACTIONS::drawLine.MakeEvent() ); - Go( &DRAWING_TOOL::DrawCircle, COMMON_ACTIONS::drawCircle.MakeEvent() ); - Go( &DRAWING_TOOL::DrawArc, COMMON_ACTIONS::drawArc.MakeEvent() ); - Go( &DRAWING_TOOL::DrawText, COMMON_ACTIONS::drawText.MakeEvent() ); - Go( &DRAWING_TOOL::DrawDimension, COMMON_ACTIONS::drawDimension.MakeEvent() ); - Go( &DRAWING_TOOL::DrawZone, COMMON_ACTIONS::drawZone.MakeEvent() ); - Go( &DRAWING_TOOL::DrawKeepout, COMMON_ACTIONS::drawKeepout.MakeEvent() ); - Go( &DRAWING_TOOL::PlaceTarget, COMMON_ACTIONS::placeTarget.MakeEvent() ); - Go( &DRAWING_TOOL::PlaceModule, COMMON_ACTIONS::placeModule.MakeEvent() ); + Go( &DRAWING_TOOL::DrawLine, COMMON_ACTIONS::drawLine.MakeEvent() ); + Go( &DRAWING_TOOL::DrawCircle, COMMON_ACTIONS::drawCircle.MakeEvent() ); + Go( &DRAWING_TOOL::DrawArc, COMMON_ACTIONS::drawArc.MakeEvent() ); + Go( &DRAWING_TOOL::DrawDimension, COMMON_ACTIONS::drawDimension.MakeEvent() ); + Go( &DRAWING_TOOL::DrawZone, COMMON_ACTIONS::drawZone.MakeEvent() ); + Go( &DRAWING_TOOL::DrawKeepout, COMMON_ACTIONS::drawKeepout.MakeEvent() ); + Go( &DRAWING_TOOL::PlaceText, COMMON_ACTIONS::placeText.MakeEvent() ); + Go( &DRAWING_TOOL::PlaceTarget, COMMON_ACTIONS::placeTarget.MakeEvent() ); + Go( &DRAWING_TOOL::PlaceModule, COMMON_ACTIONS::placeModule.MakeEvent() ); } diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index 2339cb3a9c..e05a3a59ce 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -80,7 +80,7 @@ public: * Displays a dialog that allows to input text and its settings and then lets the user decide * where to place the text. */ - int DrawText( TOOL_EVENT& aEvent ); + int PlaceText( TOOL_EVENT& aEvent ); /** * Function DrawDimension() From 79d353671bce4fcba1bbf3125261fcbaff08f295 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 1 Apr 2014 14:13:00 +0200 Subject: [PATCH 102/134] Fixed autopanning for POINT_EDITOR. --- pcbnew/tools/point_editor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 1cfdb0a001..4521607434 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -210,14 +210,12 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) if( point ) { controls->ShowCursor( true ); - controls->SetAutoPan( true ); controls->SetSnapping( true ); controls->ForceCursorPosition( true, point->GetPosition() ); } else { controls->ShowCursor( false ); - controls->SetAutoPan( false ); controls->SetSnapping( false ); controls->ForceCursorPosition( false ); } @@ -240,6 +238,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED ); controls->ForceCursorPosition( false ); m_original = *m_dragPoint; // Save the original position + controls->SetAutoPan( true ); modified = true; } @@ -267,6 +266,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) else if( evt->IsMouseUp( BUT_LEFT ) ) { + controls->SetAutoPan( false ); setAltConstraint( false ); modified = false; } From e79934b03d8041ac99d70cd4ccd176b882b18535 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 1 Apr 2014 14:35:09 +0200 Subject: [PATCH 103/134] If tool was previously active and it is called again, it is brought to the top of the active tool stack. It fixes issue of dragging of items that have EDIT_POINTs, when dragging was activated by hovering over an item and using hot key. --- common/tool/tool_manager.cpp | 8 +++++++- pcbnew/tools/edit_tool.cpp | 26 ++++++++++++-------------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index 0d25c88434..207ee71152 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -253,9 +253,15 @@ bool TOOL_MANAGER::runTool( TOOL_BASE* aTool ) return false; } - // If the tool is already active, do not invoke it again + // If the tool is already active, bring it to the top of the active tools stack if( isActive( aTool ) ) + { + m_activeTools.erase( std::find( m_activeTools.begin(), m_activeTools.end(), + aTool->GetId() ) ); + m_activeTools.push_front( aTool->GetId() ); + return false; + } aTool->Reset( TOOL_INTERACTIVE::RUN ); diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 3f912e42e5..92c0c218a2 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -79,7 +79,13 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) // Be sure that there is at least one item that we can modify if( !makeSelection( selection ) ) + { + setTransitions(); + return 0; + } + + Activate(); m_dragging = false; // Are selected items being dragged? bool restore = false; // Should items' state be restored when finishing the tool? @@ -205,7 +211,11 @@ int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) bool unselect = selection.Empty(); if( !makeSelection( selection ) ) + { + setTransitions(); + return 0; + } // Properties are displayed when there is only one item selected if( selection.Size() == 1 ) @@ -471,20 +481,8 @@ wxPoint EDIT_TOOL::getModificationPoint( const SELECTION_TOOL::SELECTION& aSelec bool EDIT_TOOL::makeSelection( const SELECTION_TOOL::SELECTION& aSelection ) { - if( aSelection.Empty() ) - { - // Try to find an item that could be modified + if( aSelection.Empty() ) // Try to find an item that could be modified m_toolMgr->RunAction( COMMON_ACTIONS::selectionSingle ); - 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; + return !aSelection.Empty(); } From 6b90eb3a64aeb2df4cbfdd4ec52ee1ef03f3dbcc Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 1 Apr 2014 17:18:43 +0200 Subject: [PATCH 104/134] Refactoring EDIT_POINTS, part 1: separated functions that operate on EDIT_POINTS and EDIT_LINES. --- pcbnew/tools/edit_points.cpp | 16 +++++- pcbnew/tools/edit_points.h | 20 ++++++-- pcbnew/tools/point_editor.cpp | 94 +++++++++++++++++------------------ 3 files changed, 78 insertions(+), 52 deletions(-) diff --git a/pcbnew/tools/edit_points.cpp b/pcbnew/tools/edit_points.cpp index 9f6069d551..1c24722862 100644 --- a/pcbnew/tools/edit_points.cpp +++ b/pcbnew/tools/edit_points.cpp @@ -83,9 +83,15 @@ EDIT_POINT* EDIT_POINTS::Previous( const EDIT_POINT& aPoint ) } } + return NULL; +} + + +EDIT_LINE* EDIT_POINTS::Previous( const EDIT_LINE& aLine ) +{ for( unsigned int i = 0; i < m_lines.size(); ++i ) { - if( m_lines[i] == aPoint ) + if( m_lines[i] == aLine ) { if( i == 0 ) return &m_lines[m_lines.size() - 1]; @@ -111,9 +117,15 @@ EDIT_POINT* EDIT_POINTS::Next( const EDIT_POINT& aPoint ) } } + return NULL; +} + + +EDIT_LINE* EDIT_POINTS::Next( const EDIT_LINE& aLine ) +{ for( unsigned int i = 0; i < m_lines.size(); ++i ) { - if( m_lines[i] == aPoint ) + if( m_lines[i] == aLine ) { if( i == m_lines.size() - 1 ) return &m_lines[0]; diff --git a/pcbnew/tools/edit_points.h b/pcbnew/tools/edit_points.h index 7177bd5241..2e5bddff62 100644 --- a/pcbnew/tools/edit_points.h +++ b/pcbnew/tools/edit_points.h @@ -73,7 +73,7 @@ public: } /** - * Function GetX() + * Function GetY() * * Returns Y coordinate of an EDIT_POINT. */ @@ -356,6 +356,8 @@ public: */ EDIT_POINT* Previous( const EDIT_POINT& aPoint ); + EDIT_LINE* Previous( const EDIT_LINE& aLine ); + /** * Function Next() * @@ -367,16 +369,28 @@ public: */ EDIT_POINT* Next( const EDIT_POINT& aPoint ); - EDIT_POINT& operator[]( unsigned int aIndex ) + EDIT_LINE* Next( const EDIT_LINE& aLine ); + + EDIT_POINT& Point( unsigned int aIndex ) { return m_points[aIndex]; } - const EDIT_POINT& operator[]( unsigned int aIndex ) const + const EDIT_POINT& Point( unsigned int aIndex ) const { return m_points[aIndex]; } + EDIT_LINE& Line( unsigned int aIndex ) + { + return m_lines[aIndex]; + } + + const EDIT_LINE& Line( unsigned int aIndex ) const + { + return m_lines[aIndex]; + } + /** * Function Size() * diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 4521607434..db398ff33e 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -63,7 +63,7 @@ public: switch( segment->GetShape() ) { case S_SEGMENT: - points->AddPoint( segment->GetStart() ); // points[0] + points->AddPoint( segment->GetStart() ); // points[0] // TODO add enums for points points->AddPoint( segment->GetEnd() ); // points[1] break; @@ -74,7 +74,7 @@ public: // Set constraints // Arc end has to stay at the same radius as the start - (*points)[2].SetConstraint( new EC_CIRCLE( (*points)[2], (*points)[0], (*points)[1] ) ); + points->Point( 2 ).SetConstraint( new EC_CIRCLE( points->Point( 2 ), points->Point( 0 ), points->Point( 1 ) ) ); break; case S_CIRCLE: @@ -99,10 +99,10 @@ public: // Lines have to be added after creating edit points, so they use EDIT_POINT references for( int i = 0; i < cornersCount - 1; ++i ) - points->AddLine( (*points)[i], (*points)[i + 1] ); + points->AddLine( points->Point( i ), points->Point( i + 1 ) ); // The last missing line, connecting the last and the first polygon point - points->AddLine( (*points)[cornersCount - 1], (*points)[0] ); + points->AddLine( points->Point( cornersCount - 1 ), points->Point( 0 ) ); break; } @@ -116,8 +116,8 @@ public: points->AddPoint( dimension->m_featureLineDO ); // Dimension height setting - edit points should move only along the feature lines - (*points)[0].SetConstraint( new EC_LINE( (*points)[0], (*points)[2] ) ); - (*points)[1].SetConstraint( new EC_LINE( (*points)[1], (*points)[3] ) ); + points->Point( 0 ).SetConstraint( new EC_LINE( points->Point( 0 ), points->Point( 2 ) ) ); + points->Point( 1 ).SetConstraint( new EC_LINE( points->Point( 1 ), points->Point( 3 ) ) ); break; } @@ -322,29 +322,29 @@ void POINT_EDITOR::updateItem() const switch( segment->GetShape() ) { case S_SEGMENT: - if( isModified( (*m_editPoints)[0] ) ) - segment->SetStart( wxPoint( (*m_editPoints)[0].GetPosition().x, - (*m_editPoints)[0].GetPosition().y ) ); + if( isModified( m_editPoints->Point( 0 ) ) ) + segment->SetStart( wxPoint( m_editPoints->Point( 0 ).GetPosition().x, + m_editPoints->Point( 0 ).GetPosition().y ) ); - else if( isModified( (*m_editPoints)[1] ) ) - segment->SetEnd( wxPoint( (*m_editPoints)[1].GetPosition().x, - (*m_editPoints)[1].GetPosition().y ) ); + else if( isModified( m_editPoints->Point( 1 ) ) ) + segment->SetEnd( wxPoint( m_editPoints->Point( 1 ).GetPosition().x, + m_editPoints->Point( 1 ).GetPosition().y ) ); break; case S_ARC: { - const VECTOR2I& center = (*m_editPoints)[0].GetPosition(); - const VECTOR2I& start = (*m_editPoints)[1].GetPosition(); - const VECTOR2I& end = (*m_editPoints)[2].GetPosition(); + const VECTOR2I& center = m_editPoints->Point( 0 ).GetPosition(); + const VECTOR2I& start = m_editPoints->Point( 1 ).GetPosition(); + const VECTOR2I& end = m_editPoints->Point( 2 ).GetPosition(); if( center != segment->GetCenter() ) { wxPoint moveVector = wxPoint( center.x, center.y ) - segment->GetCenter(); segment->Move( moveVector ); - (*m_editPoints)[1].SetPosition( segment->GetArcStart() ); - (*m_editPoints)[2].SetPosition( segment->GetArcEnd() ); + m_editPoints->Point( 1 ).SetPosition( segment->GetArcStart() ); + m_editPoints->Point( 2 ).SetPosition( segment->GetArcEnd() ); } else @@ -371,10 +371,10 @@ void POINT_EDITOR::updateItem() const case S_CIRCLE: { - const VECTOR2I& center = (*m_editPoints)[0].GetPosition(); - const VECTOR2I& end = (*m_editPoints)[1].GetPosition(); + const VECTOR2I& center = m_editPoints->Point( 0 ).GetPosition(); + const VECTOR2I& end = m_editPoints->Point( 1 ).GetPosition(); - if( isModified( (*m_editPoints)[0] ) ) + if( isModified( m_editPoints->Point( 0 ) ) ) { wxPoint moveVector = wxPoint( center.x, center.y ) - segment->GetCenter(); segment->Move( moveVector ); @@ -402,8 +402,8 @@ void POINT_EDITOR::updateItem() const for( int i = 0; i < outline->GetCornersCount(); ++i ) { - outline->SetX( i, (*m_editPoints)[i].GetPosition().x ); - outline->SetY( i, (*m_editPoints)[i].GetPosition().y ); + outline->SetX( i, m_editPoints->Point( i ).GetPosition().x ); + outline->SetY( i, m_editPoints->Point( i ).GetPosition().y ); } break; @@ -414,7 +414,7 @@ void POINT_EDITOR::updateItem() const DIMENSION* dimension = static_cast( item ); // Check which point is currently modified and updated dimension's points respectively - if( isModified( (*m_editPoints)[0] ) ) + if( isModified( m_editPoints->Point( 0 ) ) ) { VECTOR2D featureLine( m_dragPoint->GetPosition() - dimension->GetOrigin() ); VECTOR2D crossBar( dimension->GetEnd() - dimension->GetOrigin() ); @@ -425,7 +425,7 @@ void POINT_EDITOR::updateItem() const dimension->SetHeight( featureLine.EuclideanNorm() ); } - else if( isModified( (*m_editPoints)[1] ) ) + else if( isModified( m_editPoints->Point( 1 ) ) ) { VECTOR2D featureLine( m_dragPoint->GetPosition() - dimension->GetEnd() ); VECTOR2D crossBar( dimension->GetEnd() - dimension->GetOrigin() ); @@ -436,18 +436,18 @@ void POINT_EDITOR::updateItem() const dimension->SetHeight( featureLine.EuclideanNorm() ); } - else if( isModified( (*m_editPoints)[2] ) ) + else if( isModified( m_editPoints->Point( 2 ) ) ) { dimension->SetOrigin( wxPoint( m_dragPoint->GetPosition().x, m_dragPoint->GetPosition().y ) ); - (*m_editPoints)[0].SetConstraint( new EC_LINE( (*m_editPoints)[0], (*m_editPoints)[2] ) ); - (*m_editPoints)[1].SetConstraint( new EC_LINE( (*m_editPoints)[1], (*m_editPoints)[3] ) ); + m_editPoints->Point( 0 ).SetConstraint( new EC_LINE( m_editPoints->Point( 0 ), m_editPoints->Point( 2 ) ) ); + m_editPoints->Point( 1 ).SetConstraint( new EC_LINE( m_editPoints->Point( 1 ), m_editPoints->Point( 3 ) ) ); } - else if( isModified( (*m_editPoints)[3] ) ) + else if( isModified( m_editPoints->Point( 3 ) ) ) { dimension->SetEnd( wxPoint( m_dragPoint->GetPosition().x, m_dragPoint->GetPosition().y ) ); - (*m_editPoints)[0].SetConstraint( new EC_LINE( (*m_editPoints)[0], (*m_editPoints)[2] ) ); - (*m_editPoints)[1].SetConstraint( new EC_LINE( (*m_editPoints)[1], (*m_editPoints)[3] ) ); + m_editPoints->Point( 0 ).SetConstraint( new EC_LINE( m_editPoints->Point( 0 ), m_editPoints->Point( 2 ) ) ); + m_editPoints->Point( 1 ).SetConstraint( new EC_LINE( m_editPoints->Point( 1 ), m_editPoints->Point( 3 ) ) ); } break; @@ -486,19 +486,19 @@ void POINT_EDITOR::updatePoints() const switch( segment->GetShape() ) { case S_SEGMENT: - (*m_editPoints)[0].SetPosition( segment->GetStart() ); - (*m_editPoints)[1].SetPosition( segment->GetEnd() ); + m_editPoints->Point( 0 ).SetPosition( segment->GetStart() ); + m_editPoints->Point( 1 ).SetPosition( segment->GetEnd() ); break; case S_ARC: - (*m_editPoints)[0].SetPosition( segment->GetCenter() ); - (*m_editPoints)[1].SetPosition( segment->GetArcStart() ); - (*m_editPoints)[2].SetPosition( segment->GetArcEnd() ); + m_editPoints->Point( 0 ).SetPosition( segment->GetCenter() ); + m_editPoints->Point( 1 ).SetPosition( segment->GetArcStart() ); + m_editPoints->Point( 2 ).SetPosition( segment->GetArcEnd() ); break; case S_CIRCLE: - (*m_editPoints)[0].SetPosition( segment->GetCenter() ); - (*m_editPoints)[1].SetPosition( segment->GetEnd() ); + m_editPoints->Point( 0 ).SetPosition( segment->GetCenter() ); + m_editPoints->Point( 1 ).SetPosition( segment->GetEnd() ); break; default: // suppress warnings @@ -515,7 +515,7 @@ void POINT_EDITOR::updatePoints() const const CPolyLine* outline = zone->Outline(); for( int i = 0; i < outline->GetCornersCount(); ++i ) - (*m_editPoints)[i].SetPosition( outline->GetPos( i ) ); + m_editPoints->Point( i ).SetPosition( outline->GetPos( i ) ); break; } @@ -524,10 +524,10 @@ void POINT_EDITOR::updatePoints() const { const DIMENSION* dimension = static_cast( item ); - (*m_editPoints)[0].SetPosition( dimension->m_crossBarO ); - (*m_editPoints)[1].SetPosition( dimension->m_crossBarF ); - (*m_editPoints)[2].SetPosition( dimension->m_featureLineGO ); - (*m_editPoints)[3].SetPosition( dimension->m_featureLineDO ); + m_editPoints->Point( 0 ).SetPosition( dimension->m_crossBarO ); + m_editPoints->Point( 1 ).SetPosition( dimension->m_crossBarF ); + m_editPoints->Point( 2 ).SetPosition( dimension->m_featureLineGO ); + m_editPoints->Point( 3 ).SetPosition( dimension->m_featureLineDO ); break; } @@ -580,7 +580,7 @@ EDIT_POINT POINT_EDITOR::get45DegConstrainer() const case S_ARC: case S_CIRCLE: - return (*m_editPoints)[0]; // center + return m_editPoints->Point( 0 ); // center default: // suppress warnings break; @@ -593,11 +593,11 @@ EDIT_POINT POINT_EDITOR::get45DegConstrainer() const case PCB_DIMENSION_T: { // Constraint for crossbar - if( isModified( (*m_editPoints)[2] ) ) - return (*m_editPoints)[3]; + if( isModified( m_editPoints->Point( 2 ) ) ) + return m_editPoints->Point( 3 ); - else if( isModified( (*m_editPoints)[3] ) ) - return (*m_editPoints)[2]; + else if( isModified( m_editPoints->Point( 3 ) ) ) + return m_editPoints->Point( 2 ); else return EDIT_POINT( m_dragPoint->GetPosition() ); // no constraint From 0379247fd4f76efa20c867d38ee859e16e993273 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 1 Apr 2014 17:41:24 +0200 Subject: [PATCH 105/134] Refactoring EDIT_POINTS, part 2: replaced index numbers with constants. --- pcbnew/tools/point_editor.cpp | 132 +++++++++++++++++++++------------- pcbnew/tools/point_editor.h | 2 +- 2 files changed, 83 insertions(+), 51 deletions(-) diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index db398ff33e..167b8247bf 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -40,6 +40,30 @@ #include #include +// Few constants to avoid using bare numbers for point indices +enum SEG_POINTS +{ + SEG_START, SEG_END +}; + +enum ARC_POINTS +{ + ARC_CENTER, ARC_START, ARC_END +}; + +enum CIRCLE_POINTS +{ + CIRC_CENTER, CIRC_END +}; + +enum DIMENSION_POINTS +{ + DIM_CROSSBARO, + DIM_CROSSBARF, + DIM_FEATUREGO, + DIM_FEATUREDO, +}; + /** * Class POINT_EDITOR * @@ -63,23 +87,25 @@ public: switch( segment->GetShape() ) { case S_SEGMENT: - points->AddPoint( segment->GetStart() ); // points[0] // TODO add enums for points - points->AddPoint( segment->GetEnd() ); // points[1] + points->AddPoint( segment->GetStart() ); + points->AddPoint( segment->GetEnd() ); break; case S_ARC: - points->AddPoint( segment->GetCenter() ); // points[0] - points->AddPoint( segment->GetArcStart() ); // points[1] - points->AddPoint( segment->GetArcEnd() ); // points[2] + points->AddPoint( segment->GetCenter() ); + points->AddPoint( segment->GetArcStart() ); + points->AddPoint( segment->GetArcEnd() ); // Set constraints // Arc end has to stay at the same radius as the start - points->Point( 2 ).SetConstraint( new EC_CIRCLE( points->Point( 2 ), points->Point( 0 ), points->Point( 1 ) ) ); + points->Point( ARC_END ).SetConstraint( new EC_CIRCLE( points->Point( ARC_END ), + points->Point( ARC_CENTER ), + points->Point( ARC_START ) ) ); break; case S_CIRCLE: - points->AddPoint( segment->GetCenter() ); // points[0] - points->AddPoint( segment->GetEnd() ); // points[1] + points->AddPoint( segment->GetCenter() ); + points->AddPoint( segment->GetEnd() ); break; default: // suppress warnings @@ -97,7 +123,8 @@ public: for( int i = 0; i < cornersCount; ++i ) points->AddPoint( outline->GetPos( i ) ); - // Lines have to be added after creating edit points, so they use EDIT_POINT references + // Lines have to be added after creating edit points, + // as they use EDIT_POINT references for( int i = 0; i < cornersCount - 1; ++i ) points->AddLine( points->Point( i ), points->Point( i + 1 ) ); @@ -116,8 +143,10 @@ public: points->AddPoint( dimension->m_featureLineDO ); // Dimension height setting - edit points should move only along the feature lines - points->Point( 0 ).SetConstraint( new EC_LINE( points->Point( 0 ), points->Point( 2 ) ) ); - points->Point( 1 ).SetConstraint( new EC_LINE( points->Point( 1 ), points->Point( 3 ) ) ); + points->Point( DIM_CROSSBARO ).SetConstraint( new EC_LINE( points->Point( DIM_CROSSBARO ), + points->Point( DIM_FEATUREGO ) ) ); + points->Point( DIM_CROSSBARF ).SetConstraint( new EC_LINE( points->Point( DIM_CROSSBARF ), + points->Point( DIM_FEATUREDO ) ) ); break; } @@ -322,29 +351,29 @@ void POINT_EDITOR::updateItem() const switch( segment->GetShape() ) { case S_SEGMENT: - if( isModified( m_editPoints->Point( 0 ) ) ) - segment->SetStart( wxPoint( m_editPoints->Point( 0 ).GetPosition().x, - m_editPoints->Point( 0 ).GetPosition().y ) ); + if( isModified( m_editPoints->Point( SEG_START ) ) ) + segment->SetStart( wxPoint( m_editPoints->Point( SEG_START ).GetPosition().x, + m_editPoints->Point( SEG_START ).GetPosition().y ) ); - else if( isModified( m_editPoints->Point( 1 ) ) ) - segment->SetEnd( wxPoint( m_editPoints->Point( 1 ).GetPosition().x, - m_editPoints->Point( 1 ).GetPosition().y ) ); + else if( isModified( m_editPoints->Point( SEG_END ) ) ) + segment->SetEnd( wxPoint( m_editPoints->Point( SEG_END ).GetPosition().x, + m_editPoints->Point( SEG_END ).GetPosition().y ) ); break; case S_ARC: { - const VECTOR2I& center = m_editPoints->Point( 0 ).GetPosition(); - const VECTOR2I& start = m_editPoints->Point( 1 ).GetPosition(); - const VECTOR2I& end = m_editPoints->Point( 2 ).GetPosition(); + const VECTOR2I& center = m_editPoints->Point( ARC_CENTER ).GetPosition(); + const VECTOR2I& start = m_editPoints->Point( ARC_START ).GetPosition(); + const VECTOR2I& end = m_editPoints->Point( ARC_END ).GetPosition(); if( center != segment->GetCenter() ) { wxPoint moveVector = wxPoint( center.x, center.y ) - segment->GetCenter(); segment->Move( moveVector ); - m_editPoints->Point( 1 ).SetPosition( segment->GetArcStart() ); - m_editPoints->Point( 2 ).SetPosition( segment->GetArcEnd() ); + m_editPoints->Point( ARC_START ).SetPosition( segment->GetArcStart() ); + m_editPoints->Point( ARC_END ).SetPosition( segment->GetArcEnd() ); } else @@ -371,10 +400,10 @@ void POINT_EDITOR::updateItem() const case S_CIRCLE: { - const VECTOR2I& center = m_editPoints->Point( 0 ).GetPosition(); - const VECTOR2I& end = m_editPoints->Point( 1 ).GetPosition(); + const VECTOR2I& center = m_editPoints->Point( CIRC_CENTER ).GetPosition(); + const VECTOR2I& end = m_editPoints->Point( CIRC_END ).GetPosition(); - if( isModified( m_editPoints->Point( 0 ) ) ) + if( isModified( m_editPoints->Point( CIRC_CENTER ) ) ) { wxPoint moveVector = wxPoint( center.x, center.y ) - segment->GetCenter(); segment->Move( moveVector ); @@ -414,7 +443,7 @@ void POINT_EDITOR::updateItem() const DIMENSION* dimension = static_cast( item ); // Check which point is currently modified and updated dimension's points respectively - if( isModified( m_editPoints->Point( 0 ) ) ) + if( isModified( m_editPoints->Point( DIM_CROSSBARO ) ) ) { VECTOR2D featureLine( m_dragPoint->GetPosition() - dimension->GetOrigin() ); VECTOR2D crossBar( dimension->GetEnd() - dimension->GetOrigin() ); @@ -425,7 +454,7 @@ void POINT_EDITOR::updateItem() const dimension->SetHeight( featureLine.EuclideanNorm() ); } - else if( isModified( m_editPoints->Point( 1 ) ) ) + else if( isModified( m_editPoints->Point( DIM_CROSSBARF ) ) ) { VECTOR2D featureLine( m_dragPoint->GetPosition() - dimension->GetEnd() ); VECTOR2D crossBar( dimension->GetEnd() - dimension->GetOrigin() ); @@ -436,18 +465,22 @@ void POINT_EDITOR::updateItem() const dimension->SetHeight( featureLine.EuclideanNorm() ); } - else if( isModified( m_editPoints->Point( 2 ) ) ) + else if( isModified( m_editPoints->Point( DIM_FEATUREGO ) ) ) { dimension->SetOrigin( wxPoint( m_dragPoint->GetPosition().x, m_dragPoint->GetPosition().y ) ); - m_editPoints->Point( 0 ).SetConstraint( new EC_LINE( m_editPoints->Point( 0 ), m_editPoints->Point( 2 ) ) ); - m_editPoints->Point( 1 ).SetConstraint( new EC_LINE( m_editPoints->Point( 1 ), m_editPoints->Point( 3 ) ) ); + m_editPoints->Point( DIM_CROSSBARO ).SetConstraint( new EC_LINE( m_editPoints->Point( DIM_CROSSBARO ), + m_editPoints->Point( DIM_FEATUREGO ) ) ); + m_editPoints->Point( DIM_CROSSBARF ).SetConstraint( new EC_LINE( m_editPoints->Point( DIM_CROSSBARF ), + m_editPoints->Point( DIM_FEATUREDO ) ) ); } - else if( isModified( m_editPoints->Point( 3 ) ) ) + else if( isModified( m_editPoints->Point( DIM_FEATUREDO ) ) ) { dimension->SetEnd( wxPoint( m_dragPoint->GetPosition().x, m_dragPoint->GetPosition().y ) ); - m_editPoints->Point( 0 ).SetConstraint( new EC_LINE( m_editPoints->Point( 0 ), m_editPoints->Point( 2 ) ) ); - m_editPoints->Point( 1 ).SetConstraint( new EC_LINE( m_editPoints->Point( 1 ), m_editPoints->Point( 3 ) ) ); + m_editPoints->Point( DIM_CROSSBARO ).SetConstraint( new EC_LINE( m_editPoints->Point( DIM_CROSSBARO ), + m_editPoints->Point( DIM_FEATUREGO ) ) ); + m_editPoints->Point( DIM_CROSSBARF ).SetConstraint( new EC_LINE( m_editPoints->Point( DIM_CROSSBARF ), + m_editPoints->Point( DIM_FEATUREDO ) ) ); } break; @@ -486,19 +519,19 @@ void POINT_EDITOR::updatePoints() const switch( segment->GetShape() ) { case S_SEGMENT: - m_editPoints->Point( 0 ).SetPosition( segment->GetStart() ); - m_editPoints->Point( 1 ).SetPosition( segment->GetEnd() ); + m_editPoints->Point( SEG_START ).SetPosition( segment->GetStart() ); + m_editPoints->Point( SEG_END ).SetPosition( segment->GetEnd() ); break; case S_ARC: - m_editPoints->Point( 0 ).SetPosition( segment->GetCenter() ); - m_editPoints->Point( 1 ).SetPosition( segment->GetArcStart() ); - m_editPoints->Point( 2 ).SetPosition( segment->GetArcEnd() ); + m_editPoints->Point( ARC_CENTER ).SetPosition( segment->GetCenter() ); + m_editPoints->Point( ARC_START).SetPosition( segment->GetArcStart() ); + m_editPoints->Point( ARC_END ).SetPosition( segment->GetArcEnd() ); break; case S_CIRCLE: - m_editPoints->Point( 0 ).SetPosition( segment->GetCenter() ); - m_editPoints->Point( 1 ).SetPosition( segment->GetEnd() ); + m_editPoints->Point( CIRC_CENTER ).SetPosition( segment->GetCenter() ); + m_editPoints->Point( CIRC_END ).SetPosition( segment->GetEnd() ); break; default: // suppress warnings @@ -524,10 +557,10 @@ void POINT_EDITOR::updatePoints() const { const DIMENSION* dimension = static_cast( item ); - m_editPoints->Point( 0 ).SetPosition( dimension->m_crossBarO ); - m_editPoints->Point( 1 ).SetPosition( dimension->m_crossBarF ); - m_editPoints->Point( 2 ).SetPosition( dimension->m_featureLineGO ); - m_editPoints->Point( 3 ).SetPosition( dimension->m_featureLineDO ); + m_editPoints->Point( DIM_CROSSBARO ).SetPosition( dimension->m_crossBarO ); + m_editPoints->Point( DIM_CROSSBARF ).SetPosition( dimension->m_crossBarF ); + m_editPoints->Point( DIM_FEATUREGO ).SetPosition( dimension->m_featureLineGO ); + m_editPoints->Point( DIM_FEATUREDO ).SetPosition( dimension->m_featureLineDO ); break; } @@ -580,7 +613,7 @@ EDIT_POINT POINT_EDITOR::get45DegConstrainer() const case S_ARC: case S_CIRCLE: - return m_editPoints->Point( 0 ); // center + return m_editPoints->Point( CIRC_CENTER ); default: // suppress warnings break; @@ -593,11 +626,11 @@ EDIT_POINT POINT_EDITOR::get45DegConstrainer() const case PCB_DIMENSION_T: { // Constraint for crossbar - if( isModified( m_editPoints->Point( 2 ) ) ) - return m_editPoints->Point( 3 ); + if( isModified( m_editPoints->Point( DIM_FEATUREGO ) ) ) + return m_editPoints->Point( DIM_FEATUREDO ); - else if( isModified( m_editPoints->Point( 3 ) ) ) - return m_editPoints->Point( 2 ); + else if( isModified( m_editPoints->Point( DIM_FEATUREDO ) ) ) + return m_editPoints->Point( DIM_FEATUREGO ); else return EDIT_POINT( m_dragPoint->GetPosition() ); // no constraint @@ -614,7 +647,6 @@ EDIT_POINT POINT_EDITOR::get45DegConstrainer() const } - void POINT_EDITOR::breakOutline( const VECTOR2I& aBreakPoint ) { EDA_ITEM* item = m_editPoints->GetParent(); diff --git a/pcbnew/tools/point_editor.h b/pcbnew/tools/point_editor.h index 7fdf655809..b87224f613 100644 --- a/pcbnew/tools/point_editor.h +++ b/pcbnew/tools/point_editor.h @@ -95,7 +95,7 @@ private: ///> Returns a point that should be used as a constrainer for 45 degrees mode. EDIT_POINT get45DegConstrainer() const; - // TODO docs + ///> Adds a new edit point on a zone outline. void breakOutline( const VECTOR2I& aBreakPoint ); ///> Sets up handlers for various events. From 1828edbabe57868e6b0eb7e5fba2fbd8f366077d Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 2 Apr 2014 09:31:35 +0200 Subject: [PATCH 106/134] Refactoring EDIT_POINTS, part 3: constraints split to EDIT_POINTs and EDIT_LINEs. --- pcbnew/tools/edit_constraints.cpp | 10 +++++----- pcbnew/tools/edit_constraints.h | 13 +++++-------- pcbnew/tools/edit_points.h | 28 +++++++++++++++++++++++++++- pcbnew/tools/point_editor.cpp | 5 ++--- 4 files changed, 39 insertions(+), 17 deletions(-) diff --git a/pcbnew/tools/edit_constraints.cpp b/pcbnew/tools/edit_constraints.cpp index 91e14ea82d..84d417c2ab 100644 --- a/pcbnew/tools/edit_constraints.cpp +++ b/pcbnew/tools/edit_constraints.cpp @@ -90,8 +90,8 @@ void EC_CIRCLE::Apply( EDIT_POINT& aHandle ) EC_CONVERGING::EC_CONVERGING( EDIT_LINE& aLine, EDIT_POINTS& aPoints ) : - EDIT_CONSTRAINT( aLine.GetOrigin() ), - m_colinearConstraint( NULL ), m_line( aLine ), m_editPoints( aPoints ) + EDIT_CONSTRAINT( aLine ), + m_colinearConstraint( NULL ), m_editPoints( aPoints ) { // Dragged segment endings EDIT_POINT& origin = aLine.GetOrigin(); @@ -128,11 +128,11 @@ EC_CONVERGING::~EC_CONVERGING() } -void EC_CONVERGING::Apply( EDIT_POINT& aHandle ) +void EC_CONVERGING::Apply( EDIT_LINE& aHandle ) { // The dragged segment endpoints - EDIT_POINT& origin = m_line.GetOrigin(); - EDIT_POINT& end = m_line.GetEnd(); + EDIT_POINT& origin = m_constrained.GetOrigin(); + EDIT_POINT& end = m_constrained.GetEnd(); if( m_colinearConstraint ) { diff --git a/pcbnew/tools/edit_constraints.h b/pcbnew/tools/edit_constraints.h index b26c4f69f7..c86afb5a75 100644 --- a/pcbnew/tools/edit_constraints.h +++ b/pcbnew/tools/edit_constraints.h @@ -127,8 +127,8 @@ private: /** * Class EC_45DEGREE * - * EDIT_CONSTRAINT that imposes a constraint that two to be located at angle of 45 degree - * multiplicity. + * EDIT_CONSTRAINT that imposes a constraint that two points have to be located at angle of 45 + * degree multiplicity. */ class EC_45DEGREE : public EDIT_CONSTRAINT { @@ -205,10 +205,10 @@ private: /** * Class EC_CONVERGING * - * EDIT_CONSTRAINT for 3 segment: dragged and two adjacent ones, enforcing to keep their slopes + * EDIT_CONSTRAINT for 3 segments: dragged and two adjacent ones, enforcing to keep their slopes * and allows only to change ending points. Applied to zones. */ -class EC_CONVERGING : public EDIT_CONSTRAINT +class EC_CONVERGING : public EDIT_CONSTRAINT { public: EC_CONVERGING( EDIT_LINE& aLine, EDIT_POINTS& aPoints ); @@ -216,7 +216,7 @@ public: virtual ~EC_CONVERGING(); ///> @copydoc EDIT_CONSTRAINT::Apply() - virtual void Apply( EDIT_POINT& aHandle ); + virtual void Apply( EDIT_LINE& aHandle ); private: ///> Constraint for origin side segment. @@ -229,9 +229,6 @@ private: ///> m_[origin/end]SideConstraint, so it should not be freed. EDIT_CONSTRAINT* m_colinearConstraint; - ///> Dragged segment. - EDIT_LINE& m_line; - ///> EDIT_POINTS instance that stores currently modified lines. EDIT_POINTS& m_editPoints; diff --git a/pcbnew/tools/edit_points.h b/pcbnew/tools/edit_points.h index 2e5bddff62..52f54960ff 100644 --- a/pcbnew/tools/edit_points.h +++ b/pcbnew/tools/edit_points.h @@ -165,7 +165,7 @@ public: ///> Single point size in pixels static const int POINT_SIZE = 10; -protected: +private: ///> Position of EDIT_POINT VECTOR2I m_position; @@ -221,6 +221,29 @@ public: m_constraint->Apply(); } + /** + * Function SetConstraint() + * + * Sets a constraint for and EDIT_POINT. + * @param aConstraint is the constraint to be set. + */ + void SetConstraint( EDIT_CONSTRAINT* aConstraint ) + { + m_constraint.reset( aConstraint ); + } + + /** + * Function GetConstraint() + * + * Returns the constraint imposed on an EDIT_POINT. If there are no constraints, NULL is + * returned. + */ + EDIT_CONSTRAINT* GetConstraint() const + { + return m_constraint.get(); + } + + /** * Function GetOrigin() * @@ -264,6 +287,9 @@ public: private: EDIT_POINT& m_origin; ///< Origin point for a line EDIT_POINT& m_end; ///< End point for a line + + ///> Constraint for the point, NULL if none + boost::shared_ptr > m_constraint; }; diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 167b8247bf..5fd82edf53 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -575,12 +575,11 @@ void POINT_EDITOR::setAltConstraint( bool aEnabled ) if( aEnabled ) { EDIT_LINE* line = dynamic_cast( m_dragPoint ); + if( line ) { if( m_editPoints->GetParent()->Type() == PCB_ZONE_AREA_T ) - { - m_altConstraint.reset( new EC_CONVERGING( *line, *m_editPoints ) ); - } + m_altConstraint.reset( (EDIT_CONSTRAINT*)( new EC_CONVERGING( *line, *m_editPoints ) ) ); } else { From 5de41eabd1ec6550d75b3231b890ea44f01219af Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 2 Apr 2014 15:57:21 +0200 Subject: [PATCH 107/134] Added EC_SNAPLINE to make possible snapping EDIT_LINES by their ends rather than by its center. --- pcbnew/tools/edit_constraints.cpp | 18 ++++++++++++++++-- pcbnew/tools/edit_constraints.h | 28 ++++++++++++++++++++++++++++ pcbnew/tools/edit_points.h | 16 +++++++++++++--- pcbnew/tools/point_editor.cpp | 18 +++++++++++------- 4 files changed, 68 insertions(+), 12 deletions(-) diff --git a/pcbnew/tools/edit_constraints.cpp b/pcbnew/tools/edit_constraints.cpp index 84d417c2ab..f0edf9bc8b 100644 --- a/pcbnew/tools/edit_constraints.cpp +++ b/pcbnew/tools/edit_constraints.cpp @@ -131,8 +131,8 @@ EC_CONVERGING::~EC_CONVERGING() void EC_CONVERGING::Apply( EDIT_LINE& aHandle ) { // The dragged segment endpoints - EDIT_POINT& origin = m_constrained.GetOrigin(); - EDIT_POINT& end = m_constrained.GetEnd(); + EDIT_POINT& origin = aHandle.GetOrigin(); + EDIT_POINT& end = aHandle.GetEnd(); if( m_colinearConstraint ) { @@ -173,3 +173,17 @@ void EC_CONVERGING::Apply( EDIT_LINE& aHandle ) end.SetPosition( *originEndIntersect ); } } + + +EC_SNAPLINE::EC_SNAPLINE( EDIT_LINE& aLine, V2D_TRANSFORM_FUN aSnapFun ) : + EDIT_CONSTRAINT( aLine ), m_snapFun( aSnapFun ) +{} + + +void EC_SNAPLINE::Apply( EDIT_LINE& aHandle ) +{ + VECTOR2D delta = aHandle.GetEnd().GetPosition() - aHandle.GetOrigin().GetPosition(); + + aHandle.GetOrigin().SetPosition( m_snapFun( aHandle.GetOrigin().GetPosition() ) ); + aHandle.GetEnd().SetPosition( aHandle.GetOrigin().GetPosition() + delta ); +} diff --git a/pcbnew/tools/edit_constraints.h b/pcbnew/tools/edit_constraints.h index c86afb5a75..6df17e438d 100644 --- a/pcbnew/tools/edit_constraints.h +++ b/pcbnew/tools/edit_constraints.h @@ -26,6 +26,7 @@ #define EDIT_CONSTRAINTS_H_ #include +#include class EDIT_POINT; class EDIT_LINE; @@ -236,4 +237,31 @@ private: VECTOR2I m_draggedVector; }; + +/** + * Class EC_SNAPLINE + * + * EDIT_CONSTRAINT for a EDIT_LINE, one of the ends is snapped to a spot determined by a + * transform function passed as parameter (e.g. it can be snapped to a grid), instead of having + * the line center snapped to a point. + */ +class EC_SNAPLINE : public EDIT_CONSTRAINT +{ +public: + ///> Typedef for a function that determines snapping point. + typedef boost::function V2D_TRANSFORM_FUN; + + EC_SNAPLINE( EDIT_LINE& aLine, V2D_TRANSFORM_FUN aSnapFun ); + + virtual ~EC_SNAPLINE() + {} + + ///> @copydoc EDIT_CONSTRAINT::Apply() + virtual void Apply( EDIT_LINE& aHandle ); + +private: + ///> Function that determines snapping point. + V2D_TRANSFORM_FUN m_snapFun; +}; + #endif /* EDIT_CONSTRAINTS_H_ */ diff --git a/pcbnew/tools/edit_points.h b/pcbnew/tools/edit_points.h index 52f54960ff..b06ec30975 100644 --- a/pcbnew/tools/edit_points.h +++ b/pcbnew/tools/edit_points.h @@ -418,15 +418,25 @@ public: } /** - * Function Size() + * Function PointsSize() * - * Returns number of stored points. + * Returns number of stored EDIT_POINTs. */ - unsigned int Size() const + unsigned int PointsSize() const { return m_points.size(); } + /** + * Function LinesSize() + * + * Returns number of stored EDIT_LINEs. + */ + unsigned int LinesSize() const + { + return m_lines.size(); + } + ///> @copydoc VIEW_ITEM::ViewBBox() virtual const BOX2I ViewBBox() const { diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 5fd82edf53..f4aa4baa17 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -23,6 +23,7 @@ */ #include +#include #include #include @@ -64,16 +65,11 @@ enum DIMENSION_POINTS DIM_FEATUREDO, }; -/** - * Class POINT_EDITOR - * - * Tool that displays edit points allowing to modify items by dragging the points. - */ class EDIT_POINTS_FACTORY { public: - static boost::shared_ptr Make( EDA_ITEM* aItem ) + static boost::shared_ptr Make( EDA_ITEM* aItem, KIGFX::GAL* aGal ) { boost::shared_ptr points = boost::make_shared( aItem ); @@ -126,10 +122,18 @@ public: // Lines have to be added after creating edit points, // as they use EDIT_POINT references for( int i = 0; i < cornersCount - 1; ++i ) + { points->AddLine( points->Point( i ), points->Point( i + 1 ) ); + points->Line( i ).SetConstraint( + new EC_SNAPLINE( points->Line( i ), + boost::bind( &KIGFX::GAL::GetGridPoint, aGal, _1 ) ) ); + } // The last missing line, connecting the last and the first polygon point points->AddLine( points->Point( cornersCount - 1 ), points->Point( 0 ) ); + points->Line( points->LinesSize() - 1 ).SetConstraint( + new EC_SNAPLINE( points->Line( points->LinesSize() - 1 ), + boost::bind( &KIGFX::GAL::GetGridPoint, aGal, _1 ) ) ); break; } @@ -208,7 +212,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) PCB_EDIT_FRAME* editFrame = getEditFrame(); EDA_ITEM* item = selection.items.GetPickedItem( 0 ); - m_editPoints = EDIT_POINTS_FACTORY::Make( item ); + m_editPoints = EDIT_POINTS_FACTORY::Make( item, m_toolMgr->GetView()->GetGAL() ); if( !m_editPoints ) { setTransitions(); From b6aa832f83034f848aafe035df6fbfc960931a66 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 2 Apr 2014 16:30:48 +0200 Subject: [PATCH 108/134] Converted std::bind1st to boost::bind. --- pcbnew/board_undo_redo.cpp | 9 +++++---- pcbnew/pcbframe.cpp | 3 ++- pcbnew/tools/drawing_tool.cpp | 9 ++++----- pcbnew/tools/edit_tool.cpp | 11 +++++------ pcbnew/tools/selection_tool.cpp | 5 +++-- 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/pcbnew/board_undo_redo.cpp b/pcbnew/board_undo_redo.cpp index 5912380180..a720b0e48a 100644 --- a/pcbnew/board_undo_redo.cpp +++ b/pcbnew/board_undo_redo.cpp @@ -23,6 +23,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#include #include #include #include @@ -522,7 +523,7 @@ 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( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) ); } ratsnest->Remove( item ); @@ -533,7 +534,7 @@ 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( boost::bind( &KIGFX::VIEW::Add, view, _1 ) ); } ratsnest->Add( item ); @@ -549,7 +550,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( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) ); } view->Remove( item ); @@ -563,7 +564,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( boost::bind( &KIGFX::VIEW::Add, view, _1) ); } view->Add( item ); diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 6fc807c083..faf6e1645d 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -75,6 +75,7 @@ #endif #include +#include // Keys used in read/write config #define OPTKEY_DEFAULT_LINEWIDTH_VALUE wxT( "PlotLineWidth_mm" ) @@ -524,7 +525,7 @@ void PCB_EDIT_FRAME::ViewReloadBoard( const BOARD* aBoard ) const // Load modules and its additional elements for( MODULE* module = aBoard->m_Modules; module; module = module->Next() ) { - module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), view ) ); + module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) ); view->Add( module ); } diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 61b3064783..b0155f0f1f 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -22,6 +22,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#include #include "drawing_tool.h" #include "common_actions.h" @@ -706,14 +707,13 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) // Add all the drawable parts to preview preview.Add( module ); - module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW_GROUP::Add ), - &preview ) ); + module->RunOnChildren( boost::bind( &KIGFX::VIEW_GROUP::Add, &preview, _1 ) ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } else { - module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), m_view ) ); + module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, m_view, _1 ) ); m_view->Add( module ); module->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); @@ -722,8 +722,7 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) // Remove from preview preview.Remove( module ); - module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW_GROUP::Remove ), - &preview ) ); + module->RunOnChildren( boost::bind( &KIGFX::VIEW_GROUP::Remove, &preview, _1 ) ); module = NULL; // to indicate that there is no module that we currently modify m_controls->ShowCursor( true ); diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 92c0c218a2..445e7abdd7 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -30,16 +30,15 @@ #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 ) { @@ -96,7 +95,7 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) // Offset from the dragged item's center (anchor) wxPoint offset; - VIEW_CONTROLS* controls = getViewControls(); + KIGFX::VIEW_CONTROLS* controls = getViewControls(); PCB_EDIT_FRAME* editFrame = static_cast( m_toolMgr->GetEditFrame() ); controls->ShowCursor( true ); controls->SetSnapping( true ); @@ -163,7 +162,7 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) m_dragging = true; } - selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); + selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate ); } @@ -399,7 +398,7 @@ void EDIT_TOOL::remove( BOARD_ITEM* aItem ) { MODULE* module = static_cast( aItem ); module->ClearFlags(); - module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Remove ), getView() ) ); + module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, getView(), _1 ) ); // Module itself is deleted after the switch scope is finished // list of pads is rebuild by BOARD::BuildListOfNets() diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index cb37b23cdc..8c3e79adbb 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -556,7 +557,7 @@ void SELECTION_TOOL::select( BOARD_ITEM* aItem ) if( aItem->Type() == PCB_MODULE_T ) { MODULE* module = static_cast( aItem ); - module->RunOnChildren( std::bind1st( std::mem_fun( &SELECTION_TOOL::selectVisually ), this ) ); + module->RunOnChildren( boost::bind( &SELECTION_TOOL::selectVisually, this, _1 ) ); } selectVisually( aItem ); @@ -587,7 +588,7 @@ void SELECTION_TOOL::deselect( BOARD_ITEM* aItem ) if( aItem->Type() == PCB_MODULE_T ) { MODULE* module = static_cast( aItem ); - module->RunOnChildren( std::bind1st( std::mem_fun( &SELECTION_TOOL::deselectVisually ), this ) ); + module->RunOnChildren( boost::bind( &SELECTION_TOOL::deselectVisually, this, _1 ) ); } deselectVisually( aItem ); From d87680796619058389cdbe0493a3297180cc25f4 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 3 Apr 2014 09:48:06 +0200 Subject: [PATCH 109/134] Fixed cancelling dialogs in DRAWING_TOOL. --- common/tool/tool_dispatcher.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/common/tool/tool_dispatcher.cpp b/common/tool/tool_dispatcher.cpp index 8f36386766..f04dd2d69d 100644 --- a/common/tool/tool_dispatcher.cpp +++ b/common/tool/tool_dispatcher.cpp @@ -251,14 +251,14 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) if( type == wxEVT_KEY_UP ) { - if( key == WXK_ESCAPE ) // ESC is the special key for cancelling tools - evt = TOOL_EVENT( TC_COMMAND, TA_CANCEL_TOOL ); - else - evt = TOOL_EVENT( TC_KEYBOARD, TA_KEY_UP, key | mods ); + evt = TOOL_EVENT( TC_KEYBOARD, TA_KEY_UP, key | mods ); } else { - evt = TOOL_EVENT( TC_KEYBOARD, TA_KEY_DOWN, key | mods ); + if( key == WXK_ESCAPE ) // ESC is the special key for cancelling tools + evt = TOOL_EVENT( TC_COMMAND, TA_CANCEL_TOOL ); + else + evt = TOOL_EVENT( TC_KEYBOARD, TA_KEY_DOWN, key | mods ); } } From 1ef68d73e56f0e18608c7c9a200fa0ab9aba4caa Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 3 Apr 2014 10:24:27 +0200 Subject: [PATCH 110/134] Fixed missing transitions for EDIT_TOOLs. --- pcbnew/tools/edit_tool.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 445e7abdd7..1c84cc10c5 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -266,7 +266,11 @@ int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) bool unselect = selection.Empty(); if( !makeSelection( selection ) ) + { + setTransitions(); + return 0; + } wxPoint rotatePoint = getModificationPoint( selection ); @@ -312,7 +316,11 @@ int EDIT_TOOL::Flip( TOOL_EVENT& aEvent ) bool unselect = selection.Empty(); if( !makeSelection( selection ) ) + { + setTransitions(); + return 0; + } wxPoint flipPoint = getModificationPoint( selection ); @@ -354,7 +362,11 @@ int EDIT_TOOL::Remove( TOOL_EVENT& aEvent ) const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); if( !makeSelection( selection ) ) + { + setTransitions(); + return 0; + } // Get a copy of the selected items set PICKED_ITEMS_LIST selectedItems = selection.items; From bad6cdaa06fe4962bf1a77cf6b9fa9df827e0c7f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 4 Apr 2014 09:01:17 +0200 Subject: [PATCH 111/134] TEXTE_MODULE relative position is updated when absolute position is changed (and viceversa). --- pcbnew/class_text_mod.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pcbnew/class_text_mod.h b/pcbnew/class_text_mod.h index 97e15ab202..5917759cd0 100644 --- a/pcbnew/class_text_mod.h +++ b/pcbnew/class_text_mod.h @@ -87,11 +87,13 @@ public: virtual void SetPosition( const wxPoint& aPos ) { m_Pos = aPos; + SetLocalCoord(); } void Move( const wxPoint& aMoveVector ) { m_Pos += aMoveVector; + SetLocalCoord(); } void Rotate( const wxPoint& aRotCentre, double aAngle ); @@ -110,7 +112,7 @@ public: void SetVisible( bool isVisible ) { m_NoShow = !isVisible; } bool IsVisible() const { return !m_NoShow; } - void SetPos0( const wxPoint& aPos ) { m_Pos0 = aPos; } + void SetPos0( const wxPoint& aPos ) { m_Pos0 = aPos; SetDrawCoord(); } const wxPoint& GetPos0() const { return m_Pos0; } void Copy( TEXTE_MODULE* source ); // copy structure From 4c5afc46afedc15366ffa5d62a021eb4fea38145 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 4 Apr 2014 11:50:15 +0200 Subject: [PATCH 112/134] Added possibility of switching tools by the right toolbar buttons, without deactivating the current tool first (previously tools did not switch if there was one active). --- include/tool/tool_manager.h | 20 ++++ pcbnew/basepcbframe.cpp | 4 +- pcbnew/edit.cpp | 211 ++++++++++++++++++---------------- pcbnew/router/router_tool.cpp | 3 +- pcbnew/tools/drawing_tool.cpp | 14 +++ pcbnew/tools/pcb_tools.cpp | 2 +- 6 files changed, 152 insertions(+), 102 deletions(-) diff --git a/include/tool/tool_manager.h b/include/tool/tool_manager.h index 1103a7f890..7689a9a3c8 100644 --- a/include/tool/tool_manager.h +++ b/include/tool/tool_manager.h @@ -186,6 +186,26 @@ public: return m_editFrame; } + /** + * Returns id of the tool that is on the top of the active tools stack + * (was invoked the most recently). + * @return Id of the currently used tool. + */ + int GetCurrentToolId() const + { + return m_activeTools.front(); + } + + /** + * Returns the tool that is on the top of the active tools stack + * (was invoked the most recently). + * @return Pointer to the currently used tool. + */ + TOOL_BASE* GetCurrentTool() const + { + return FindTool( GetCurrentToolId() ); + } + /** * Defines a state transition - the events that cause a given handler method in the tool * to be called. Called by TOOL_INTERACTIVE::Go(). May be called from a coroutine context. diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index 0e93394930..76c31e62a6 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -633,7 +633,7 @@ void PCB_BASE_FRAME::SetToolID( int aId, int aCursor, const wxString& aToolMsg ) // handle color changes for transitions in and out of ID_TRACK_BUTT if( ( GetToolId() == ID_TRACK_BUTT && aId != ID_TRACK_BUTT ) - || ( GetToolId() != ID_TRACK_BUTT && aId== ID_TRACK_BUTT ) ) + || ( GetToolId() != ID_TRACK_BUTT && aId == ID_TRACK_BUTT ) ) { if( DisplayOpt.ContrastModeDisplay ) redraw = true; @@ -641,7 +641,7 @@ void PCB_BASE_FRAME::SetToolID( int aId, int aCursor, const wxString& aToolMsg ) // must do this after the tool has been set, otherwise pad::Draw() does // not show proper color when DisplayOpt.ContrastModeDisplay is true. - if( redraw && m_canvas) + if( redraw && m_canvas ) m_canvas->Refresh(); } diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index eff1aa15b5..0fbe391318 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -1370,109 +1370,124 @@ void PCB_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent ) if( GetToolId() == id ) return; - INSTALL_UNBUFFERED_DC( dc, m_canvas ); - - // Stop the current command and deselect the current tool. - m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() ); - - switch( id ) - { - case ID_NO_TOOL_SELECTED: - SetToolID( id, m_canvas->GetDefaultCursor(), wxEmptyString ); - break; - - case ID_TRACK_BUTT: - if( g_Drc_On ) - SetToolID( id, wxCURSOR_PENCIL, _( "Add tracks" ) ); - else - SetToolID( id, wxCURSOR_QUESTION_ARROW, _( "Add tracks" ) ); - - if( (GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 ) - { - Compile_Ratsnest( &dc, true ); - } - - break; - - case ID_PCB_MODULE_BUTT: - SetToolID( id, wxCURSOR_PENCIL, _( "Add module" ) ); - break; - - case ID_PCB_ZONES_BUTT: - SetToolID( id, wxCURSOR_PENCIL, _( "Add zones" ) ); - - if( DisplayOpt.DisplayZonesMode != 0 ) - DisplayInfoMessage( this, _( "Warning: zone display is OFF!!!" ) ); - - if( !GetBoard()->IsHighLightNetON() && (GetBoard()->GetHighLightNetCode() > 0 ) ) - HighLight( &dc ); - - break; - - case ID_PCB_KEEPOUT_AREA_BUTT: - SetToolID( id, wxCURSOR_PENCIL, _( "Add keepout" ) ); - break; - - case ID_PCB_MIRE_BUTT: - SetToolID( id, wxCURSOR_PENCIL, _( "Add layer alignment target" ) ); - break; - - case ID_PCB_PLACE_OFFSET_COORD_BUTT: - SetToolID( id, wxCURSOR_PENCIL, _( "Adjust zero" ) ); - break; - - case ID_PCB_PLACE_GRID_COORD_BUTT: - SetToolID( id, wxCURSOR_PENCIL, _( "Adjust grid origin" ) ); - break; - - case ID_PCB_ADD_LINE_BUTT: - SetToolID( id, wxCURSOR_PENCIL, _( "Add graphic line" ) ); - break; - - case ID_PCB_ARC_BUTT: - SetToolID( id, wxCURSOR_PENCIL, _( "Add graphic arc" ) ); - break; - - case ID_PCB_CIRCLE_BUTT: - SetToolID( id, wxCURSOR_PENCIL, _( "Add graphic circle" ) ); - break; - - case ID_PCB_ADD_TEXT_BUTT: - SetToolID( id, wxCURSOR_PENCIL, _( "Add text" ) ); - break; - - case ID_COMPONENT_BUTT: - SetToolID( id, wxCURSOR_HAND, _( "Add module" ) ); - break; - - case ID_PCB_DIMENSION_BUTT: - SetToolID( id, wxCURSOR_PENCIL, _( "Add dimension" ) ); - break; - - case ID_PCB_DELETE_ITEM_BUTT: - SetToolID( id, wxCURSOR_BULLSEYE, _( "Delete item" ) ); - break; - - case ID_PCB_HIGHLIGHT_BUTT: - SetToolID( id, wxCURSOR_HAND, _( "Highlight net" ) ); - break; - - case ID_PCB_SHOW_1_RATSNEST_BUTT: - SetToolID( id, wxCURSOR_HAND, _( "Select rats nest" ) ); - - if( ( GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK ) == 0 ) - Compile_Ratsnest( &dc, true ); - - break; - } - if( IsGalCanvasActive() ) { std::string actionName = COMMON_ACTIONS::TranslateLegacyId( id ); if( !actionName.empty() ) - m_toolManager.RunAction( actionName ); + { + const int MAX_TRIALS = 10; + int trials = 0; - return; + // Cancel the current tool + // TODO while sending a lot of cancel events works for sure, it is not the most + // elegant way to cancel a tool, this should be probably done another way + while( m_toolManager.GetCurrentTool()->GetName() != "pcbnew.InteractiveSelection" && + trials++ < MAX_TRIALS ) + { + TOOL_EVENT cancel( TC_ANY, TA_CANCEL_TOOL ); + m_toolManager.ProcessEvent( cancel ); + } + + m_toolManager.RunAction( actionName ); + } + } + else + { + INSTALL_UNBUFFERED_DC( dc, m_canvas ); + + // Stop the current command and deselect the current tool. + m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() ); + + switch( id ) + { + case ID_NO_TOOL_SELECTED: + SetToolID( id, m_canvas->GetDefaultCursor(), wxEmptyString ); + break; + + case ID_TRACK_BUTT: + if( g_Drc_On ) + SetToolID( id, wxCURSOR_PENCIL, _( "Add tracks" ) ); + else + SetToolID( id, wxCURSOR_QUESTION_ARROW, _( "Add tracks" ) ); + + if( (GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 ) + { + Compile_Ratsnest( &dc, true ); + } + + break; + + case ID_PCB_MODULE_BUTT: + SetToolID( id, wxCURSOR_PENCIL, _( "Add module" ) ); + break; + + case ID_PCB_ZONES_BUTT: + SetToolID( id, wxCURSOR_PENCIL, _( "Add zones" ) ); + + if( DisplayOpt.DisplayZonesMode != 0 ) + DisplayInfoMessage( this, _( "Warning: zone display is OFF!!!" ) ); + + if( !GetBoard()->IsHighLightNetON() && (GetBoard()->GetHighLightNetCode() > 0 ) ) + HighLight( &dc ); + + break; + + case ID_PCB_KEEPOUT_AREA_BUTT: + SetToolID( id, wxCURSOR_PENCIL, _( "Add keepout" ) ); + break; + + case ID_PCB_MIRE_BUTT: + SetToolID( id, wxCURSOR_PENCIL, _( "Add layer alignment target" ) ); + break; + + case ID_PCB_PLACE_OFFSET_COORD_BUTT: + SetToolID( id, wxCURSOR_PENCIL, _( "Adjust zero" ) ); + break; + + case ID_PCB_PLACE_GRID_COORD_BUTT: + SetToolID( id, wxCURSOR_PENCIL, _( "Adjust grid origin" ) ); + break; + + case ID_PCB_ADD_LINE_BUTT: + SetToolID( id, wxCURSOR_PENCIL, _( "Add graphic line" ) ); + break; + + case ID_PCB_ARC_BUTT: + SetToolID( id, wxCURSOR_PENCIL, _( "Add graphic arc" ) ); + break; + + case ID_PCB_CIRCLE_BUTT: + SetToolID( id, wxCURSOR_PENCIL, _( "Add graphic circle" ) ); + break; + + case ID_PCB_ADD_TEXT_BUTT: + SetToolID( id, wxCURSOR_PENCIL, _( "Add text" ) ); + break; + + case ID_COMPONENT_BUTT: + SetToolID( id, wxCURSOR_HAND, _( "Add module" ) ); + break; + + case ID_PCB_DIMENSION_BUTT: + SetToolID( id, wxCURSOR_PENCIL, _( "Add dimension" ) ); + break; + + case ID_PCB_DELETE_ITEM_BUTT: + SetToolID( id, wxCURSOR_BULLSEYE, _( "Delete item" ) ); + break; + + case ID_PCB_HIGHLIGHT_BUTT: + SetToolID( id, wxCURSOR_HAND, _( "Highlight net" ) ); + break; + + case ID_PCB_SHOW_1_RATSNEST_BUTT: + SetToolID( id, wxCURSOR_HAND, _( "Select rats nest" ) ); + + if( ( GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK ) == 0 ) + Compile_Ratsnest( &dc, true ); + + break; + } } } diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 88e797b92b..2608b2d21e 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -432,6 +433,7 @@ int ROUTER_TOOL::Main( TOOL_EVENT& aEvent ) // SetContextMenu ( m_menu ); // setMsgPanel(true, 0, wxT("KiRouter"), wxT("Pick an item to start routing")); + getEditFrame()->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Add tracks" ) ); ctls->SetSnapping( true ); ctls->ShowCursor( true ); @@ -469,4 +471,3 @@ int ROUTER_TOOL::Main( TOOL_EVENT& aEvent ) return 0; } - diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index b0155f0f1f..1d85ec6906 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -69,12 +70,16 @@ void DRAWING_TOOL::Reset( RESET_REASON aReason ) int DRAWING_TOOL::DrawLine( TOOL_EVENT& aEvent ) { + m_frame->SetToolID( ID_PCB_ADD_LINE_BUTT, wxCURSOR_PENCIL, _( "Add graphic line" ) ); + return drawSegment( S_SEGMENT, true ); } int DRAWING_TOOL::DrawCircle( TOOL_EVENT& aEvent ) { + m_frame->SetToolID( ID_PCB_CIRCLE_BUTT, wxCURSOR_PENCIL, _( "Add graphic circle" ) ); + return drawSegment( S_CIRCLE, false ); } @@ -100,6 +105,7 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) m_controls->SetSnapping( true ); Activate(); + m_frame->SetToolID( ID_PCB_ARC_BUTT, wxCURSOR_PENCIL, _( "Add graphic arc" ) ); enum ARC_STEPS { @@ -286,6 +292,7 @@ int DRAWING_TOOL::PlaceText( TOOL_EVENT& aEvent ) m_controls->SetAutoPan( true ); Activate(); + m_frame->SetToolID( ID_PCB_ADD_TEXT_BUTT, wxCURSOR_PENCIL, _( "Add text" ) ); // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) @@ -390,6 +397,7 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) m_controls->SetSnapping( true ); Activate(); + m_frame->SetToolID( ID_PCB_DIMENSION_BUTT, wxCURSOR_PENCIL, _( "Add dimension" ) ); enum DIMENSION_STEPS { @@ -549,12 +557,16 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) int DRAWING_TOOL::DrawZone( TOOL_EVENT& aEvent ) { + m_frame->SetToolID( ID_PCB_ZONES_BUTT, wxCURSOR_PENCIL, _( "Add zones" ) ); + return drawZone( false ); } int DRAWING_TOOL::DrawKeepout( TOOL_EVENT& aEvent ) { + m_frame->SetToolID( ID_PCB_KEEPOUT_AREA_BUTT, wxCURSOR_PENCIL, _( "Add keepout" ) ); + return drawZone( true ); } @@ -581,6 +593,7 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) m_controls->SetAutoPan( true ); Activate(); + m_frame->SetToolID( ID_PCB_MIRE_BUTT, wxCURSOR_PENCIL, _( "Add layer alignment target" ) ); // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) @@ -656,6 +669,7 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) m_controls->SetAutoPan( true ); Activate(); + m_frame->SetToolID( ID_PCB_MODULE_BUTT, wxCURSOR_HAND, _( "Add module" ) ); // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index 4d618615dc..154ea93d46 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -68,7 +68,7 @@ void PCB_EDIT_FRAME::setupTools() m_toolManager.RegisterTool( new PCBNEW_CONTROL ); m_toolManager.SetEnvironment( NULL, GetGalCanvas()->GetView(), - GetGalCanvas()->GetViewControls(), this ); + GetGalCanvas()->GetViewControls(), this ); m_toolManager.ResetTools( TOOL_BASE::RUN ); // Run the selection tool, it is supposed to be always active From ba275918e3ea416fb7e04f07144ced4d1d34dc1c Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 4 Apr 2014 11:56:04 +0200 Subject: [PATCH 113/134] Renamed [class_]drawpanel_gal.[cpp|h] to [class_]draw_panel_gal.[cpp|h] to follow current naming scheme. --- common/CMakeLists.txt | 2 +- common/draw_frame.cpp | 2 +- common/draw_panel.cpp | 2 +- common/{drawpanel_gal.cpp => draw_panel_gal.cpp} | 2 +- common/tool/tool_dispatcher.cpp | 2 +- common/tool/tool_manager.cpp | 2 +- common/zoom.cpp | 2 +- cvpcb/class_DisplayFootprintsFrame.cpp | 2 +- include/{class_drawpanel_gal.h => class_draw_panel_gal.h} | 2 +- pcbnew/basepcbframe.cpp | 2 +- pcbnew/board_undo_redo.cpp | 2 +- pcbnew/class_pcb_layer_widget.cpp | 2 +- pcbnew/dialogs/dialog_display_options.cpp | 2 +- pcbnew/dialogs/dialog_general_options.cpp | 2 +- pcbnew/drc.cpp | 2 +- pcbnew/initpcb.cpp | 2 +- pcbnew/pcbframe.cpp | 2 +- pcbnew/router/router_tool.cpp | 2 +- pcbnew/tools/pcb_tools.cpp | 2 +- pcbnew/tools/pcbnew_control.cpp | 2 +- pcbnew/tools/selection_tool.cpp | 2 +- 21 files changed, 21 insertions(+), 21 deletions(-) rename common/{drawpanel_gal.cpp => draw_panel_gal.cpp} (99%) rename include/{class_drawpanel_gal.h => class_draw_panel_gal.h} (99%) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index f6deda5e49..406e707cef 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -29,7 +29,7 @@ add_custom_target( set( GAL_SRCS # Common part - drawpanel_gal.cpp + draw_panel_gal.cpp painter.cpp worksheet_viewitem.cpp gal/graphics_abstraction_layer.cpp diff --git a/common/draw_frame.cpp b/common/draw_frame.cpp index 80230e245f..4b7f50fb81 100644 --- a/common/draw_frame.cpp +++ b/common/draw_frame.cpp @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/common/draw_panel.cpp b/common/draw_panel.cpp index 1e3adb750b..9861fbdd80 100644 --- a/common/draw_panel.cpp +++ b/common/draw_panel.cpp @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include diff --git a/common/drawpanel_gal.cpp b/common/draw_panel_gal.cpp similarity index 99% rename from common/drawpanel_gal.cpp rename to common/draw_panel_gal.cpp index 947e854fa6..67550dc3a8 100644 --- a/common/drawpanel_gal.cpp +++ b/common/draw_panel_gal.cpp @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include #include diff --git a/common/tool/tool_dispatcher.cpp b/common/tool/tool_dispatcher.cpp index f04dd2d69d..f89c7ee03f 100644 --- a/common/tool/tool_dispatcher.cpp +++ b/common/tool/tool_dispatcher.cpp @@ -31,7 +31,7 @@ #include #include -#include +#include #include #include diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index 207ee71152..eff64f267d 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -44,7 +44,7 @@ #include #include -#include +#include using boost::optional; diff --git a/common/zoom.cpp b/common/zoom.cpp index b942a33f25..b7393cd54f 100644 --- a/common/zoom.cpp +++ b/common/zoom.cpp @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/cvpcb/class_DisplayFootprintsFrame.cpp b/cvpcb/class_DisplayFootprintsFrame.cpp index f320465c8b..a43f6bdf99 100644 --- a/cvpcb/class_DisplayFootprintsFrame.cpp +++ b/cvpcb/class_DisplayFootprintsFrame.cpp @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/class_drawpanel_gal.h b/include/class_draw_panel_gal.h similarity index 99% rename from include/class_drawpanel_gal.h rename to include/class_draw_panel_gal.h index b7f92c2209..4ec05ed65d 100644 --- a/include/class_drawpanel_gal.h +++ b/include/class_draw_panel_gal.h @@ -23,7 +23,7 @@ */ /** - * @file class_drawpanel_gal.h: + * @file class_draw_panel_gal.h: * @brief EDA_DRAW_PANEL_GAL class definition. */ diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index 76c31e62a6..12d783e143 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -51,7 +51,7 @@ #include #include -#include +#include #include #include #include diff --git a/pcbnew/board_undo_redo.cpp b/pcbnew/board_undo_redo.cpp index a720b0e48a..22878bfcfc 100644 --- a/pcbnew/board_undo_redo.cpp +++ b/pcbnew/board_undo_redo.cpp @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include diff --git a/pcbnew/class_pcb_layer_widget.cpp b/pcbnew/class_pcb_layer_widget.cpp index e9a8042775..41e346a2a0 100644 --- a/pcbnew/class_pcb_layer_widget.cpp +++ b/pcbnew/class_pcb_layer_widget.cpp @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include diff --git a/pcbnew/dialogs/dialog_display_options.cpp b/pcbnew/dialogs/dialog_display_options.cpp index 1e140d94d9..5ad1e752f4 100644 --- a/pcbnew/dialogs/dialog_display_options.cpp +++ b/pcbnew/dialogs/dialog_display_options.cpp @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include diff --git a/pcbnew/dialogs/dialog_general_options.cpp b/pcbnew/dialogs/dialog_general_options.cpp index af29d9796a..b506f56e2e 100644 --- a/pcbnew/dialogs/dialog_general_options.cpp +++ b/pcbnew/dialogs/dialog_general_options.cpp @@ -43,7 +43,7 @@ #include #include -#include +#include #include #include #include diff --git a/pcbnew/drc.cpp b/pcbnew/drc.cpp index 630475ac23..dc875e47fc 100644 --- a/pcbnew/drc.cpp +++ b/pcbnew/drc.cpp @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include diff --git a/pcbnew/initpcb.cpp b/pcbnew/initpcb.cpp index ee146c2177..dba920d780 100644 --- a/pcbnew/initpcb.cpp +++ b/pcbnew/initpcb.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include #include diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index faf6e1645d..0a518104d3 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -74,7 +74,7 @@ #include #endif -#include +#include #include // Keys used in read/write config diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 2608b2d21e..a2e98f71de 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -21,7 +21,7 @@ #include #include -#include "class_drawpanel_gal.h" +#include "class_draw_panel_gal.h" #include "class_board_item.h" #include "class_board.h" diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index 154ea93d46..0decc244d7 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -31,7 +31,7 @@ #include #include -#include +#include #include #include "selection_tool.h" diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp index 0a04fc0f88..f01203178f 100644 --- a/pcbnew/tools/pcbnew_control.cpp +++ b/pcbnew/tools/pcbnew_control.cpp @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 8c3e79adbb..1b8f013a0b 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include #include From 024bf9dd847d96f15fa4844541be15f493559335 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 4 Apr 2014 12:01:30 +0200 Subject: [PATCH 114/134] Fixed GAL canvas freeze when ordered twice to change to the same GAL canvas (e.g. double F11). --- common/draw_panel_gal.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/common/draw_panel_gal.cpp b/common/draw_panel_gal.cpp index 67550dc3a8..a8c1dc0f67 100644 --- a/common/draw_panel_gal.cpp +++ b/common/draw_panel_gal.cpp @@ -194,14 +194,14 @@ void EDA_DRAW_PANEL_GAL::StopDrawing() void EDA_DRAW_PANEL_GAL::SwitchBackend( GalType aGalType ) { - // Protect from refreshing during backend switch - m_pendingRefresh = true; - m_refreshTimer.Stop(); - // Do not do anything if the currently used GAL is correct if( aGalType == m_currentGal && m_gal != NULL ) return; + // Prevent refreshing canvas during backend switch + m_pendingRefresh = true; + m_refreshTimer.Stop(); + delete m_gal; switch( aGalType ) From 14687a45a7cf171bf2862b8f826ac21929f3dddf Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 4 Apr 2014 12:56:50 +0200 Subject: [PATCH 115/134] Fixed occasional crashes on undo/redo while dragging. --- pcbnew/tools/edit_tool.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 1c84cc10c5..5be7f25396 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -111,6 +111,12 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) break; // Finish } + else if( evt->Action() == TA_UNDO_REDO ) + { + unselect = true; + break; + } + // Dispatch TOOL_ACTIONs else if( evt->Category() == TC_COMMAND ) { From 8b8e8d8f7f492776d702a11b0306f530cb279921 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 4 Apr 2014 13:03:41 +0200 Subject: [PATCH 116/134] Fixed crashes related to ratsnest on canvas change. --- pcbnew/pcbframe.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 0a518104d3..697d4f9019 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -692,6 +692,7 @@ void PCB_EDIT_FRAME::SwitchCanvas( wxCommandEvent& aEvent ) switch( id ) { case ID_MENU_CANVAS_DEFAULT: + Compile_Ratsnest( NULL, true ); UseGalCanvas( false ); break; From 89da70fe94f34a6c76542e8c93ce7350a92a3ef7 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 4 Apr 2014 15:43:30 +0200 Subject: [PATCH 117/134] Edit->Global Deletions & Edit->Cleanup Tracks and Vias work in GAL, without toggling between canvases. --- pcbnew/clean.cpp | 53 ++++++++++++++++------- pcbnew/deltrack.cpp | 7 +++ pcbnew/dialogs/dialog_global_deletion.cpp | 52 +++++++++++++++++----- pcbnew/dialogs/dialog_global_deletion.h | 33 +++++++++++--- 4 files changed, 111 insertions(+), 34 deletions(-) diff --git a/pcbnew/clean.cpp b/pcbnew/clean.cpp index e90a496bf0..9acd8215f5 100644 --- a/pcbnew/clean.cpp +++ b/pcbnew/clean.cpp @@ -38,18 +38,19 @@ #include #include #include +#include // Helper class used to clean tracks and vias -class TRACKS_CLEANER: CONNECTIONS +class TRACKS_CLEANER : CONNECTIONS { private: - BOARD * m_Brd; + BOARD* m_Brd; bool m_deleteUnconnectedTracks; bool m_mergeSegments; bool m_cleanVias; public: - TRACKS_CLEANER( BOARD * aPcb ); + TRACKS_CLEANER( BOARD* aPcb ); /** * the cleanup function. @@ -102,8 +103,7 @@ private: * merge aTrackRef and aCandidate, when possible, * i.e. when they are colinear, same width, and obviously same layer */ - TRACK* mergeCollinearSegmentIfPossible( TRACK* aTrackRef, - TRACK* aCandidate, int aEndType ); + TRACK* mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK* aCandidate, int aEndType ); }; /* Install the cleanup dialog frame to know what should be cleaned @@ -161,7 +161,7 @@ bool TRACKS_CLEANER::CleanupBoard() return modified; } -TRACKS_CLEANER::TRACKS_CLEANER( BOARD * aPcb ): CONNECTIONS( aPcb ) +TRACKS_CLEANER::TRACKS_CLEANER( BOARD* aPcb ) : CONNECTIONS( aPcb ) { m_Brd = aPcb; m_deleteUnconnectedTracks = false; @@ -177,22 +177,22 @@ void TRACKS_CLEANER::buildTrackConnectionInfo() BuildTracksCandidatesList( m_Brd->m_Track, NULL); // clear flags and variables used in cleanup - for( TRACK * track = m_Brd->m_Track; track; track = track->Next() ) + for( TRACK* track = m_Brd->m_Track; track; track = track->Next() ) { track->start = NULL; track->end = NULL; track->m_PadsConnected.clear(); - track->SetState( START_ON_PAD|END_ON_PAD|BUSY, false ); + track->SetState( START_ON_PAD | END_ON_PAD | BUSY, false ); } // Build connections info tracks to pads SearchTracksConnectedToPads(); - for( TRACK * track = m_Brd->m_Track; track; track = track->Next() ) + for( TRACK* track = m_Brd->m_Track; track; track = track->Next() ) { // Mark track if connected to pads for( unsigned jj = 0; jj < track->m_PadsConnected.size(); jj++ ) { - D_PAD * pad = track->m_PadsConnected[jj]; + D_PAD* pad = track->m_PadsConnected[jj]; if( pad->HitTest( track->GetStart() ) ) { @@ -240,6 +240,8 @@ bool TRACKS_CLEANER::clean_vias() continue; // delete via + m_Brd->GetRatsnest()->Remove( alt_track ); + alt_track->ViewRelease(); alt_track->UnLink(); delete alt_track; modified = true; @@ -258,11 +260,13 @@ bool TRACKS_CLEANER::clean_vias() // if one pad through is found, the via can be removed for( unsigned ii = 0; ii < track->m_PadsConnected.size(); ii++ ) { - D_PAD * pad = track->m_PadsConnected[ii]; + D_PAD* pad = track->m_PadsConnected[ii]; - if( (pad->GetLayerMask() & ALL_CU_LAYERS) == ALL_CU_LAYERS ) + if( ( pad->GetLayerMask() & ALL_CU_LAYERS ) == ALL_CU_LAYERS ) { // redundant: via delete it + m_Brd->GetRatsnest()->Remove( track ); + track->ViewRelease(); track->UnLink(); delete track; modified = true; @@ -291,7 +295,8 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() { item_erased = false; TRACK* next_track; - for( TRACK * track = m_Brd->m_Track; track ; track = next_track ) + + for( TRACK* track = m_Brd->m_Track; track ; track = next_track ) { next_track = track->Next(); @@ -312,7 +317,7 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() LAYER_NUM top_layer, bottom_layer; ZONE_CONTAINER* zone; - if( (type_end & START_ON_PAD ) == 0 ) + if( ( type_end & START_ON_PAD ) == 0 ) { TRACK* other = track->GetTrace( m_Brd->m_Track, NULL, FLG_START ); @@ -334,7 +339,7 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() } } - if( (other == NULL) && (zone == NULL) ) + if( ( other == NULL ) && ( zone == NULL ) ) { flag_erase |= 1; } @@ -422,7 +427,7 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() via->GetNetCode() ); } - if( (other == NULL) && (zone == NULL) ) + if( ( other == NULL ) && ( zone == NULL ) ) flag_erase |= 0x20; track->SetState( BUSY, false ); @@ -433,6 +438,8 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() if( flag_erase ) { // remove segment from board + m_Brd->GetRatsnest()->Remove( track ); + track->ViewRelease(); track->DeleteStructure(); // iterate, because a track connected to the deleted track // is now perhaps now not connected and should be deleted @@ -461,7 +468,11 @@ bool TRACKS_CLEANER::clean_segments() nextsegment = segment->Next(); if( segment->IsNull() ) // Length segment = 0; delete it + { + m_Brd->GetRatsnest()->Remove( segment ); + segment->ViewRelease(); segment->DeleteStructure(); + } } // Delete redundant segments, i.e. segments having the same end points @@ -493,6 +504,8 @@ bool TRACKS_CLEANER::clean_segments() // Delete redundant point if( erase ) { + m_Brd->GetRatsnest()->Remove( other ); + other->ViewRelease(); other->DeleteStructure(); modified = true; } @@ -548,6 +561,8 @@ bool TRACKS_CLEANER::clean_segments() if( segDelete ) { no_inc = 1; + m_Brd->GetRatsnest()->Remove( segDelete ); + segDelete->ViewRelease(); segDelete->DeleteStructure(); modified = true; } @@ -589,6 +604,8 @@ bool TRACKS_CLEANER::clean_segments() if( segDelete ) { no_inc = 1; + m_Brd->GetRatsnest()->Remove( segDelete ); + segDelete->ViewRelease(); segDelete->DeleteStructure(); modified = true; } @@ -688,6 +705,7 @@ TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK* aTrackRef->SetStart( aCandidate->GetEnd()); aTrackRef->start = aCandidate->end; aTrackRef->SetState( START_ON_PAD, aCandidate->GetState( END_ON_PAD) ); + aTrackRef->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); return aCandidate; } else @@ -695,6 +713,7 @@ TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK* aTrackRef->SetStart( aCandidate->GetStart() ); aTrackRef->start = aCandidate->start; aTrackRef->SetState( START_ON_PAD, aCandidate->GetState( START_ON_PAD) ); + aTrackRef->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); return aCandidate; } } @@ -711,6 +730,7 @@ TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK* aTrackRef->SetEnd( aCandidate->GetEnd() ); aTrackRef->end = aCandidate->end; aTrackRef->SetState( END_ON_PAD, aCandidate->GetState( END_ON_PAD) ); + aTrackRef->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); return aCandidate; } else @@ -718,6 +738,7 @@ TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK* aTrackRef->SetEnd( aCandidate->GetStart() ); aTrackRef->end = aCandidate->start; aTrackRef->SetState( END_ON_PAD, aCandidate->GetState( START_ON_PAD) ); + aTrackRef->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); return aCandidate; } } diff --git a/pcbnew/deltrack.cpp b/pcbnew/deltrack.cpp index a4012d76fc..42c98cd605 100644 --- a/pcbnew/deltrack.cpp +++ b/pcbnew/deltrack.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -124,6 +125,8 @@ TRACK* PCB_EDIT_FRAME::Delete_Segment( wxDC* DC, TRACK* aTrack ) DLIST* container = (DLIST*)aTrack->GetList(); wxASSERT( container ); + GetBoard()->GetRatsnest()->Remove( aTrack ); + aTrack->ViewRelease(); container->Remove( aTrack ); // redraw the area where the track was @@ -174,6 +177,8 @@ void PCB_EDIT_FRAME::Delete_net( wxDC* DC, TRACK* aTrack ) if( segm->GetNetCode() != net_code_delete ) break; + GetBoard()->GetRatsnest()->Remove( segm ); + segm->ViewRelease(); GetBoard()->m_Track.Remove( segm ); // redraw the area where the track was @@ -219,6 +224,8 @@ void PCB_EDIT_FRAME::Remove_One_Track( wxDC* DC, TRACK* pt_segm ) << TO_UTF8( TRACK::ShowState( tracksegment->GetStatus() ) ) \ << std::endl; ) + GetBoard()->GetRatsnest()->Remove( tracksegment ); + tracksegment->ViewRelease(); GetBoard()->m_Track.Remove( tracksegment ); // redraw the area where the track was diff --git a/pcbnew/dialogs/dialog_global_deletion.cpp b/pcbnew/dialogs/dialog_global_deletion.cpp index 99ff3f3e92..318da30d64 100644 --- a/pcbnew/dialogs/dialog_global_deletion.cpp +++ b/pcbnew/dialogs/dialog_global_deletion.cpp @@ -1,7 +1,27 @@ -/** - * @file dialog_global_deletion.cpp +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 1992-2014 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 */ +#include #include #include @@ -9,6 +29,7 @@ #include #include #include +#include #include #include @@ -80,14 +101,15 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete( ) } else { - if( !IsOK( this, _( "Are you sure you want to delete the selected items?" ) ) ) return; BOARD* pcb = m_Parent->GetBoard(); PICKED_ITEMS_LIST pickersList; ITEM_PICKER itemPicker( NULL, UR_DELETED ); - BOARD_ITEM* item, * nextitem; + BOARD_ITEM* item; + BOARD_ITEM* nextitem; + RN_DATA* ratsnest = pcb->GetRatsnest(); LAYER_MSK layers_filter = ALL_LAYERS; @@ -101,12 +123,13 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete( ) while( item != NULL ) { - if( GetLayerMask( item->GetLayer() ) & layers_filter ) { itemPicker.SetItem( item ); pickersList.PushItem( itemPicker ); pcb->Remove( item ); + item->ViewRelease(); + ratsnest->Remove( item ); gen_rastnest = true; } else @@ -138,6 +161,7 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete( ) { itemPicker.SetItem( item ); pickersList.PushItem( itemPicker ); + item->ViewRelease(); item->UnLink(); } } @@ -155,6 +179,7 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete( ) { itemPicker.SetItem( item ); pickersList.PushItem( itemPicker ); + item->ViewRelease(); item->UnLink(); } } @@ -162,7 +187,6 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete( ) if( m_DelModules->GetValue() ) { - for( item = pcb->m_Modules; item; item = nextitem ) { nextitem = item->Next(); @@ -173,6 +197,10 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete( ) { itemPicker.SetItem( item ); pickersList.PushItem( itemPicker ); + static_cast( item )->RunOnChildren( + boost::bind( &KIGFX::VIEW_ITEM::ViewRelease, _1 ) ); + ratsnest->Remove( item ); + item->ViewRelease(); item->UnLink(); gen_rastnest = true; } @@ -189,27 +217,29 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete( ) if( !m_TrackFilterAR->GetValue() ) track_mask_filter |= TRACK_AR; - TRACK * nexttrack; + TRACK* nexttrack; for( TRACK *track = pcb->m_Track; track != NULL; track = nexttrack ) { nexttrack = track->Next(); - if( (track->GetState( TRACK_LOCKED | TRACK_AR ) & track_mask_filter) != 0 ) + if( ( track->GetState( TRACK_LOCKED | TRACK_AR ) & track_mask_filter ) != 0 ) continue; - if( (track->GetState( TRACK_LOCKED | TRACK_AR ) == 0) && + if( ( track->GetState( TRACK_LOCKED | TRACK_AR ) == 0 ) && !m_TrackFilterNormal->GetValue() ) continue; - if( (track->Type() == PCB_VIA_T) && !m_TrackFilterVias->GetValue() ) + if( ( track->Type() == PCB_VIA_T ) && !m_TrackFilterVias->GetValue() ) continue; - if( (track->GetLayerMask() & layers_filter) == 0 ) + if( ( track->GetLayerMask() & layers_filter ) == 0 ) continue; itemPicker.SetItem( track ); pickersList.PushItem( itemPicker ); + track->ViewRelease(); + ratsnest->Remove( track ); track->UnLink(); gen_rastnest = true; } diff --git a/pcbnew/dialogs/dialog_global_deletion.h b/pcbnew/dialogs/dialog_global_deletion.h index 4742a9ea04..e38b4955b0 100644 --- a/pcbnew/dialogs/dialog_global_deletion.h +++ b/pcbnew/dialogs/dialog_global_deletion.h @@ -1,6 +1,25 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: dialog_global_deletion.h -///////////////////////////////////////////////////////////////////////////// +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 1992-2014 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 + */ #ifndef _DIALOG_GLOBAL_DELETION_H_ #define _DIALOG_GLOBAL_DELETION_H_ @@ -9,20 +28,20 @@ class DIALOG_GLOBAL_DELETION: public DIALOG_GLOBAL_DELETION_BASE { -private: - PCB_EDIT_FRAME * m_Parent; - LAYER_NUM m_currentLayer; - public: DIALOG_GLOBAL_DELETION( PCB_EDIT_FRAME* parent ); void SetCurrentLayer( LAYER_NUM aLayer ); private: + PCB_EDIT_FRAME* m_Parent; + LAYER_NUM m_currentLayer; + void OnOkClick( wxCommandEvent& event ) { AcceptPcbDelete(); EndModal(wxID_OK); } + void OnCancelClick( wxCommandEvent& event ) { EndModal(wxID_CANCEL); From b3318dad5d5e28c06cf422b58f4df7a8a4f444f6 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 4 Apr 2014 15:49:37 +0200 Subject: [PATCH 118/134] High contrast color got blueish by accident - fixed. --- common/painter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/painter.cpp b/common/painter.cpp index 7828623377..47efd47425 100644 --- a/common/painter.cpp +++ b/common/painter.cpp @@ -59,7 +59,7 @@ RENDER_SETTINGS::~RENDER_SETTINGS() void RENDER_SETTINGS::update() { - m_hiContrastColor = COLOR4D( m_hiContrastFactor, m_hiContrastFactor, m_highlightFactor, + m_hiContrastColor = COLOR4D( m_hiContrastFactor, m_hiContrastFactor, m_hiContrastFactor, m_layerOpacity ); } From 4741d5607c9e373d35845f73744b2410f08ab05c Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 4 Apr 2014 16:48:45 +0200 Subject: [PATCH 119/134] Elements visibility are updated in the GAL. --- pcbnew/pcbframe.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 697d4f9019..f602df3d53 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -980,6 +980,7 @@ bool PCB_EDIT_FRAME::IsElementVisible( int aElement ) const void PCB_EDIT_FRAME::SetElementVisibility( int aElement, bool aNewState ) { + GetGalCanvas()->GetView()->SetLayerVisible( ITEM_GAL_LAYER( aElement ), aNewState ); GetBoard()->SetElementVisibility( aElement, aNewState ); m_Layers->SetRenderState( aElement, aNewState ); } From 9a84944fba63b25a2e1b33ce77d5e81952a8b53d Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 4 Apr 2014 16:58:44 +0200 Subject: [PATCH 120/134] Corrected zone display settings for GAL. --- pcbnew/dialogs/dialog_general_options.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pcbnew/dialogs/dialog_general_options.cpp b/pcbnew/dialogs/dialog_general_options.cpp index b506f56e2e..9adc32bdf6 100644 --- a/pcbnew/dialogs/dialog_general_options.cpp +++ b/pcbnew/dialogs/dialog_general_options.cpp @@ -193,19 +193,19 @@ void PCB_EDIT_FRAME::OnSelectOptionToolbar( wxCommandEvent& event ) case ID_TB_OPTIONS_SHOW_ZONES: DisplayOpt.DisplayZonesMode = 0; - updateType = PCB_ZONE_T; + updateType = PCB_ZONE_AREA_T; m_canvas->Refresh(); break; case ID_TB_OPTIONS_SHOW_ZONES_DISABLE: DisplayOpt.DisplayZonesMode = 1; - updateType = PCB_ZONE_T; + updateType = PCB_ZONE_AREA_T; m_canvas->Refresh(); break; case ID_TB_OPTIONS_SHOW_ZONES_OUTLINES_ONLY: DisplayOpt.DisplayZonesMode = 2; - updateType = PCB_ZONE_T; + updateType = PCB_ZONE_AREA_T; m_canvas->Refresh(); break; From a6917280fe15097a7b66e270f23d284da852bcb3 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 4 Apr 2014 17:40:00 +0200 Subject: [PATCH 121/134] Added net highlighting. --- include/painter.h | 24 ++++++++++++++++++--- pcbnew/tools/selection_tool.cpp | 37 ++++++++++++++++++++++++++++++--- pcbnew/tools/selection_tool.h | 8 +++++++ 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/include/painter.h b/include/painter.h index 004c93e35e..34376d985d 100644 --- a/include/painter.h +++ b/include/painter.h @@ -109,6 +109,26 @@ public: return ( m_activeLayers.count( aLayerId ) > 0 ); } + /** + * Function GetHighlight + * Returns current highlight setting. + * @return True if highlight is enabled, false otherwise. + */ + bool GetHighlight() const + { + return m_highlightEnabled; + } + + /** + * Function GetHighlightNetCode + * Returns netcode of currently highlighted net. + * @return Netcode of currently highlighted net. + */ + int GetHighlightNetCode() const + { + return m_highlightNetcode; + } + /** * Function SetHighlight * Turns on/off highlighting - it may be done for the active layer or the specified net. @@ -119,9 +139,7 @@ public: inline void SetHighlight( bool aEnabled, int aNetcode = -1 ) { m_highlightEnabled = aEnabled; - - if( aNetcode > 0 ) - m_highlightNetcode = aNetcode; + m_highlightNetcode = aNetcode; } /** diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 1b8f013a0b..6fdc83dd4e 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -112,10 +112,17 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) // single click? Select single object else if( evt->IsClick( BUT_LEFT ) ) { - if( !m_additive ) - clearSelection(); + if( evt->Modifier( MD_CTRL ) ) + { + highlightNet( evt->Position() ); + } + else + { + if( !m_additive ) + clearSelection(); - selectSingle( evt->Position() ); + selectSingle( evt->Position() ); + } } // right click? if there is any object - show the context menu @@ -650,6 +657,30 @@ bool SELECTION_TOOL::selectionContains( const VECTOR2I& aPoint ) const } +void SELECTION_TOOL::highlightNet( const VECTOR2I& aPoint ) +{ + KIGFX::RENDER_SETTINGS* render = getView()->GetPainter()->GetSettings(); + GENERAL_COLLECTORS_GUIDE guide = getEditFrame()->GetCollectorsGuide(); + GENERAL_COLLECTOR collector; + int net = -1; + + // Find a connected item for which we are going to highlight a net + collector.Collect( getModel( PCB_T ), GENERAL_COLLECTOR::PadsTracksOrZones, + wxPoint( aPoint.x, aPoint.y ), guide ); + bool enableHighlight = ( collector.GetCount() > 0 ); + + // Obtain net code for the clicked item + if( enableHighlight ) + net = static_cast( collector[0] )->GetNetCode(); + + if( enableHighlight != render->GetHighlight() || net != render->GetHighlightNetCode() ) + { + render->SetHighlight( enableHighlight, net ); + getView()->UpdateAllLayersColor(); + } +} + + void SELECTION_TOOL::SELECTION::clear() { items.ClearItemsList(); diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h index ca46f8bbdd..609fcafda5 100644 --- a/pcbnew/tools/selection_tool.h +++ b/pcbnew/tools/selection_tool.h @@ -221,6 +221,14 @@ private: */ bool selectionContains( const VECTOR2I& aPoint ) const; + /** + * Function highlightNet() + * Looks for a BOARD_CONNECTED_ITEM in a given spot, and if one is found - it enables + * highlight for its net. + * @param aPoint is the point where an item is expected (world coordinates). + */ + void highlightNet( const VECTOR2I& aPoint ); + /// Visual representation of selection box SELECTION_AREA* m_selArea; From a0fb4ed0c1112603077b2611af7fa48577522942 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 4 Apr 2014 17:42:35 +0200 Subject: [PATCH 122/134] Bruteforce module update after a netlist reload. --- include/wxPcbStruct.h | 2 +- pcbnew/netlist.cpp | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index f382658ee3..e0334d4e6c 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -1475,7 +1475,7 @@ public: /** * Function ReadPcbNetlist - * reads \a aNetlistFileName and ppdates the footprints (load missing footprints and + * reads \a aNetlistFileName and updates the footprints (load missing footprints and * delete on demand extra footprints) on the board. * Update connectivity info, references, values and "TIME STAMP" * diff --git a/pcbnew/netlist.cpp b/pcbnew/netlist.cpp index 258bea0c8f..764b5fbe5c 100644 --- a/pcbnew/netlist.cpp +++ b/pcbnew/netlist.cpp @@ -27,9 +27,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#include #include #include #include +#include #include #include #include @@ -59,6 +61,7 @@ void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName, wxString msg; NETLIST netlist; NETLIST_READER* netlistReader; + KIGFX::VIEW* view = GetGalCanvas()->GetView(); netlist.SetIsDryRun( aIsDryRun ); netlist.SetFindByTimeStamp( aSelectByTimeStamp ); @@ -93,6 +96,16 @@ void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName, if( !netlist.IsDryRun() ) GetScreen()->ClearUndoRedoList(); + if( !netlist.IsDryRun() ) + { + // Remove old modules + for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() ) + { + module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) ); + view->Remove( module ); + } + } + netlist.SortByReference(); GetBoard()->ReplaceNetlist( netlist, aDeleteSinglePadNets, aReporter ); @@ -104,6 +117,13 @@ void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName, SetCurItem( NULL ); + // Reload modules + for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() ) + { + module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) ); + GetGalCanvas()->GetView()->Add( module ); + } + if( aDeleteUnconnectedTracks && GetBoard()->m_Track ) { // Remove erroneous tracks. This should probably pushed down to the #BOARD object. From 6fa2f060fa3bcbfbfb9aa6459da7416fd4a1518d Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 7 Apr 2014 13:32:09 +0200 Subject: [PATCH 123/134] Formatted ttl library to comply with KiCad coding policy. --- common/geometry/hetriang.cpp | 1246 +++++++------ include/ttl/halfedge/hedart.h | 175 +- include/ttl/halfedge/hetraits.h | 223 +-- include/ttl/halfedge/hetriang.h | 484 ++--- include/ttl/ttl.h | 2979 ++++++++++++++++--------------- include/ttl/ttl_util.h | 118 +- pcbnew/ratsnest_data.cpp | 34 +- pcbnew/ratsnest_data.h | 14 +- pcbnew/ratsnest_viewitem.cpp | 4 +- 9 files changed, 2707 insertions(+), 2570 deletions(-) diff --git a/common/geometry/hetriang.cpp b/common/geometry/hetriang.cpp index eb5e59ecf7..2172413966 100644 --- a/common/geometry/hetriang.cpp +++ b/common/geometry/hetriang.cpp @@ -48,685 +48,681 @@ #include #include - using namespace hed; -using namespace std; - #ifdef TTL_USE_NODE_ID - int Node::id_count = 0; + int NODE::id_count = 0; #endif //#define DEBUG_HE #ifdef DEBUG_HE #include - static void errorAndExit(char* message) { - cout << "\n!!! ERROR: "<< message << " !!!\n" << endl; exit(-1); - } +static void errorAndExit( char* aMessage ) +{ + cout << "\n!!! ERROR: "<< aMessage << " !!!\n" << endl; + exit( -1 ); +} #endif -//-------------------------------------------------------------------------------------------------- -static EdgePtr getLeadingEdgeInTriangle(const EdgePtr& e) { - EdgePtr edge = e; - - // Code: 3EF (assumes triangle) - if (!edge->isLeadingEdge()) { - edge = edge->getNextEdgeInFace(); - if (!edge->isLeadingEdge()) - edge = edge->getNextEdgeInFace(); - } - - if (!edge->isLeadingEdge()) { - return EdgePtr(); - } - - return edge; -} +static EDGE_PTR getLeadingEdgeInTriangle( const EDGE_PTR& aEdge ) +{ + EDGE_PTR edge = aEdge; + // Code: 3EF (assumes triangle) + if( !edge->IsLeadingEdge() ) + { + edge = edge->GetNextEdgeInFace(); -//-------------------------------------------------------------------------------------------------- -static void getLimits(NodesContainer::iterator first, - NodesContainer::iterator last, - int& xmin, int& ymin, - int& xmax, int& ymax) { - - xmin = ymin = std::numeric_limits::min(); - xmax = ymax = std::numeric_limits::max(); - - NodesContainer::iterator it; - for (it = first; it != last; ++it) { - xmin = min(xmin, (*it)->GetX()); - ymin = min(ymin, (*it)->GetY()); - xmax = max(xmax, (*it)->GetX()); - ymax = max(ymax, (*it)->GetY()); - } -} - - -//-------------------------------------------------------------------------------------------------- -EdgePtr Triangulation::initTwoEnclosingTriangles(NodesContainer::iterator first, - NodesContainer::iterator last) { - - int xmin, ymin, xmax, ymax; - getLimits(first, last, xmin, ymin, xmax, ymax); - - // Add 10% of range: - double fac = 10.0; - double dx = (xmax-xmin)/fac; - double dy = (ymax-ymin)/fac; - - 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 = boost::make_shared(); - EdgePtr e2d = boost::make_shared(); - - // lower triangle - EdgePtr e11 = boost::make_shared(); - EdgePtr e12 = boost::make_shared(); - - // upper triangle - EdgePtr e21 = boost::make_shared(); - EdgePtr e22 = boost::make_shared(); - - // lower triangle - e1d->setSourceNode(n3); - e1d->setNextEdgeInFace(e11); - e1d->setTwinEdge(e2d); - addLeadingEdge(e1d); - - e11->setSourceNode(n1); - e11->setNextEdgeInFace(e12); - - e12->setSourceNode(n2); - e12->setNextEdgeInFace(e1d); - - // upper triangle - e2d->setSourceNode(n1); - e2d->setNextEdgeInFace(e21); - e2d->setTwinEdge(e1d); - addLeadingEdge(e2d); - - e21->setSourceNode(n3); - e21->setNextEdgeInFace(e22); - - e22->setSourceNode(n4); - e22->setNextEdgeInFace(e2d); - - return e11; -} - - -//-------------------------------------------------------------------------------------------------- -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) { - - cleanAll(); - - EdgePtr bedge = initTwoEnclosingTriangles(first, last); - Dart dc(bedge); - - Dart d_iter = dc; - - NodesContainer::iterator it; - for (it = first; it != last; ++it) { - helper->insertNode(d_iter, *it); - } - - // In general (e.g. for the triangle based data structure), the initial dart - // may have been changed. - // It is the users responsibility to get a valid boundary dart here. - // The half-edge data structure preserves the initial dart. - // (A dart at the boundary can also be found by trying to locate a - // triangle "outside" the triangulation.) - - // Assumes rectangular domain - helper->removeRectangularBoundary(dc); -} - - -//-------------------------------------------------------------------------------------------------- -void Triangulation::removeTriangle(EdgePtr& edge) { - - EdgePtr e1 = getLeadingEdgeInTriangle(edge); - -#ifdef DEBUG_HE - if (!e1) - errorAndExit("Triangulation::removeTriangle: could not find leading edge"); -#endif - - removeLeadingEdgeFromList(e1); - // cout << "No leading edges = " << leadingEdges_.size() << endl; - // Remove the triangle - EdgePtr e2(e1->getNextEdgeInFace()); - EdgePtr e3(e2->getNextEdgeInFace()); - - e1->clear(); - e2->clear(); - e3->clear(); -} - - -//-------------------------------------------------------------------------------------------------- -void Triangulation::reverse_splitTriangle(EdgePtr& edge) { - - // Reverse operation of splitTriangle - - 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()); - le = getLeadingEdgeInTriangle(e2); -#ifdef DEBUG_HE - if (!le) - errorAndExit("Triangulation::removeTriangle: could not find leading edge"); -#endif - removeLeadingEdgeFromList(le); - - EdgePtr e3(edge->getTwinEdge()->getNextEdgeInFace()->getNextEdgeInFace()); - le = getLeadingEdgeInTriangle(e3); -#ifdef DEBUG_HE - if (!le) - errorAndExit("Triangulation::removeTriangle: could not find leading edge"); -#endif - removeLeadingEdgeFromList(le); - - // The three triangles at the node have now been removed - // 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); - e2->setNextEdgeInFace(e3); - e3->setNextEdgeInFace(e1); - addLeadingEdge(e1); -} - - -//-------------------------------------------------------------------------------------------------- -Dart Triangulation::createDart() { - - // Return an arbitrary CCW dart - return Dart(*leadingEdges_.begin()); -} - - -//-------------------------------------------------------------------------------------------------- -bool Triangulation::removeLeadingEdgeFromList(EdgePtr& leadingEdge) { - - // Remove the edge from the list of leading edges, - // but don't delete it. - // Also set flag for leading edge to false. - // Must search from start of list. Since edges are added to the - // start of the list during triangulation, this operation will - // normally be fast (when used in the triangulation algorithm) - list::iterator it; - for (it = leadingEdges_.begin(); it != leadingEdges_.end(); ++it) { - - EdgePtr edge = *it; - if (edge == leadingEdge) { - - edge->setAsLeadingEdge(false); - it = leadingEdges_.erase(it); - - return true; + if( !edge->IsLeadingEdge() ) + edge = edge->GetNextEdgeInFace(); } - } - - return false; + + if( !edge->IsLeadingEdge() ) + { + return EDGE_PTR(); + } + + return edge; } -//-------------------------------------------------------------------------------------------------- -void Triangulation::cleanAll() { - BOOST_FOREACH(EdgePtr& edge, leadingEdges_) - edge->setNextEdgeInFace(EdgePtr()); +static void getLimits( NODES_CONTAINER::iterator aFirst, NODES_CONTAINER::iterator aLast, + int& aXmin, int& aYmin, int& aXmax, int& aYmax) +{ + aXmin = aYmin = std::numeric_limits::min(); + aXmax = aYmax = std::numeric_limits::max(); + + NODES_CONTAINER::iterator it; + + for( it = aFirst; it != aLast; ++it ) + { + aXmin = std::min( aXmin, ( *it )->GetX() ); + aYmin = std::min( aYmin, ( *it )->GetY() ); + aXmax = std::max( aXmax, ( *it )->GetX() ); + aYmax = std::max( aYmax, ( *it )->GetY() ); + } } -//-------------------------------------------------------------------------------------------------- -void Triangulation::swapEdge(Dart& dart) { - swapEdge(dart.getEdge()); +EDGE_PTR TRIANGULATION::InitTwoEnclosingTriangles( NODES_CONTAINER::iterator aFirst, + NODES_CONTAINER::iterator aLast) +{ + int xmin, ymin, xmax, ymax; + getLimits( aFirst, aLast, xmin, ymin, xmax, ymax ); + + // Add 10% of range: + double fac = 10.0; + double dx = ( xmax - xmin ) / fac; + double dy = ( ymax - ymin ) / fac; + + NODE_PTR n1 = boost::make_shared( xmin - dx, ymin - dy ); + NODE_PTR n2 = boost::make_shared( xmax + dx, ymin - dy ); + NODE_PTR n3 = boost::make_shared( xmax + dx, ymax + dy ); + NODE_PTR n4 = boost::make_shared( xmin - dx, ymax + dy ); + + // diagonal + EDGE_PTR e1d = boost::make_shared(); + EDGE_PTR e2d = boost::make_shared(); + + // lower triangle + EDGE_PTR e11 = boost::make_shared(); + EDGE_PTR e12 = boost::make_shared(); + + // upper triangle + EDGE_PTR e21 = boost::make_shared(); + EDGE_PTR e22 = boost::make_shared(); + + // lower triangle + e1d->SetSourceNode( n3 ); + e1d->SetNextEdgeInFace( e11 ); + e1d->SetTwinEdge( e2d ); + addLeadingEdge( e1d ); + + e11->SetSourceNode( n1 ); + e11->SetNextEdgeInFace( e12 ); + + e12->SetSourceNode( n2 ); + e12->SetNextEdgeInFace( e1d ); + + // upper triangle + e2d->SetSourceNode( n1 ); + e2d->SetNextEdgeInFace( e21 ); + e2d->SetTwinEdge( e1d ); + addLeadingEdge( e2d ); + + e21->SetSourceNode( n3 ); + e21->SetNextEdgeInFace( e22 ); + + e22->SetSourceNode( n4 ); + e22->SetNextEdgeInFace( e2d ); + + return e11; } -//-------------------------------------------------------------------------------------------------- -void Triangulation::splitTriangle(Dart& dart, const NodePtr& point) { - EdgePtr edge = splitTriangle(dart.getEdge(), point); - dart.init(edge); +TRIANGULATION::TRIANGULATION() +{ + m_helper = new ttl::TRIANGULATION_HELPER( *this ); } -//-------------------------------------------------------------------------------------------------- -void Triangulation::reverse_splitTriangle(Dart& dart) { - reverse_splitTriangle(dart.getEdge()); +TRIANGULATION::TRIANGULATION( const TRIANGULATION& aTriangulation ) +{ + // Triangulation: Copy constructor not present + assert( false ); } -//-------------------------------------------------------------------------------------------------- -void Triangulation::removeBoundaryTriangle(Dart& d) { - removeTriangle(d.getEdge()); +TRIANGULATION::~TRIANGULATION() +{ + cleanAll(); + delete m_helper; +} + + +void TRIANGULATION::CreateDelaunay( NODES_CONTAINER::iterator aFirst, + NODES_CONTAINER::iterator aLast ) +{ + cleanAll(); + + EDGE_PTR bedge = InitTwoEnclosingTriangles( aFirst, aLast ); + DART dc( bedge ); + + DART d_iter = dc; + + NODES_CONTAINER::iterator it; + for( it = aFirst; it != aLast; ++it ) + { + m_helper->InsertNode( d_iter, *it ); + } + + // In general (e.g. for the triangle based data structure), the initial dart + // may have been changed. + // It is the users responsibility to get a valid boundary dart here. + // The half-edge data structure preserves the initial dart. + // (A dart at the boundary can also be found by trying to locate a + // triangle "outside" the triangulation.) + + // Assumes rectangular domain + m_helper->RemoveRectangularBoundary( dc ); +} + + +void TRIANGULATION::RemoveTriangle( EDGE_PTR& aEdge ) +{ + EDGE_PTR e1 = getLeadingEdgeInTriangle( aEdge ); + +#ifdef DEBUG_HE + if( !e1 ) + errorAndExit( "Triangulation::removeTriangle: could not find leading aEdge" ); +#endif + + removeLeadingEdgeFromList( e1 ); + // cout << "No leading edges = " << leadingEdges_.size() << endl; + // Remove the triangle + EDGE_PTR e2( e1->GetNextEdgeInFace() ); + EDGE_PTR e3( e2->GetNextEdgeInFace() ); + + e1->Clear(); + e2->Clear(); + e3->Clear(); +} + + +void TRIANGULATION::ReverseSplitTriangle( EDGE_PTR& aEdge ) +{ + // Reverse operation of splitTriangle + EDGE_PTR e1( aEdge->GetNextEdgeInFace() ); + EDGE_PTR le( getLeadingEdgeInTriangle( e1 ) ); +#ifdef DEBUG_HE + if (!le) + errorAndExit("Triangulation::removeTriangle: could not find leading edge"); +#endif + removeLeadingEdgeFromList( le ); + + EDGE_PTR e2( e1->GetNextEdgeInFace()->GetTwinEdge()->GetNextEdgeInFace() ); + le = getLeadingEdgeInTriangle( e2 ); +#ifdef DEBUG_HE + if (!le) + errorAndExit("Triangulation::removeTriangle: could not find leading edge"); +#endif + removeLeadingEdgeFromList( le ); + + EDGE_PTR e3( aEdge->GetTwinEdge()->GetNextEdgeInFace()->GetNextEdgeInFace() ); + le = getLeadingEdgeInTriangle( e3 ); +#ifdef DEBUG_HE + if (!le) + errorAndExit("Triangulation::removeTriangle: could not find leading edge"); +#endif + removeLeadingEdgeFromList( le ); + + // The three triangles at the node have now been removed + // 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 + EDGE_PTR estar = aEdge; + EDGE_PTR 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 ); + e2->SetNextEdgeInFace( e3 ); + e3->SetNextEdgeInFace( e1 ); + addLeadingEdge( e1 ); +} + + +DART TRIANGULATION::CreateDart() +{ + // Return an arbitrary CCW dart + return DART( *m_leadingEdges.begin() ); +} + + +bool TRIANGULATION::removeLeadingEdgeFromList( EDGE_PTR& aLeadingEdge ) +{ + // Remove the edge from the list of leading edges, + // but don't delete it. + // Also set flag for leading edge to false. + // Must search from start of list. Since edges are added to the + // start of the list during triangulation, this operation will + // normally be fast (when used in the triangulation algorithm) + std::list::iterator it; + for( it = m_leadingEdges.begin(); it != m_leadingEdges.end(); ++it ) + { + EDGE_PTR edge = *it; + + if( edge == aLeadingEdge ) + { + edge->SetAsLeadingEdge( false ); + it = m_leadingEdges.erase( it ); + + return true; + } + } + + return false; +} + + +void TRIANGULATION::cleanAll() +{ + BOOST_FOREACH( EDGE_PTR& edge, m_leadingEdges ) + edge->SetNextEdgeInFace( EDGE_PTR() ); +} + + +void TRIANGULATION::swapEdge( DART& aDart ) +{ + SwapEdge( aDart.GetEdge() ); +} + + +void TRIANGULATION::splitTriangle( DART& aDart, const NODE_PTR& aPoint ) +{ + EDGE_PTR edge = SplitTriangle( aDart.GetEdge(), aPoint ); + aDart.Init( edge ); +} + + +void TRIANGULATION::reverseSplitTriangle( DART& aDart ) +{ + ReverseSplitTriangle( aDart.GetEdge() ); +} + + +void TRIANGULATION::removeBoundaryTriangle( DART& aDart ) +{ + RemoveTriangle( aDart.GetEdge() ); } #ifdef TTL_USE_NODE_FLAG -//-------------------------------------------------------------------------------------------------- -// This is a "template" for accessing all nodes (but multiple tests) -void Triangulation::flagNodes(bool flag) const { - - list::const_iterator it; - for (it = leadingEdges_.begin(); it != leadingEdges_.end(); ++it) { - EdgePtr edge = *it; - - for (int i = 0; i < 3; ++i) { - edge->getSourceNode()->SetFlag(flag); - edge = edge->getNextEdgeInFace(); - } - } -} +void TRIANGULATION::FlagNodes( bool aFlag ) const +{ + std::list::const_iterator it; + for( it = m_leadingEdges.begin(); it != m_leadingEdges.end(); ++it ) + { + EDGE_PTR edge = *it; - -//-------------------------------------------------------------------------------------------------- -list* Triangulation::getNodes() const { - - flagNodes(false); - list* nodeList = new list; - - list::const_iterator it; - for (it = leadingEdges_.begin(); it != leadingEdges_.end(); ++it) { - EdgePtr edge = *it; - - for (int i = 0; i < 3; ++i) { - const NodePtr& node = edge->getSourceNode(); - - if (node->GetFlag() == false) { - nodeList->push_back(node); - node->SetFlag(true); - } - edge = edge->getNextEdgeInFace(); - } - } - return nodeList; -} -#endif - - -//-------------------------------------------------------------------------------------------------- -list* Triangulation::getEdges(bool skip_boundary_edges) const { - - // collect all arcs (one half edge for each arc) - // (boundary edges are also collected). - - list::const_iterator it; - list* elist = new list; - for (it = leadingEdges_.begin(); it != leadingEdges_.end(); ++it) { - EdgePtr edge = *it; - for (int i = 0; i < 3; ++i) { - EdgePtr twinedge = edge->getTwinEdge(); - // only one of the half-edges - - if ( (!twinedge && !skip_boundary_edges) || - (twinedge && ((size_t)edge.get() > (size_t)twinedge.get())) ) - elist->push_front(edge); - - edge = edge->getNextEdgeInFace(); - } - } - return elist; -} - - -//-------------------------------------------------------------------------------------------------- -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 - // Returns a half edge with source node as the new node - -// double x, y, z; -// x = point.x(); -// y = point.y(); -// z = point.z(); - - // e#_n are new edges - // e# are existing edges - // e#_n and e##_n are new twin edges - // e##_n are edges incident to the new node - - // Add the node to the structure - //NodePtr new_node(new Node(x,y,z)); - - NodePtr n1(edge->getSourceNode()); - EdgePtr e1(edge); - - EdgePtr e2(edge->getNextEdgeInFace()); - NodePtr n2(e2->getSourceNode()); - - EdgePtr e3(e2->getNextEdgeInFace()); - NodePtr n3(e3->getSourceNode()); - - 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); - e2_n->setSourceNode(n2); - e22_n->setSourceNode(point); - e3_n->setSourceNode(n3); - e33_n->setSourceNode(point); - - e1_n->setTwinEdge(e11_n); - e11_n->setTwinEdge(e1_n); - e2_n->setTwinEdge(e22_n); - e22_n->setTwinEdge(e2_n); - e3_n->setTwinEdge(e33_n); - e33_n->setTwinEdge(e3_n); - - e1_n->setNextEdgeInFace(e33_n); - e2_n->setNextEdgeInFace(e11_n); - e3_n->setNextEdgeInFace(e22_n); - - e11_n->setNextEdgeInFace(e1); - e22_n->setNextEdgeInFace(e2); - e33_n->setNextEdgeInFace(e3); - - // and update old's next edge - e1->setNextEdgeInFace(e2_n); - e2->setNextEdgeInFace(e3_n); - e3->setNextEdgeInFace(e1_n); - - // add the three new leading edges, - // Must remove the old leading edge from the list. - // Use the field telling if an edge is a leading edge - // NOTE: Must search in the list!!! - - if (e1->isLeadingEdge()) - removeLeadingEdgeFromList(e1); - else if (e2->isLeadingEdge()) - removeLeadingEdgeFromList(e2); - else if(e3->isLeadingEdge()) - removeLeadingEdgeFromList(e3); - else - assert( false ); // one of the edges should be leading - - addLeadingEdge(e1_n); - addLeadingEdge(e2_n); - addLeadingEdge(e3_n); - - // Return a half edge incident to the new node (with the new node as source node) - - return e11_n; -} - - -//-------------------------------------------------------------------------------------------------- -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 - // functions in TriangulationHelper now) - - // 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()); - - // avoid node to be dereferenced to zero and deleted - NodePtr nR(eR_2->getSourceNode()); - NodePtr nL(eL_2->getSourceNode()); - - eL->setSourceNode(nR); - eR->setSourceNode(nL); - - // and now 6 1-sewings - eL->setNextEdgeInFace(eL_2); - eL_2->setNextEdgeInFace(eR_1); - eR_1->setNextEdgeInFace(eL); - - eR->setNextEdgeInFace(eR_2); - eR_2->setNextEdgeInFace(eL_1); - eL_1->setNextEdgeInFace(eR); - - if (eL->isLeadingEdge()) - removeLeadingEdgeFromList(eL); - else if (eL_1->isLeadingEdge()) - removeLeadingEdgeFromList(eL_1); - else if (eL_2->isLeadingEdge()) - removeLeadingEdgeFromList(eL_2); - - if (eR->isLeadingEdge()) - removeLeadingEdgeFromList(eR); - else if (eR_1->isLeadingEdge()) - removeLeadingEdgeFromList(eR_1); - else if (eR_2->isLeadingEdge()) - removeLeadingEdgeFromList(eR_2); - - addLeadingEdge(eL); - addLeadingEdge(eR); -} - - -////-------------------------------------------------------------------------- -//static void printEdge(const Dart& dart, ostream& ofile) { -// -// Dart d0 = dart; -// d0.alpha0(); -// -// ofile << dart.x() << " " << dart.y() << endl; -// ofile << d0.x() << " " << d0.y() << endl; -//} - - -//-------------------------------------------------------------------------- -bool Triangulation::checkDelaunay() const { - - // ???? outputs !!!! - // ofstream os("qweND.dat"); - const list& leadingEdges = getLeadingEdges(); - - list::const_iterator it; - bool ok = true; - int noNotDelaunay = 0; - - for (it = leadingEdges.begin(); it != leadingEdges.end(); ++it) { - EdgePtr edge = *it; - - for (int i = 0; i < 3; ++i) { - EdgePtr twinedge = edge->getTwinEdge(); - - // only one of the half-edges - if (!twinedge || (size_t)edge.get() > (size_t)twinedge.get()) { - Dart dart(edge); - if (helper->swapTestDelaunay(dart)) { - noNotDelaunay++; - - //printEdge(dart,os); os << "\n"; - ok = false; - //cout << "............. not Delaunay .... " << endl; + for( int i = 0; i < 3; ++i ) + { + edge->GetSourceNode()->SetFlag( aFlag ); + edge = edge->GetNextEdgeInFace(); } - } - edge = edge->getNextEdgeInFace(); } - } - -#ifdef DEBUG_HE - cout << "!!! Triangulation is NOT Delaunay: " << noNotDelaunay << " edges\n" << endl; +} + + +std::list* TRIANGULATION::GetNodes() const +{ + FlagNodes( false ); + std::list* nodeList = new std::list; + std::list::const_iterator it; + + for( it = m_leadingEdges.begin(); it != m_leadingEdges.end(); ++it ) + { + EDGE_PTR edge = *it; + + for( int i = 0; i < 3; ++i ) + { + const NODE_PTR& node = edge->GetSourceNode(); + + if( node->GetFlag() == false ) + { + nodeList->push_back( node ); + node->SetFlag( true ); + } + edge = edge->GetNextEdgeInFace(); + } + } + return nodeList; +} #endif - - return ok; -} -//-------------------------------------------------------------------------------------------------- -void Triangulation::optimizeDelaunay() { +std::list* TRIANGULATION::GetEdges( bool aSkipBoundaryEdges ) const +{ + // collect all arcs (one half edge for each arc) + // (boundary edges are also collected). + std::list::const_iterator it; + std::list* elist = new std::list; - // This function is also present in ttl where it is implemented - // generically. - // The implementation below is tailored for the half-edge data structure, - // and is thus more efficient + for( it = m_leadingEdges.begin(); it != m_leadingEdges.end(); ++it ) + { + EDGE_PTR edge = *it; + for( int i = 0; i < 3; ++i ) + { + EDGE_PTR twinedge = edge->GetTwinEdge(); + // only one of the half-edges - // Collect all interior edges (one half edge for each arc) - bool skip_boundary_edges = true; - list* elist = getEdges(skip_boundary_edges); - - // Assumes that elist has only one half-edge for each arc. - bool cycling_check = true; - bool optimal = false; - list::const_iterator it; - while(!optimal) { - optimal = true; - for (it = elist->begin(); it != elist->end(); ++it) { - EdgePtr edge = *it; - - Dart dart(edge); - // Constrained edges should not be swapped - if (helper->swapTestDelaunay(dart, cycling_check)) { - optimal = false; - swapEdge(edge); - } + if( ( !twinedge && !aSkipBoundaryEdges ) + || ( twinedge && ( (size_t) edge.get() > (size_t) twinedge.get() ) ) ) + elist->push_front( edge ); + + edge = edge->GetNextEdgeInFace(); + } } - } - delete elist; + + return elist; } -//-------------------------------------------------------------------------------------------------- -EdgePtr Triangulation::getInteriorNode() const { - - const list& leadingEdges = getLeadingEdges(); - list::const_iterator it; - for (it = leadingEdges.begin(); it != leadingEdges.end(); ++it) { - EdgePtr edge = *it; - - // multiple checks, but only until found - for (int i = 0; i < 3; ++i) { - if (edge->getTwinEdge()) { - - if (!helper->isBoundaryNode(Dart(edge))) - return edge; - } - edge = edge->getNextEdgeInFace(); +EDGE_PTR TRIANGULATION::SplitTriangle( EDGE_PTR& aEdge, const NODE_PTR& aPoint ) +{ + // Add a node by just splitting a triangle into three triangles + // Assumes the half aEdge is located in the triangle + // Returns a half aEdge with source node as the new node + + // e#_n are new edges + // e# are existing edges + // e#_n and e##_n are new twin edges + // e##_n are edges incident to the new node + + // Add the node to the structure + //NODE_PTR new_node(new Node(x,y,z)); + + NODE_PTR n1( aEdge->GetSourceNode() ); + EDGE_PTR e1( aEdge ); + + EDGE_PTR e2( aEdge->GetNextEdgeInFace() ); + NODE_PTR n2( e2->GetSourceNode() ); + + EDGE_PTR e3( e2->GetNextEdgeInFace() ); + NODE_PTR n3( e3->GetSourceNode() ); + + EDGE_PTR e1_n = boost::make_shared(); + EDGE_PTR e11_n = boost::make_shared(); + EDGE_PTR e2_n = boost::make_shared(); + EDGE_PTR e22_n = boost::make_shared(); + EDGE_PTR e3_n = boost::make_shared(); + EDGE_PTR e33_n = boost::make_shared(); + + e1_n->SetSourceNode( n1 ); + e11_n->SetSourceNode( aPoint ); + e2_n->SetSourceNode( n2 ); + e22_n->SetSourceNode( aPoint ); + e3_n->SetSourceNode( n3 ); + e33_n->SetSourceNode( aPoint ); + + e1_n->SetTwinEdge( e11_n ); + e11_n->SetTwinEdge( e1_n ); + e2_n->SetTwinEdge( e22_n ); + e22_n->SetTwinEdge( e2_n ); + e3_n->SetTwinEdge( e33_n ); + e33_n->SetTwinEdge( e3_n ); + + e1_n->SetNextEdgeInFace( e33_n ); + e2_n->SetNextEdgeInFace( e11_n ); + e3_n->SetNextEdgeInFace( e22_n ); + + e11_n->SetNextEdgeInFace( e1 ); + e22_n->SetNextEdgeInFace( e2 ); + e33_n->SetNextEdgeInFace( e3 ); + + // and update old's next aEdge + e1->SetNextEdgeInFace( e2_n ); + e2->SetNextEdgeInFace( e3_n ); + e3->SetNextEdgeInFace( e1_n ); + + // add the three new leading edges, + // Must remove the old leading aEdge from the list. + // Use the field telling if an aEdge is a leading aEdge + // NOTE: Must search in the list!!! + + if( e1->IsLeadingEdge() ) + removeLeadingEdgeFromList( e1 ); + else if( e2->IsLeadingEdge() ) + removeLeadingEdgeFromList( e2 ); + else if( e3->IsLeadingEdge() ) + removeLeadingEdgeFromList( e3 ); + else + assert( false ); // one of the edges should be leading + + addLeadingEdge( e1_n ); + addLeadingEdge( e2_n ); + addLeadingEdge( e3_n ); + + // Return a half aEdge incident to the new node (with the new node as source node) + + return e11_n; +} + + +void TRIANGULATION::SwapEdge( EDGE_PTR& aDiagonal ) +{ + // Note that diagonal is both input and output and it is always + // kept in counterclockwise direction (this is not required by all + // functions in TriangulationHelper now) + + // Swap by rotating counterclockwise + // Use the same objects - no deletion or new objects + EDGE_PTR eL( aDiagonal ); + EDGE_PTR eR( eL->GetTwinEdge() ); + EDGE_PTR eL_1( eL->GetNextEdgeInFace() ); + EDGE_PTR eL_2( eL_1->GetNextEdgeInFace() ); + EDGE_PTR eR_1( eR->GetNextEdgeInFace() ); + EDGE_PTR eR_2( eR_1->GetNextEdgeInFace() ); + + // avoid node to be dereferenced to zero and deleted + NODE_PTR nR( eR_2->GetSourceNode() ); + NODE_PTR nL( eL_2->GetSourceNode() ); + + eL->SetSourceNode( nR ); + eR->SetSourceNode( nL ); + + // and now 6 1-sewings + eL->SetNextEdgeInFace( eL_2 ); + eL_2->SetNextEdgeInFace( eR_1 ); + eR_1->SetNextEdgeInFace( eL ); + + eR->SetNextEdgeInFace( eR_2 ); + eR_2->SetNextEdgeInFace( eL_1 ); + eL_1->SetNextEdgeInFace( eR ); + + if( eL->IsLeadingEdge() ) + removeLeadingEdgeFromList( eL ); + else if( eL_1->IsLeadingEdge() ) + removeLeadingEdgeFromList( eL_1 ); + else if( eL_2->IsLeadingEdge() ) + removeLeadingEdgeFromList( eL_2 ); + + if( eR->IsLeadingEdge() ) + removeLeadingEdgeFromList( eR ); + else if( eR_1->IsLeadingEdge() ) + removeLeadingEdgeFromList( eR_1 ); + else if( eR_2->IsLeadingEdge() ) + removeLeadingEdgeFromList( eR_2 ); + + addLeadingEdge( eL ); + addLeadingEdge( eR ); +} + + +bool TRIANGULATION::CheckDelaunay() const +{ + // ???? outputs !!!! + // ofstream os("qweND.dat"); + const std::list& leadingEdges = GetLeadingEdges(); + + std::list::const_iterator it; + bool ok = true; + int noNotDelaunay = 0; + + for( it = leadingEdges.begin(); it != leadingEdges.end(); ++it ) + { + EDGE_PTR edge = *it; + + for( int i = 0; i < 3; ++i ) + { + EDGE_PTR twinedge = edge->GetTwinEdge(); + + // only one of the half-edges + if( !twinedge || (size_t) edge.get() > (size_t) twinedge.get() ) + { + DART dart( edge ); + if( m_helper->SwapTestDelaunay( dart ) ) + { + noNotDelaunay++; + + //printEdge(dart,os); os << "\n"; + ok = false; + //cout << "............. not Delaunay .... " << endl; + } + } + + edge = edge->GetNextEdgeInFace(); + } } - } - return EdgePtr(); // no boundary nodes + +#ifdef DEBUG_HE + cout << "!!! Triangulation is NOT Delaunay: " << noNotDelaunay << " edges\n" << endl; +#endif + + return ok; } -//-------------------------------------------------------------------------------------------------- -EdgePtr Triangulation::getBoundaryEdgeInTriangle(const EdgePtr& e) const { - EdgePtr edge = e; - - if (helper->isBoundaryEdge(Dart(edge))) - return edge; +void TRIANGULATION::OptimizeDelaunay() +{ + // This function is also present in ttl where it is implemented + // generically. + // The implementation below is tailored for the half-edge data structure, + // and is thus more efficient - edge = edge->getNextEdgeInFace(); - if (helper->isBoundaryEdge(Dart(edge))) - return edge; + // Collect all interior edges (one half edge for each arc) + bool skip_boundary_edges = true; + std::list* elist = GetEdges( skip_boundary_edges ); - edge = edge->getNextEdgeInFace(); - if (helper->isBoundaryEdge(Dart(edge))) - return edge; - - return EdgePtr(); -} + // Assumes that elist has only one half-edge for each arc. + bool cycling_check = true; + bool optimal = false; + std::list::const_iterator it; + while( !optimal ) + { + optimal = true; -//-------------------------------------------------------------------------------------------------- -EdgePtr Triangulation::getBoundaryEdge() const { + for( it = elist->begin(); it != elist->end(); ++it ) + { + EDGE_PTR edge = *it; - // Get an arbitrary (CCW) boundary edge - // If the triangulation is closed, NULL is returned - - const list& leadingEdges = getLeadingEdges(); - list::const_iterator it; - EdgePtr edge; - - for (it = leadingEdges.begin(); it != leadingEdges.end(); ++it) { - edge = getBoundaryEdgeInTriangle(*it); - - if (edge) - return edge; - } - return EdgePtr(); -} - - -//-------------------------------------------------------------------------------------------------- -void Triangulation::printEdges(ofstream& os) const { - - // Print source node and target node for each edge face by face, - // but only one of the half-edges. - - const list& leadingEdges = getLeadingEdges(); - list::const_iterator it; - for (it = leadingEdges.begin(); it != leadingEdges.end(); ++it) { - EdgePtr edge = *it; - - for (int i = 0; i < 3; ++i) { - EdgePtr twinedge = edge->getTwinEdge(); - - // Print only one edge (the highest value of the pointer) - if (!twinedge || (size_t)edge.get() > (size_t)twinedge.get()) { - // Print source node and target node - NodePtr node = edge->getSourceNode(); - os << node->GetX() << " " << node->GetY() << endl; - node = edge->getTargetNode(); - os << node->GetX() << " " << node->GetY() << endl; - os << '\n'; // blank line - } - edge = edge->getNextEdgeInFace(); + DART dart( edge ); + // Constrained edges should not be swapped + if( m_helper->SwapTestDelaunay( dart, cycling_check ) ) + { + optimal = false; + SwapEdge( edge ); + } + } + } + + delete elist; +} + + +EDGE_PTR TRIANGULATION::GetInteriorNode() const +{ + const std::list& leadingEdges = GetLeadingEdges(); + std::list::const_iterator it; + + for( it = leadingEdges.begin(); it != leadingEdges.end(); ++it ) + { + EDGE_PTR edge = *it; + + // multiple checks, but only until found + for( int i = 0; i < 3; ++i ) + { + if( edge->GetTwinEdge() ) + { + if( !m_helper->IsBoundaryNode( DART( edge ) ) ) + return edge; + } + + edge = edge->GetNextEdgeInFace(); + } + } + + return EDGE_PTR(); // no boundary nodes +} + + +EDGE_PTR TRIANGULATION::GetBoundaryEdgeInTriangle( const EDGE_PTR& aEdge ) const +{ + EDGE_PTR edge = aEdge; + + if( m_helper->IsBoundaryEdge( DART( edge ) ) ) + return edge; + + edge = edge->GetNextEdgeInFace(); + if( m_helper->IsBoundaryEdge( DART( edge ) ) ) + return edge; + + edge = edge->GetNextEdgeInFace(); + if( m_helper->IsBoundaryEdge( DART( edge ) ) ) + return edge; + + return EDGE_PTR(); +} + + +EDGE_PTR TRIANGULATION::GetBoundaryEdge() const +{ + // Get an arbitrary (CCW) boundary edge + // If the triangulation is closed, NULL is returned + const std::list& leadingEdges = GetLeadingEdges(); + std::list::const_iterator it; + EDGE_PTR edge; + + for( it = leadingEdges.begin(); it != leadingEdges.end(); ++it ) + { + edge = GetBoundaryEdgeInTriangle( *it ); + + if( edge ) + return edge; + } + return EDGE_PTR(); +} + + +void TRIANGULATION::PrintEdges( std::ofstream& aOutput ) const +{ + // Print source node and target node for each edge face by face, + // but only one of the half-edges. + const std::list& leadingEdges = GetLeadingEdges(); + std::list::const_iterator it; + + for( it = leadingEdges.begin(); it != leadingEdges.end(); ++it ) + { + EDGE_PTR edge = *it; + + for( int i = 0; i < 3; ++i ) + { + EDGE_PTR twinedge = edge->GetTwinEdge(); + + // Print only one edge (the highest value of the pointer) + if( !twinedge || (size_t) edge.get() > (size_t) twinedge.get() ) + { + // Print source node and target node + NODE_PTR node = edge->GetSourceNode(); + aOutput << node->GetX() << " " << node->GetY() << std::endl; + node = edge->GetTargetNode(); + aOutput << node->GetX() << " " << node->GetY() << std::endl; + aOutput << '\n'; // blank line + } + + edge = edge->GetNextEdgeInFace(); + } } - } } diff --git a/include/ttl/halfedge/hedart.h b/include/ttl/halfedge/hedart.h index f85678963a..2749c5087c 100644 --- a/include/ttl/halfedge/hedart.h +++ b/include/ttl/halfedge/hedart.h @@ -40,111 +40,152 @@ #ifndef _HALF_EDGE_DART_ #define _HALF_EDGE_DART_ - #include +namespace hed +{ +/** + * \class Dart + * \brief \b %Dart class for the half-edge data structure. + * + * See \ref api for a detailed description of how the member functions + * should be implemented. + */ +class DART +{ + EDGE_PTR m_edge; -namespace hed { + /// Dart direction: true if dart is counterclockwise in face + bool m_dir; - - //------------------------------------------------------------------------------------------------ - // Dart class for the half-edge data structure - //------------------------------------------------------------------------------------------------ - - /** \class Dart - * \brief \b %Dart class for the half-edge data structure. - * - * See \ref api for a detailed description of how the member functions - * should be implemented. - */ - - class Dart { - - EdgePtr edge_; - bool dir_; // true if dart is counterclockwise in face - - public: +public: /// Default constructor - Dart() { dir_ = true; } + DART() + { + m_dir = true; + } /// Constructor - Dart(const EdgePtr& edge, bool dir = true) { edge_ = edge; dir_ = dir; } + DART( const EDGE_PTR& aEdge, bool aDir = true ) + { + m_edge = aEdge; + m_dir = aDir; + } /// Copy constructor - Dart(const Dart& dart) { edge_ = dart.edge_; dir_ = dart.dir_; } + DART( const DART& aDart ) + { + m_edge = aDart.m_edge; + m_dir = aDart.m_dir; + } /// Destructor - ~Dart() {} + ~DART() + { + } /// Assignment operator - Dart& operator = (const Dart& dart) { - if (this == &dart) + DART& operator=( const DART& aDart ) + { + if( this == &aDart ) + return *this; + + m_edge = aDart.m_edge; + m_dir = aDart.m_dir; + return *this; - edge_ = dart.edge_; - dir_ = dart.dir_; - return *this; } /// Comparing dart objects - bool operator==(const Dart& dart) const { - if (dart.edge_ == edge_ && dart.dir_ == dir_) - return true; - return false; + bool operator==( const DART& aDart ) const + { + return ( aDart.m_edge == m_edge && aDart.m_dir == m_dir ); } /// Comparing dart objects - bool operator!=(const Dart& dart) const { - return !(dart==*this); + bool operator!=( const DART& aDart ) const + { + return !( aDart == *this ); } /// Maps the dart to a different node - Dart& alpha0() { dir_ = !dir_; return *this; } + DART& Alpha0() + { + m_dir = !m_dir; + return *this; + } /// Maps the dart to a different edge - Dart& alpha1() { - if (dir_) { - edge_ = edge_->getNextEdgeInFace()->getNextEdgeInFace(); - dir_ = false; - } - else { - edge_ = edge_->getNextEdgeInFace(); - dir_ = true; - } - return *this; + DART& Alpha1() + { + if( m_dir ) + { + m_edge = m_edge->GetNextEdgeInFace()->GetNextEdgeInFace(); + m_dir = false; + } + else + { + m_edge = m_edge->GetNextEdgeInFace(); + m_dir = true; + } + + return *this; } /// Maps the dart to a different triangle. \b Note: the dart is not changed if it is at the boundary! - Dart& alpha2() { - if (edge_->getTwinEdge()) { - edge_ = edge_->getTwinEdge(); - dir_ = !dir_; - } - // else, the dart is at the boundary and should not be changed - return *this; + DART& Alpha2() + { + if( m_edge->GetTwinEdge() ) + { + m_edge = m_edge->GetTwinEdge(); + m_dir = !m_dir; + } + + // else, the dart is at the boundary and should not be changed + return *this; } - - // Utilities not required by TTL - // ----------------------------- - /** @name Utilities not required by TTL */ //@{ + void Init( const EDGE_PTR& aEdge, bool aDir = true ) + { + m_edge = aEdge; + m_dir = aDir; + } - void init(const EdgePtr& edge, bool dir = true) { edge_ = edge; dir_ = dir; } + double X() const + { + return GetNode()->GetX(); + } - double x() const { return getNode()->GetX(); } // x-coordinate of source node - double y() const { return getNode()->GetY(); } // y-coordinate of source node + double Y() const + { + return GetNode()->GetY(); + } - bool isCounterClockWise() const { return dir_; } + bool IsCCW() const + { + return m_dir; + } - const NodePtr& getNode() const { return dir_ ? edge_->getSourceNode() : edge_->getTargetNode(); } - const NodePtr& getOppositeNode() const { return dir_ ? edge_->getTargetNode() : edge_->getSourceNode(); } - EdgePtr& getEdge() { return edge_; } + const NODE_PTR& GetNode() const + { + return m_dir ? m_edge->GetSourceNode() : m_edge->GetTargetNode(); + } + + const NODE_PTR& GetOppositeNode() const + { + return m_dir ? m_edge->GetTargetNode() : m_edge->GetSourceNode(); + } + + EDGE_PTR& GetEdge() + { + return m_edge; + } //@} // End of Utilities not required by TTL +}; - }; - -}; // End of hed namespace +} // End of hed namespace #endif diff --git a/include/ttl/halfedge/hetraits.h b/include/ttl/halfedge/hetraits.h index e24cd0697d..04288a0ba5 100644 --- a/include/ttl/halfedge/hetraits.h +++ b/include/ttl/halfedge/hetraits.h @@ -40,136 +40,149 @@ #ifndef _HALF_EDGE_TRAITS_ #define _HALF_EDGE_TRAITS_ - #include #include - -namespace hed { - - - //------------------------------------------------------------------------------------------------ - // Traits class for the half-edge data structure - //------------------------------------------------------------------------------------------------ - - /** \struct TTLtraits - * \brief \b Traits class (static struct) for the half-edge data structure. - * - * The member functions are those required by different function templates - * in the TTL. Documentation is given here to explain what actions - * should be carried out on the actual data structure as required by the functions - * in the \ref ttl namespace. - * - * The source code of \c %HeTraits.h shows how the traits class is implemented for the - * half-edge data structure. - * - * \see \ref api - * - */ - - struct TTLtraits { +namespace hed +{ +/** + * \struct TTLtraits + * \brief \b Traits class (static struct) for the half-edge data structure. + * + * The member functions are those required by different function templates + * in the TTL. Documentation is given here to explain what actions + * should be carried out on the actual data structure as required by the functions + * in the \ref ttl namespace. + * + * The source code of \c %HeTraits.h shows how the traits class is implemented for the + * half-edge data structure. + * + * \see \ref api + */ +struct TTLtraits +{ + /** + * The floating point type used in calculations involving scalar products and cross products. + */ + typedef double REAL_TYPE; - /** The floating point type used in calculations - * involving scalar products and cross products. - */ - typedef double real_type; - - - //---------------------------------------------------------------------------------------------- - // ------------------------------- Geometric Predicates Group --------------------------------- - //---------------------------------------------------------------------------------------------- - /** @name Geometric Predicates */ //@{ + /** + * Scalar product between two 2D vectors represented as darts.\n + * + * ttl_util::scalarProduct2d can be used. + */ + static REAL_TYPE ScalarProduct2D( const DART& aV1, const DART& aV2 ) + { + DART v10 = aV1; + v10.Alpha0(); - //---------------------------------------------------------------------------------------------- - /** Scalar product between two 2D vectors represented as darts.\n - * - * ttl_util::scalarProduct2d can be used. - */ - static real_type scalarProduct2d(const Dart& v1, const Dart& v2) { - Dart v10 = v1; v10.alpha0(); - Dart v20 = v2; v20.alpha0(); - return ttl_util::scalarProduct2d(v10.x()-v1.x(), v10.y()-v1.y(), - v20.x()-v2.x(), v20.y()-v2.y()); + DART v20 = aV2; + v20.Alpha0(); + + return ttl_util::ScalarProduct2D( v10.X() - aV1.X(), v10.Y() - aV1.Y(), + v20.X() - aV2.X(), v20.Y() - aV2.Y() ); } + /** + * Scalar product between two 2D vectors. + * The first vector is represented by a dart \e v, and the second + * vector has direction from the source node of \e v to the point \e p.\n + * + * ttl_util::ScalarProduct2D can be used. + */ + static REAL_TYPE ScalarProduct2D( const DART& aV, const NODE_PTR& aP ) + { + DART d0 = aV; + d0.Alpha0(); - //---------------------------------------------------------------------------------------------- - /** Scalar product between two 2D vectors. - * The first vector is represented by a dart \e v, and the second - * vector has direction from the source node of \e v to the point \e p.\n - * - * ttl_util::scalarProduct2d can be used. - */ - static real_type scalarProduct2d(const Dart& v, const NodePtr& p) { - Dart d0 = v; d0.alpha0(); - return ttl_util::scalarProduct2d(d0.x() - v.x(), d0.y() - v.y(), - p->GetX() - v.x(), p->GetY() - v.y()); + return ttl_util::ScalarProduct2D( d0.X() - aV.X(), d0.Y() - aV.Y(), + aP->GetX() - aV.X(), aP->GetY() - aV.Y() ); } + /** + * Cross product between two vectors in the plane represented as darts. + * The z-component of the cross product is returned.\n + * + * ttl_util::CrossProduct2D can be used. + */ + static REAL_TYPE CrossProduct2D( const DART& aV1, const DART& aV2 ) + { + DART v10 = aV1; + v10.Alpha0(); - //---------------------------------------------------------------------------------------------- - /** Cross product between two vectors in the plane represented as darts. - * The z-component of the cross product is returned.\n - * - * ttl_util::crossProduct2d can be used. - */ - static real_type crossProduct2d(const Dart& v1, const Dart& v2) { - Dart v10 = v1; v10.alpha0(); - Dart v20 = v2; v20.alpha0(); - return ttl_util::crossProduct2d(v10.x()-v1.x(), v10.y()-v1.y(), - v20.x()-v2.x(), v20.y()-v2.y()); + DART v20 = aV2; + v20.Alpha0(); + + return ttl_util::CrossProduct2D( v10.X() - aV1.X(), v10.Y() - aV1.Y(), + v20.X() - aV2.X(), v20.Y() - aV2.Y() ); } + /** + * Cross product between two vectors in the plane. + * The first vector is represented by a dart \e v, and the second + * vector has direction from the source node of \e v to the point \e p. + * The z-component of the cross product is returned.\n + * + * ttl_util::CrossProduct2d can be used. + */ + static REAL_TYPE CrossProduct2D( const DART& aV, const NODE_PTR& aP ) + { + DART d0 = aV; + d0.Alpha0(); - //---------------------------------------------------------------------------------------------- - /** Cross product between two vectors in the plane. - * The first vector is represented by a dart \e v, and the second - * vector has direction from the source node of \e v to the point \e p. - * The z-component of the cross product is returned.\n - * - * ttl_util::crossProduct2d can be used. - */ - static real_type crossProduct2d(const Dart& v, const NodePtr& p) { - Dart d0 = v; d0.alpha0(); - return ttl_util::crossProduct2d(d0.x() - v.x(), d0.y() - v.y(), - p->GetX() - v.x(), p->GetY() - v.y()); + return ttl_util::CrossProduct2D( d0.X() - aV.X(), d0.Y() - aV.Y(), + aP->GetX() - aV.X(), aP->GetY() - aV.Y() ); } + /** + * Let \e n1 and \e n2 be the nodes associated with two darts, and let \e p + * be a point in the plane. Return a positive value if \e n1, \e n2, + * and \e p occur in counterclockwise order; a negative value if they occur + * in clockwise order; and zero if they are collinear. + */ + static REAL_TYPE Orient2D( const DART& aN1, const DART& aN2, const NODE_PTR& aP ) + { + REAL_TYPE pa[2]; + REAL_TYPE pb[2]; + REAL_TYPE pc[2]; - //---------------------------------------------------------------------------------------------- - /** Let \e n1 and \e n2 be the nodes associated with two darts, and let \e p - * be a point in the plane. Return a positive value if \e n1, \e n2, - * and \e p occur in counterclockwise order; a negative value if they occur - * in clockwise order; and zero if they are collinear. - */ - static real_type orient2d(const Dart& n1, const Dart& n2, const NodePtr& p) { - real_type pa[2]; real_type pb[2]; real_type pc[2]; - pa[0] = n1.x(); pa[1] = n1.y(); - pb[0] = n2.x(); pb[1] = n2.y(); - pc[0] = p->GetX(); pc[1] = p->GetY(); - return ttl_util::orient2dfast(pa, pb, pc); + pa[0] = aN1.X(); + pa[1] = aN1.Y(); + pb[0] = aN2.X(); + pb[1] = aN2.Y(); + pc[0] = aP->GetX(); + pc[1] = aP->GetY(); + + return ttl_util::Orient2DFast( pa, pb, pc ); } + /** + * This is the same predicate as represented with the function above, + * but with a slighty different interface: + * The last parameter is given as a dart where the source node of the dart + * represents a point in the plane. + * This function is required for constrained triangulation. + */ + static REAL_TYPE Orient2D( const DART& aN1, const DART& aN2, const DART& aP ) + { + REAL_TYPE pa[2]; + REAL_TYPE pb[2]; + REAL_TYPE pc[2]; - //---------------------------------------------------------------------------------------------- - /** This is the same predicate as represented with the function above, - * but with a slighty different interface: - * The last parameter is given as a dart where the source node of the dart - * represents a point in the plane. - * This function is required for constrained triangulation. - */ - static real_type orient2d(const Dart& n1, const Dart& n2, const Dart& p) { - real_type pa[2]; real_type pb[2]; real_type pc[2]; - pa[0] = n1.x(); pa[1] = n1.y(); - pb[0] = n2.x(); pb[1] = n2.y(); - pc[0] = p.x(); pc[1] = p.y(); - return ttl_util::orient2dfast(pa, pb, pc); + pa[0] = aN1.X(); + pa[1] = aN1.Y(); + pb[0] = aN2.X(); + pb[1] = aN2.Y(); + pc[0] = aP.X(); + pc[1] = aP.Y(); + + return ttl_util::Orient2DFast( pa, pb, pc ); } //@} // End of Geometric Predicates Group - }; +}; }; // End of hed namespace diff --git a/include/ttl/halfedge/hetriang.h b/include/ttl/halfedge/hetriang.h index 2c5380864e..f84c542e5a 100644 --- a/include/ttl/halfedge/hetriang.h +++ b/include/ttl/halfedge/hetriang.h @@ -42,11 +42,9 @@ #ifndef _HE_TRIANG_H_ #define _HE_TRIANG_H_ - #define TTL_USE_NODE_ID // Each node gets it's own unique id #define TTL_USE_NODE_FLAG // Each node gets a flag (can be set to true or false) - #include #include #include @@ -55,43 +53,40 @@ #include #include -namespace ttl { - class TriangulationHelper; +namespace ttl +{ + class TRIANGULATION_HELPER; }; -//-------------------------------------------------------------------------------------------------- -// The half-edge data structure -//-------------------------------------------------------------------------------------------------- - -namespace hed { - // Helper typedefs - class Node; - class Edge; - typedef boost::shared_ptr NodePtr; - typedef boost::shared_ptr EdgePtr; - typedef boost::weak_ptr EdgeWeakPtr; - typedef std::vector NodesContainer; - - //------------------------------------------------------------------------------------------------ - // Node class for data structures - //------------------------------------------------------------------------------------------------ - - /** \class Node - * \brief \b Node class for data structures (Inherits from HandleId) - * - * \note - * - To enable node IDs, TTL_USE_NODE_ID must be defined. - * - To enable node flags, TTL_USE_NODE_FLAG must be defined. - * - TTL_USE_NODE_ID and TTL_USE_NODE_FLAG should only be enabled if this functionality is - * required by the application, because they increase the memory usage for each Node object. - */ - - class Node { +/** + * The half-edge data structure + */ +namespace hed +{ +// Helper typedefs +class NODE; +class EDGE; +typedef boost::shared_ptr NODE_PTR; +typedef boost::shared_ptr EDGE_PTR; +typedef boost::weak_ptr EDGE_WEAK_PTR; +typedef std::vector NODES_CONTAINER; +/** + * \class NODE + * \brief \b Node class for data structures (Inherits from HandleId) + * + * \note + * - To enable node IDs, TTL_USE_NODE_ID must be defined. + * - To enable node flags, TTL_USE_NODE_FLAG must be defined. + * - TTL_USE_NODE_ID and TTL_USE_NODE_FLAG should only be enabled if this functionality is + * required by the application, because they increase the memory usage for each Node object. + */ +class NODE +{ protected: #ifdef TTL_USE_NODE_FLAG /// TTL_USE_NODE_FLAG must be defined - bool flag_; + bool m_flag; #endif #ifdef TTL_USE_NODE_ID @@ -99,303 +94,378 @@ protected: static int id_count; /// A unique id for each node (TTL_USE_NODE_ID must be defined) - int id_; + int m_id; #endif - int x_, y_; + /// Node coordinates + int m_x, m_y; - unsigned int refCount_; + /// Reference count + unsigned int m_refCount; public: /// Constructor - Node( int x = 0, int y = 0 ) : + NODE( int aX = 0, int aY = 0 ) : #ifdef TTL_USE_NODE_FLAG - flag_( false ), + m_flag( false ), #endif #ifdef TTL_USE_NODE_ID - id_( id_count++ ), + m_id( id_count++ ), #endif - x_( x ), y_( y ), refCount_( 0 ) {} + m_x( aX ), m_y( aY ), m_refCount( 0 ) + { + } /// Destructor - ~Node() {} + ~NODE() {} /// Returns the x-coordinate - int GetX() const { return x_; } + int GetX() const + { + return m_x; + } /// Returns the y-coordinate - int GetY() const { return y_; } + int GetY() const + { + return m_y; + } #ifdef TTL_USE_NODE_ID /// Returns the id (TTL_USE_NODE_ID must be defined) - int Id() const { return id_; } + int Id() const + { + return m_id; + } #endif #ifdef TTL_USE_NODE_FLAG /// Sets the flag (TTL_USE_NODE_FLAG must be defined) - void SetFlag(bool aFlag) { flag_ = aFlag; } + void SetFlag( bool aFlag ) + { + m_flag = aFlag; + } /// Returns the flag (TTL_USE_NODE_FLAG must be defined) - const bool& GetFlag() const { return flag_; } + const bool& GetFlag() const + { + return m_flag; + } #endif - void IncRefCount() { refCount_++; } - void DecRefCount() { refCount_--; } - unsigned int GetRefCount() const { return refCount_; } - }; // End of class Node + void IncRefCount() + { + m_refCount++; + } + + void DecRefCount() + { + m_refCount--; + } + + unsigned int GetRefCount() const + { + return m_refCount; + } +}; - //------------------------------------------------------------------------------------------------ - // Edge class in the half-edge data structure - //------------------------------------------------------------------------------------------------ - - /** \class Edge - * \brief \b %Edge class in the in the half-edge data structure. - */ - - class Edge { - public: +/** + * \class EDGE + * \brief \b %Edge class in the in the half-edge data structure. + */ +class EDGE +{ +public: /// Constructor - Edge() : weight_(0), isLeadingEdge_(false) {} + EDGE() : m_weight( 0 ), m_isLeadingEdge( false ) + { + } /// Destructor - virtual ~Edge() {} + virtual ~EDGE() + { + } /// Sets the source node - void setSourceNode(const NodePtr& node) { sourceNode_ = node; } + void SetSourceNode( const NODE_PTR& aNode ) + { + m_sourceNode = aNode; + } /// Sets the next edge in face - void setNextEdgeInFace(const EdgePtr& edge) { nextEdgeInFace_ = edge; } + void SetNextEdgeInFace( const EDGE_PTR& aEdge ) + { + m_nextEdgeInFace = aEdge; + } /// Sets the twin edge - void setTwinEdge(const EdgePtr& edge) { twinEdge_ = edge; } + void SetTwinEdge( const EDGE_PTR& aEdge ) + { + m_twinEdge = aEdge; + } /// Sets the edge as a leading edge - void setAsLeadingEdge(bool val=true) { isLeadingEdge_ = val; } + void SetAsLeadingEdge( bool aLeading = true ) + { + m_isLeadingEdge = aLeading; + } /// Checks if an edge is a leading edge - bool isLeadingEdge() const { return isLeadingEdge_; } + bool IsLeadingEdge() const + { + return m_isLeadingEdge; + } /// Returns the twin edge - EdgePtr getTwinEdge() const { return twinEdge_.lock(); }; + EDGE_PTR GetTwinEdge() const + { + return m_twinEdge.lock(); + } - void clearTwinEdge() { twinEdge_.reset(); } + void ClearTwinEdge() + { + m_twinEdge.reset(); + } /// Returns the next edge in face - const EdgePtr& getNextEdgeInFace() const { return nextEdgeInFace_; } + const EDGE_PTR& GetNextEdgeInFace() const + { + return m_nextEdgeInFace; + } /// Retuns the source node - const NodePtr& getSourceNode() const { return sourceNode_; } + const NODE_PTR& GetSourceNode() const + { + return m_sourceNode; + } /// Returns the target node - virtual const NodePtr& getTargetNode() const { return nextEdgeInFace_->getSourceNode(); } - - void setWeight( unsigned int weight ) { weight_ = weight; } - - unsigned int getWeight() const { return weight_; } - - void clear() + virtual const NODE_PTR& GetTargetNode() const { - sourceNode_.reset(); - nextEdgeInFace_.reset(); + return m_nextEdgeInFace->GetSourceNode(); + } - if( !twinEdge_.expired() ) + void SetWeight( unsigned int weight ) + { + m_weight = weight; + } + + unsigned int GetWeight() const + { + return m_weight; + } + + void Clear() + { + m_sourceNode.reset(); + m_nextEdgeInFace.reset(); + + if( !m_twinEdge.expired() ) { - twinEdge_.lock()->clearTwinEdge(); - twinEdge_.reset(); + m_twinEdge.lock()->ClearTwinEdge(); + m_twinEdge.reset(); } } - protected: - NodePtr sourceNode_; - EdgeWeakPtr twinEdge_; - EdgePtr nextEdgeInFace_; - unsigned int weight_; - bool isLeadingEdge_; - }; // End of class Edge +protected: + NODE_PTR m_sourceNode; + EDGE_WEAK_PTR m_twinEdge; + EDGE_PTR m_nextEdgeInFace; + unsigned int m_weight; + bool m_isLeadingEdge; +}; - /** \class EdgeMST - * \brief \b Specialization of %Edge class to be used for Minimum Spanning Tree algorithm. + /** + * \class EDGE_MST + * \brief \b Specialization of %EDGE class to be used for Minimum Spanning Tree algorithm. */ - class EdgeMST : public Edge - { - private: - NodePtr target_; +class EDGE_MST : public EDGE +{ +private: + NODE_PTR m_target; - public: - EdgeMST( const NodePtr& source, const NodePtr& target, unsigned int weight = 0 ) : - target_(target) - { sourceNode_ = source; weight_ = weight; } - - EdgeMST( const Edge& edge ) +public: + EDGE_MST( const NODE_PTR& aSource, const NODE_PTR& aTarget, unsigned int aWeight = 0 ) : + m_target( aTarget ) { - sourceNode_ = edge.getSourceNode(); - target_ = edge.getTargetNode(); - weight_ = edge.getWeight(); + m_sourceNode = aSource; + m_weight = aWeight; } - ~EdgeMST() {}; + EDGE_MST( const EDGE& edge ) + { + m_sourceNode = edge.GetSourceNode(); + m_target = edge.GetTargetNode(); + m_weight = edge.GetWeight(); + } + + ~EDGE_MST() + { + } /// @copydoc Edge::setSourceNode() - virtual const NodePtr& getTargetNode() const { return target_; } - }; + virtual const NODE_PTR& GetTargetNode() const + { + return m_target; + } +}; +class DART; // Forward declaration (class in this namespace) - //------------------------------------------------------------------------------------------------ - class Dart; // Forward declaration (class in this namespace) +/** + * \class TRIANGULATION + * \brief \b %Triangulation class for the half-edge data structure with adaption to TTL. + */ +class TRIANGULATION +{ +protected: + /// One half-edge for each arc + std::list m_leadingEdges; - //------------------------------------------------------------------------------------------------ - // Triangulation class in the half-edge data structure - //------------------------------------------------------------------------------------------------ + ttl::TRIANGULATION_HELPER* m_helper; - /** \class Triangulation - * \brief \b %Triangulation class for the half-edge data structure with adaption to TTL. - */ - - class Triangulation { - - protected: - std::list leadingEdges_; // one half-edge for each arc - - ttl::TriangulationHelper* helper; - - void addLeadingEdge(EdgePtr& edge) { - edge->setAsLeadingEdge(); - leadingEdges_.push_front( edge ); + void addLeadingEdge( EDGE_PTR& aEdge ) + { + aEdge->SetAsLeadingEdge(); + m_leadingEdges.push_front( aEdge ); } - bool removeLeadingEdgeFromList(EdgePtr& leadingEdge); + bool removeLeadingEdgeFromList( EDGE_PTR& aLeadingEdge ); 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); + * + *
+ * \image html swapEdge.gif + *
+ * + * \param aDart + * 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& aDart ); - /** 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, const NodePtr& point); + /** + * 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 aDart + * Output: A CCW dart incident with the new node; see the figure. + */ + void splitTriangle( DART& aDart, const NODE_PTR& aPoint ); - /** 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); + /** + * 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 reverseSplitTriangle( DART& aDart ); - /** Removes a triangle with an edge at the boundary of the triangulation - * in the actual data structure - */ - void removeBoundaryTriangle(Dart& d); + /** + * Removes a triangle with an edge at the boundary of the triangulation + * in the actual data structure + */ + void removeBoundaryTriangle( DART& aDart ); - public: +public: /// Default constructor - Triangulation(); - + TRIANGULATION(); + /// Copy constructor - Triangulation(const Triangulation& tr); + TRIANGULATION( const TRIANGULATION& aTriangulation ); /// Destructor - ~Triangulation(); - + ~TRIANGULATION(); + /// Creates a Delaunay triangulation from a set of points - void createDelaunay(NodesContainer::iterator first, - NodesContainer::iterator last); + void CreateDelaunay( NODES_CONTAINER::iterator aFirst, NODES_CONTAINER::iterator aLast ); /// Creates an initial Delaunay triangulation from two enclosing triangles // When using rectangular boundary - loop through all points and expand. // (Called from createDelaunay(...) when starting) - EdgePtr initTwoEnclosingTriangles(NodesContainer::iterator first, - NodesContainer::iterator last); - + EDGE_PTR InitTwoEnclosingTriangles( NODES_CONTAINER::iterator aFirst, + NODES_CONTAINER::iterator aLast ); // These two functions are required by TTL for Delaunay triangulation - + /// Swaps the edge associated with diagonal - void swapEdge(EdgePtr& diagonal); + void SwapEdge( EDGE_PTR& aDiagonal ); /// Splits the triangle associated with edge into three new triangles joining at point - EdgePtr splitTriangle(EdgePtr& edge, const NodePtr& point); - + EDGE_PTR SplitTriangle( EDGE_PTR& aEdge, const NODE_PTR& aPoint ); // Functions required by TTL for removing nodes in a Delaunay triangulation - + /// Removes the boundary triangle associated with edge - void removeTriangle(EdgePtr& edge); // boundary triangle required + void RemoveTriangle( EDGE_PTR& aEdge ); // boundary triangle required /// The reverse operation of removeTriangle - void reverse_splitTriangle(EdgePtr& edge); + void ReverseSplitTriangle( EDGE_PTR& aEdge ); /// Creates an arbitrary CCW dart - Dart createDart(); + DART CreateDart(); /// Returns a list of "triangles" (one leading half-edge for each triangle) - const std::list& getLeadingEdges() const { return leadingEdges_; } + const std::list& GetLeadingEdges() const + { + return m_leadingEdges; + } /// Returns the number of triangles - int noTriangles() const { return (int)leadingEdges_.size(); } - + int NoTriangles() const + { + return (int) m_leadingEdges.size(); + } + /// Returns a list of half-edges (one half-edge for each arc) - std::list* getEdges(bool skip_boundary_edges = false) const; + std::list* GetEdges( bool aSkipBoundaryEdges = false ) const; #ifdef TTL_USE_NODE_FLAG /// Sets flag in all the nodes - void flagNodes(bool flag) const; + void FlagNodes( bool aFlag ) const; /// Returns a list of nodes. This function requires TTL_USE_NODE_FLAG to be defined. \see Node. - std::list* getNodes() const; + std::list* GetNodes() const; #endif /// Swaps edges until the triangulation is Delaunay (constrained edges are not swapped) - void optimizeDelaunay(); + void OptimizeDelaunay(); /// Checks if the triangulation is Delaunay - bool checkDelaunay() const; + bool CheckDelaunay() const; /// Returns an arbitrary interior node (as the source node of the returned edge) - EdgePtr getInteriorNode() const; + EDGE_PTR GetInteriorNode() const; - EdgePtr getBoundaryEdgeInTriangle(const EdgePtr& e) const; + EDGE_PTR GetBoundaryEdgeInTriangle( const EDGE_PTR& aEdge ) const; /// Returns an arbitrary boundary edge - EdgePtr getBoundaryEdge() const; + EDGE_PTR GetBoundaryEdge() const; /// Print edges for plotting with, e.g., gnuplot - void printEdges(std::ofstream& os) const; - - friend class ttl::TriangulationHelper; - - }; // End of class Triangulation - + void PrintEdges( std::ofstream& aOutput ) const; + friend class ttl::TRIANGULATION_HELPER; +}; }; // End of hed namespace #endif diff --git a/include/ttl/ttl.h b/include/ttl/ttl.h index 7de2e7b08d..fae9a8434d 100644 --- a/include/ttl/ttl.h +++ b/include/ttl/ttl.h @@ -40,19 +40,18 @@ #ifndef _TTL_H_ #define _TTL_H_ - #include #include // Debugging #ifdef DEBUG_TTL - static void errorAndExit(char* message) { - cout << "\n!!! ERROR: " << message << " !!!\n" << endl; +static void errorAndExit( char* aMessage ) +{ + cout << "\n!!! ERROR: " << aMessage << " !!!\n" << endl; exit(-1); - } +} #endif - // Next on TOPOLOGY: // - get triangle strips // - weighted graph, algorithms using a weight (real) for each edge, @@ -63,559 +62,557 @@ // - analyze in detail locateFace: e.g. detect 0-orbit in case of infinite loop // around a node etc. - -/** \brief Main interface to TTL +/** + * \brief Main interface to TTL * -* This namespace contains the basic generic algorithms for the TTL, -* the Triangulation Template Library.\n +* This namespace contains the basic generic algorithms for the TTL, +* the Triangulation Template Library.\n * -* Examples of functionality are: -* - Incremental Delaunay triangulation -* - Constrained triangulation -* - Insert/remove nodes and constrained edges -* - Traversal operations -* - Misc. queries for extracting information for visualisation systems etc. +* Examples of functionality are: +* - Incremental Delaunay triangulation +* - Constrained triangulation +* - Insert/remove nodes and constrained edges +* - Traversal operations +* - Misc. queries for extracting information for visualisation systems etc. * -* \par General requirements and assumptions: -* - \e DartType and \e TraitsType should be implemented in accordance with the description -* in \ref api. -* - A \b "Requires:" section in the documentation of a function template -* shows which functionality is required in \e TraitsType to -* support that specific function.\n -* Functionalty required in \e DartType is the same (almost) for all -* function templates; see \ref api and the example referred to. -* - When a reference to a \e dart object is passed to a function in TTL, -* it is assumed that it is oriented \e counterclockwise (CCW) in a triangle -* unless it is explicitly mentioned that it can also be \e clockwise (CW). -* The same applies for a dart that is passed from a function in TTL to -* the users TraitsType class (or struct). -* - When an edge (represented with a dart) is swapped, it is assumed that darts -* outside the quadrilateral where the edge is a diagonal are not affected by -* the swap. Thus, \ref hed::TTLtraits::swapEdge "TraitsType::swapEdge" -* must be implemented in accordance with this rule. +* \par General requirements and assumptions: +* - \e DART_TYPE and \e TRAITS_TYPE should be implemented in accordance with the description +* in \ref api. +* - A \b "Requires:" section in the documentation of a function template +* shows which functionality is required in \e TRAITS_TYPE to +* support that specific function.\n +* Functionalty required in \e DART_TYPE is the same (almost) for all +* function templates; see \ref api and the example referred to. +* - When a reference to a \e dart object is passed to a function in TTL, +* it is assumed that it is oriented \e counterclockwise (CCW) in a triangle +* unless it is explicitly mentioned that it can also be \e clockwise (CW). +* The same applies for a dart that is passed from a function in TTL to +* the users TRAITS_TYPE class (or struct). +* - When an edge (represented with a dart) is swapped, it is assumed that darts +* outside the quadrilateral where the edge is a diagonal are not affected by +* the swap. Thus, \ref hed::TTLtraits::swapEdge "TRAITS_TYPE::swapEdge" +* must be implemented in accordance with this rule. * -* \par Glossary: -* - General terms are explained in \ref api. -* - \e CCW - counterclockwise -* - \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 get_0_orbit_interior and get_0_orbit_boundary -* - \e arc - In a triangulation an arc is equivalent with an edge +* \par Glossary: +* - General terms are explained in \ref api. +* - \e CCW - counterclockwise +* - \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 get_0_orbit_interior and get_0_orbit_boundary +* - \e arc - In a triangulation an arc is equivalent with an edge * -* \see -* \ref ttl_util and \ref api +* \see +* \ref ttl_util and \ref api * -* \author -* �yvind Hjelle, oyvindhj@ifi.uio.no +* \author +* �yvind Hjelle, oyvindhj@ifi.uio.no */ -namespace ttl { - -class TriangulationHelper +namespace ttl +{ +class TRIANGULATION_HELPER { #ifndef DOXYGEN_SHOULD_SKIP_THIS public: - TriangulationHelper(hed::Triangulation& triang) : triangulation(triang) - { - } + TRIANGULATION_HELPER( hed::TRIANGULATION& aTriang ) : + m_triangulation( aTriang ) + { + } - // Delaunay Triangulation - // ---------------------- - template - bool insertNode(DartType& dart, PointType& point); + // Delaunay Triangulation + template + bool InsertNode( DART_TYPE& aDart, POINT_TYPE& aPoint ); - template - void removeRectangularBoundary(DartType& dart); + template + void RemoveRectangularBoundary( DART_TYPE& aDart ); - template - void removeNode(DartType& dart); + template + void RemoveNode( DART_TYPE& aDart ); - template - void removeBoundaryNode(DartType& dart); + template + void RemoveBoundaryNode( DART_TYPE& aDart ); - template - void removeInteriorNode(DartType& dart); + template + void RemoveInteriorNode( DART_TYPE& aDart ); + // Topological and Geometric Queries + // --------------------------------- + template + static bool LocateFaceSimplest( const POINT_TYPE& aPoint, DART_TYPE& aDart ); - // Topological and Geometric Queries - // --------------------------------- - template - static bool locateFaceSimplest(const PointType& point, DartType& dart); + template + static bool LocateTriangle( const POINT_TYPE& aPoint, DART_TYPE& aDart ); - template - static bool locateTriangle(const PointType& point, DartType& dart); + template + static bool InTriangleSimplest( const POINT_TYPE& aPoint, const DART_TYPE& aDart ); - template - static bool inTriangleSimplest(const PointType& point, const DartType& dart); + template + static bool InTriangle( const POINT_TYPE& aPoint, const DART_TYPE& aDart ); - template - static bool inTriangle(const PointType& point, const DartType& dart); + template + static void GetBoundary( const DART_TYPE& aDart, DART_LIST_TYPE& aBoundary ); - template - static void getBoundary(const DartType& dart, DartListType& boundary); + template + static bool IsBoundaryEdge( const DART_TYPE& aDart ); - template - static bool isBoundaryEdge(const DartType& dart); + template + static bool IsBoundaryFace( const DART_TYPE& aDart ); - template - static bool isBoundaryFace(const DartType& dart); + template + static bool IsBoundaryNode( const DART_TYPE& aDart ); - template - static bool isBoundaryNode(const DartType& dart); + template + static int GetDegreeOfNode( const DART_TYPE& aDart ); - template - static int getDegreeOfNode(const DartType& dart); + template + static void Get0OrbitInterior( const DART_TYPE& aDart, DART_LIST_TYPE& aOrbit ); - template - static void get_0_orbit_interior(const DartType& dart, DartListType& orbit); + template + static void Get0OrbitBoundary( const DART_TYPE& aDart, DART_LIST_TYPE& aOrbit ); - template - static void get_0_orbit_boundary(const DartType& dart, DartListType& orbit); + template + static bool Same0Orbit( const DART_TYPE& aD1, const DART_TYPE& aD2 ); - template - static bool same_0_orbit(const DartType& d1, const DartType& d2); + template + static bool Same1Orbit( const DART_TYPE& aD1, const DART_TYPE& aD2 ); - template - static bool same_1_orbit(const DartType& d1, const DartType& d2); + template + static bool Same2Orbit( const DART_TYPE& aD1, const DART_TYPE& aD2 ); - template - static bool same_2_orbit(const DartType& d1, const DartType& d2); + template + static bool SwappableEdge( const DART_TYPE& aDart, bool aAllowDegeneracy = false ); - template - static bool swappableEdge(const DartType& dart, bool allowDegeneracy = false); + template + static void PositionAtNextBoundaryEdge( DART_TYPE& aDart ); - template - static void positionAtNextBoundaryEdge(DartType& dart); + template + static bool ConvexBoundary( const DART_TYPE& aDart ); - template - static bool convexBoundary(const DartType& dart); + // Utilities for Delaunay Triangulation + // ------------------------------------ + template + void OptimizeDelaunay( DART_LIST_TYPE& aElist ); + template + void OptimizeDelaunay( DART_LIST_TYPE& aElist, const typename DART_LIST_TYPE::iterator aEnd ); - // Utilities for Delaunay Triangulation - // ------------------------------------ - template - void optimizeDelaunay(DartListType& elist); + template + bool SwapTestDelaunay( const DART_TYPE& aDart, bool aCyclingCheck = false ) const; - template - void optimizeDelaunay(DartListType& elist, const typename DartListType::iterator end); + template + void RecSwapDelaunay( DART_TYPE& aDiagonal ); - template - bool swapTestDelaunay(const DartType& dart, bool cycling_check = false) const; + template + void SwapEdgesAwayFromInteriorNode( DART_TYPE& aDart, LIST_TYPE& aSwappedEdges ); - template - void recSwapDelaunay(DartType& diagonal); + template + void SwapEdgesAwayFromBoundaryNode( DART_TYPE& aDart, LIST_TYPE& aSwappedEdges ); - template - void swapEdgesAwayFromInteriorNode(DartType& dart, ListType& swapped_edges); + template + void SwapEdgeInList( const typename DART_LIST_TYPE::iterator& aIt, DART_LIST_TYPE& aElist ); - template - void swapEdgesAwayFromBoundaryNode(DartType& dart, ListType& swapped_edges); - - template - void swapEdgeInList(const typename DartListType::iterator& it, DartListType& elist); - - - // Constrained Triangulation - // ------------------------- - template - static DartType insertConstraint(DartType& dstart, DartType& dend, bool optimize_delaunay); + // Constrained Triangulation + // ------------------------- + template + static DART_TYPE InsertConstraint( DART_TYPE& aDStart, DART_TYPE& aDEnd, bool aOptimizeDelaunay ); private: - hed::Triangulation& triangulation; + hed::TRIANGULATION& m_triangulation; - template - void insertNodes(ForwardIterator first, ForwardIterator last, DartType& dart); + template + void insertNodes( FORWARD_ITERATOR aFirst, FORWARD_ITERATOR aLast, DART_TYPE& aDart ); - template - static bool isMemberOfFace(const TopologyElementType& topologyElement, const DartType& dart); + template + static bool isMemberOfFace( const TOPOLOGY_ELEMENT_TYPE& aTopologyElement, const DART_TYPE& aDart ); - template - static bool locateFaceWithNode(const NodeType& node, DartType& dart_iter); + template + static bool locateFaceWithNode( const NODE_TYPE& aNode, DART_TYPE& aDartIter ); - template - static void getAdjacentTriangles(const DartType& dart, DartType& t1, DartType& t2, DartType& t3); + template + static void getAdjacentTriangles( const DART_TYPE& aDart, DART_TYPE& aT1, DART_TYPE& aT2, + DART_TYPE& aT3 ); - template - static void getNeighborNodes(const DartType& dart, std::list& node_list, bool& boundary); + template + static void getNeighborNodes( const DART_TYPE& aDart, std::list& aNodeList, + bool& aBoundary ); - template - static bool degenerateTriangle(const DartType& dart); + template + static bool degenerateTriangle( const DART_TYPE& aDart ); }; #endif // DOXYGEN_SHOULD_SKIP_THIS - //------------------------------------------------------------------------------------------------ - // ------------------------------- Delaunay Triangulation Group --------------------------------- - //------------------------------------------------------------------------------------------------ - /** @name Delaunay Triangulation */ - //@{ - - //------------------------------------------------------------------------------------------------ - /** Inserts a new node in an existing Delaunay triangulation and - * swaps edges to obtain a new Delaunay triangulation. - * This is the basic function for incremental Delaunay triangulation. - * When starting from a set of points, an initial Delaunay triangulation - * 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, - * removeRectangularBoundary can be called to remove triangles - * at the boundary of the triangulation so that the boundary - * form the convex hull of the points. - * - * Note that this incremetal scheme will run much faster if the points - * have been sorted lexicographically on \e x and \e y. - * - * \param dart - * An arbitrary CCW dart in the tringulation.\n - * Output: A CCW dart incident to the new node. - * - * \param point - * A point (node) to be inserted in the triangulation. - * - * \retval bool - * \c true if \e point was inserted; \c false if not.\n - * If \e point is outside the triangulation, or the input dart is not valid, - * \c false is returned. - * - * \require - * - \ref hed::TTLtraits::splitTriangle "TraitsType::splitTriangle" (DartType&, const PointType&) - * - * \using - * - locateTriangle - * - recSwapDelaunay - * - * \note - * - For efficiency reasons \e dart should be close to the insertion \e point. - * - * \see - * removeRectangularBoundary - */ - template - bool TriangulationHelper::insertNode(DartType& dart, PointType& point) { +//@{ +/** + * Inserts a new node in an existing Delaunay triangulation and + * swaps edges to obtain a new Delaunay triangulation. + * This is the basic function for incremental Delaunay triangulation. + * When starting from a set of points, an initial Delaunay triangulation + * 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, + * removeRectangularBoundary can be called to remove triangles + * at the boundary of the triangulation so that the boundary + * form the convex hull of the points. + * + * Note that this incremetal scheme will run much faster if the points + * have been sorted lexicographically on \e x and \e y. + * + * \param aDart + * An arbitrary CCW dart in the tringulation.\n + * Output: A CCW dart incident to the new node. + * + * \param aPoint + * A point (node) to be inserted in the triangulation. + * + * \retval bool + * \c true if \e point was inserted; \c false if not.\n + * If \e point is outside the triangulation, or the input dart is not valid, + * \c false is returned. + * + * \require + * - \ref hed::TTLtraits::splitTriangle "TRAITS_TYPE::splitTriangle" (DART_TYPE&, const POINT_TYPE&) + * + * \using + * - locateTriangle + * - RecSwapDelaunay + * + * \note + * - For efficiency reasons \e dart should be close to the insertion \e point. + * + * \see + * removeRectangularBoundary + */ +template +bool TRIANGULATION_HELPER::InsertNode( DART_TYPE& aDart, POINT_TYPE& aPoint ) +{ + bool found = LocateTriangle( aPoint, aDart ); - bool found = locateTriangle(point, dart); - if (!found) { + if( !found ) + { #ifdef DEBUG_TTL - cout << "ERROR: Triangulation::insertNode: NO triangle found. /n"; + cout << "ERROR: Triangulation::insertNode: NO triangle found. /n"; #endif - return false; + return false; } - + // ??? can we hide the dart? this is not possible if one triangle only - triangulation.splitTriangle(dart, point); - - DartType d1 = dart; - d1.alpha2().alpha1().alpha2().alpha0().alpha1(); - - DartType d2 = dart; - d2.alpha1().alpha0().alpha1(); - + m_triangulation.splitTriangle( aDart, aPoint ); + + DART_TYPE d1 = aDart; + d1.Alpha2().Alpha1().Alpha2().Alpha0().Alpha1(); + + DART_TYPE d2 = aDart; + d2.Alpha1().Alpha0().Alpha1(); + // Preserve a dart as output incident to the node and CCW - DartType d3 = dart; - d3.alpha2(); - dart = d3; // and see below - //DartType dsav = d3; - d3.alpha0().alpha1(); - - //if (!TraitsType::fixedEdge(d1) && !isBoundaryEdge(d1)) { - if (!isBoundaryEdge(d1)) { - d1.alpha2(); - recSwapDelaunay(d1); + DART_TYPE d3 = aDart; + d3.Alpha2(); + aDart = d3; // and see below + //DART_TYPE dsav = d3; + d3.Alpha0().Alpha1(); + + //if (!TRAITS_TYPE::fixedEdge(d1) && !IsBoundaryEdge(d1)) { + if( !IsBoundaryEdge( d1 ) ) + { + d1.Alpha2(); + RecSwapDelaunay( d1 ); } - - //if (!TraitsType::fixedEdge(d2) && !isBoundaryEdge(d2)) { - if (!isBoundaryEdge(d2)) { - d2.alpha2(); - recSwapDelaunay(d2); + + //if (!TRAITS_TYPE::fixedEdge(d2) && !IsBoundaryEdge(d2)) { + if( !IsBoundaryEdge( d2 ) ) + { + d2.Alpha2(); + RecSwapDelaunay( d2 ); } - + // Preserve the incoming dart as output incident to the node and CCW - //d = dsav.alpha2(); - dart.alpha2(); - //if (!TraitsType::fixedEdge(d3) && !isBoundaryEdge(d3)) { - if (!isBoundaryEdge(d3)) { - d3.alpha2(); - recSwapDelaunay(d3); + //d = dsav.Alpha2(); + aDart.Alpha2(); + //if (!TRAITS_TYPE::fixedEdge(d3) && !IsBoundaryEdge(d3)) { + if( !IsBoundaryEdge( d3 ) ) + { + d3.Alpha2(); + RecSwapDelaunay( d3 ); } - + return true; - } +} +//------------------------------------------------------------------------------------------------ +// Private/Hidden function (might change later) +template +void TRIANGULATION_HELPER::insertNodes( FORWARD_ITERATOR aFirst, FORWARD_ITERATOR aLast, + DART_TYPE& aDart ) +{ - //------------------------------------------------------------------------------------------------ - // Private/Hidden function (might change later) - template - 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. - - ForwardIterator it; - for (it = first; it != last; ++it) { - insertNode(dart, **it); + + FORWARD_ITERATOR it; + for( it = aFirst; it != aLast; ++it ) + { + InsertNode( aDart, **it ); } - } +} - //------------------------------------------------------------------------------------------------ - /** Removes the rectangular boundary of a triangulation as a final step of an - * incremental Delaunay triangulation. - * The four nodes at the corners will be removed and the resulting triangulation - * will have a convex boundary and be Delaunay. - * - * \param dart - * A CCW dart at the boundary of the triangulation\n - * Output: A CCW dart at the new boundary - * - * \using - * - removeBoundaryNode - * - * \note - * - This function requires that the boundary of the triangulation is - * a rectangle with four nodes (one in each corner). - */ - template - void TriangulationHelper::removeRectangularBoundary(DartType& dart) { - - DartType d_next = dart; - DartType d_iter; - - for (int i = 0; i < 4; i++) { - d_iter = d_next; - d_next.alpha0(); - positionAtNextBoundaryEdge(d_next); - removeBoundaryNode(d_iter); +/** Removes the rectangular boundary of a triangulation as a final step of an + * incremental Delaunay triangulation. + * The four nodes at the corners will be removed and the resulting triangulation + * will have a convex boundary and be Delaunay. + * + * \param dart + * A CCW dart at the boundary of the triangulation\n + * Output: A CCW dart at the new boundary + * + * \using + * - RemoveBoundaryNode + * + * \note + * - This function requires that the boundary of the m_triangulation is + * a rectangle with four nodes (one in each corner). + */ +template +void TRIANGULATION_HELPER::RemoveRectangularBoundary( DART_TYPE& aDart ) +{ + DART_TYPE d_next = aDart; + DART_TYPE d_iter; + + for( int i = 0; i < 4; i++ ) + { + d_iter = d_next; + d_next.Alpha0(); + PositionAtNextBoundaryEdge( d_next ); + RemoveBoundaryNode( d_iter ); } - - dart = d_next; // Return a dart at the new boundary - } + aDart = d_next; // Return a dart at the new boundary +} - //------------------------------------------------------------------------------------------------ - /** Removes the node associated with \e dart and - * updates the triangulation to be Delaunay. - * - * \using - * - 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 TriangulationHelper::removeNode(DartType& dart) { - - if (isBoundaryNode(dart)) - removeBoundaryNode(dart); +/** Removes the node associated with \e dart and + * updates the triangulation to be Delaunay. + * + * \using + * - 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 TRIANGULATION_HELPER::RemoveNode( DART_TYPE& aDart ) +{ + + if( isBoundaryNode( aDart ) ) + RemoveBoundaryNode( aDart ); else - removeInteriorNode(dart); - } + RemoveInteriorNode( aDart ); +} +/** Removes the boundary node associated with \e dart and + * updates the triangulation to be Delaunay. + * + * \using + * - SwapEdgesAwayFromBoundaryNode + * - OptimizeDelaunay + * + * \require + * - \ref hed::TTLtraits::removeBoundaryTriangle "TRAITS_TYPE::removeBoundaryTriangle" (Dart&) + */ +template +void TRIANGULATION_HELPER::RemoveBoundaryNode( DART_TYPE& aDart ) +{ - //------------------------------------------------------------------------------------------------ - /** Removes the boundary node associated with \e dart and - * updates the triangulation to be Delaunay. - * - * \using - * - swapEdgesAwayFromBoundaryNode - * - optimizeDelaunay - * - * \require - * - \ref hed::TTLtraits::removeBoundaryTriangle "TraitsType::removeBoundaryTriangle" (Dart&) - */ - template - void TriangulationHelper::removeBoundaryNode(DartType& dart) { - // ... and update Delaunay // - CCW dart must be given (for remove) // - No dart is delivered back now (but this is possible if - // we assume that there is not only one triangle left in the triangulation. - + // we assume that there is not only one triangle left in the m_triangulation. + // Position at boundary edge and CCW - if (!isBoundaryEdge(dart)) { - dart.alpha1(); // ensures that next function delivers back a CCW dart (if the given dart is CCW) - positionAtNextBoundaryEdge(dart); + if( !IsBoundaryEdge( aDart ) ) + { + aDart.Alpha1(); // ensures that next function delivers back a CCW dart (if the given dart is CCW) + PositionAtNextBoundaryEdge( aDart ); } - std::list swapped_edges; - swapEdgesAwayFromBoundaryNode(dart, swapped_edges); - + std::list swapped_edges; + SwapEdgesAwayFromBoundaryNode( aDart, swapped_edges ); + // Remove boundary triangles and remove the new boundary from the list // of swapped edges, see below. - DartType d_iter = dart; - DartType dnext = dart; + DART_TYPE d_iter = aDart; + DART_TYPE dnext = aDart; bool bend = false; - while (bend == false) { - dnext.alpha1().alpha2(); - if (isBoundaryEdge(dnext)) - bend = true; // Stop when boundary - - // Generic: Also remove the new boundary from the list of swapped edges - DartType n_bedge = d_iter; - n_bedge.alpha1().alpha0().alpha1().alpha2(); // new boundary edge - - // ??? can we avoid find if we do this in swap away? - 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 - triangulation.removeBoundaryTriangle(d_iter); - d_iter = dnext; + while( bend == false ) + { + dnext.Alpha1().Alpha2(); + if( IsBoundaryEdge( dnext ) ) + bend = true; // Stop when boundary + + // Generic: Also remove the new boundary from the list of swapped edges + DART_TYPE n_bedge = d_iter; + n_bedge.Alpha1().Alpha0().Alpha1().Alpha2(); // new boundary edge + + // ??? can we avoid find if we do this in swap away? + 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 + m_triangulation.removeBoundaryTriangle( d_iter ); + d_iter = dnext; } - + // Optimize Delaunay - typedef std::list DartListType; - optimizeDelaunay(swapped_edges); - } + typedef std::list DART_LIST_TYPE; + OptimizeDelaunay( swapped_edges ); +} - //------------------------------------------------------------------------------------------------ - /** Removes the interior node associated with \e dart and - * updates the triangulation to be Delaunay. - * - * \using - * - swapEdgesAwayFromInteriorNode - * - optimizeDelaunay - * - * \require - * - \ref hed::TTLtraits::reverse_splitTriangle "TraitsType::reverse_splitTriangle" (Dart&) - * - * \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 TriangulationHelper::removeInteriorNode(DartType& dart) { - +/** Removes the interior node associated with \e dart and + * updates the triangulation to be Delaunay. + * + * \using + * - SwapEdgesAwayFromInteriorNode + * - OptimizeDelaunay + * + * \require + * - \ref hed::TTLtraits::reverse_splitTriangle "TRAITS_TYPE::reverse_splitTriangle" (Dart&) + * + * \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 TRIANGULATION_HELPER::RemoveInteriorNode( DART_TYPE& aDart ) +{ // ... and update to Delaunay. // Must allow degeneracy temporarily, see comments in swap edges away // Assumes: // - revese_splitTriangle does not affect darts // outside the resulting triangle. - + // 1) Swaps edges away from the node until degree=3 (generic) // 2) Removes the remaining 3 triangles and creates a new to fill the hole // unsplitTriangle which is required - // 3) Runs LOP on the platelet to obtain a Delaunay triangulation + // 3) Runs LOP on the platelet to obtain a Delaunay m_triangulation // (No dart is delivered as output) - + // Assumes dart is counterclockwise - - std::list swapped_edges; - swapEdgesAwayFromInteriorNode(dart, swapped_edges); - + + std::list swapped_edges; + SwapEdgesAwayFromInteriorNode( aDart, swapped_edges ); + // The reverse operation of split triangle: // Make one triangle of the three triangles at the node associated with dart - // TraitsType:: - triangulation.reverse_splitTriangle(dart); - + // TRAITS_TYPE:: + m_triangulation.reverseSplitTriangle( aDart ); + // ???? Not generic yet if we are very strict: // When calling unsplit triangle, darts at the three opposite sides may // change! // Should we hide them longer away??? This is possible since they cannot // be boundary edges. // ----> Or should we just require that they are not changed??? - + // Make the swapped-away edges Delaunay. // Note the theoretical result: if there are no edges in the list, // the triangulation is Delaunay already - - optimizeDelaunay(swapped_edges); - } - //@} // End of Delaunay Triangulation Group + OptimizeDelaunay( swapped_edges ); +} +//@} // End of Delaunay Triangulation Group - //------------------------------------------------------------------------------------------------ - // -------------------------- Topological and Geometric Queries Group --------------------------- - //------------------------------------------------------------------------------------------------ - - /** @name Topological and Geometric Queries */ - //@{ - - //------------------------------------------------------------------------------------------------ - // Private/Hidden function (might change later) - template - bool TriangulationHelper::isMemberOfFace(const TopologyElementType& topologyElement, const DartType& dart) { - +/** @name Topological and Geometric Queries */ +//@{ +//------------------------------------------------------------------------------------------------ +// Private/Hidden function (might change later) +template +bool TRIANGULATION_HELPER::isMemberOfFace( const TOPOLOGY_ELEMENT_TYPE& aTopologyElement, + const DART_TYPE& aDart ) +{ // Check if the given topology element (node, edge or face) is a member of the face // Assumes: - // - DartType::isMember(TopologyElementType) - - DartType dart_iter = dart; - do { - if (dart_iter.isMember(topologyElement)) - return true; - dart_iter.alpha0().alpha1(); - } while (dart_iter != dart); + // - DART_TYPE::isMember(TOPOLOGY_ELEMENT_TYPE) + + DART_TYPE dart_iter = aDart; + do + { + if( dart_iter.isMember( aTopologyElement ) ) + return true; + dart_iter.Alpha0().Alpha1(); + } + while( dart_iter != aDart ); + return false; - } +} - - //------------------------------------------------------------------------------------------------ - // Private/Hidden function (might change later) - template - bool TriangulationHelper::locateFaceWithNode(const NodeType& node, DartType& dart_iter) { +//------------------------------------------------------------------------------------------------ +// Private/Hidden function (might change later) +template +bool TRIANGULATION_HELPER::locateFaceWithNode( const NODE_TYPE& aNode, DART_TYPE& aDartIter ) +{ // Locate a face in the topology structure with the given node as a member // Assumes: - // - TraitsType::orient2d(DartType, DartType, NodeType) - // - DartType::isMember(NodeType) + // - TRAITS_TYPE::Orient2D(DART_TYPE, DART_TYPE, NODE_TYPE) + // - DART_TYPE::isMember(NODE_TYPE) // - Note that if false is returned, the node might still be in the // topology structure. Application programmer // should check all if by hypothesis the node is in the topology structure; - // see doc. on locateTriangle. - - bool status = locateFaceSimplest(node, dart_iter); - if (status == false) - return status; - - // True was returned from locateFaceSimplest, but if the located triangle is + // see doc. on LocateTriangle. + + bool status = LocateFaceSimplest( aNode, aDartIter ); + + if( status == false ) + return status; + + // True was returned from LocateFaceSimplest, but if the located triangle is // degenerate and the node is on the extension of the edges, // the node might still be inside. Check if node is a member and return false // if not. (Still the node might be in the topology structure, see doc. above - // and in locateTriangle(const PointType& point, DartType& dart_iter) - - return isMemberOfFace(node, dart_iter); - } + // and in locateTriangle(const POINT_TYPE& point, DART_TYPE& dart_iter) + return isMemberOfFace( aNode, aDartIter ); +} - //------------------------------------------------------------------------------------------------ - /** Locates the face containing a given point. - * It is assumed that the tessellation (e.g. a triangulation) is \e regular in the sense that - * there are no holes, the boundary is convex and there are no degenerate faces. - * - * \param point - * A point to be located - * - * \param dart - * An arbitrary CCW dart in the triangulation\n - * Output: A CCW dart in the located face - * - * \retval bool - * \c true if a face is found; \c false if not. - * - * \require - * - \ref hed::TTLtraits::orient2d "TraitsType::orient2d" (DartType&, DartType&, PointType&) - * - * \note - * - If \c false is returned, \e point may still be inside a face if the tessellation is not - * \e regular as explained above. - * - * \see - * locateTriangle - */ - template - bool TriangulationHelper::locateFaceSimplest(const PointType& point, DartType& dart) { +/** Locates the face containing a given point. + * It is assumed that the tessellation (e.g. a triangulation) is \e regular in the sense that + * there are no holes, the boundary is convex and there are no degenerate faces. + * + * \param aPoint + * A point to be located + * + * \param aDart + * An arbitrary CCW dart in the triangulation\n + * Output: A CCW dart in the located face + * + * \retval bool + * \c true if a face is found; \c false if not. + * + * \require + * - \ref hed::TTLtraits::Orient2D "TRAITS_TYPE::Orient2D" (DART_TYPE&, DART_TYPE&, POINT_TYPE&) + * + * \note + * - If \c false is returned, \e point may still be inside a face if the tessellation is not + * \e regular as explained above. + * + * \see + * LocateTriangle + */ +template +bool TRIANGULATION_HELPER::LocateFaceSimplest( const POINT_TYPE& aPoint, DART_TYPE& aDart ) +{ // 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 @@ -623,867 +620,867 @@ private: // convex faces (works for general convex faces) // Not specialized for triangles, but ok? // - // TraitsType::orint2d(PointType) is the half open half-plane defined + // TRAITS_TYPE::orint2d(POINT_TYPE) is the half open half-plane defined // by the dart: // n1 = dart.node() - // n2 = dart.alpha0().node + // n2 = dart.Alpha0().node // Only the following gives true: // ((n2->x()-n1->x())*(point.y()-n1->y()) >= (point.x()-n1->x())*(n2->y()-n1->y())) - - DartType dart_start; - dart_start = dart; - DartType dart_prev; - - DartType d0; - for (;;) { - d0 = dart; - d0.alpha0(); - if (TraitsType::orient2d(dart, d0, point) >= 0) { - dart.alpha0().alpha1(); - if (dart == dart_start) - return true; // left to all edges in face - } - else { - dart_prev = dart; - dart.alpha2(); - if (dart == dart_prev) - return false; // iteration to outside boundary - - dart_start = dart; - dart_start.alpha0(); - - dart.alpha1(); // avoid twice on same edge and ccw in next - } + + DART_TYPE dart_start; + dart_start = aDart; + DART_TYPE dart_prev; + + DART_TYPE d0; + for( ;; ) + { + d0 = aDart; + d0.Alpha0(); + + if( TRAITS_TYPE::Orient2D( aDart, d0, aPoint ) >= 0 ) + { + aDart.Alpha0().Alpha1(); + if( aDart == dart_start ) + return true; // left to all edges in face + } + else + { + dart_prev = aDart; + aDart.Alpha2(); + + if( aDart == dart_prev ) + return false; // iteration to outside boundary + + dart_start = aDart; + dart_start.Alpha0(); + + aDart.Alpha1(); // avoid twice on same edge and ccw in next + } } - } +} - //------------------------------------------------------------------------------------------------ - /** Locates the triangle containing a given point. - * It is assumed that the triangulation is \e regular in the sense that there - * are no holes and the boundary is convex. - * This function deals with degeneracy to some extent, but round-off errors may still - * lead to a wrong result if triangles are degenerate. - * - * \param point - * A point to be located - * - * \param dart - * An arbitrary CCW dart in the triangulation\n - * Output: A CCW dart in the located triangle - * - * \retval bool - * \c true if a triangle is found; \c false if not.\n - * If \e point is outside the triangulation, in which case \c false is returned, - * then the edge associated with \e dart will be at the boundary of the triangulation. - * - * \using - * - locateFaceSimplest - * - inTriangle - */ - template - bool TriangulationHelper::locateTriangle(const PointType& point, DartType& dart) { +/** Locates the triangle containing a given point. + * It is assumed that the triangulation is \e regular in the sense that there + * are no holes and the boundary is convex. + * This function deals with degeneracy to some extent, but round-off errors may still + * lead to a wrong result if triangles are degenerate. + * + * \param point + * A point to be located + * + * \param dart + * An arbitrary CCW dart in the triangulation\n + * Output: A CCW dart in the located triangle + * + * \retval bool + * \c true if a triangle is found; \c false if not.\n + * If \e point is outside the m_triangulation, in which case \c false is returned, + * then the edge associated with \e dart will be at the boundary of the m_triangulation. + * + * \using + * - LocateFaceSimplest + * - InTriangle + */ +template +bool TRIANGULATION_HELPER::LocateTriangle( const POINT_TYPE& aPoint, DART_TYPE& aDart ) +{ // 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 - + // Thus, if false is returned, the point might still be inside a triangle in // the triangulation. But this will probably only occur in the following cases: // i) There are holes in the triangulation which causes the procedure to stop. - // ii) The boundary of the triangulation is not convex. + // ii) The boundary of the m_triangulation is not convex. // ii) There might be degenerate triangles interior to the triangulation, or on the // the boundary, which in some cases might cause the procedure to stop there due // to the logic of the algorithm. - + // It is the application programmer's responsibility to check further if false is // returned. For example, if by hypothesis the point is inside a triangle // in the triangulation and and false is returned, then all triangles in the // triangulation should be checked by the application. This can be done using // the function: - // bool inTriangle(const PointType& point, const DartType& dart). - - + // bool inTriangle(const POINT_TYPE& point, const DART_TYPE& dart). + // Assumes: - // - crossProduct2d, scalarProduct2d etc., see functions called - - bool status = locateFaceSimplest(point, dart); - if (status == false) - return status; + // - CrossProduct2D, ScalarProduct2D etc., see functions called + + bool status = LocateFaceSimplest( aPoint, aDart ); + if( status == false ) + return status; + // There may be degeneracy, i.e., the point might be outside the triangle // on the extension of the edges of a degenerate triangle. - + // The next call returns true if inside a non-degenerate or a degenerate triangle, // but false if the point coincides with the "supernode" in the case where all // edges are degenerate. - return inTriangle(point, dart); - } + return InTriangle( aPoint, aDart ); +} - - //------------------------------------------------------------------------------------------------ - /** Checks if \e point is inside the triangle associated with \e dart. - * A fast and simple function that does not deal with degeneracy. - * - * \param dart - * A CCW dart in the triangle - * - * \require - * - \ref hed::TTLtraits::orient2d "TraitsType::orient2d" (DartType&, DartType&, PointType&) - * - * \see - * inTriangle for a more robust function - */ - template - bool TriangulationHelper::inTriangleSimplest(const PointType& point, const DartType& dart) { - +//------------------------------------------------------------------------------------------------ +/** Checks if \e point is inside the triangle associated with \e dart. + * A fast and simple function that does not deal with degeneracy. + * + * \param aDart + * A CCW dart in the triangle + * + * \require + * - \ref hed::TTLtraits::Orient2D "TRAITS_TYPE::Orient2D" (DART_TYPE&, DART_TYPE&, POINT_TYPE&) + * + * \see + * InTriangle for a more robust function + */ +template +bool TRIANGULATION_HELPER::InTriangleSimplest( const POINT_TYPE& aPoint, const DART_TYPE& aDart ) +{ // 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 // edges of a degenerate triangle + + DART_TYPE d_iter = aDart; + DART_TYPE d0 = d_iter; + d0.Alpha0(); - DartType d_iter = dart; - DartType d0 = d_iter; - d0.alpha0(); - if (!TraitsType::orient2d(d_iter, d0, point) >= 0) - return false; - - d_iter.alpha0().alpha1(); + if( !TRAITS_TYPE::Orient2D( d_iter, d0, aPoint ) >= 0 ) + return false; + + d_iter.Alpha0().Alpha1(); d0 = d_iter; - d0.alpha0(); - if (!TraitsType::orient2d(d_iter, d0, point) >= 0) - return false; + d0.Alpha0(); - d_iter.alpha0().alpha1(); + if( !TRAITS_TYPE::Orient2D( d_iter, d0, aPoint ) >= 0 ) + return false; + + d_iter.Alpha0().Alpha1(); d0 = d_iter; - d0.alpha0(); - if (!TraitsType::orient2d(d_iter, d0, point) >= 0) - return false; + d0.Alpha0(); + if( !TRAITS_TYPE::Orient2D( d_iter, d0, aPoint ) >= 0 ) + return false; + return true; - } +} +/** Checks if \e point is inside the triangle associated with \e dart. + * This function deals with degeneracy to some extent, but round-off errors may still + * lead to wrong result if the triangle is degenerate. + * + * \param aDart + * A CCW dart in the triangle + * + * \require + * - \ref hed::TTLtraits::CrossProduct2D "TRAITS_TYPE::CrossProduct2D" (DART_TYPE&, POINT_TYPE&) + * - \ref hed::TTLtraits::ScalarProduct2D "TRAITS_TYPE::ScalarProduct2D" (DART_TYPE&, POINT_TYPE&) + * + * \see + * InTriangleSimplest + */ +template +bool TRIANGULATION_HELPER::InTriangle( const POINT_TYPE& aPoint, const DART_TYPE& aDart ) +{ - //------------------------------------------------------------------------------------------------ - /** Checks if \e point is inside the triangle associated with \e dart. - * This function deals with degeneracy to some extent, but round-off errors may still - * lead to wrong result if the triangle is degenerate. - * - * \param dart - * A CCW dart in the triangle - * - * \require - * - \ref hed::TTLtraits::crossProduct2d "TraitsType::crossProduct2d" (DartType&, PointType&) - * - \ref hed::TTLtraits::scalarProduct2d "TraitsType::scalarProduct2d" (DartType&, PointType&) - * - * \see - * inTriangleSimplest - */ - template - 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 // notInE1 && notInE1.neghbour ? - - + // Returns true if inside (but not necessarily strictly inside) // Works for degenerate triangles, but not when all edges are degenerate, - // and the point coincides with all nodes; + // and the aPoint coincides with all nodes; // then false is always returned. - - typedef typename TraitsType::real_type real_type; - - DartType dart_iter = dart; - - real_type cr1 = TraitsType::crossProduct2d(dart_iter, point); - if (cr1 < 0) - return false; - - dart_iter.alpha0().alpha1(); - real_type cr2 = TraitsType::crossProduct2d(dart_iter, point); - - if (cr2 < 0) - return false; - - dart_iter.alpha0().alpha1(); - real_type cr3 = TraitsType::crossProduct2d(dart_iter, point); - if (cr3 < 0) - return false; - + + typedef typename TRAITS_TYPE::REAL_TYPE REAL_TYPE; + + DART_TYPE dart_iter = aDart; + + REAL_TYPE cr1 = TRAITS_TYPE::CrossProduct2D( dart_iter, aPoint ); + if( cr1 < 0 ) + return false; + + dart_iter.Alpha0().Alpha1(); + REAL_TYPE cr2 = TRAITS_TYPE::CrossProduct2D( dart_iter, aPoint ); + + if( cr2 < 0 ) + return false; + + dart_iter.Alpha0().Alpha1(); + REAL_TYPE cr3 = TRAITS_TYPE::CrossProduct2D( dart_iter, aPoint ); + if( cr3 < 0 ) + return false; + // All cross products are >= 0 // Check for degeneracy - - if (cr1 != 0 || cr2 != 0 || cr3 != 0) - return true; // inside non-degenerate face - + if( cr1 != 0 || cr2 != 0 || cr3 != 0 ) + return true; // inside non-degenerate face + // All cross-products are zero, i.e. degenerate triangle, check if inside - // Strategy: d.scalarProduct2d >= 0 && alpha0(d).d.scalarProduct2d >= 0 for one of - // the edges. But if all edges are degenerate and the point is on (all) the nodes, + // Strategy: d.ScalarProduct2D >= 0 && alpha0(d).d.ScalarProduct2D >= 0 for one of + // the edges. But if all edges are degenerate and the aPoint is on (all) the nodes, // then "false is returned". - - DartType dart_tmp = dart_iter; - real_type sc1 = TraitsType::scalarProduct2d(dart_tmp,point); - real_type sc2 = TraitsType::scalarProduct2d(dart_tmp.alpha0(), point); - - if (sc1 >= 0 && sc2 >= 0) { - // test for degenerate edge - if (sc1 != 0 || sc2 != 0) - return true; // interior to this edge or on a node (but see comment above) + + DART_TYPE dart_tmp = dart_iter; + REAL_TYPE sc1 = TRAITS_TYPE::ScalarProduct2D( dart_tmp, aPoint ); + REAL_TYPE sc2 = TRAITS_TYPE::ScalarProduct2D( dart_tmp.Alpha0(), aPoint ); + + if( sc1 >= 0 && sc2 >= 0 ) + { + // test for degenerate edge + if( sc1 != 0 || sc2 != 0 ) + return true; // interior to this edge or on a node (but see comment above) } + + dart_tmp = dart_iter.Alpha0().Alpha1(); + sc1 = TRAITS_TYPE::ScalarProduct2D( dart_tmp, aPoint ); + sc2 = TRAITS_TYPE::ScalarProduct2D( dart_tmp.Alpha0(), aPoint ); - dart_tmp = dart_iter.alpha0().alpha1(); - sc1 = TraitsType::scalarProduct2d(dart_tmp,point); - sc2 = TraitsType::scalarProduct2d(dart_tmp.alpha0(),point); - if (sc1 >= 0 && sc2 >= 0) { - // test for degenerate edge - if (sc1 != 0 || sc2 != 0) - return true; // interior to this edge or on a node (but see comment above) + if( sc1 >= 0 && sc2 >= 0 ) + { + // test for degenerate edge + if( sc1 != 0 || sc2 != 0 ) + return true; // interior to this edge or on a node (but see comment above) } + + dart_tmp = dart_iter.Alpha1(); + sc1 = TRAITS_TYPE::ScalarProduct2D( dart_tmp, aPoint ); + sc2 = TRAITS_TYPE::ScalarProduct2D( dart_tmp.Alpha0(), aPoint ); - dart_tmp = dart_iter.alpha1(); - sc1 = TraitsType::scalarProduct2d(dart_tmp,point); - sc2 = TraitsType::scalarProduct2d(dart_tmp.alpha0(),point); - if (sc1 >= 0 && sc2 >= 0) { - // test for degenerate edge - if (sc1 != 0 || sc2 != 0) - return true; // interior to this edge or on a node (but see comment above) + if( sc1 >= 0 && sc2 >= 0 ) + { + // test for degenerate edge + if( sc1 != 0 || sc2 != 0 ) + return true; // interior to this edge or on a node (but see comment above) } - + // Not on any of the edges of the degenerate triangle. - // The only possibility for the point to be "inside" is that all edges are degenerate + // The only possibility for the aPoint to be "inside" is that all edges are degenerate // and the point coincide with all nodes. So false is returned in this case. - + return false; - } +} //------------------------------------------------------------------------------------------------ - // Private/Hidden function (might change later) - template - void TriangulationHelper::getAdjacentTriangles(const DartType& dart, DartType& t1, DartType& t2, DartType& t3) { - - DartType dart_iter = dart; - +// Private/Hidden function (might change later) +template +void TRIANGULATION_HELPER::getAdjacentTriangles( const DART_TYPE& aDart, DART_TYPE& aT1, + DART_TYPE& aT2, DART_TYPE& aT3 ) +{ + + DART_TYPE dart_iter = aDart; + // add first - if (dart_iter.alpha2() != dart) { - t1 = dart_iter; - dart_iter = dart; + if( dart_iter.Alpha2() != aDart ) + { + aT1 = dart_iter; + dart_iter = aDart; } - + // add second - dart_iter.alpha0(); - dart_iter.alpha1(); - DartType dart_prev = dart_iter; - if ((dart_iter.alpha2()) != dart_prev) { - t2 = dart_iter; - dart_iter = dart_prev; + dart_iter.Alpha0(); + dart_iter.Alpha1(); + DART_TYPE dart_prev = dart_iter; + + if( ( dart_iter.Alpha2() ) != dart_prev ) + { + aT2 = dart_iter; + dart_iter = dart_prev; } - + // add third - dart_iter.alpha0(); - dart_iter.alpha1(); + dart_iter.Alpha0(); + dart_iter.Alpha1(); dart_prev = dart_iter; - if ((dart_iter.alpha2()) != dart_prev) - t3 = dart_iter; - } + if( ( dart_iter.Alpha2() ) != dart_prev ) + aT3 = dart_iter; +} - //------------------------------------------------------------------------------------------------ - /** Gets the boundary as sequence of darts, where the edges associated with the darts are boundary - * edges, given a dart with an associating edge at the boundary of a topology structure. - * The first dart in the sequence will be the given one, and the others will have the same - * orientation (CCW or CW) as the first. - * Assumes that the given dart is at the boundary. - * - * \param dart - * A dart at the boundary (CCW or CW) - * - * \param boundary - * A sequence of darts, where the associated edges are the boundary edges - * - * \require - * - DartListType::push_back (DartType&) - */ - template - void TriangulationHelper::getBoundary(const DartType& dart, DartListType& boundary) { +//------------------------------------------------------------------------------------------------ +/** Gets the boundary as sequence of darts, where the edges associated with the darts are boundary + * edges, given a dart with an associating edge at the boundary of a topology structure. + * The first dart in the sequence will be the given one, and the others will have the same + * orientation (CCW or CW) as the first. + * Assumes that the given dart is at the boundary. + * + * \param aDart + * A dart at the boundary (CCW or CW) + * + * \param aBoundary + * A sequence of darts, where the associated edges are the boundary edges + * + * \require + * - DART_LIST_TYPE::push_back (DART_TYPE&) + */ +template +void TRIANGULATION_HELPER::GetBoundary( const DART_TYPE& aDart, DART_LIST_TYPE& aBoundary ) +{ // assumes the given dart is at the boundary (by edge) - - DartType dart_iter(dart); - boundary.push_back(dart_iter); // Given dart as first element - dart_iter.alpha0(); - positionAtNextBoundaryEdge(dart_iter); - - while (dart_iter != dart) { - boundary.push_back(dart_iter); - dart_iter.alpha0(); - positionAtNextBoundaryEdge(dart_iter); + + DART_TYPE dart_iter( aDart ); + aBoundary.push_back( dart_iter ); // Given dart as first element + dart_iter.Alpha0(); + PositionAtNextBoundaryEdge( dart_iter ); + + while( dart_iter != aDart ) + { + aBoundary.push_back( dart_iter ); + dart_iter.Alpha0(); + PositionAtNextBoundaryEdge( dart_iter ); } - } +} - - //------------------------------------------------------------------------------------------------ - /* - // Asumes a fixed point (a boundary edge) is given - // - template - class boundary_1_Iterator { // i.e. "circulator" - - DartType current_; - public: - boundaryEdgeIterator(const DartType& dart) {current_ = dart;} - DartType& operator * () const {return current_;} - void operator ++ () {current_.alpha0(); positionAtNextBoundaryEdge(current_);} - }; - */ - - - //------------------------------------------------------------------------------------------------ - /** Checks if the edge associated with \e dart is at - * the boundary of the triangulation. - * - * \par Implements: - * \code - * DartType dart_iter = dart; - * if (dart_iter.alpha2() == dart) - * return true; - * else - * return false; - * \endcode - */ - template - bool TriangulationHelper::isBoundaryEdge(const DartType& dart) { +/** Checks if the edge associated with \e dart is at + * the boundary of the m_triangulation. + * + * \par Implements: + * \code + * DART_TYPE dart_iter = dart; + * if (dart_iter.Alpha2() == dart) + * return true; + * else + * return false; + * \endcode + */ +template +bool TRIANGULATION_HELPER::IsBoundaryEdge( const DART_TYPE& aDart ) +{ + DART_TYPE dart_iter = aDart; - DartType dart_iter = dart; - if (dart_iter.alpha2() == dart) - return true; - else - return false; - } - - - //------------------------------------------------------------------------------------------------ - /** Checks if the face associated with \e dart is at - * the boundary of the triangulation. - */ - template - bool TriangulationHelper::isBoundaryFace(const DartType& dart) { - - // Strategy: boundary if alpha2(d)=d - - DartType dart_iter(dart); - DartType dart_prev; - - do { - dart_prev = dart_iter; - - if (dart_iter.alpha2() == dart_prev) + if( dart_iter.Alpha2() == aDart ) return true; - else - dart_iter = dart_prev; // back again - - dart_iter.alpha0(); - dart_iter.alpha1(); - - } while (dart_iter != dart); - - return false; - } + else + return false; +} - - //------------------------------------------------------------------------------------------------ - /** Checks if the node associated with \e dart is at - * the boundary of the triangulation. - */ - template - bool TriangulationHelper::isBoundaryNode(const DartType& dart) { - +/** Checks if the face associated with \e dart is at + * the boundary of the m_triangulation. + */ +template +bool TRIANGULATION_HELPER::IsBoundaryFace( const DART_TYPE& aDart ) +{ // Strategy: boundary if alpha2(d)=d - - DartType dart_iter(dart); - DartType dart_prev; - + + DART_TYPE dart_iter( aDart ); + DART_TYPE dart_prev; + + do + { + dart_prev = dart_iter; + + if( dart_iter.Alpha2() == dart_prev ) + return true; + else + dart_iter = dart_prev; // back again + + dart_iter.Alpha0(); + dart_iter.Alpha1(); + + } while( dart_iter != aDart ); + + return false; +} + +/** Checks if the node associated with \e dart is at + * the boundary of the m_triangulation. + */ +template +bool TRIANGULATION_HELPER::IsBoundaryNode( const DART_TYPE& aDart ) +{ + // Strategy: boundary if alpha2(d)=d + + DART_TYPE dart_iter( aDart ); + DART_TYPE dart_prev; + // If input dart is reached again, then internal node // If alpha2(d)=d, then boundary - - do { - dart_iter.alpha1(); - dart_prev = dart_iter; - dart_iter.alpha2(); - - if (dart_iter == dart_prev) - return true; - - } while (dart_iter != dart); - + + do + { + dart_iter.Alpha1(); + dart_prev = dart_iter; + dart_iter.Alpha2(); + + if( dart_iter == dart_prev ) + return true; + + } while( dart_iter != aDart ); + return false; - } +} +/** Returns the degree of the node associated with \e dart. + * + * \par Definition: + * The \e degree (or valency) of a node \e V in a m_triangulation, + * is defined as the number of edges incident with \e V, i.e., + * the number of edges joining \e V with another node in the triangulation. + */ +template +int TRIANGULATION_HELPER::GetDegreeOfNode( const DART_TYPE& aDart ) +{ + DART_TYPE dart_iter( aDart ); + DART_TYPE dart_prev; - //------------------------------------------------------------------------------------------------ - /** Returns the degree of the node associated with \e dart. - * - * \par Definition: - * The \e degree (or valency) of a node \e V in a triangulation, - * is defined as the number of edges incident with \e V, i.e., - * the number of edges joining \e V with another node in the triangulation. - */ - template - int TriangulationHelper::getDegreeOfNode(const DartType& dart) { - - DartType dart_iter(dart); - DartType dart_prev; - // If input dart is reached again, then interior node // If alpha2(d)=d, then boundary - + int degree = 0; bool boundaryVisited = false; - do { - dart_iter.alpha1(); - degree++; - dart_prev = dart_iter; - - dart_iter.alpha2(); - - if (dart_iter == dart_prev) { - if (!boundaryVisited) { - boundaryVisited = true; - // boundary is reached first time, count in the reversed direction - degree++; // count the start since it is not done above - dart_iter = dart; - dart_iter.alpha2(); + do + { + dart_iter.Alpha1(); + degree++; + dart_prev = dart_iter; + + dart_iter.Alpha2(); + + if( dart_iter == dart_prev ) + { + if( !boundaryVisited ) + { + boundaryVisited = true; + // boundary is reached first time, count in the reversed direction + degree++; // count the start since it is not done above + dart_iter = aDart; + dart_iter.Alpha2(); + } else + return degree; } - else - return degree; - } - - } while (dart_iter != dart); - + + } while( dart_iter != aDart ); + return degree; - } +} +// Modification of GetDegreeOfNode: +// Strategy, reverse the list and start in the other direction if the boundary +// is reached. NB. copying of darts but ok., or we could have collected pointers, +// but the memory management. - //------------------------------------------------------------------------------------------------ - // Modification of getDegreeOfNode: - // Strategy, reverse the list and start in the other direction if the boundary - // is reached. NB. copying of darts but ok., or we could have collected pointers, - // but the memory management. - - // NOTE: not symmetry if we choose to collect opposite edges - // now we collect darts with radiating edges - - // Remember that we must also copy the node, but ok with push_back - // The size of the list will be the degree of the node - - // No CW/CCW since topology only - - - // Each dart consists of an incident edge and an adjacent node. - // But note that this is only how we interpret the dart in this implementation. - // Given this list, how can we find the opposite edges: - // We can perform alpha1 on each, but for boundary nodes we will get one edge twice. - // But this is will always be the last dart! - // The darts in the list are in sequence and starts with the alpha0(dart) - // alpha0, alpha1 and alpha2 +// NOTE: not symmetry if we choose to collect opposite edges +// now we collect darts with radiating edges - // Private/Hidden function - template - void TriangulationHelper::getNeighborNodes(const DartType& dart, - std::list& node_list, bool& boundary) { - - DartType dart_iter(dart); - - dart_iter.alpha0(); // position the dart at an opposite node - - DartType dart_prev = dart_iter; - +// Remember that we must also copy the node, but ok with push_back +// The size of the list will be the degree of the node + +// No CW/CCW since topology only + +// Each dart consists of an incident edge and an adjacent node. +// But note that this is only how we interpret the dart in this implementation. +// Given this list, how can we find the opposite edges: +// We can perform alpha1 on each, but for boundary nodes we will get one edge twice. +// But this is will always be the last dart! +// The darts in the list are in sequence and starts with the alpha0(dart) +// alpha0, alpha1 and alpha2 + +// Private/Hidden function +template +void TRIANGULATION_HELPER::getNeighborNodes( const DART_TYPE& aDart, + std::list& aNodeList, bool& aBoundary ) +{ + DART_TYPE dart_iter( aDart ); + dart_iter.Alpha0(); // position the dart at an opposite node + + DART_TYPE dart_prev = dart_iter; bool start_at_boundary = false; - dart_iter.alpha2(); - if (dart_iter == dart_prev) - start_at_boundary = true; + dart_iter.Alpha2(); + + if( dart_iter == dart_prev ) + start_at_boundary = true; else - dart_iter = dart_prev; // back again - - DartType dart_start = dart_iter; - - do { - node_list.push_back(dart_iter); - dart_iter.alpha1(); - dart_iter.alpha0(); - dart_iter.alpha1(); - dart_prev = dart_iter; - dart_iter.alpha2(); - if (dart_iter == dart_prev) { - // boundary reached - boundary = true; - if (start_at_boundary == true) { - // add the dart which now is positioned at the opposite boundary - node_list.push_back(dart_iter); - return; - } - else { - // call the function again such that we start at the boundary - // first clear the list and reposition to the initial node - dart_iter.alpha0(); - node_list.clear(); - getNeighborNodes(dart_iter, node_list, boundary); - return; // after one recursive step - } - } - } while (dart_iter != dart_start); - - boundary = false; - } + dart_iter = dart_prev; // back again + DART_TYPE dart_start = dart_iter; - //------------------------------------------------------------------------------------------------ - /** Gets the 0-orbit around an interior node. - * - * \param dart - * A dart (CCW or CW) positioned at an \e interior node. - * - * \retval orbit - * Sequence of darts with one orbit for each arc. All the darts have the same - * orientation (CCW or CW) as \e dart, and \e dart is the first element - * in the sequence. - * - * \require - * - DartListType::push_back (DartType&) - * - * \see - * get_0_orbit_boundary - */ - template - void TriangulationHelper::get_0_orbit_interior(const DartType& dart, DartListType& orbit) { - - DartType d_iter = dart; - orbit.push_back(d_iter); - d_iter.alpha1().alpha2(); - - while (d_iter != dart) { - orbit.push_back(d_iter); - d_iter.alpha1().alpha2(); + do + { + aNodeList.push_back( dart_iter ); + dart_iter.Alpha1(); + dart_iter.Alpha0(); + dart_iter.Alpha1(); + dart_prev = dart_iter; + dart_iter.Alpha2(); + + if( dart_iter == dart_prev ) + { + // boundary reached + aBoundary = true; + + if( start_at_boundary == true ) + { + // add the dart which now is positioned at the opposite boundary + aNodeList.push_back( dart_iter ); + return; + } + else + { + // call the function again such that we start at the boundary + // first clear the list and reposition to the initial node + dart_iter.Alpha0(); + aNodeList.clear(); + getNeighborNodes( dart_iter, aNodeList, aBoundary ); + + return; // after one recursive step + } + } } - } + while( dart_iter != dart_start ); + aBoundary = false; +} - //------------------------------------------------------------------------------------------------ - /** Gets the 0-orbit around a node at the boundary - * - * \param dart - * A dart (CCW or CW) positioned at a \e boundary \e node and at a \e boundary \e edge. - * - * \retval orbit - * Sequence of darts with one orbit for each arc. All the darts, \e exept \e the \e last one, - * have the same orientation (CCW or CW) as \e dart, and \e dart is the first element - * in the sequence. - * - * \require - * - DartListType::push_back (DartType&) - * - * \note - * - The last dart in the sequence have opposite orientation compared to the others! - * - * \see - * get_0_orbit_interior - */ - template - void TriangulationHelper::get_0_orbit_boundary(const DartType& dart, DartListType& orbit) { +/** Gets the 0-orbit around an interior node. + * + * \param aDart + * A dart (CCW or CW) positioned at an \e interior node. + * + * \retval aOrbit + * Sequence of darts with one orbit for each arc. All the darts have the same + * orientation (CCW or CW) as \e dart, and \e dart is the first element + * in the sequence. + * + * \require + * - DART_LIST_TYPE::push_back (DART_TYPE&) + * + * \see + * Get0OrbitBoundary + */ +template +void TRIANGULATION_HELPER::Get0OrbitInterior( const DART_TYPE& aDart, DART_LIST_TYPE& aOrbit ) +{ + DART_TYPE d_iter = aDart; + aOrbit.push_back( d_iter ); + d_iter.Alpha1().Alpha2(); + + while( d_iter != aDart ) + { + aOrbit.push_back( d_iter ); + d_iter.Alpha1().Alpha2(); + } +} + +/** Gets the 0-orbit around a node at the boundary + * + * \param aDart + * A dart (CCW or CW) positioned at a \e boundary \e node and at a \e boundary \e edge. + * + * \retval orbit + * Sequence of darts with one orbit for each arc. All the darts, \e exept \e the \e last one, + * have the same orientation (CCW or CW) as \e dart, and \e dart is the first element + * in the sequence. + * + * \require + * - DART_LIST_TYPE::push_back (DART_TYPE&) + * + * \note + * - The last dart in the sequence have opposite orientation compared to the others! + * + * \see + * Get0OrbitInterior + */ +template +void TRIANGULATION_HELPER::Get0OrbitBoundary( const DART_TYPE& aDart, DART_LIST_TYPE& aOrbit ) +{ + DART_TYPE dart_prev; + DART_TYPE d_iter = aDart; - DartType dart_prev; - DartType d_iter = dart; - do { - orbit.push_back(d_iter); - d_iter.alpha1(); - dart_prev = d_iter; - d_iter.alpha2(); - } while (d_iter != dart_prev); - - orbit.push_back(d_iter); // the last one with opposite orientation - } + do + { + aOrbit.push_back( d_iter ); + d_iter.Alpha1(); + dart_prev = d_iter; + d_iter.Alpha2(); + } + while( d_iter != dart_prev ); + aOrbit.push_back( d_iter ); // the last one with opposite orientation +} - //------------------------------------------------------------------------------------------------ - /** Checks if the two darts belong to the same 0-orbit, i.e., - * if they share a node. - * \e d1 and/or \e d2 can be CCW or CW. - * - * (This function also examines if the the node associated with - * \e d1 is at the boundary, which slows down the function (slightly). - * If it is known that the node associated with \e d1 is an interior - * node and a faster version is needed, the user should implement his/her - * own version.) - */ - template - bool TriangulationHelper::same_0_orbit(const DartType& d1, const DartType& d2) { - +/** Checks if the two darts belong to the same 0-orbit, i.e., + * if they share a node. + * \e d1 and/or \e d2 can be CCW or CW. + * + * (This function also examines if the the node associated with + * \e d1 is at the boundary, which slows down the function (slightly). + * If it is known that the node associated with \e d1 is an interior + * node and a faster version is needed, the user should implement his/her + * own version.) + */ +template +bool TRIANGULATION_HELPER::Same0Orbit( const DART_TYPE& aD1, const DART_TYPE& aD2 ) +{ // Two copies of the same dart - DartType d_iter = d2; - DartType d_end = d2; - - if (isBoundaryNode(d_iter)) { - // position at both boundary edges - positionAtNextBoundaryEdge(d_iter); - d_end.alpha1(); - positionAtNextBoundaryEdge(d_end); + DART_TYPE d_iter = aD2; + DART_TYPE d_end = aD2; + + if( isBoundaryNode( d_iter ) ) + { + // position at both boundary edges + PositionAtNextBoundaryEdge( d_iter ); + d_end.Alpha1(); + PositionAtNextBoundaryEdge( d_end ); } - - for (;;) { - if (d_iter == d1) - return true; - d_iter.alpha1(); - if (d_iter == d1) - return true; - d_iter.alpha2(); - if (d_iter == d_end) - break; + + for( ;; ) + { + if( d_iter == aD1 ) + return true; + + d_iter.Alpha1(); + + if( d_iter == aD1 ) + return true; + + d_iter.Alpha2(); + + if( d_iter == d_end ) + break; } - + return false; - } +} - - //------------------------------------------------------------------------------------------------ - /** Checks if the two darts belong to the same 1-orbit, i.e., - * if they share an edge. - * \e d1 and/or \e d2 can be CCW or CW. - */ - template - bool TriangulationHelper::same_1_orbit(const DartType& d1, const DartType& d2) { +/** Checks if the two darts belong to the same 1-orbit, i.e., + * if they share an edge. + * \e d1 and/or \e d2 can be CCW or CW. + */ +template +bool TRIANGULATION_HELPER::Same1Orbit( const DART_TYPE& aD1, const DART_TYPE& aD2 ) +{ + DART_TYPE d_iter = aD2; - DartType d_iter = d2; // (Also works at the boundary) - if (d_iter == d1 || d_iter.alpha0() == d1 || d_iter.alpha2() == d1 || d_iter.alpha0() == d1) - return true; - return false; - } + return ( d_iter == aD1 || d_iter.Alpha0() == aD1 || + d_iter.Alpha2() == aD1 || d_iter.Alpha0() == aD1 ); +} - - //------------------------------------------------------------------------------------------------ - /** Checks if the two darts belong to the same 2-orbit, i.e., - * if they lie in the same triangle. - * \e d1 and/or \e d2 can be CCW or CW - */ - template - bool TriangulationHelper::same_2_orbit(const DartType& d1, const DartType& d2) { +//------------------------------------------------------------------------------------------------ +/** Checks if the two darts belong to the same 2-orbit, i.e., + * if they lie in the same triangle. + * \e d1 and/or \e d2 can be CCW or CW + */ +template +bool TRIANGULATION_HELPER::Same2Orbit( const DART_TYPE& aD1, const DART_TYPE& aD2 ) +{ + DART_TYPE d_iter = aD2; - DartType d_iter = d2; - if (d_iter == d1 || d_iter.alpha0() == d1 || - d_iter.alpha1() == d1 || d_iter.alpha0() == d1 || - d_iter.alpha1() == d1 || d_iter.alpha0() == d1) - return true; - return false; - } - + return ( d_iter == aD1 || d_iter.Alpha0() == aD1 || d_iter.Alpha1() == aD1 || + d_iter.Alpha0() == aD1 || d_iter.Alpha1() == aD1 || d_iter.Alpha0() == aD1 ); +} - //------------------------------------------------------------------------------------------------ - // Private/Hidden function - template - bool TriangulationHelper::degenerateTriangle(const DartType& dart) { - +// Private/Hidden function +template +bool TRIANGULATION_HELPER::degenerateTriangle( const DART_TYPE& aDart ) +{ // Check if triangle is degenerate // Assumes CCW dart - - DartType d1 = dart; - DartType d2 = d1; - d2.alpha1(); - if (TraitsType::crossProduct2d(d1,d2) == 0) - return true; - - return false; - } - - //------------------------------------------------------------------------------------------------ - /** Checks if the edge associated with \e dart is swappable, i.e., if the edge - * is a diagonal in a \e strictly convex (or convex) quadrilateral. - * - * \param allowDegeneracy - * If set to true, the function will also return true if the numerical calculations - * indicate that the quadrilateral is convex only, and not necessarily strictly - * convex. - * - * \require - * - \ref hed::TTLtraits::crossProduct2d "TraitsType::crossProduct2d" (Dart&, Dart&) - */ - template - bool TriangulationHelper::swappableEdge(const DartType& dart, bool allowDegeneracy) { + DART_TYPE d1 = aDart; + DART_TYPE d2 = d1; + d2.Alpha1(); + return ( TRAITS_TYPE::CrossProduct2D( d1, d2 ) == 0 ); +} + +/** Checks if the edge associated with \e dart is swappable, i.e., if the edge + * is a diagonal in a \e strictly convex (or convex) quadrilateral. + * + * \param aAllowDegeneracy + * If set to true, the function will also return true if the numerical calculations + * indicate that the quadrilateral is convex only, and not necessarily strictly + * convex. + * + * \require + * - \ref hed::TTLtraits::CrossProduct2D "TRAITS_TYPE::CrossProduct2D" (Dart&, Dart&) + */ +template +bool TRIANGULATION_HELPER::SwappableEdge( const DART_TYPE& aDart, bool aAllowDegeneracy ) +{ // How "safe" is it? - - if (isBoundaryEdge(dart)) - return false; - + + if( IsBoundaryEdge( aDart ) ) + return false; + // "angles" are at the diagonal - DartType d1 = dart; - d1.alpha2().alpha1(); - DartType d2 = dart; - d2.alpha1(); - if (allowDegeneracy) { - if (TraitsType::crossProduct2d(d1,d2) < 0.0) - return false; + DART_TYPE d1 = aDart; + d1.Alpha2().Alpha1(); + DART_TYPE d2 = aDart; + d2.Alpha1(); + + if( aAllowDegeneracy ) + { + if( TRAITS_TYPE::CrossProduct2D( d1, d2 ) < 0.0 ) + return false; } - else { - if (TraitsType::crossProduct2d(d1,d2) <= 0.0) - return false; + else + { + if( TRAITS_TYPE::CrossProduct2D( d1, d2 ) <= 0.0 ) + return false; } - + // Opposite side (still angle at the diagonal) - d1 = dart; - d1.alpha0(); + d1 = aDart; + d1.Alpha0(); d2 = d1; - d1.alpha1(); - d2.alpha2().alpha1(); - - if (allowDegeneracy) { - if (TraitsType::crossProduct2d(d1,d2) < 0.0) - return false; + d1.Alpha1(); + d2.Alpha2().Alpha1(); + + if( aAllowDegeneracy ) + { + if( TRAITS_TYPE::CrossProduct2D( d1, d2 ) < 0.0 ) + return false; } - else { - if (TraitsType::crossProduct2d(d1,d2) <= 0.0) - return false; + else + { + if( TRAITS_TYPE::CrossProduct2D( d1, d2 ) <= 0.0 ) + return false; } + return true; - } +} +/** Given a \e dart, CCW or CW, positioned in a 0-orbit at the boundary of a tessellation. + * Position \e dart at a boundary edge in the same 0-orbit.\n + * If the given \e dart is CCW, \e dart is positioned at the left boundary edge + * and will be CW.\n + * If the given \e dart is CW, \e dart is positioned at the right boundary edge + * and will be CCW. + * + * \note + * - The given \e dart must have a source node at the boundary, otherwise an + * infinit loop occurs. + */ +template +void TRIANGULATION_HELPER::PositionAtNextBoundaryEdge( DART_TYPE& aDart ) +{ + DART_TYPE dart_prev; - //------------------------------------------------------------------------------------------------ - /** Given a \e dart, CCW or CW, positioned in a 0-orbit at the boundary of a tessellation. - * Position \e dart at a boundary edge in the same 0-orbit.\n - * If the given \e dart is CCW, \e dart is positioned at the left boundary edge - * and will be CW.\n - * If the given \e dart is CW, \e dart is positioned at the right boundary edge - * and will be CCW. - * - * \note - * - The given \e dart must have a source node at the boundary, otherwise an - * infinit loop occurs. - */ - template - void TriangulationHelper::positionAtNextBoundaryEdge(DartType& dart) { - - DartType dart_prev; - // If alpha2(d)=d, then boundary - - //old convention: dart.alpha0(); - do { - dart.alpha1(); - dart_prev = dart; - dart.alpha2(); - } while (dart != dart_prev); - } - - //------------------------------------------------------------------------------------------------ - /** Checks if the boundary of a triangulation is convex. - * - * \param dart - * A CCW dart at the boundary of the triangulation - * - * \require - * - \ref hed::TTLtraits::crossProduct2d "TraitsType::crossProduct2d" (const Dart&, const Dart&) - */ - template - bool TriangulationHelper::convexBoundary(const DartType& dart) { - - std::list blist; - getBoundary(dart, blist); - - int no; - no = (int)blist.size(); - typename std::list::const_iterator bit = blist.begin(); - DartType d1 = *bit; - ++bit; - DartType d2; - bool convex = true; - for (; bit != blist.end(); ++bit) { - d2 = *bit; - double crossProd = TraitsType::crossProduct2d(d1, d2); - if (crossProd < 0.0) { - //cout << "!!! Boundary is NOT convex: crossProd = " << crossProd << endl; - convex = false; - return convex; - } - d1 = d2; + //old convention: dart.Alpha0(); + do + { + aDart.Alpha1(); + dart_prev = aDart; + aDart.Alpha2(); } - + while( aDart != dart_prev ); +} + +/** Checks if the boundary of a triangulation is convex. + * + * \param dart + * A CCW dart at the boundary of the m_triangulation + * + * \require + * - \ref hed::TTLtraits::CrossProduct2D "TRAITS_TYPE::CrossProduct2D" (const Dart&, const Dart&) + */ +template +bool TRIANGULATION_HELPER::ConvexBoundary( const DART_TYPE& aDart ) +{ + std::list blist; + getBoundary( aDart, blist ); + + int no; + no = (int) blist.size(); + typename std::list::const_iterator bit = blist.begin(); + DART_TYPE d1 = *bit; + ++bit; + DART_TYPE d2; + bool convex = true; + + for( ; bit != blist.end(); ++bit ) + { + d2 = *bit; + double crossProd = TRAITS_TYPE::CrossProduct2D( d1, d2 ); + + if( crossProd < 0.0 ) + { + //cout << "!!! Boundary is NOT convex: crossProd = " << crossProd << endl; + convex = false; + return convex; + } + + d1 = d2; + } + // Check the last angle d2 = *blist.begin(); - double crossProd = TraitsType::crossProduct2d(d1, d2); - if (crossProd < 0.0) { - //cout << "!!! Boundary is NOT convex: crossProd = " << crossProd << endl; - convex = false; + double crossProd = TRAITS_TYPE::CrossProduct2D( d1, d2 ); + + if( crossProd < 0.0 ) + { + //cout << "!!! Boundary is NOT convex: crossProd = " << crossProd << endl; + convex = false; } - + //if (convex) // cout << "\n---> Boundary is convex\n" << endl; //cout << endl; return convex; - } +} - //@} // End of Topological and Geometric Queries Group +//@} // End of Topological and Geometric Queries Group +/** @name Utilities for Delaunay Triangulation */ +//@{ +//------------------------------------------------------------------------------------------------ +/** Optimizes the edges in the given sequence according to the + * \e Delaunay criterion, i.e., such that the edge will fullfill the + * \e circumcircle criterion (or equivalently the \e MaxMin + * angle criterion) with respect to the quadrilaterals where + * they are diagonals. + * + * \param aElist + * The sequence of edges + * + * \require + * - \ref hed::TTLtraits::swapEdge "TRAITS_TYPE::swapEdge" (DART_TYPE& \e dart)\n + * \b Note: Must be implemented such that \e dart is delivered back in a position as + * seen if it was glued to the edge when swapping (rotating) the edge CCW + * + * \using + * - swapTestDelaunay + */ +template +void TRIANGULATION_HELPER::OptimizeDelaunay( DART_LIST_TYPE& aElist ) +{ + OptimizeDelaunay( aElist, aElist.end() ); +} - //------------------------------------------------------------------------------------------------ - // ------------------------ Utilities for Delaunay Triangulation Group -------------------------- - //------------------------------------------------------------------------------------------------ - - /** @name Utilities for Delaunay Triangulation */ - //@{ - - //------------------------------------------------------------------------------------------------ - /** Optimizes the edges in the given sequence according to the - * \e Delaunay criterion, i.e., such that the edge will fullfill the - * \e circumcircle criterion (or equivalently the \e MaxMin - * angle criterion) with respect to the quadrilaterals where - * they are diagonals. - * - * \param elist - * The sequence of edges - * - * \require - * - \ref hed::TTLtraits::swapEdge "TraitsType::swapEdge" (DartType& \e dart)\n - * \b Note: Must be implemented such that \e dart is delivered back in a position as - * seen if it was glued to the edge when swapping (rotating) the edge CCW - * - * \using - * - swapTestDelaunay - */ - template - void TriangulationHelper::optimizeDelaunay(DartListType& elist) { - optimizeDelaunay(elist, elist.end()); - } - - - //------------------------------------------------------------------------------------------------ - template - void TriangulationHelper::optimizeDelaunay(DartListType& elist, const typename DartListType::iterator end) { - +//------------------------------------------------------------------------------------------------ +template +void TRIANGULATION_HELPER::OptimizeDelaunay( DART_LIST_TYPE& aElist, + const typename DART_LIST_TYPE::iterator aEnd ) +{ // CCW darts // Optimize here means Delaunay, but could be any criterion by // requiring a "should swap" in the traits class, or give // a function object? // Assumes that elist has only one dart for each arc. // Darts outside the quadrilateral are preserved - + // For some data structures it is possible to preserve // all darts when swapping. Thus a preserve_darts_when swapping // ccould be given to indicate this and we would gain performance by avoiding // find in list. - + // Requires that swap retuns a dart in the "same position when rotated CCW" // (A vector instead of a list may be better.) - + // First check that elist is not empty - if (elist.empty()) + if( aElist.empty() ) return; // Avoid cycling by more extensive circumcircle test bool cycling_check = true; bool optimal = false; - typename DartListType::iterator it; + typename DART_LIST_TYPE::iterator it; - typename DartListType::iterator end_opt = end; + typename DART_LIST_TYPE::iterator end_opt = aEnd; // Hmm... The following code is trying to derefence an iterator that may // be invalid. This may lead to debug error on Windows, so we comment out @@ -1491,231 +1488,240 @@ private: // problems... // // last_opt is passed the end of the "active list" - //typename DartListType::iterator end_opt; + //typename DART_LIST_TYPE::iterator end_opt; //if (*end != NULL) // end_opt = end; //else // end_opt = elist.end(); - while(!optimal) { - optimal = true; - for (it = elist.begin(); it != end_opt; ++it) { - if (swapTestDelaunay(*it, cycling_check)) { + while( !optimal ) + { + optimal = true; + for( it = aElist.begin(); it != end_opt; ++it ) + { + 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) - // 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) - - swapEdgeInList(it, elist); - - optimal = false; - } // end if should swap - } // end for + SwapEdgeInList( it, aElist ); + + optimal = false; + } // end if should swap + } // end for } // end pass - } +} - - //------------------------------------------------------------------------------------------------ - /** Checks if the edge associated with \e dart should be swapped according - * to the \e Delaunay criterion, i.e., the \e circumcircle criterion (or - * equivalently the \e MaxMin angle criterion). - * - * \param cycling_check - * Must be set to \c true when used in connection with optimization algorithms, - * e.g., optimizeDelaunay. This will avoid cycling and infinite loops in nearly - * neutral cases. - * - * \require - * - \ref hed::TTLtraits::scalarProduct2d "TraitsType::scalarProduct2d" (DartType&, DartType&) - * - \ref hed::TTLtraits::crossProduct2d "TraitsType::crossProduct2d" (DartType&, DartType&) - */ - template +/** Checks if the edge associated with \e dart should be swapped according + * to the \e Delaunay criterion, i.e., the \e circumcircle criterion (or + * equivalently the \e MaxMin angle criterion). + * + * \param aCyclingCheck + * Must be set to \c true when used in connection with optimization algorithms, + * e.g., OptimizeDelaunay. This will avoid cycling and infinite loops in nearly + * neutral cases. + * + * \require + * - \ref hed::TTLtraits::ScalarProduct2D "TRAITS_TYPE::ScalarProduct2D" (DART_TYPE&, DART_TYPE&) + * - \ref hed::TTLtraits::CrossProduct2D "TRAITS_TYPE::CrossProduct2D" (DART_TYPE&, DART_TYPE&) + */ +template #if ((_MSC_VER > 0) && (_MSC_VER < 1300))//#ifdef _MSC_VER - bool TriangulationHelper::swapTestDelaunay(const DartType& dart, bool cycling_check = false) const { +bool TRIANGULATION_HELPER::SwapTestDelaunay(const DART_TYPE& aDart, bool aCyclingCheck = false) const +{ #else - bool TriangulationHelper::swapTestDelaunay(const DartType& dart, bool cycling_check) const { +bool TRIANGULATION_HELPER::SwapTestDelaunay( const DART_TYPE& aDart, bool aCyclingCheck ) const +{ #endif - // The general strategy is taken from Cline & Renka. They claim that // their algorithm insure numerical stability, but experiments show // that this is not correct for neutral, or almost neutral cases. // I have extended this strategy (without using tolerances) to avoid // cycling and infinit loops when used in connection with LOP algorithms; // see the comments below. - - typedef typename TraitsType::real_type real_type; - - if (isBoundaryEdge(dart)) - return false; - - DartType v11 = dart; - v11.alpha1().alpha0(); - DartType v12 = v11; - v12.alpha1(); - - DartType v22 = dart; - v22.alpha2().alpha1().alpha0(); - DartType v21 = v22; - v21.alpha1(); - - real_type cos1 = TraitsType::scalarProduct2d(v11,v12); - real_type cos2 = TraitsType::scalarProduct2d(v21,v22); - + + typedef typename TRAITS_TYPE::REAL_TYPE REAL_TYPE; + + if( IsBoundaryEdge( aDart ) ) + return false; + + DART_TYPE v11 = aDart; + v11.Alpha1().Alpha0(); + DART_TYPE v12 = v11; + v12.Alpha1(); + + DART_TYPE v22 = aDart; + v22.Alpha2().Alpha1().Alpha0(); + DART_TYPE v21 = v22; + v21.Alpha1(); + + REAL_TYPE cos1 = TRAITS_TYPE::ScalarProduct2D( v11, v12 ); + REAL_TYPE cos2 = TRAITS_TYPE::ScalarProduct2D( v21, v22 ); + // "Angles" are opposite to the diagonal. // The diagonals should be swapped iff (t1+t2) .gt. 180 // degrees. The following two tests insure numerical // stability according to Cline & Renka. But experiments show // that cycling may still happen; see the aditional test below. - if (cos1 >= 0 && cos2 >= 0) // both angles are grater or equual 90 - return false; - if (cos1 < 0 && cos2 < 0) // both angles are less than 90 - return true; - - real_type sin1 = TraitsType::crossProduct2d(v11,v12); - real_type sin2 = TraitsType::crossProduct2d(v21,v22); - real_type sin12 = sin1*cos2 + cos1*sin2; - if (sin12 >= 0) // equality represents a neutral case - return false; - - if (cycling_check) { - // situation so far is sin12 < 0. Test if this also - // happens for the swapped edge. - - // The numerical calculations so far indicate that the edge is - // not Delaunay and should not be swapped. But experiments show that - // in neutral cases, or almost neutral cases, it may happen that - // the swapped edge may again be found to be not Delaunay and thus - // be swapped if we return true here. This may lead to cycling and - // an infinte loop when used, e.g., in connection with optimizeDelaunay. - // - // In an attempt to avoid this we test if the swapped edge will - // also be found to be not Delaunay by repeating the last test above - // for the swapped edge. - // We now rely on the general requirement for TraitsType::swapEdge which - // should deliver CCW dart back in "the same position"; see the general - // description. This will insure numerical stability as the next calculation - // is the same as if this function was called again with the swapped edge. - // Cycling is thus impossible provided that the initial tests above does - // not result in ambiguity (and they should probably not do so). - - v11.alpha0(); - v12.alpha0(); - v21.alpha0(); - v22.alpha0(); - // as if the edge was swapped/rotated CCW - cos1 = TraitsType::scalarProduct2d(v22,v11); - cos2 = TraitsType::scalarProduct2d(v12,v21); - sin1 = TraitsType::crossProduct2d(v22,v11); - sin2 = TraitsType::crossProduct2d(v12,v21); - sin12 = sin1*cos2 + cos1*sin2; - if (sin12 < 0) { - // A neutral case, but the tests above lead to swapping + if( cos1 >= 0 && cos2 >= 0 ) // both angles are grater or equual 90 return false; - } + + if( cos1 < 0 && cos2 < 0 ) // both angles are less than 90 + return true; + + REAL_TYPE sin1 = TRAITS_TYPE::CrossProduct2D( v11, v12 ); + REAL_TYPE sin2 = TRAITS_TYPE::CrossProduct2D( v21, v22 ); + REAL_TYPE sin12 = sin1 * cos2 + cos1 * sin2; + + if( sin12 >= 0 ) // equality represents a neutral case + return false; + + if( aCyclingCheck ) + { + // situation so far is sin12 < 0. Test if this also + // happens for the swapped edge. + + // The numerical calculations so far indicate that the edge is + // not Delaunay and should not be swapped. But experiments show that + // in neutral cases, or almost neutral cases, it may happen that + // the swapped edge may again be found to be not Delaunay and thus + // be swapped if we return true here. This may lead to cycling and + // an infinte loop when used, e.g., in connection with OptimizeDelaunay. + // + // In an attempt to avoid this we test if the swapped edge will + // also be found to be not Delaunay by repeating the last test above + // for the swapped edge. + // We now rely on the general requirement for TRAITS_TYPE::swapEdge which + // should deliver CCW dart back in "the same position"; see the general + // description. This will insure numerical stability as the next calculation + // is the same as if this function was called again with the swapped edge. + // Cycling is thus impossible provided that the initial tests above does + // not result in ambiguity (and they should probably not do so). + + v11.Alpha0(); + v12.Alpha0(); + v21.Alpha0(); + v22.Alpha0(); + // as if the edge was swapped/rotated CCW + cos1 = TRAITS_TYPE::ScalarProduct2D( v22, v11 ); + cos2 = TRAITS_TYPE::ScalarProduct2D( v12, v21 ); + sin1 = TRAITS_TYPE::CrossProduct2D( v22, v11 ); + sin2 = TRAITS_TYPE::CrossProduct2D( v12, v21 ); + sin12 = sin1 * cos2 + cos1 * sin2; + + if( sin12 < 0 ) + { + // A neutral case, but the tests above lead to swapping + return false; + } } - + return true; - } +} +//----------------------------------------------------------------------- +// +// x +//" / \ " +// / | \ Darts: +//oe2 / | \ oe2 = oppEdge2 +// x....|....x +// \ d| d/ d = diagonal (input and output) +// \ | / +// oe1 \ / oe1 = oppEdge1 +// x +// +//----------------------------------------------------------------------- +/** Recursively swaps edges in the triangulation according to the \e Delaunay criterion. + * + * \param aDiagonal + * A CCW dart representing the edge where the recursion starts from. + * + * \require + * - \ref hed::TTLtraits::swapEdge "TRAITS_TYPE::swapEdge" (DART_TYPE&)\n + * \b Note: Must be implemented such that the darts outside the quadrilateral + * are not affected by the swap. + * + * \using + * - Calls itself recursively + */ +template +void TRIANGULATION_HELPER::RecSwapDelaunay( DART_TYPE& aDiagonal ) +{ + if( !SwapTestDelaunay( aDiagonal ) ) + // ??? swapTestDelaunay also checks if boundary, so this can be optimized + return; - //----------------------------------------------------------------------- - // - // x - //" / \ " - // / | \ Darts: - //oe2 / | \ oe2 = oppEdge2 - // x....|....x - // \ d| d/ d = diagonal (input and output) - // \ | / - // oe1 \ / oe1 = oppEdge1 - // x - // - //----------------------------------------------------------------------- - /** Recursively swaps edges in the triangulation according to the \e Delaunay criterion. - * - * \param diagonal - * A CCW dart representing the edge where the recursion starts from. - * - * \require - * - \ref hed::TTLtraits::swapEdge "TraitsType::swapEdge" (DartType&)\n - * \b Note: Must be implemented such that the darts outside the quadrilateral - * are not affected by the swap. - * - * \using - * - Calls itself recursively - */ - template - void TriangulationHelper::recSwapDelaunay(DartType& diagonal) { - - 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(); + DART_TYPE oppEdge1 = aDiagonal; + oppEdge1.Alpha1(); bool b1; - if (isBoundaryEdge(oppEdge1)) - b1 = true; - else { - b1 = false; - oppEdge1.alpha2(); + + if( IsBoundaryEdge( oppEdge1 ) ) + b1 = true; + else + { + b1 = false; + oppEdge1.Alpha2(); } - - - DartType oppEdge2 = diagonal; - oppEdge2.alpha0().alpha1().alpha0(); + + DART_TYPE oppEdge2 = aDiagonal; + oppEdge2.Alpha0().Alpha1().Alpha0(); bool b2; - if (isBoundaryEdge(oppEdge2)) - b2 = true; - else { - b2 = false; - oppEdge2.alpha2(); + + if( IsBoundaryEdge( oppEdge2 ) ) + b2 = true; + else + { + b2 = false; + oppEdge2.Alpha2(); } - + // Swap the given diagonal - triangulation.swapEdge(diagonal); - - if (!b1) - recSwapDelaunay(oppEdge1); - if (!b2) - recSwapDelaunay(oppEdge2); - } + m_triangulation.swapEdge( aDiagonal ); + if( !b1 ) + RecSwapDelaunay( oppEdge1 ); + + if( !b2 ) + RecSwapDelaunay( oppEdge2 ); +} + +/** 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 RemoveInteriorNode + * + * \retval dart + * A CCW dart incident with the node + * + * \par Assumes: + * - The node associated with \e dart is interior to the + * triangulation. + * + * \require + * - \ref hed::TTLtraits::swapEdge "TRAITS_TYPE::swapEdge" (DART_TYPE& \e dart)\n + * \b Note: Must be implemented such that \e dart is delivered back in a position as + * seen if it was glued to the edge when swapping (rotating) the edge CCW + * + * \note + * - A degenerate triangle may be left at the node. + * - The function is not unique as it depends on which dart + * at the node that is given as input. + * + * \see + * SwapEdgesAwayFromBoundaryNode + */ +template +void TRIANGULATION_HELPER::SwapEdgesAwayFromInteriorNode( DART_TYPE& aDart, + LIST_TYPE& aSwappedEdges ) +{ - //------------------------------------------------------------------------------------------------ - /** 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 removeInteriorNode - * - * \retval dart - * A CCW dart incident with the node - * - * \par Assumes: - * - The node associated with \e dart is interior to the - * triangulation. - * - * \require - * - \ref hed::TTLtraits::swapEdge "TraitsType::swapEdge" (DartType& \e dart)\n - * \b Note: Must be implemented such that \e dart is delivered back in a position as - * seen if it was glued to the edge when swapping (rotating) the edge CCW - * - * \note - * - A degenerate triangle may be left at the node. - * - The function is not unique as it depends on which dart - * at the node that is given as input. - * - * \see - * swapEdgesAwayFromBoundaryNode - */ - template - void TriangulationHelper::swapEdgesAwayFromInteriorNode(DartType& dart, ListType& swapped_edges) { - // Same iteration as in fixEdgesAtCorner, but not boundary - DartType dnext = dart; - + DART_TYPE dnext = aDart; + // Allow degeneracy, otherwise we might end up with degree=4. // For example, the reverse operation of inserting a point on an // existing edge gives a situation where all edges are non-swappable. @@ -1724,53 +1730,56 @@ private: // ??? An alternative here is to wait with degeneracy till we get an // infinite loop with degree > 3. bool allowDegeneracy = true; - - int degree = getDegreeOfNode(dart); - DartType d_iter; - while (degree > 3) { - d_iter = dnext; - dnext.alpha1().alpha2(); - - 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 - DartType swapped_edge = d_iter; // it was delivered back - swapped_edge.alpha2().alpha0(); // CCW (if not at boundary) - swapped_edges.push_back(swapped_edge); - - degree--; - } + + int degree = getDegreeOfNode( aDart ); + DART_TYPE d_iter; + + while( degree > 3 ) + { + d_iter = dnext; + dnext.Alpha1().Alpha2(); + + if( SwappableEdge( d_iter, allowDegeneracy ) ) + { + m_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 + DART_TYPE swapped_edge = d_iter; // it was delivered back + swapped_edge.Alpha2().Alpha0(); // CCW (if not at boundary) + aSwappedEdges.push_back( swapped_edge ); + + degree--; + } } + // Output, incident to the node - dart = dnext; - } + aDart = dnext; +} - - //------------------------------------------------------------------------------------------------ - /** 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 removeBoundaryNode - * - * \retval dart - * A CCW dart incident with the node - * - * \require - * - \ref hed::TTLtraits::swapEdge "TraitsType::swapEdge" (DartType& \e dart)\n - * \b Note: Must be implemented such that \e dart is delivered back in a position as - * seen if it was glued to the edge when swapping (rotating) the edge CCW - * - * \par Assumes: - * - The node associated with \e dart is at the boundary of the triangulation. - * - * \see - * swapEdgesAwayFromInteriorNode - */ - template - void TriangulationHelper::swapEdgesAwayFromBoundaryNode(DartType& dart, ListType& swapped_edges) { - +/** 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 RemoveBoundaryNode + * + * \retval dart + * A CCW dart incident with the node + * + * \require + * - \ref hed::TTLtraits::swapEdge "TRAITS_TYPE::swapEdge" (DART_TYPE& \e dart)\n + * \b Note: Must be implemented such that \e dart is delivered back in a position as + * seen if it was glued to the edge when swapping (rotating) the edge CCW + * + * \par Assumes: + * - The node associated with \e dart is at the boundary of the m_triangulation. + * + * \see + * SwapEdgesAwayFromInteriorNode + */ +template +void TRIANGULATION_HELPER::SwapEdgesAwayFromBoundaryNode( DART_TYPE& aDart, + LIST_TYPE& aSwappedEdges ) +{ // All darts that are swappable. // To treat collinear nodes at an existing boundary, we must allow degeneracy // when swapping to the boundary. @@ -1780,98 +1789,108 @@ private: // Assume for the swap in the traits class: // - 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 = getDegreeOfNode(dart); - -passes: - - // Swap swappable edges that radiate from the node away - DartType d_iter = dart; // ???? can simply use dart - d_iter.alpha1().alpha2(); // first not at boundary - DartType d_next = d_iter; - bool bend = false; - bool swapped_next_to_boundary = false; - bool swapped_in_pass = false; - - bool allowDegeneracy; // = true; - DartType tmp1, tmp2; - - while (!bend) { - - d_next.alpha1().alpha2(); - if (isBoundaryEdge(d_next)) - bend = true; // then it is CW since alpha2 - - // To allow removing among collinear nodes at the boundary, - // degenerate triangles must be allowed - // (they will be removed when used in connection with removeBoundaryNode) - tmp1 = d_iter; tmp1.alpha1(); - tmp2 = d_iter; tmp2.alpha2().alpha1(); // don't bother with boundary (checked later) - - if (isBoundaryEdge(tmp1) && isBoundaryEdge(tmp2)) - allowDegeneracy = true; - else - allowDegeneracy = false; - - 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 - // other swapps - DartType swapped_edge = d_iter; // it was delivered back - swapped_edge.alpha2().alpha0(); // CCW - swapped_edges.push_back(swapped_edge); - - //degree--; // if degree is 2, or bend=true, we are done - swapped_in_pass = true; - if (bend) - swapped_next_to_boundary = true; + + passes: + // Swap swappable edges that radiate from the node away + DART_TYPE d_iter = aDart; // ???? can simply use dart + d_iter.Alpha1().Alpha2(); // first not at boundary + DART_TYPE d_next = d_iter; + bool bend = false; + bool swapped_next_to_boundary = false; + bool swapped_in_pass = false; + + bool allowDegeneracy; // = true; + DART_TYPE tmp1, tmp2; + + while( !bend ) + { + d_next.Alpha1().Alpha2(); + + if( IsBoundaryEdge( d_next ) ) + bend = true; // then it is CW since alpha2 + + // To allow removing among collinear nodes at the boundary, + // degenerate triangles must be allowed + // (they will be removed when used in connection with RemoveBoundaryNode) + tmp1 = d_iter; + tmp1.Alpha1(); + tmp2 = d_iter; + tmp2.Alpha2().Alpha1(); // don't bother with boundary (checked later) + + if( IsBoundaryEdge( tmp1 ) && IsBoundaryEdge( tmp2 ) ) + allowDegeneracy = true; + else + allowDegeneracy = false; + + if( SwappableEdge( d_iter, allowDegeneracy ) ) + { + m_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 + // other swapps + DART_TYPE swapped_edge = d_iter; // it was delivered back + swapped_edge.Alpha2().Alpha0(); // CCW + aSwappedEdges.push_back( swapped_edge ); + + //degree--; // if degree is 2, or bend=true, we are done + swapped_in_pass = true; + if( bend ) + swapped_next_to_boundary = true; + } + + if( !bend ) + d_iter = d_next; } - if (!bend) - d_iter = d_next; - } - - // Deliver a dart as output in the same position as the incoming dart - if (swapped_next_to_boundary) { - // Assume that "swapping is CCW and dart is preserved in the same position - d_iter.alpha1().alpha0().alpha1(); // CW and see below - } - else { - d_iter.alpha1(); // CW and see below - } - positionAtNextBoundaryEdge(d_iter); // CCW - - dart = d_iter; // for next pass or output - - // If a dart was swapped in this iteration we must run it more - if (swapped_in_pass) - goto passes; - } + // Deliver a dart as output in the same position as the incoming dart + if( swapped_next_to_boundary ) + { + // Assume that "swapping is CCW and dart is preserved in the same position + d_iter.Alpha1().Alpha0().Alpha1(); // CW and see below + } + else + { + d_iter.Alpha1(); // CW and see below + } + PositionAtNextBoundaryEdge( d_iter ); // CCW - //------------------------------------------------------------------------------------------------ - /** Swap the the edge associated with iterator \e it and update affected darts - * in \e elist accordingly. - * The darts affected by the swap are those in the same quadrilateral. - * Thus, if one want to preserve one or more of these darts on should - * keep them in \e elist. - */ - template - void TriangulationHelper::swapEdgeInList(const typename DartListType::iterator& it, DartListType& elist) { + aDart = d_iter; // for next pass or output + + // If a dart was swapped in this iteration we must run it more + if( swapped_in_pass ) + goto passes; +} + +/** Swap the the edge associated with iterator \e it and update affected darts + * in \e elist accordingly. + * The darts affected by the swap are those in the same quadrilateral. + * Thus, if one want to preserve one or more of these darts on should + * keep them in \e elist. + */ +template +void TRIANGULATION_HELPER::SwapEdgeInList( const typename DART_LIST_TYPE::iterator& aIt, + DART_LIST_TYPE& aElist ) +{ + + typename DART_LIST_TYPE::iterator it1, it2, it3, it4; + DART_TYPE dart( *aIt ); + + //typename TRAITS_TYPE::DART_TYPE d1 = dart; d1.Alpha2().Alpha1(); + //typename TRAITS_TYPE::DART_TYPE d2 = d1; d2.Alpha0().Alpha1(); + //typename TRAITS_TYPE::DART_TYPE d3 = dart; d3.Alpha0().Alpha1(); + //typename TRAITS_TYPE::DART_TYPE d4 = d3; d4.Alpha0().Alpha1(); + DART_TYPE d1 = dart; + d1.Alpha2().Alpha1(); + DART_TYPE d2 = d1; + d2.Alpha0().Alpha1(); + DART_TYPE d3 = dart; + d3.Alpha0().Alpha1(); + DART_TYPE d4 = d3; + d4.Alpha0().Alpha1(); - typename DartListType::iterator it1, it2, it3, it4; - DartType dart(*it); - - //typename TraitsType::DartType d1 = dart; d1.alpha2().alpha1(); - //typename TraitsType::DartType d2 = d1; d2.alpha0().alpha1(); - //typename TraitsType::DartType d3 = dart; d3.alpha0().alpha1(); - //typename TraitsType::DartType d4 = d3; d4.alpha0().alpha1(); - DartType d1 = dart; d1.alpha2().alpha1(); - DartType d2 = d1; d2.alpha0().alpha1(); - DartType d3 = dart; d3.alpha0().alpha1(); - DartType d4 = d3; d4.alpha0().alpha1(); - // Find pinters to the darts that may change. // ??? Note, this is not very efficient since we must use find, which is O(N), // four times. @@ -1881,37 +1900,49 @@ passes: // - sould we use another container type or, // - erase them and reinsert? // - or use two lists? - it1 = find(elist.begin(), elist.end(), d1); - it2 = find(elist.begin(), elist.end(), d2); - it3 = find(elist.begin(), elist.end(), d3); - it4 = find(elist.begin(), elist.end(), d4); - - triangulation.swapEdge(dart); + it1 = find( aElist.begin(), aElist.end(), d1 ); + it2 = find( aElist.begin(), aElist.end(), d2 ); + it3 = find( aElist.begin(), aElist.end(), d3 ); + it4 = find( aElist.begin(), aElist.end(), d4 ); + + m_triangulation.swapEdge( dart ); // Update the current dart which may have changed - *it = dart; - + *aIt = dart; + // Update darts that may have changed again (if they were present) // Note that dart is delivered back after swapping - if (it1 != elist.end()) { - d1 = dart; d1.alpha1().alpha0(); - *it1 = d1; + if( it1 != aElist.end() ) + { + d1 = dart; + d1.Alpha1().Alpha0(); + *it1 = d1; } - if (it2 != elist.end()) { - d2 = dart; d2.alpha2().alpha1(); - *it2 = d2; + + if( it2 != aElist.end() ) + { + d2 = dart; + d2.Alpha2().Alpha1(); + *it2 = d2; } - if (it3 != elist.end()) { - d3 = dart; d3.alpha2().alpha1().alpha0().alpha1(); - *it3 = d3; + + if( it3 != aElist.end() ) + { + d3 = dart; + d3.Alpha2().Alpha1().Alpha0().Alpha1(); + *it3 = d3; } - if (it4 != elist.end()) { - d4 = dart; d4.alpha0().alpha1(); - *it4 = d4; + + if( it4 != aElist.end() ) + { + d4 = dart; + d4.Alpha0().Alpha1(); + *it4 = d4; } - } - - //@} // End of Utilities for Delaunay Triangulation Group - -}; // End of ttl namespace scope (but other files may also contain functions for ttl) +} + +//@} // End of Utilities for Delaunay Triangulation Group + +} +// End of ttl namespace scope (but other files may also contain functions for ttl) #endif // _TTL_H_ diff --git a/include/ttl/ttl_util.h b/include/ttl/ttl_util.h index cfdf509531..398f6f316e 100644 --- a/include/ttl/ttl_util.h +++ b/include/ttl/ttl_util.h @@ -3,11 +3,11 @@ * Applied Mathematics, Norway. * * Contact information: E-mail: tor.dokken@sintef.no - * SINTEF ICT, Department of Applied Mathematics, + * SINTEF ICT, DeaPArtment of Applied Mathematics, * P.O. Box 124 Blindern, * 0314 Oslo, Norway. * - * This file is part of TTL. + * This file is aPArt of TTL. * * TTL is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -16,7 +16,7 @@ * * TTL 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 + * MERCHANTABILITY or FITNESS FOR A aPARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public @@ -40,28 +40,22 @@ #ifndef _TTL_UTIL_H_ #define _TTL_UTIL_H_ - #include #include - #ifdef _MSC_VER # if _MSC_VER < 1300 # include # endif #endif - -//using namespace std; - - /** \brief Utilities * -* This name space contains utility functions for TTL.\n +* This name saPAce contains utility functions for TTL.\n * * Point and vector algebra such as scalar product and cross product * between vectors are implemented here. -* These functions are required by functions in the \ref ttl namespace, +* These functions are required by functions in the \ref ttl namesaPAce, * where they are assumed to be present in the \ref hed::TTLtraits "TTLtraits" class. * Thus, the user can call these functions from the traits class. * For efficiency reasons, the user may consider implementing these @@ -77,67 +71,59 @@ * ttl and \ref api * * \author -* Øyvind Hjelle, oyvindhj@ifi.uio.no +* �yvind Hjelle, oyvindhj@ifi.uio.no */ +namespace ttl_util +{ +/** @name Computational geometry */ +//@{ +/** Scalar product between two 2D vectors. + * + * \aPAr Returns: + * \code + * aDX1*aDX2 + aDY1*aDY2 + * \endcode + */ +template +REAL_TYPE ScalarProduct2D( REAL_TYPE aDX1, REAL_TYPE aDY1, REAL_TYPE aDX2, REAL_TYPE aDY2 ) +{ + return aDX1 * aDX2 + aDY1 * aDY2; +} -namespace ttl_util { +/** Cross product between two 2D vectors. (The z-component of the actual cross product.) + * + * \aPAr Returns: + * \code + * aDX1*aDY2 - aDY1*aDX2 + * \endcode + */ +template +REAL_TYPE CrossProduct2D( REAL_TYPE aDX1, REAL_TYPE aDY1, REAL_TYPE aDX2, REAL_TYPE aDY2 ) +{ + return aDX1 * aDY2 - aDY1 * aDX2; +} +/** Returns a positive value if the 2D nodes/points \e aPA, \e aPB, and + * \e aPC occur in counterclockwise order; a negative value if they occur + * in clockwise order; and zero if they are collinear. + * + * \note + * - This is a finite arithmetic fast version. It can be made more robust using + * exact arithmetic schemes by Jonathan Richard Shewchuk. See + * http://www-2.cs.cmu.edu/~quake/robust.html + */ +template +REAL_TYPE Orient2DFast( REAL_TYPE aPA[2], REAL_TYPE aPB[2], REAL_TYPE aPC[2] ) +{ + REAL_TYPE acx = aPA[0] - aPC[0]; + REAL_TYPE bcx = aPB[0] - aPC[0]; + REAL_TYPE acy = aPA[1] - aPC[1]; + REAL_TYPE bcy = aPB[1] - aPC[1]; - //------------------------------------------------------------------------------------------------ - // ------------------------------ Computational Geometry Group ---------------------------------- - //------------------------------------------------------------------------------------------------ - - /** @name Computational geometry */ - //@{ - - //------------------------------------------------------------------------------------------------ - /** Scalar product between two 2D vectors. - * - * \par Returns: - * \code - * dx1*dx2 + dy1*dy2 - * \endcode - */ - template - real_type scalarProduct2d(real_type dx1, real_type dy1, real_type dx2, real_type dy2) { - return dx1*dx2 + dy1*dy2; - } - - - //------------------------------------------------------------------------------------------------ - /** Cross product between two 2D vectors. (The z-component of the actual cross product.) - * - * \par Returns: - * \code - * dx1*dy2 - dy1*dx2 - * \endcode - */ - template - real_type crossProduct2d(real_type dx1, real_type dy1, real_type dx2, real_type dy2) { - return dx1*dy2 - dy1*dx2; - } - - - //------------------------------------------------------------------------------------------------ - /** Returns a positive value if the 2D nodes/points \e pa, \e pb, and - * \e pc occur in counterclockwise order; a negative value if they occur - * in clockwise order; and zero if they are collinear. - * - * \note - * - This is a finite arithmetic fast version. It can be made more robust using - * exact arithmetic schemes by Jonathan Richard Shewchuk. See - * http://www-2.cs.cmu.edu/~quake/robust.html - */ - template - real_type orient2dfast(real_type pa[2], real_type pb[2], real_type pc[2]) { - real_type acx = pa[0] - pc[0]; - real_type bcx = pb[0] - pc[0]; - real_type acy = pa[1] - pc[1]; - real_type bcy = pb[1] - pc[1]; return acx * bcy - acy * bcx; - } +} -}; // End of ttl_util namespace scope +} // namespace ttl_util #endif // _TTL_UTIL_H_ diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index b2bc4d5899..f74a412479 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -68,7 +68,7 @@ bool sortDistance( const RN_NODE_PTR& aOrigin, const RN_NODE_PTR& aNode1, bool sortWeight( const RN_EDGE_PTR& aEdge1, const RN_EDGE_PTR& aEdge2 ) { - return aEdge1->getWeight() < aEdge2->getWeight(); + return aEdge1->GetWeight() < aEdge2->GetWeight(); } @@ -92,7 +92,7 @@ bool operator!=( const RN_NODE_PTR& aFirst, const RN_NODE_PTR& aSecond ) bool isEdgeConnectingNode( const RN_EDGE_PTR& aEdge, const RN_NODE_PTR& aNode ) { - return aEdge->getSourceNode() == aNode || aEdge->getTargetNode() == aNode; + return aEdge->GetSourceNode() == aNode || aEdge->GetTargetNode() == aNode; } @@ -125,8 +125,8 @@ std::vector* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges, { RN_EDGE_PTR& dt = *aEdges.begin(); - int srcTag = tags[dt->getSourceNode()]; - int trgTag = tags[dt->getTargetNode()]; + int srcTag = tags[dt->GetSourceNode()]; + int trgTag = tags[dt->GetTargetNode()]; // Check if by adding this edge we are going to join two different forests if( srcTag != trgTag ) @@ -139,7 +139,7 @@ std::vector* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges, // Move nodes that were marked with old tag to the list marked with the new tag cycles[srcTag].splice( cycles[srcTag].end(), cycles[trgTag] ); - if( dt->getWeight() == 0 ) // Skip already existing connections (weight == 0) + if( dt->GetWeight() == 0 ) // Skip already existing connections (weight == 0) { mstExpectedSize--; } @@ -148,9 +148,9 @@ std::vector* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges, // 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() ); + RN_EDGE_MST_PTR newEdge = boost::make_shared( dt->GetSourceNode(), + dt->GetTargetNode(), + dt->GetWeight() ); mst->push_back( newEdge ); ++mstSize; } @@ -169,8 +169,8 @@ std::vector* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges, void RN_NET::validateEdge( RN_EDGE_PTR& aEdge ) { - RN_NODE_PTR source = aEdge->getSourceNode(); - RN_NODE_PTR target = aEdge->getTargetNode(); + RN_NODE_PTR source = aEdge->GetSourceNode(); + RN_NODE_PTR target = aEdge->GetTargetNode(); bool valid = true; // If any of nodes belonging to the edge has the flag set, @@ -280,13 +280,13 @@ void RN_NET::compute() std::partial_sort_copy( boardNodes.begin(), boardNodes.end(), nodes.begin(), nodes.end() ); TRIANGULATOR triangulator; - triangulator.createDelaunay( nodes.begin(), nodes.end() ); - boost::scoped_ptr triangEdges( triangulator.getEdges() ); + triangulator.CreateDelaunay( nodes.begin(), nodes.end() ); + boost::scoped_ptr triangEdges( triangulator.GetEdges() ); // Compute weight/distance for edges resulting from triangulation RN_LINKS::RN_EDGE_LIST::iterator eit, eitEnd; for( eit = (*triangEdges).begin(), eitEnd = (*triangEdges).end(); eit != eitEnd; ++eit ) - (*eit)->setWeight( getDistance( (*eit)->getSourceNode(), (*eit)->getTargetNode() ) ); + (*eit)->SetWeight( getDistance( (*eit)->GetSourceNode(), (*eit)->GetTargetNode() ) ); // Add the currently existing connections list to the results of triangulation std::copy( boardEdges.begin(), boardEdges.end(), std::front_inserter( *triangEdges ) ); @@ -508,8 +508,8 @@ void RN_NET::RemoveItem( const TRACK* aTrack ) RN_EDGE_PTR& edge = m_tracks.at( aTrack ); // Save nodes, so they can be cleared later - RN_NODE_PTR aBegin = edge->getSourceNode(); - RN_NODE_PTR aEnd = edge->getTargetNode(); + 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 @@ -696,8 +696,8 @@ std::list RN_NET::GetNodes( const BOARD_CONNECTED_ITEM* aItem ) con const TRACK* track = static_cast( aItem ); RN_EDGE_PTR edge = m_tracks.at( track ); - nodes.push_back( edge->getSourceNode() ); - nodes.push_back( edge->getTargetNode() ); + nodes.push_back( edge->GetSourceNode() ); + nodes.push_back( edge->GetTargetNode() ); } break; diff --git a/pcbnew/ratsnest_data.h b/pcbnew/ratsnest_data.h index 712909f2fa..afc9c0935f 100644 --- a/pcbnew/ratsnest_data.h +++ b/pcbnew/ratsnest_data.h @@ -50,13 +50,13 @@ class ZONE_CONTAINER; class CPolyPt; // Preserve KiCad coding style policy -typedef hed::Node RN_NODE; -typedef hed::NodePtr RN_NODE_PTR; -typedef hed::Edge RN_EDGE; -typedef hed::EdgePtr RN_EDGE_PTR; -typedef hed::EdgeMST RN_EDGE_MST; -typedef boost::shared_ptr RN_EDGE_MST_PTR; -typedef hed::Triangulation TRIANGULATOR; +typedef hed::NODE RN_NODE; +typedef hed::NODE_PTR RN_NODE_PTR; +typedef hed::EDGE RN_EDGE; +typedef hed::EDGE_PTR RN_EDGE_PTR; +typedef hed::EDGE_MST RN_EDGE_MST; +typedef hed::TRIANGULATION TRIANGULATOR; +typedef boost::shared_ptr RN_EDGE_MST_PTR; bool operator==( const RN_NODE_PTR& aFirst, const RN_NODE_PTR& aSecond ); bool operator!=( const RN_NODE_PTR& aFirst, const RN_NODE_PTR& aSecond ); diff --git a/pcbnew/ratsnest_viewitem.cpp b/pcbnew/ratsnest_viewitem.cpp index 5de2527111..ffe88c3c7f 100644 --- a/pcbnew/ratsnest_viewitem.cpp +++ b/pcbnew/ratsnest_viewitem.cpp @@ -97,8 +97,8 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const BOOST_FOREACH( const RN_EDGE_PTR& edge, *edges ) { - const RN_NODE_PTR& sourceNode = edge->getSourceNode(); - const RN_NODE_PTR& targetNode = edge->getTargetNode(); + const RN_NODE_PTR& sourceNode = edge->GetSourceNode(); + const RN_NODE_PTR& targetNode = edge->GetTargetNode(); VECTOR2D source( sourceNode->GetX(), sourceNode->GetY() ); VECTOR2D target( targetNode->GetX(), targetNode->GetY() ); From 7dc08c871808ec48a28c635453089ac6f844055d Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 7 Apr 2014 13:50:18 +0200 Subject: [PATCH 124/134] Fixed switching back to selection tool using the right toolbar buttons in pcbnew (GAL). --- pcbnew/edit.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index 0fbe391318..3aad9dc78f 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -1374,7 +1374,7 @@ void PCB_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent ) { std::string actionName = COMMON_ACTIONS::TranslateLegacyId( id ); - if( !actionName.empty() ) + if( !actionName.empty() || id == ID_NO_TOOL_SELECTED ) { const int MAX_TRIALS = 10; int trials = 0; @@ -1389,7 +1389,8 @@ void PCB_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent ) m_toolManager.ProcessEvent( cancel ); } - m_toolManager.RunAction( actionName ); + if( !actionName.empty() ) + m_toolManager.RunAction( actionName ); } } else From cc445391e980eb1231580d53a6bd66c4dbbb3ee3 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 7 Apr 2014 13:59:27 +0200 Subject: [PATCH 125/134] Items that may be modified using EDIT_POINTs used to stay selected after pressing ESC (only EDIT_POINTs got away) - fixed. --- pcbnew/tools/point_editor.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index f4aa4baa17..1b6ed99e20 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -315,6 +315,9 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) modified = false; } + // Let the selection tool receive the event too + m_toolMgr->PassEvent(); + break; } From c5b65e1ec42fee9390315299616834e67153056f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 7 Apr 2014 14:30:38 +0200 Subject: [PATCH 126/134] Fixed outline breaking for zones (points were not always created in the double click point). --- pcbnew/tools/point_editor.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 1b6ed99e20..f7e5b374c2 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -338,6 +338,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) controls->ShowCursor( false ); controls->SetAutoPan( false ); controls->SetSnapping( false ); + controls->ForceCursorPosition( false ); } setTransitions(); @@ -672,9 +673,9 @@ void POINT_EDITOR::breakOutline( const VECTOR2I& aBreakPoint ) VECTOR2I( outline->GetPos( nextNearestIdx ) ) ); unsigned int nearestDist = side.Distance( aBreakPoint ); - for( int i = 0; i < outline->GetCornersCount() - 2; ++i ) + for( int i = 0; i < outline->GetCornersCount() - 1; ++i ) { - SEG side( VECTOR2I( outline->GetPos( i ) ), VECTOR2I( outline->GetPos( i + 1 ) ) ); + side = SEG( VECTOR2I( outline->GetPos( i ) ), VECTOR2I( outline->GetPos( i + 1 ) ) ); unsigned int distance = side.Distance( aBreakPoint ); if( distance < nearestDist ) From 89161331e4224736ea59013b1d66ca609efb46c2 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 7 Apr 2014 15:35:50 +0200 Subject: [PATCH 127/134] Fixed refreshing issues (DRC, new items after reloading netlist and probably many other places). --- common/view/view.cpp | 6 +++--- include/view/view_item.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/common/view/view.cpp b/common/view/view.cpp index 08de942811..4bf71ec638 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -99,11 +99,11 @@ void VIEW::Add( VIEW_ITEM* aItem ) MarkTargetDirty( l.target ); } - if( aItem->viewRequiredUpdate() != VIEW_ITEM::NONE ) - MarkForUpdate( aItem ); - if( m_dynamic ) aItem->viewAssign( this ); + + if( aItem->viewRequiredUpdate() != VIEW_ITEM::NONE ) + MarkForUpdate( aItem ); } diff --git a/include/view/view_item.h b/include/view/view_item.h index a64b1b22db..6540ea3c82 100644 --- a/include/view/view_item.h +++ b/include/view/view_item.h @@ -174,7 +174,7 @@ public: ALL = 0xff }; - VIEW_ITEM() : m_view( NULL ), m_visible( true ), m_requiredUpdate( NONE ), + VIEW_ITEM() : m_view( NULL ), m_visible( true ), m_requiredUpdate( ALL ), m_groups( NULL ), m_groupsSize( 0 ) {} /** @@ -184,7 +184,7 @@ public: { ViewRelease(); delete[] m_groups; - }; + } /** * Function Type From 82661dc3a61e66103c26475b8db4109f0c2a2088 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 7 Apr 2014 16:04:54 +0200 Subject: [PATCH 128/134] GAL defaults to Cairo, so KiCad does not fail on completely OpenGL incapable systems. Board is cached in GAL only when the canvas is activated. --- pcbnew/basepcbframe.cpp | 2 +- pcbnew/pcbframe.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index 12d783e143..0e4299eaef 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -157,7 +157,7 @@ PCB_BASE_FRAME::PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, ID_DRAWFRAME_T SetGalCanvas( new EDA_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), m_FrameSize, - EDA_DRAW_PANEL_GAL::GAL_TYPE_OPENGL ) ); + EDA_DRAW_PANEL_GAL::GAL_TYPE_CAIRO ) ); // Hide by default, it has to be explicitly shown GetGalCanvas()->Hide(); diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index f602df3d53..302a9574c8 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -490,13 +490,13 @@ void PCB_EDIT_FRAME::SetBoard( BOARD* aBoard ) { PCB_BASE_FRAME::SetBoard( aBoard ); - if( GetGalCanvas() ) + if( IsGalCanvasActive() ) { ViewReloadBoard( aBoard ); // update the tool manager with the new board and its view. m_toolManager.SetEnvironment( aBoard, GetGalCanvas()->GetView(), - GetGalCanvas()->GetViewControls(), this ); + GetGalCanvas()->GetViewControls(), this ); m_toolManager.ResetTools( TOOL_BASE::MODEL_RELOAD ); } } From e6fd3934d10b0e9e8c0124dd0fb50c99e8538183 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Apr 2014 16:57:22 +0200 Subject: [PATCH 129/134] Fixed ratsnest update after removing items. --- pcbnew/tools/edit_tool.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 5be7f25396..8dac46385c 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -395,10 +395,7 @@ int EDIT_TOOL::Remove( TOOL_EVENT& aEvent ) remove( item ); } - // Rebuild list of pads and nets if necessary - BOARD* board = getModel( PCB_T ); - if( !( board->m_Status_Pcb & NET_CODES_OK ) ) - board->BuildListOfNets(); + getModel( PCB_T )->GetRatsnest()->Recalculate(); setTransitions(); From 371b2f7c0e56ad89d575e9d3ca58081fa9bf7389 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Apr 2014 17:01:22 +0200 Subject: [PATCH 130/134] Fixed vias layer order. --- pcbnew/basepcbframe.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index 0e4299eaef..3abbba0aff 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -87,7 +87,7 @@ const LAYER_NUM PCB_BASE_FRAME::GAL_LAYER_ORDER[] = ITEM_GAL_LAYER( RATSNEST_VISIBLE ), ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), - ITEM_GAL_LAYER( VIAS_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ), + ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ), NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE ), ITEM_GAL_LAYER( PAD_FR_VISIBLE ), SOLDERMASK_N_FRONT, NETNAMES_GAL_LAYER( LAYER_16_NETNAMES_VISIBLE ), LAYER_N_FRONT, From 50b202fe99b4b6cb144a534c305e56f467157620 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Apr 2014 17:05:05 +0200 Subject: [PATCH 131/134] Hot keys specific to a tool have priority over global hot keys (TOOL_ACTION scope: AS_GLOBAL/AS_CONTEXT is finally handled properly). --- common/tool/action_manager.cpp | 76 +++++++++++++++++++++++++-------- common/tool/tool_manager.cpp | 19 +++++++++ include/tool/action_manager.h | 11 ++--- include/tool/tool_action.h | 15 +++++++ include/tool/tool_manager.h | 10 +++++ pcbnew/router/router_tool.cpp | 10 ++--- pcbnew/tools/common_actions.cpp | 5 ++- 7 files changed, 114 insertions(+), 32 deletions(-) diff --git a/common/tool/action_manager.cpp b/common/tool/action_manager.cpp index bc1a8be368..24ee6ca818 100644 --- a/common/tool/action_manager.cpp +++ b/common/tool/action_manager.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include ACTION_MANAGER::ACTION_MANAGER( TOOL_MANAGER* aToolManager ) : @@ -43,7 +44,12 @@ ACTION_MANAGER::~ACTION_MANAGER() void ACTION_MANAGER::RegisterAction( TOOL_ACTION* aAction ) { - assert( aAction->GetId() == -1 ); // Check if the TOOL_ACTION was not registered before + // Check if the TOOL_ACTION was not registered before + assert( aAction->GetId() == -1 ); + // TOOL_ACTIONs are supposed to be named [appName.]toolName.actionName (with dots between) + // action name without specifying at least toolName is not valid + assert( aAction->GetName().find( '.', 0 ) != std::string::npos ); + assert( m_actionNameIndex.find( aAction->m_name ) == m_actionNameIndex.end() ); assert( m_actionIdIndex.find( aAction->m_id ) == m_actionIdIndex.end() ); @@ -53,13 +59,7 @@ 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; - } + m_actionHotKeys[aAction->m_currentHotKey].push_back( aAction ); } @@ -72,7 +72,15 @@ void ACTION_MANAGER::UnregisterAction( TOOL_ACTION* aAction ) aAction->setId( -1 ); if( aAction->HasHotKey() ) - m_actionHotKeys.erase( aAction->m_currentHotKey ); + { + std::list& actions = m_actionHotKeys[aAction->m_currentHotKey]; + std::list::iterator action = std::find( actions.begin(), actions.end(), aAction ); + + if( action != actions.end() ) + actions.erase( action ); + else + assert( false ); + } } @@ -107,18 +115,52 @@ void ACTION_MANAGER::RunAction( const TOOL_ACTION* aAction ) const bool ACTION_MANAGER::RunHotKey( int aHotKey ) const { - std::map::const_iterator it = m_actionHotKeys.find( aHotKey ); + HOTKEY_LIST::const_iterator it = m_actionHotKeys.find( aHotKey ); if( it == m_actionHotKeys.end() ) return false; // no appropriate action found for the hotkey - RunAction( it->second ); + const std::list& actions = it->second; + + // Choose the action that has the highest priority on the active tools stack + // If there is none, run the global action associated with the hot key + int highestPriority = -1, priority = -1; + const TOOL_ACTION* context = NULL; // pointer to context action of the highest priority tool + const TOOL_ACTION* global = NULL; // pointer to global action, if there is no context action + + BOOST_FOREACH( const TOOL_ACTION* action, actions ) + { + if( action->GetScope() == AS_GLOBAL ) + { + // Store the global action for the hot key in case there was no possible + // context actions to run + assert( global == NULL ); // there should be only one global action per hot key + global = action; + + continue; + } + + TOOL_BASE* tool = m_toolMgr->FindTool( action->GetToolName() ); + + if( tool ) + { + priority = m_toolMgr->GetPriority( tool->GetId() ); + + if( priority >= 0 && priority > highestPriority ) + { + highestPriority = priority; + context = action; + } + } + } + + if( !global && !context ) // currently there is no valid action to run + return false; + + if( context ) + RunAction( context ); + else if( global ) + RunAction( global ); return true; } - - -void ACTION_MANAGER::ClearHotKey( int aHotKey ) -{ - m_actionHotKeys.erase( aHotKey ); -} diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index eff64f267d..8c05ca5282 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -301,6 +301,25 @@ void TOOL_MANAGER::ResetTools( TOOL_BASE::RESET_REASON aReason ) } +int TOOL_MANAGER::GetPriority( int aToolId ) const +{ + int priority = 0; + + for( std::deque::const_iterator it = m_activeTools.begin(), + itEnd = m_activeTools.end(); it != itEnd; ++it ) + { + std::cout << FindTool( *it )->GetName() << std::endl; + + if( *it == aToolId ) + return priority; + + ++priority; + } + + return -1; +} + + void TOOL_MANAGER::ScheduleNextState( TOOL_BASE* aTool, TOOL_STATE_FUNC& aHandler, const TOOL_EVENT_LIST& aConditions ) { diff --git a/include/tool/action_manager.h b/include/tool/action_manager.h index b38b329abc..626f795eff 100644 --- a/include/tool/action_manager.h +++ b/include/tool/action_manager.h @@ -25,6 +25,7 @@ #ifndef ACTION_MANAGER_H_ #define ACTION_MANAGER_H_ +#include #include #include @@ -97,13 +98,6 @@ public: */ 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; @@ -115,7 +109,8 @@ private: std::map m_actionNameIndex; ///> Map for indexing actions by their hotkeys - std::map m_actionHotKeys; + typedef std::map > HOTKEY_LIST; + HOTKEY_LIST m_actionHotKeys; }; #endif /* ACTION_MANAGER_H_ */ diff --git a/include/tool/tool_action.h b/include/tool/tool_action.h index 4d91ea982f..8fb81e5d8d 100644 --- a/include/tool/tool_action.h +++ b/include/tool/tool_action.h @@ -171,6 +171,21 @@ public: m_menuDescription = aDescription; } + TOOL_ACTION_SCOPE GetScope() const + { + return m_scope; + } + + /** + * Returns name of the tool associated with the action. It is basically the action name + * stripped of the last part (e.g. for "pcbnew.InteractiveDrawing.drawCircle" it is + * "pcbnew.InteractiveDrawing"). + */ + std::string GetToolName() const + { + return m_name.substr( 0, m_name.rfind( '.' ) ); + } + private: friend class ACTION_MANAGER; diff --git a/include/tool/tool_manager.h b/include/tool/tool_manager.h index 7689a9a3c8..1e4563a7e0 100644 --- a/include/tool/tool_manager.h +++ b/include/tool/tool_manager.h @@ -206,6 +206,16 @@ public: return FindTool( GetCurrentToolId() ); } + /** + * Returns priority of a given tool. Higher number means that the tool is closer to the + * beginning of the active tools queue (i.e. receives events earlier, tools with lower + * priority receive events later). + * @param aToolId is the id of queried tool. + * @return The priority of a given tool. If returned number is negative, then it means that + * the tool id is invalid or the tool is not active. + */ + int GetPriority( int aToolId ) const; + /** * Defines a state transition - the events that cause a given handler method in the tool * to be called. Called by TOOL_INTERACTIVE::Go(). May be called from a coroutine context. diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index a2e98f71de..dd24327678 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -45,11 +45,11 @@ using namespace KIGFX; using boost::optional; -static TOOL_ACTION ACT_AutoEndRoute( "AutoEndRoute", AS_CONTEXT, 'G' ); -static TOOL_ACTION ACT_PlaceVia( "PlaceVia", AS_CONTEXT, 'V' ); -static TOOL_ACTION ACT_OpenRouteOptions( "OpenRouterOptions", AS_CONTEXT, 'Y' ); -static TOOL_ACTION ACT_SwitchPosture( "SwitchPosture", AS_CONTEXT, '/' ); -static TOOL_ACTION ACT_EndTrack( "EndTrack", AS_CONTEXT, WXK_END ); +static TOOL_ACTION ACT_AutoEndRoute( "pcbnew.InteractiveRouter.AutoEndRoute", AS_CONTEXT, 'G' ); +static TOOL_ACTION ACT_PlaceVia( "pcbnew.InteractiveRouter.PlaceVia", AS_CONTEXT, 'V' ); +static TOOL_ACTION ACT_OpenRouteOptions( "pcbnew.InteractiveRouter.OpenRouterOptions", AS_CONTEXT, 'T' ); +static TOOL_ACTION ACT_SwitchPosture( "pcbnew.InteractiveRouter.SwitchPosture", AS_CONTEXT, '/' ); +static TOOL_ACTION ACT_EndTrack( "pcbnew.InteractiveRouter.EndTrack", AS_CONTEXT, WXK_END ); ROUTER_TOOL::ROUTER_TOOL() : TOOL_INTERACTIVE( "pcbnew.InteractiveRouter" ) diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 63f4f91712..90a235e9ac 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -43,11 +43,11 @@ TOOL_ACTION COMMON_ACTIONS::editActivate( "pcbnew.InteractiveEdit", "Move", "Moves the selected item(s)" ); TOOL_ACTION COMMON_ACTIONS::rotate( "pcbnew.rotate", - AS_CONTEXT, 'R', + AS_GLOBAL, 'R', "Rotate", "Rotates selected item(s)" ); TOOL_ACTION COMMON_ACTIONS::flip( "pcbnew.flip", - AS_CONTEXT, 'F', + AS_GLOBAL, 'F', "Flip", "Flips selected item(s)" ); TOOL_ACTION COMMON_ACTIONS::remove( "pcbnew.InteractiveEdit.remove", @@ -58,6 +58,7 @@ TOOL_ACTION COMMON_ACTIONS::properties( "pcbnew.InteractiveEdit.properties", AS_GLOBAL, 'E', "Properties...", "Displays properties window" ); + // Drawing tool actions TOOL_ACTION COMMON_ACTIONS::drawLine( "pcbnew.InteractiveDrawing.line", AS_GLOBAL, 0, From 3f8d9da31fb2c598c59a0851447abd1bc0a3d450 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Apr 2014 17:33:22 +0200 Subject: [PATCH 132/134] Key events are handled by wxEVT_CHAR instead of wxEVT_KEY_[UP|DOWN]. Fixed issue of chars that require modifiers (e.g. ? is Shift+/ on US keyboard layout). --- common/draw_panel_gal.cpp | 3 +-- common/tool/action_manager.cpp | 16 +++++++++++++-- common/tool/tool_dispatcher.cpp | 21 ++++++++++--------- common/tool/tool_event.cpp | 3 +-- common/tool/tool_manager.cpp | 2 +- include/tool/tool_event.h | 36 ++++++++++++++------------------- pcbnew/router/router_tool.cpp | 14 ++++++------- pcbnew/tools/common_actions.cpp | 10 ++++----- pcbnew/tools/drawing_tool.cpp | 8 ++++---- 9 files changed, 60 insertions(+), 53 deletions(-) diff --git a/common/draw_panel_gal.cpp b/common/draw_panel_gal.cpp index a8c1dc0f67..0ec6a1130b 100644 --- a/common/draw_panel_gal.cpp +++ b/common/draw_panel_gal.cpp @@ -83,8 +83,7 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin 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_CHAR, 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/tool/action_manager.cpp b/common/tool/action_manager.cpp index 24ee6ca818..51c85aa273 100644 --- a/common/tool/action_manager.cpp +++ b/common/tool/action_manager.cpp @@ -115,10 +115,22 @@ void ACTION_MANAGER::RunAction( const TOOL_ACTION* aAction ) const bool ACTION_MANAGER::RunHotKey( int aHotKey ) const { - HOTKEY_LIST::const_iterator it = m_actionHotKeys.find( aHotKey ); + int key = std::toupper( aHotKey & ~MD_MODIFIER_MASK ); + int mod = aHotKey & MD_MODIFIER_MASK; + HOTKEY_LIST::const_iterator it = m_actionHotKeys.find( key | mod ); + + // If no luck, try without modifier, to handle keys that require a modifier + // e.g. to get ? you need to press Shift+/ without US keyboard layout + // Hardcoding ? as Shift+/ is a bad idea, as on another layout you may need to press a + // different combination if( it == m_actionHotKeys.end() ) - return false; // no appropriate action found for the hotkey + { + it = m_actionHotKeys.find( key ); + + if( it == m_actionHotKeys.end() ) + return false; // no appropriate action found for the hotkey + } const std::list& actions = it->second; diff --git a/common/tool/tool_dispatcher.cpp b/common/tool/tool_dispatcher.cpp index f89c7ee03f..a387d6581a 100644 --- a/common/tool/tool_dispatcher.cpp +++ b/common/tool/tool_dispatcher.cpp @@ -243,23 +243,26 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) } // Keyboard handling - else if( type == wxEVT_KEY_UP || type == wxEVT_KEY_DOWN ) + else if( type == wxEVT_CHAR ) { wxKeyEvent* ke = static_cast( &aEvent ); int key = ke->GetKeyCode(); int mods = decodeModifiers( ke ); - if( type == wxEVT_KEY_UP ) + if( mods & MD_CTRL ) { - evt = TOOL_EVENT( TC_KEYBOARD, TA_KEY_UP, key | mods ); + // wxWidgets have a quirk related to Ctrl+letter hot keys handled by CHAR_EVT + // http://docs.wxwidgets.org/trunk/classwx_key_event.html: + // "char events for ASCII letters in this case carry codes corresponding to the ASCII + // value of Ctrl-Latter, i.e. 1 for Ctrl-A, 2 for Ctrl-B and so on until 26 for Ctrl-Z." + if( key >= WXK_CONTROL_A && key <= WXK_CONTROL_Z ) + key += 'A' - 1; } + + if( key == WXK_ESCAPE ) // ESC is the special key for cancelling tools + evt = TOOL_EVENT( TC_COMMAND, TA_CANCEL_TOOL ); else - { - if( key == WXK_ESCAPE ) // ESC is the special key for cancelling tools - evt = TOOL_EVENT( TC_COMMAND, TA_CANCEL_TOOL ); - else - evt = TOOL_EVENT( TC_KEYBOARD, TA_KEY_DOWN, key | mods ); - } + evt = TOOL_EVENT( TC_KEYBOARD, TA_KEY_PRESSED, key | mods ); } if( evt ) diff --git a/common/tool/tool_event.cpp b/common/tool/tool_event.cpp index 07460f3571..50739ba419 100644 --- a/common/tool/tool_event.cpp +++ b/common/tool/tool_event.cpp @@ -81,8 +81,7 @@ const std::string TOOL_EVENT::Format() const { TA_MOUSE_DRAG, "drag" }, { TA_MOUSE_MOTION, "motion" }, { TA_MOUSE_WHEEL, "wheel" }, - { TA_KEY_UP, "key-up" }, - { TA_KEY_DOWN, "key-down" }, + { TA_KEY_PRESSED, "key-pressed" }, { TA_VIEW_REFRESH, "view-refresh" }, { TA_VIEW_ZOOM, "view-zoom" }, { TA_VIEW_PAN, "view-pan" }, diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index 8c05ca5282..e83b8fc6d2 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -417,7 +417,7 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent ) bool TOOL_MANAGER::dispatchStandardEvents( TOOL_EVENT& aEvent ) { - if( aEvent.Action() == TA_KEY_UP ) + if( aEvent.Action() == TA_KEY_PRESSED ) { // Check if there is a hotkey associated if( m_actionMgr->RunHotKey( aEvent.Modifier() | aEvent.KeyCode() ) ) diff --git a/include/tool/tool_event.h b/include/tool/tool_event.h index 4571b5a9f8..bdfe8a8a10 100644 --- a/include/tool/tool_event.h +++ b/include/tool/tool_event.h @@ -64,36 +64,35 @@ enum TOOL_ACTIONS TA_MOUSE_WHEEL = 0x0040, TA_MOUSE = 0x007f, - TA_KEY_UP = 0x0080, - TA_KEY_DOWN = 0x0100, - TA_KEYBOARD = TA_KEY_UP | TA_KEY_DOWN, + TA_KEY_PRESSED = 0x0080, + TA_KEYBOARD = TA_KEY_PRESSED, // View related events - TA_VIEW_REFRESH = 0x0200, - TA_VIEW_ZOOM = 0x0400, - TA_VIEW_PAN = 0x0800, - TA_VIEW_DIRTY = 0x1000, - TA_VIEW = 0x1e00, + TA_VIEW_REFRESH = 0x0100, + TA_VIEW_ZOOM = 0x0200, + TA_VIEW_PAN = 0x0400, + TA_VIEW_DIRTY = 0x0800, + TA_VIEW = 0x0f00, - TA_CHANGE_LAYER = 0x2000, + TA_CHANGE_LAYER = 0x1000, // Tool cancel event. Issued automagically when the user hits escape or selects End Tool from // the context menu. - TA_CANCEL_TOOL = 0x4000, + TA_CANCEL_TOOL = 0x2000, // 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 = 0x8000, + TA_CONTEXT_MENU_UPDATE = 0x4000, // Context menu choice. Sent if the user picked something from the context menu or // closed it without selecting anything. - TA_CONTEXT_MENU_CHOICE = 0x10000, + TA_CONTEXT_MENU_CHOICE = 0x8000, // This event is sent *before* undo/redo command is performed. - TA_UNDO_REDO = 0x20000, + TA_UNDO_REDO = 0x10000, // Tool action (allows to control tools) - TA_ACTION = 0x40000, + TA_ACTION = 0x20000, TA_ANY = 0xffffffff }; @@ -277,14 +276,9 @@ public: return m_keyCode; } - bool IsKeyUp() const + bool IsKeyPressed() const { - return m_actions == TA_KEY_UP; - } - - bool IsKeyDown() const - { - return m_actions == TA_KEY_DOWN; + return m_actions == TA_KEY_PRESSED; } void SetMouseDragOrigin( const VECTOR2D& aP ) diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index dd24327678..8fe733fb8c 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -45,11 +45,11 @@ using namespace KIGFX; using boost::optional; -static TOOL_ACTION ACT_AutoEndRoute( "pcbnew.InteractiveRouter.AutoEndRoute", AS_CONTEXT, 'G' ); -static TOOL_ACTION ACT_PlaceVia( "pcbnew.InteractiveRouter.PlaceVia", AS_CONTEXT, 'V' ); -static TOOL_ACTION ACT_OpenRouteOptions( "pcbnew.InteractiveRouter.OpenRouterOptions", AS_CONTEXT, 'T' ); -static TOOL_ACTION ACT_SwitchPosture( "pcbnew.InteractiveRouter.SwitchPosture", AS_CONTEXT, '/' ); -static TOOL_ACTION ACT_EndTrack( "pcbnew.InteractiveRouter.EndTrack", AS_CONTEXT, WXK_END ); +//static TOOL_ACTION ACT_AutoEndRoute( "pcbnew.InteractiveRouter.AutoEndRoute", AS_CONTEXT, 'G' ); +//static TOOL_ACTION ACT_PlaceVia( "pcbnew.InteractiveRouter.PlaceVia", AS_CONTEXT, 'V' ); +//static TOOL_ACTION ACT_OpenRouteOptions( "pcbnew.InteractiveRouter.OpenRouterOptions", AS_CONTEXT, 'T' ); +//static TOOL_ACTION ACT_SwitchPosture( "pcbnew.InteractiveRouter.SwitchPosture", AS_CONTEXT, '/' ); +//static TOOL_ACTION ACT_EndTrack( "pcbnew.InteractiveRouter.EndTrack", AS_CONTEXT, WXK_END ); ROUTER_TOOL::ROUTER_TOOL() : TOOL_INTERACTIVE( "pcbnew.InteractiveRouter" ) @@ -367,9 +367,9 @@ void ROUTER_TOOL::startRouting() m_router->Move( m_endSnapPoint, m_endItem ); } - else if( evt->IsKeyUp() ) + else if( evt->IsKeyPressed() ) { - switch( evt->KeyCode() ) + switch( std::toupper( evt->KeyCode() ) ) { case 'V': { diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 90a235e9ac..3ff65af56b 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -148,11 +148,11 @@ TOOL_ACTION COMMON_ACTIONS::highContrastMode( "pcbnew.highContrastMode", "", "" ); TOOL_ACTION COMMON_ACTIONS::highContrastInc( "pcbnew.highContrastInc", - AS_GLOBAL, MD_SHIFT + '.', // shift+. == > + AS_GLOBAL, '>', "", "" ); TOOL_ACTION COMMON_ACTIONS::highContrastDec( "pcbnew.highContrastDec", - AS_GLOBAL, MD_SHIFT + 60, // shift+, == < + AS_GLOBAL, '<', "", "" ); @@ -198,11 +198,11 @@ TOOL_ACTION COMMON_ACTIONS::layerPrev( "pcbnew.layerPrev", "", "" ); TOOL_ACTION COMMON_ACTIONS::layerAlphaInc( "pcbnew.layerAlphaInc", - AS_GLOBAL, MD_SHIFT + ']', // shift+] == } + AS_GLOBAL, '}', "", "" ); TOOL_ACTION COMMON_ACTIONS::layerAlphaDec( "pcbnew.layerAlphaDec", - AS_GLOBAL, MD_SHIFT + '[', // shift+[ == { + AS_GLOBAL, '{', "", "" ); @@ -252,7 +252,7 @@ TOOL_ACTION COMMON_ACTIONS::switchUnits( "pcbnew.switchUnits", "", "" ); TOOL_ACTION COMMON_ACTIONS::showHelp( "pcbnew.showHelp", - AS_GLOBAL, MD_SHIFT + '/', // shift+/ == ? + AS_GLOBAL, '?', "", "" ); diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 1d85ec6906..34af899d35 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -135,7 +135,7 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) break; } - else if( evt->IsKeyUp() && step != SET_ORIGIN ) + else if( evt->IsKeyPressed() && step != SET_ORIGIN ) { int width = arc->GetWidth(); @@ -427,7 +427,7 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) break; } - else if( evt->IsKeyUp() && step != SET_ORIGIN ) + else if( evt->IsKeyPressed() && step != SET_ORIGIN ) { width = dimension->GetWidth(); @@ -603,7 +603,7 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) if( evt->IsCancel() ) break; - else if( evt->IsKeyUp() ) + else if( evt->IsKeyPressed() ) { int width = target->GetWidth(); @@ -822,7 +822,7 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) m_controls->SetAutoPan( false ); } - else if( graphic && evt->IsKeyUp() ) + else if( graphic && evt->IsKeyPressed() ) { int width = graphic->GetWidth(); From bff37e504e1ec732463b6190c0826154a27c15b6 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 15 Apr 2014 16:36:23 +0200 Subject: [PATCH 133/134] wxWidgets 2.8 compatibility fixes. --- common/tool/tool_dispatcher.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/common/tool/tool_dispatcher.cpp b/common/tool/tool_dispatcher.cpp index a387d6581a..502dccfbdb 100644 --- a/common/tool/tool_dispatcher.cpp +++ b/common/tool/tool_dispatcher.cpp @@ -251,6 +251,12 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) if( mods & MD_CTRL ) { +#if !wxCHECK_VERSION( 2, 9, 0 ) + // I really look forward to the day when we will use only one version of wxWidgets.. + const int WXK_CONTROL_A = 1; + const int WXK_CONTROL_Z = 26; +#endif + // wxWidgets have a quirk related to Ctrl+letter hot keys handled by CHAR_EVT // http://docs.wxwidgets.org/trunk/classwx_key_event.html: // "char events for ASCII letters in this case carry codes corresponding to the ASCII From fa5a6e5dd2f8c8def7b93950d58adbfa11a997a0 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Sun, 4 May 2014 20:20:49 +0200 Subject: [PATCH 134/134] Clearing m_hiddentItems to avoid PNS crashes. --- pcbnew/router/pns_router.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pcbnew/router/pns_router.cpp b/pcbnew/router/pns_router.cpp index 72d4cb7960..9a57b50b16 100644 --- a/pcbnew/router/pns_router.cpp +++ b/pcbnew/router/pns_router.cpp @@ -470,6 +470,8 @@ void PNS_ROUTER::EraseView() item->ViewSetVisible( true ); } + m_hiddenItems.clear(); + if( m_previewItems ) { m_previewItems->FreeItems();