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() {