diff --git a/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowMaskTab.cpp b/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowMaskTab.cpp
index c90fccd9e4b72a00a4ba8e906e1f781b88bb14b8..3cce4254663201da8da378d915dc8bd0103cf735 100644
--- a/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowMaskTab.cpp
+++ b/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowMaskTab.cpp
@@ -120,6 +120,13 @@ m_left(NULL), m_top(NULL), m_right(NULL), m_bottom(NULL)
   m_ring_rectangle->setToolTip("Draw a rectangular ring (Shift+Alt+R)");
   m_ring_rectangle->setShortcut(QKeySequence("Shift+Alt+R"));
 
+  m_free_draw = new QPushButton();
+  m_free_draw->setCheckable(true);
+  m_free_draw->setAutoExclusive(true);
+  m_free_draw->setIcon(QIcon(":/MaskTools/brush.png"));
+  m_free_draw->setToolTip("Draw an arbitrary shape (Shift+Alt+A)");
+  m_free_draw->setShortcut(QKeySequence("Shift+Alt+A"));
+
   QHBoxLayout* toolBox = new QHBoxLayout();
   toolBox->addWidget(m_move);
   toolBox->addWidget(m_pointer);
@@ -127,6 +134,7 @@ m_left(NULL), m_top(NULL), m_right(NULL), m_bottom(NULL)
   toolBox->addWidget(m_rectangle);
   toolBox->addWidget(m_ring_ellipse);
   toolBox->addWidget(m_ring_rectangle);
+  toolBox->addWidget(m_free_draw);
   toolBox->addStretch();
   toolBox->setSpacing(2);
   toolBox->setMargin(0);
@@ -137,6 +145,7 @@ m_left(NULL), m_top(NULL), m_right(NULL), m_bottom(NULL)
   connect(m_rectangle,SIGNAL(clicked()),this,SLOT(setActivity()));
   connect(m_ring_ellipse,SIGNAL(clicked()),this,SLOT(setActivity()));
   connect(m_ring_rectangle,SIGNAL(clicked()),this,SLOT(setActivity()));
+  connect(m_free_draw,SIGNAL(clicked()),this,SLOT(setActivity()));
   m_move->setChecked(true);
   QFrame* toolGroup = new QFrame();
   toolGroup->setLayout(toolBox);
@@ -340,6 +349,8 @@ void InstrumentWindowMaskTab::selectTool(Activity tool)
     break;
   case DrawRectangularRing: m_ring_rectangle->setChecked(true);
     break;
+  case DrawFree: m_free_draw->setChecked(true);
+    break;
   default: throw std::invalid_argument("Invalid tool type.");
   }
   setActivity();
@@ -362,37 +373,44 @@ void InstrumentWindowMaskTab::setActivity()
   else if (m_pointer->isChecked())
   {
     m_activity = Select;
-    m_instrWindow->getSurface()->setInteractionMode(ProjectionSurface::DrawMode);
+    m_instrWindow->getSurface()->setInteractionMode(ProjectionSurface::DrawRegularMode);
     m_activeTool->setText("Tool: Shape editing");
   }
   else if (m_ellipse->isChecked())
   {
     m_activity = DrawEllipse;
     m_instrWindow->getSurface()->startCreatingShape2D("ellipse",borderColor,fillColor);
-    m_instrWindow->getSurface()->setInteractionMode(ProjectionSurface::DrawMode);
+    m_instrWindow->getSurface()->setInteractionMode(ProjectionSurface::DrawRegularMode);
     m_activeTool->setText("Tool: Ellipse");
   }
   else if (m_rectangle->isChecked())
   {
     m_activity = DrawRectangle;
     m_instrWindow->getSurface()->startCreatingShape2D("rectangle",borderColor,fillColor);
-    m_instrWindow->getSurface()->setInteractionMode(ProjectionSurface::DrawMode);
+    m_instrWindow->getSurface()->setInteractionMode(ProjectionSurface::DrawRegularMode);
     m_activeTool->setText("Tool: Rectangle");
   }
   else if (m_ring_ellipse->isChecked())
   {
     m_activity = DrawEllipticalRing;
     m_instrWindow->getSurface()->startCreatingShape2D("ring ellipse",borderColor,fillColor);
-    m_instrWindow->getSurface()->setInteractionMode(ProjectionSurface::DrawMode);
+    m_instrWindow->getSurface()->setInteractionMode(ProjectionSurface::DrawRegularMode);
     m_activeTool->setText("Tool: Elliptical ring");
   }
   else if (m_ring_rectangle->isChecked())
   {
     m_activity = DrawRectangularRing;
     m_instrWindow->getSurface()->startCreatingShape2D("ring rectangle",borderColor,fillColor);
-    m_instrWindow->getSurface()->setInteractionMode(ProjectionSurface::DrawMode);
+    m_instrWindow->getSurface()->setInteractionMode(ProjectionSurface::DrawRegularMode);
     m_activeTool->setText("Tool: Rectangular ring");
   }
+  else if (m_free_draw->isChecked())
+  {
+    m_activity = DrawFree;
+    m_instrWindow->getSurface()->startCreatingFreeShape(borderColor,fillColor);
+    m_instrWindow->getSurface()->setInteractionMode(ProjectionSurface::DrawFreeMode);
+    m_activeTool->setText("Tool: Free draw");
+  }
   m_instrWindow->updateInfoText();
 }
 
@@ -401,7 +419,11 @@ void InstrumentWindowMaskTab::setActivity()
   */
 void InstrumentWindowMaskTab::shapeCreated()
 {
-  setSelectActivity();
+  if (!isVisible()) return;
+  if (m_activity != DrawFree)
+  {
+    setSelectActivity();
+  }
   enableApplyButtons();
 }
 
@@ -463,6 +485,7 @@ void InstrumentWindowMaskTab::shapesCleared()
 void InstrumentWindowMaskTab::clearShapes()
 {
     m_instrWindow->getSurface()->clearMask();
+    setSelectActivity();
 }
 
 void InstrumentWindowMaskTab::showEvent (QShowEvent *)
diff --git a/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowMaskTab.h b/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowMaskTab.h
index 5ef2db91bee8a2ac2946f64ce750114bdf99d62c..bb5093e1a48791a5eb84523d48743201091823c0 100644
--- a/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowMaskTab.h
+++ b/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowMaskTab.h
@@ -54,7 +54,7 @@ class InstrumentWindowMaskTab: public InstrumentWindowTab
   Q_OBJECT
 public:
   enum Mode {Mask, Group, ROI};
-  enum Activity {Move,Select,DrawEllipse,DrawRectangle,DrawEllipticalRing,DrawRectangularRing};
+  enum Activity {Move,Select,DrawEllipse,DrawRectangle,DrawEllipticalRing,DrawRectangularRing,DrawFree};
 
   InstrumentWindowMaskTab(InstrumentWindow* instrWindow);
   void initSurface();
@@ -129,6 +129,7 @@ protected:
   QPushButton* m_rectangle;
   QPushButton* m_ring_ellipse;
   QPushButton* m_ring_rectangle;
+  QPushButton* m_free_draw;
 
   QPushButton* m_apply;
   QPushButton* m_apply_to_view;
diff --git a/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowPickTab.cpp b/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowPickTab.cpp
index 05247a3929590148097e37ed1dabe406f0a4a91c..f49c0a553dada231bfbf167e2413e54d2c64d922 100644
--- a/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowPickTab.cpp
+++ b/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowPickTab.cpp
@@ -197,6 +197,12 @@ m_plotTypeCache(0)
   m_ring_rectangle->setIcon(QIcon(":/PickTools/selection-box-ring.png"));
   m_ring_rectangle->setToolTip("Draw a rectangular ring");
 
+  m_free_draw = new QPushButton();
+  m_free_draw->setCheckable(true);
+  m_free_draw->setAutoExclusive(true);
+  m_free_draw->setIcon(QIcon(":/PickTools/brush.png"));
+  m_free_draw->setToolTip("Draw an arbitrary shape");
+
   m_edit = new QPushButton();
   m_edit->setCheckable(true);
   m_edit->setAutoExclusive(true);
@@ -222,6 +228,7 @@ m_plotTypeCache(0)
   toolBox->addWidget(m_rectangle,0,3);
   toolBox->addWidget(m_ring_ellipse,0,4);
   toolBox->addWidget(m_ring_rectangle,0,5);
+  toolBox->addWidget(m_free_draw,0,6);
   toolBox->addWidget(m_one,1,0);
   toolBox->addWidget(m_tube,1,1);
   toolBox->addWidget(m_peak,1,2);
@@ -237,6 +244,7 @@ m_plotTypeCache(0)
   connect(m_ellipse,SIGNAL(clicked()),this,SLOT(setSelectionType()));
   connect(m_ring_ellipse,SIGNAL(clicked()),this,SLOT(setSelectionType()));
   connect(m_ring_rectangle,SIGNAL(clicked()),this,SLOT(setSelectionType()));
+  connect(m_free_draw,SIGNAL(clicked()),this,SLOT(setSelectionType()));
   connect(m_edit,SIGNAL(clicked()),this,SLOT(setSelectionType()));
 
   // lay out the widgets
@@ -404,13 +412,13 @@ void InstrumentWindowPickTab::setSelectionType()
   {
     m_selectionType = ErasePeak;
     m_activeTool->setText("Tool: Erase crystal peak(s)");
-    surfaceMode = ProjectionSurface::EraseMode;
+    surfaceMode = ProjectionSurface::ErasePeakMode;
   }
   else if (m_rectangle->isChecked())
   {
     m_selectionType = Draw;
     m_activeTool->setText("Tool: Rectangle");
-    surfaceMode = ProjectionSurface::DrawMode;
+    surfaceMode = ProjectionSurface::DrawRegularMode;
     plotType = DetectorPlotController::Single;
     m_instrWindow->getSurface()->startCreatingShape2D("rectangle",Qt::green,QColor(255,255,255,80));
   }
@@ -418,7 +426,7 @@ void InstrumentWindowPickTab::setSelectionType()
   {
     m_selectionType = Draw;
     m_activeTool->setText("Tool: Ellipse");
-    surfaceMode = ProjectionSurface::DrawMode;
+    surfaceMode = ProjectionSurface::DrawRegularMode;
     plotType = DetectorPlotController::Single;
     m_instrWindow->getSurface()->startCreatingShape2D("ellipse",Qt::green,QColor(255,255,255,80));
   }
@@ -426,7 +434,7 @@ void InstrumentWindowPickTab::setSelectionType()
   {
     m_selectionType = Draw;
     m_activeTool->setText("Tool: Elliptical ring");
-    surfaceMode = ProjectionSurface::DrawMode;
+    surfaceMode = ProjectionSurface::DrawRegularMode;
     plotType = DetectorPlotController::Single;
     m_instrWindow->getSurface()->startCreatingShape2D("ring ellipse",Qt::green,QColor(255,255,255,80));
   }
@@ -434,15 +442,23 @@ void InstrumentWindowPickTab::setSelectionType()
   {
     m_selectionType = Draw;
     m_activeTool->setText("Tool: Rectangular ring");
-    surfaceMode = ProjectionSurface::DrawMode;
+    surfaceMode = ProjectionSurface::DrawRegularMode;
     plotType = DetectorPlotController::Single;
     m_instrWindow->getSurface()->startCreatingShape2D("ring rectangle",Qt::green,QColor(255,255,255,80));
   }
+  else if (m_free_draw->isChecked())
+  {
+    m_selectionType = Draw;
+    m_activeTool->setText("Tool: Arbitrary shape");
+    surfaceMode = ProjectionSurface::DrawFreeMode;
+    plotType = DetectorPlotController::Single;
+    m_instrWindow->getSurface()->startCreatingFreeShape(Qt::green,QColor(255,255,255,80));
+  }
   else if (m_edit->isChecked())
   {
     m_selectionType = Draw;
     m_activeTool->setText("Tool: Shape editing");
-    surfaceMode = ProjectionSurface::DrawMode;
+    surfaceMode = ProjectionSurface::DrawRegularMode;
     plotType = DetectorPlotController::Single;
   }
   m_plotController->setPlotType( plotType );
@@ -451,7 +467,7 @@ void InstrumentWindowPickTab::setSelectionType()
   {
     surface->setInteractionMode( surfaceMode );
     auto interactionMode = surface->getInteractionMode();
-    if ( interactionMode == ProjectionSurface::DrawMode || interactionMode == ProjectionSurface::MoveMode )
+    if ( interactionMode == ProjectionSurface::DrawRegularMode || interactionMode == ProjectionSurface::MoveMode )
     {
         updatePlotMultipleDetectors();
     }
@@ -529,7 +545,7 @@ void InstrumentWindowPickTab::changedIntegrationRange(double,double)
   if ( surface )
   {
     auto interactionMode = surface->getInteractionMode();
-    if ( interactionMode == ProjectionSurface::DrawMode || interactionMode == ProjectionSurface::MoveMode )
+    if ( interactionMode == ProjectionSurface::DrawRegularMode || interactionMode == ProjectionSurface::MoveMode )
     {
         updatePlotMultipleDetectors();
     }
@@ -629,6 +645,8 @@ void InstrumentWindowPickTab::selectTool(const ToolType tool)
     break;
   case DrawEllipse: m_ellipse->setChecked(true);
     break;
+  case DrawFree: m_free_draw->setChecked(true);
+    break;
   case EditShape: m_edit->setChecked(true);
     break;
   default: throw std::invalid_argument("Invalid tool type.");
@@ -668,7 +686,11 @@ void InstrumentWindowPickTab::updateSelectionInfoDisplay()
  */
 void InstrumentWindowPickTab::shapeCreated()
 {
+  if ( !isVisible() ) return;
+  if (!m_free_draw->isChecked())
+  {
     selectTool( EditShape );
+  }
 }
 
 /**
diff --git a/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowPickTab.h b/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowPickTab.h
index ec169a6b904f917b7301cad5e29acf69816e44a8..5bcdf5c420fcbe6b22a105b1d72bd1e90bf8a399 100644
--- a/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowPickTab.h
+++ b/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowPickTab.h
@@ -47,7 +47,7 @@ public:
   ///   SelectPeak: click on a peak marker or draw a rubber-band selector to select peak
   ///               markers. Selected peaks can be deleted by pressing the Delete key.
   enum SelectionType {Single=0,AddPeak,ErasePeak,SingleDetectorSelection,Tube, Draw};
-  enum ToolType {Zoom,PixelSelect,TubeSelect,PeakSelect,PeakErase, DrawEllipse, DrawRectangle, EditShape};
+  enum ToolType {Zoom,PixelSelect,TubeSelect,PeakSelect,PeakErase, DrawEllipse, DrawRectangle, DrawFree, EditShape};
 
   InstrumentWindowPickTab(InstrumentWindow* instrWindow);
   bool canUpdateTouchedDetector()const;
@@ -91,6 +91,7 @@ private:
   QPushButton *m_ellipse;      ///< Button switching on drawing a elliptical selection region
   QPushButton *m_ring_ellipse; ///< Button switching on drawing a elliptical ring selection region
   QPushButton *m_ring_rectangle; ///< Button switching on drawing a rectangular ring selection region
+  QPushButton *m_free_draw;      ///< Button switching on drawing a region of arbitrary shape
   QPushButton *m_edit;           ///< Button switching on edditing the selection region
   bool m_plotSum;
 
diff --git a/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.cpp b/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.cpp
index cd8e0151e575838b1d05707d676ee92dc73ba563..1c6a0052da5fb529510990d2b153790c8ae3dee3 100644
--- a/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.cpp
+++ b/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.cpp
@@ -62,7 +62,7 @@ ProjectionSurface::ProjectionSurface(const InstrumentActor* rootActor):
 
   // create and connect the mask drawing input controller
   InputControllerDrawShape* drawController = new InputControllerDrawShape(this);
-  setInputController(DrawMode, drawController);
+  setInputController(DrawRegularMode, drawController);
   connect(drawController,SIGNAL(addShape(QString,int,int,QColor,QColor)),&m_maskShapes,SLOT(addShape(QString,int,int,QColor,QColor)));
   connect(this,SIGNAL(signalToStartCreatingShape2D(QString,QColor,QColor)),drawController,SLOT(startCreatingShape2D(QString,QColor,QColor)));
   connect(drawController,SIGNAL(moveRightBottomTo(int,int)),&m_maskShapes,SLOT(moveRightBottomTo(int,int)));
@@ -70,7 +70,6 @@ ProjectionSurface::ProjectionSurface(const InstrumentActor* rootActor):
   connect(drawController,SIGNAL(selectCtrlAt(int,int)),&m_maskShapes,SLOT(addToSelectionShapeAt(int,int)));
   connect(drawController,SIGNAL(moveBy(int,int)),&m_maskShapes,SLOT(moveShapeOrControlPointBy(int,int)));
   connect(drawController,SIGNAL(touchPointAt(int,int)),&m_maskShapes,SLOT(touchShapeOrControlPointAt(int,int)));
-  connect(drawController,SIGNAL(disabled()),&m_maskShapes,SLOT(deselectAll()));
   connect(drawController,SIGNAL(removeSelectedShapes()),&m_maskShapes,SLOT(removeSelectedShapes()));
   connect(drawController,SIGNAL(deselectAll()),&m_maskShapes,SLOT(deselectAll()));
   connect(drawController,SIGNAL(restoreOverrideCursor()),&m_maskShapes,SLOT(restoreOverrideCursor()));
@@ -78,9 +77,16 @@ ProjectionSurface::ProjectionSurface(const InstrumentActor* rootActor):
   connect(drawController,SIGNAL(finishSelection(QRect)),this,SLOT(selectMultipleMasks(QRect)));
   connect(drawController,SIGNAL(finishSelection(QRect)),this,SIGNAL(shapeChangeFinished()));
 
+  InputControllerDrawAndErase* freeDrawController = new InputControllerDrawAndErase(this);
+  setInputController(DrawFreeMode, freeDrawController);
+  connect(this,SIGNAL(signalToStartCreatingFreeShape(QColor,QColor)),freeDrawController,SLOT(startCreatingShape2D(QColor,QColor)));
+  connect(freeDrawController,SIGNAL(addShape(const QPolygonF&,QColor,QColor)),&m_maskShapes,SLOT(addFreeShape(const QPolygonF&,QColor,QColor)));
+  connect(freeDrawController,SIGNAL(draw(const QPolygonF&)),&m_maskShapes,SLOT(drawFree(const QPolygonF&)));
+  connect(freeDrawController,SIGNAL(erase(const QPolygonF&)),&m_maskShapes,SLOT(eraseFree(const QPolygonF&)));
+
   // create and connect the peak eraser controller
   InputControllerErase* eraseController = new InputControllerErase(this);
-  setInputController(EraseMode, eraseController);
+  setInputController(ErasePeakMode, eraseController);
   connect(eraseController,SIGNAL(erase(QRect)),this,SLOT(erasePeaks(QRect)));
 }
 
@@ -138,7 +144,7 @@ void ProjectionSurface::draw(MantidGLWidget *widget)const
   if ( m_viewChanged && ( m_redrawPicking
                           || m_interactionMode == PickSingleMode
                           || m_interactionMode == PickTubeMode
-                          || m_interactionMode == DrawMode ) )
+                          || m_interactionMode == DrawRegularMode ) )
   {
     draw(widget,true);
     m_redrawPicking = false;
@@ -435,7 +441,7 @@ void ProjectionSurface::setInteractionMode(int mode)
     controller = m_inputControllers[m_interactionMode];
     if ( !controller ) throw std::logic_error("Input controller doesn't exist.");
     controller->onEnabled();
-    if ( mode != DrawMode )
+    if ( mode != DrawRegularMode && mode != DrawFreeMode )
     {
         m_maskShapes.deselectAll();
         foreach(PeakOverlay* po, m_peakShapes)
@@ -473,10 +479,13 @@ QString ProjectionSurface::getInfoText() const
         return "Move cursor over instrument to see detector information. ";
     case AddPeakMode:
         return "Click on a detector then click on the mini-plot to add a peak.";
-    case DrawMode:
+    case DrawRegularMode:
         return "Select a tool button to draw a new shape. "
                 "Click on shapes to select. Click and move to edit.";
-    case EraseMode:
+    case DrawFreeMode:
+        return "Draw by holding the left button down. "
+                "Erase with the right button.";
+    case ErasePeakMode:
         return "Click and move the mouse to erase peaks. "
                 "Rotate the wheel to resize the cursor.";
     }
@@ -566,6 +575,11 @@ void ProjectionSurface::startCreatingShape2D(const QString& type,const QColor& b
   emit signalToStartCreatingShape2D(type,borderColor,fillColor);
 }
 
+void ProjectionSurface::startCreatingFreeShape(const QColor& borderColor,const QColor& fillColor)
+{
+  emit signalToStartCreatingFreeShape(borderColor,fillColor);
+}
+
 /**
  * Return a combined list of peak parkers from all overlays
  * @param detID :: The detector ID of interest
@@ -679,7 +693,7 @@ void ProjectionSurface::setShowPeakLabelsFlag(bool on)
   */
 void ProjectionSurface::setSelectionRect(const QRect &rect)
 {
-    if ( m_interactionMode != DrawMode || !m_maskShapes.hasSelection() )
+    if ( m_interactionMode != DrawRegularMode || !m_maskShapes.hasSelection() )
     {
         m_selectRect = rect;
     }
diff --git a/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.h b/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.h
index 33b4a96a7badc9e2716a931a536476cbb9271d87..161484368e8dbf3a447f194382b48c04c4bf59c4 100644
--- a/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.h
+++ b/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.h
@@ -56,7 +56,16 @@ class ProjectionSurface: public QObject
 {
   Q_OBJECT
 public:
-  enum InteractionMode {MoveMode = 0, PickSingleMode, PickTubeMode, AddPeakMode, DrawMode, EraseMode, InteractionModeSize };
+  enum InteractionMode {
+    MoveMode = 0,
+    PickSingleMode,
+    PickTubeMode,
+    AddPeakMode,
+    DrawRegularMode,
+    DrawFreeMode,
+    ErasePeakMode,
+    InteractionModeSize
+  };
   /// Constructor
   ProjectionSurface(const InstrumentActor* rootActor);
   /// Destructor
@@ -140,6 +149,11 @@ public:
   /// @param fillColor :: The fill color.
   void startCreatingShape2D(const QString& type,const QColor& borderColor,const QColor& fillColor = QColor());
 
+  /// Initialize interactive creation of a free draw shape.
+  /// @param borderColor :: The color of the shape outline.
+  /// @param fillColor :: The fill color.
+  void startCreatingFreeShape(const QColor& borderColor,const QColor& fillColor = QColor());
+
   // Properties methods which allow the mask shapes to be modified with a property browser.
 
   /// Return a list of all properties of type double of the currently selected shape.
@@ -200,6 +214,7 @@ signals:
 
   // shape manipulation
   void signalToStartCreatingShape2D(const QString& type,const QColor& borderColor,const QColor& fillColor);
+  void signalToStartCreatingFreeShape(const QColor& borderColor,const QColor& fillColor);
   void shapeCreated();
   void shapeSelected();
   void shapesDeselected();
diff --git a/MantidPlot/src/Mantid/InstrumentWidget/RectF.h b/MantidPlot/src/Mantid/InstrumentWidget/RectF.h
index 264fa5172962f55ee9dca3f5bad3c2683710a96a..570edc68c82538e2d404db9e8c051ce5bc9fb47a 100644
--- a/MantidPlot/src/Mantid/InstrumentWidget/RectF.h
+++ b/MantidPlot/src/Mantid/InstrumentWidget/RectF.h
@@ -197,4 +197,16 @@ inline std::ostream& operator << (std::ostream& ostr, const RectF& rect)
     return ostr;
 }
 
+inline std::ostream& operator << (std::ostream& ostr, const QRectF& rect)
+{
+  ostr << '[' << rect.left() << ',' << rect.right() << ';' << rect.top() << ',' << rect.bottom() << ']';
+    return ostr;
+}
+
+inline std::ostream& operator << (std::ostream& ostr, const QPointF& p)
+{
+    ostr << '(' << p.x() << ',' << p.y() << ')';
+    return ostr;
+}
+
 #endif // RECTF_H
diff --git a/MantidPlot/src/Mantid/InstrumentWidget/Shape2D.cpp b/MantidPlot/src/Mantid/InstrumentWidget/Shape2D.cpp
index 9543dcdaf288d31f17ef511e964d9e0d3d0def7a..0a40a6ff188c653ab6e139072d4222438edba486 100644
--- a/MantidPlot/src/Mantid/InstrumentWidget/Shape2D.cpp
+++ b/MantidPlot/src/Mantid/InstrumentWidget/Shape2D.cpp
@@ -5,6 +5,9 @@
 #include <QMouseEvent>
 #include <QWheelEvent>
 
+#include <QLine>
+#include <QMap>
+
 #include <iostream>
 #include <algorithm>
 #include <stdexcept>
@@ -487,3 +490,154 @@ void Shape2DRing::setColor(const QColor &color)
     m_outer_shape->setColor(color);
 }
 
+//------------------------------------------------------------------------------
+
+/// Construct a zero-sized shape.
+Shape2DFree::Shape2DFree(const QPointF& p):
+  m_polygon(QRectF(p,p))
+{
+  resetBoundingRect();
+}
+
+/// The shape can be selected if it contains the point.
+bool Shape2DFree::selectAt(const QPointF& p)const
+{
+  return contains(p);
+}
+
+/// Check if a point is inside the shape.
+bool Shape2DFree::contains(const QPointF& p)const
+{
+  return m_polygon.containsPoint(p,Qt::OddEvenFill);
+}
+
+/// Add to a larger shape.
+void Shape2DFree::addToPath(QPainterPath& path) const
+{
+  path.addPolygon(m_polygon);
+}
+
+/// Draw.
+void Shape2DFree::drawShape(QPainter& painter) const
+{
+  QPainterPath path;
+  path.addPolygon(m_polygon);
+  painter.fillPath(path, m_fill_color);
+  painter.drawPath(m_outline);
+}
+
+/// Rescale polygon's verices to fit to the new bounding rect.
+void Shape2DFree::refit()
+{
+  auto brOld = getPolygonBoundingRect();
+  auto &brNew = m_boundingRect;
+  if (brNew.xSpan() < 0.0) brNew.xFlip();
+  if (brNew.ySpan() < 0.0) brNew.yFlip();
+
+  auto xs0 = brNew.x0();
+  auto x0 = brOld.x0();
+  auto xScale = brNew.width() / brOld.width();
+
+  auto ys0 = brNew.y0();
+  auto y0 = brOld.y0();
+  auto yScale = brNew.height() / brOld.height();
+  for(int i = 0; i < m_polygon.size(); ++i)
+  {
+    auto &p = m_polygon[i];
+    p.rx() = xs0 + xScale * (p.x() - x0);
+    p.ry() = ys0 + yScale * (p.y() - y0);
+  }
+  resetBoundingRect();
+}
+
+/// Recalculate the bounding rect.
+/// Also make the new border outline.
+/// QPolygonF cannot have holes or disjointed parts,
+/// it's a single closed line. The outline (implemented as a QPainterPath)
+/// makes it look like it have holes.
+void Shape2DFree::resetBoundingRect()
+{
+  m_boundingRect = getPolygonBoundingRect();
+  // Clear the outline path.
+  m_outline = QPainterPath();
+  if (m_polygon.isEmpty()) return;
+
+  // If the polygon has apparent holes/discontinuities
+  // it will have extra pairs of edges which we don't want
+  // to draw.
+  auto n = m_polygon.size() - 1;
+  // Find those vertices at which we must break the polygon
+  // to get rid of these extra edges.
+  QList<int> breaks;
+  breaks.push_back(0);
+  for(int i = 1; i < m_polygon.size() - 1; ++i)
+  {
+    auto p = m_polygon[i];
+    auto j = m_polygon.indexOf(p, i + 1);
+    if (j != -1)
+    {
+      auto i1 = i + 1;
+      auto j1 = j - 1;
+      if (m_polygon[i1] == m_polygon[j1])
+      {
+        breaks.push_back(i);
+        breaks.push_back(i1);
+        breaks.push_back(j1);
+        breaks.push_back(j);
+      }
+    }
+  }
+  if (breaks.back() != n)
+  {
+    breaks.push_back(n);
+  }
+  qSort(breaks);
+
+  m_outline.moveTo(m_polygon[0]);
+  int j1 = 0;
+  // Add contiguous portions of the polygon to the outline
+  // and break at points from breaks list.
+  for(int i = 0; i < breaks.size(); ++i)
+  {
+    auto j = breaks[i];
+    if (j == j1 + 1)
+    {
+      m_outline.moveTo(m_polygon[j]);
+    }
+    else
+    {
+      for(auto k = j1; k <= j; ++k)
+      {
+        m_outline.lineTo(m_polygon[k]);
+      }
+    }
+    j1 = j;
+  }
+}
+
+/// Convert the bounding rect computed by QPolygonF to RectF
+RectF Shape2DFree::getPolygonBoundingRect() const
+{
+  auto br = m_polygon.boundingRect();
+  auto x0 = br.left();
+  auto x1 = br.right();
+  if (x0 > x1) std::swap(x0, x1);
+  auto y0 = br.bottom();
+  auto y1 = br.top();
+  if (y0 > y1) std::swap(y0, y1);
+  return RectF(QPointF(x0,y0), QPointF(x1,y1));
+}
+
+/// Add a polygon to this shape.
+void Shape2DFree::addPolygon(const QPolygonF& polygon)
+{
+  m_polygon = m_polygon.united(polygon);
+  resetBoundingRect();
+}
+
+/// Subtract a polygon from this shape.
+void Shape2DFree::subtractPolygon(const QPolygonF& polygon)
+{
+  m_polygon = m_polygon.subtracted(polygon);
+  resetBoundingRect();
+}
diff --git a/MantidPlot/src/Mantid/InstrumentWidget/Shape2D.h b/MantidPlot/src/Mantid/InstrumentWidget/Shape2D.h
index 9ab6d058a2001d0381f6127df001f56de3594d72..d1db694c15db59ffc266130b33aa33db730608c8 100644
--- a/MantidPlot/src/Mantid/InstrumentWidget/Shape2D.h
+++ b/MantidPlot/src/Mantid/InstrumentWidget/Shape2D.h
@@ -147,6 +147,13 @@ protected:
   bool m_visible;  ///< flag to show or hide the shape
 };
 
+/**
+ * An ellipse with the axes parallel to the x and y axes on the screen.
+ *
+ * It has a QPointF property "center" defining the centre of the ellipse
+ * and double properties "radius1" and "radius2" equal to distances from
+ * the centre to the curve along the x and y axes.
+ */
 class Shape2DEllipse: public Shape2D
 {
 public:
@@ -169,6 +176,11 @@ protected:
   virtual void refit(){}
 };
 
+/**
+ * A axis aligned rectangle.
+ *
+ * No specific properties.
+ */
 class Shape2DRectangle: public Shape2D
 {
 public:
@@ -184,6 +196,13 @@ protected:
   virtual void refit(){}
 };
 
+/**
+ * A ring: area bounded by two curves of the same shape but different size.
+ *
+ * The constructor takes a curve shape and the ring widths in the x and y
+ * directions.
+ * It has QPointF "centre" property and "xwidth" and "ywidth" double properties.
+ */
 class Shape2DRing: public Shape2D
 {
 public:
@@ -216,5 +235,31 @@ protected:
   double m_yWidth;
 };
 
+/**
+ * An arbitrary shape. Implemented as a polygon.
+ * It can have disjointed parts and holes.
+ *
+ * No shape specific properties.
+ */
+class Shape2DFree: public Shape2D
+{
+public:
+  Shape2DFree(const QPointF& p);
+  virtual Shape2D* clone()const{return new Shape2DFree(*this);}
+  virtual bool selectAt(const QPointF& p)const;
+  virtual bool contains(const QPointF& p)const;
+  virtual void addToPath(QPainterPath& path) const;
+  void addPolygon(const QPolygonF& polygon);
+  void subtractPolygon(const QPolygonF& polygon);
+protected:
+  virtual void drawShape(QPainter& painter) const;
+  virtual void refit();
+  virtual void resetBoundingRect();
+private:
+  RectF getPolygonBoundingRect() const;
+  QPolygonF m_polygon;    ///< Implements the shape.
+  QPainterPath m_outline; ///< Object to draw the shape's border.
+};
+
 
 #endif /*MANTIDPLOT_SHAPE2D_H_*/
diff --git a/MantidPlot/src/Mantid/InstrumentWidget/Shape2DCollection.cpp b/MantidPlot/src/Mantid/InstrumentWidget/Shape2DCollection.cpp
index 7ccdfae2720dc618b08d36661f890ae3138ae61a..dcbb04b15d4e764292ac601c3cffcda4c42b11ae 100644
--- a/MantidPlot/src/Mantid/InstrumentWidget/Shape2DCollection.cpp
+++ b/MantidPlot/src/Mantid/InstrumentWidget/Shape2DCollection.cpp
@@ -204,6 +204,10 @@ Shape2D* Shape2DCollection::createShape(const QString& type,int x,int y) const
   {
      return new Shape2DRectangle(p,QSizeF(0,0));
   }
+  else if (type.toLower() == "free")
+  {
+     return new Shape2DFree(p);
+  }
 
   QStringList complexType = type.split(' ',QString::SkipEmptyParts);
 
@@ -735,3 +739,48 @@ void Shape2DCollection::changeBorderColor(const QColor &color)
     }
 }
 
+/**
+ * Add a Shape2D object allowing free drawing.
+ * @param poly :: Initial shape.
+ * @param borderColor :: The border colour.
+ * @param fillColor :: The fill colour.
+ */
+void Shape2DCollection::addFreeShape(const QPolygonF& poly,const QColor& borderColor,const QColor& fillColor)
+{
+  auto freeShape = dynamic_cast<Shape2DFree*>(m_currentShape);
+  if (!freeShape)
+  {
+    if (poly.isEmpty()) throw std::logic_error("Cannot create a shape from empty polygon.");
+    auto p = m_transform.inverted().map(poly[0]);
+    addShape("free", static_cast<int>(p.x()), static_cast<int>(p.y()), borderColor, fillColor);
+  }
+  drawFree(poly);
+}
+
+/**
+ * Draw the shape by adding a polygon to it.
+ */
+void Shape2DCollection::drawFree(const QPolygonF& polygon)
+{
+  auto freeShape = dynamic_cast<Shape2DFree*>(m_currentShape);
+  if (freeShape)
+  {
+    auto transform = m_transform.inverted();
+    freeShape->addPolygon(transform.map(polygon));
+    emit shapeChanged();
+  }
+}
+
+/**
+ * Erase part of the shape by subtracting a polygon from it.
+ */
+void Shape2DCollection::eraseFree(const QPolygonF& polygon)
+{
+  auto freeShape = dynamic_cast<Shape2DFree*>(m_currentShape);
+  if (freeShape)
+  {
+    auto transform = m_transform.inverted();
+    freeShape->subtractPolygon(transform.map(polygon));
+    emit shapeChanged();
+  }
+}
diff --git a/MantidPlot/src/Mantid/InstrumentWidget/Shape2DCollection.h b/MantidPlot/src/Mantid/InstrumentWidget/Shape2DCollection.h
index ed62362b346e512483106b443c0753e103618b01..53ca3567f83948faeadff5a8d4c1543f02bca995 100644
--- a/MantidPlot/src/Mantid/InstrumentWidget/Shape2DCollection.h
+++ b/MantidPlot/src/Mantid/InstrumentWidget/Shape2DCollection.h
@@ -88,6 +88,7 @@ signals:
 
 public slots:
   void addShape(const QString& type,int x,int y,const QColor& borderColor,const QColor& fillColor);
+  void addFreeShape(const QPolygonF&,const QColor& borderColor,const QColor& fillColor);
   void deselectAll();
   void moveRightBottomTo(int,int);
   void selectShapeOrControlPointAt(int x,int y);
@@ -96,6 +97,8 @@ public slots:
   void touchShapeOrControlPointAt(int x,int y);
   void removeSelectedShapes();
   void restoreOverrideCursor();
+  void drawFree(const QPolygonF& polygon);
+  void eraseFree(const QPolygonF& polygon);
 
 protected:
   virtual void drawShape(QPainter& ) const{} // never called
diff --git a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InputController.h b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InputController.h
index 6c2b3ab4330b8d0449a41efd133838c1cdd18e17..7d9e9547ac954f6f44286ed5227efabd958fe6d9 100644
--- a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InputController.h
+++ b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InputController.h
@@ -5,6 +5,7 @@
 #include <QObject>
 #include <QRect>
 #include <QColor>
+#include <QPolygonF>
 
 class QMouseEvent;
 class QWheelEvent;
@@ -31,6 +32,7 @@ class EXPORT_OPT_MANTIDQT_MANTIDWIDGETS InputController : public QObject {
   Q_OBJECT
 public:
   explicit InputController(QObject *parent, bool contextAllowed = true);
+  virtual ~InputController(){}
 
   virtual void mousePressEvent(QMouseEvent *) {}
   virtual void mouseMoveEvent(QMouseEvent *) {}
@@ -197,37 +199,100 @@ private:
 };
 
 /**
-    Controller for moving the instrument on an unwrapped surface.
+    Controller for free drawing on an unwrapped surface.
   */
-class EXPORT_OPT_MANTIDQT_MANTIDWIDGETS InputControllerErase : public InputController {
+class EXPORT_OPT_MANTIDQT_MANTIDWIDGETS InputControllerDraw : public InputController {
   Q_OBJECT
 
 public:
-  InputControllerErase(QObject *parent);
-  ~InputControllerErase();
+  InputControllerDraw(QObject *parent);
+  ~InputControllerDraw();
   virtual void mousePressEvent(QMouseEvent *);
   virtual void mouseMoveEvent(QMouseEvent *);
   virtual void mouseReleaseEvent(QMouseEvent *);
   virtual void wheelEvent(QWheelEvent *);
 
-  virtual void onPaint(QPainter &);
   virtual void enterEvent(QEvent *);
   virtual void leaveEvent(QEvent *);
 
-signals:
-  void erase(const QRect &);
+protected:
+  int cursorSize() const {return m_size;}
+  bool isLeftButtonPressed() const {return m_isLeftButtonPressed;}
+  bool isRightButtonPressed() const {return m_isRightButtonPressed;}
+  bool isActive() const {return m_isActive;}
 
 private:
-  void drawCursor();
+  void redrawCursor();
+  virtual void signalLeftClick() = 0;
+  virtual void signalRightClick();
+  virtual void drawCursor(QPixmap *cursor) = 0;
+  virtual void setPosition(const QPoint &pos) = 0;
+  virtual void resize() = 0;
 
   const int m_max_size;
-  int m_size; ///< Size of the eraser
-  bool m_isButtonPressed;
+  int m_size; ///< Size of the cursor
+  bool m_isLeftButtonPressed;
+  bool m_isRightButtonPressed;
   bool m_isActive;
-  QRect m_rect;
   QPixmap *m_cursor;
+};
+
+/**
+    Controller for erasing peaks on an unwrapped surface.
+  */
+class EXPORT_OPT_MANTIDQT_MANTIDWIDGETS InputControllerErase : public InputControllerDraw {
+  Q_OBJECT
+
+public:
+  InputControllerErase(QObject *parent);
+  ~InputControllerErase();
+  void onPaint(QPainter &);
+
+signals:
+  void erase(const QRect &);
+
+private:
+  void drawCursor(QPixmap *cursor);
+  void signalLeftClick();
+  void setPosition(const QPoint &pos);
+  void resize();
+
+  QRect m_rect;
   QPixmap *m_image;
 };
+
+/**
+    Controller for drawing and erasing arbitrary shapes on an unwrapped surface.
+  */
+class EXPORT_OPT_MANTIDQT_MANTIDWIDGETS InputControllerDrawAndErase : public InputControllerDraw {
+  Q_OBJECT
+
+public:
+  InputControllerDrawAndErase(QObject *parent);
+
+signals:
+  void draw(const QPolygonF &);
+  void erase(const QPolygonF &);
+  void addShape(const QPolygonF &poly, const QColor &borderColor,
+                const QColor &fillColor);
+
+public slots:
+  void startCreatingShape2D(const QColor &borderColor, const QColor &fillColor);
+
+private:
+  void drawCursor(QPixmap *cursor);
+  void signalLeftClick();
+  void signalRightClick();
+  void setPosition(const QPoint &pos);
+  void resize();
+  void makePolygon();
+
+  QPoint m_pos;
+  QPolygonF m_rect;
+  QColor m_borderColor, m_fillColor;
+  bool m_creating;
+};
+
 }
 }
 
diff --git a/MantidQt/MantidWidgets/src/InputController.cpp b/MantidQt/MantidWidgets/src/InputController.cpp
index b707dea7b2dd8c6e402b5d0c3b5745f80c846bec..afc5d3d445b33e9739ee4fc1cb6b667c42e17455 100644
--- a/MantidQt/MantidWidgets/src/InputController.cpp
+++ b/MantidQt/MantidWidgets/src/InputController.cpp
@@ -6,7 +6,7 @@
 #include <QCursor>
 #include <QApplication>
 
-#include <iostream>
+#include <cmath>
 
 namespace MantidQt {
 namespace MantidWidgets {
@@ -315,112 +315,250 @@ void InputControllerMoveUnwrapped::mouseReleaseEvent(QMouseEvent *)
 /**
   * Constructor.
   */
-InputControllerErase::InputControllerErase(QObject *parent):
+InputControllerDraw::InputControllerDraw(QObject *parent):
 InputController(parent),
 m_max_size(32),
 m_size(30),
-m_isButtonPressed(false),
+m_isLeftButtonPressed(false),
+m_isRightButtonPressed(false),
 m_isActive(false),
-m_rect( 0, 0, m_size, m_size )
+m_cursor(NULL)
 {
-    m_cursor = new QPixmap(m_max_size,m_max_size);
-    drawCursor();
-    m_image = new QPixmap(":/PickTools/eraser.png");
 }
 
-InputControllerErase::~InputControllerErase()
+InputControllerDraw::~InputControllerDraw()
 {
     delete m_cursor;
-    delete m_image;
 }
 
 /**
   * Process the mouse press event.
   */
-void InputControllerErase::mousePressEvent(QMouseEvent *event)
+void InputControllerDraw::mousePressEvent(QMouseEvent *event)
 {
     m_isActive = true;
-    m_rect.moveTopLeft(QPoint(event->x(),event->y()));
+    setPosition(QPoint(event->x(),event->y()));
     if (event->button() == Qt::LeftButton)
     {
-        m_isButtonPressed = true;
-        emit erase( m_rect );
+        m_isLeftButtonPressed = true;
+        signalLeftClick();
+    }
+    else if (event->button() == Qt::RightButton)
+    {
+        m_isRightButtonPressed = true;
+        signalRightClick();
     }
 }
 
 /**
   * Process the mouse move event.
   */
-void InputControllerErase::mouseMoveEvent(QMouseEvent *event)
+void InputControllerDraw::mouseMoveEvent(QMouseEvent *event)
 {
     m_isActive = true;
-    m_rect.moveTopLeft(QPoint(event->x(),event->y()));
-    if ( m_isButtonPressed )
+    setPosition(QPoint(event->x(),event->y()));
+    if ( m_isLeftButtonPressed )
+    {
+        signalLeftClick();
+    }
+    else if ( m_isRightButtonPressed )
     {
-        emit erase( m_rect );
+        signalRightClick();
     }
 }
 
 /**
   * Process the mouse button release event.
   */
-void InputControllerErase::mouseReleaseEvent(QMouseEvent *)
+void InputControllerDraw::mouseReleaseEvent(QMouseEvent *event)
 {
-    m_isButtonPressed = false;
+    if (event->button() == Qt::LeftButton)
+    {
+        m_isLeftButtonPressed = false;
+    }
+    else if (event->button() == Qt::RightButton)
+    {
+        m_isRightButtonPressed = false;
+    }
 }
 
-void InputControllerErase::wheelEvent(QWheelEvent *event)
+void InputControllerDraw::wheelEvent(QWheelEvent *event)
 {
     int d = m_size + ( event->delta() > 0 ? 4 : -4 );
     if ( d > 2 && d < m_max_size )
     {
         m_size = d;
-        drawCursor();
+        resize();
+        redrawCursor();
         QApplication::restoreOverrideCursor();
         QApplication::setOverrideCursor(QCursor( *m_cursor, 0, 0 ));
     }
 }
 
+void InputControllerDraw::enterEvent(QEvent *)
+{
+    redrawCursor();
+    QApplication::setOverrideCursor(QCursor( *m_cursor, 0, 0 ));
+    m_isActive = true;
+}
+
+void InputControllerDraw::leaveEvent(QEvent *)
+{
+    QApplication::restoreOverrideCursor();
+    m_isActive = false;
+}
+
+void InputControllerDraw::redrawCursor()
+{
+  if (!m_cursor)
+  {
+    m_cursor = new QPixmap(m_max_size,m_max_size);
+  }
+  drawCursor(m_cursor);
+}
+
+void InputControllerDraw::signalRightClick()
+{
+}
+
+//--------------------------------------------------------------------------------
+
+InputControllerErase::InputControllerErase(QObject *parent): InputControllerDraw(parent),
+  m_rect( 0, 0, cursorSize(), cursorSize() ) 
+{
+  m_image = new QPixmap(":/PickTools/eraser.png");
+}
+
+InputControllerErase::~InputControllerErase()
+{
+  delete m_image;
+}
+
+void InputControllerErase::signalLeftClick()
+{
+  emit erase(m_rect);
+}
+
 void InputControllerErase::onPaint(QPainter& painter)
 {
-    if ( m_isActive && !m_isButtonPressed )
+    if ( isActive() && !isLeftButtonPressed() )
     {
         painter.drawPixmap(m_rect.bottomRight(),*m_image);
     }
 }
 
-void InputControllerErase::enterEvent(QEvent *)
+void InputControllerErase::drawCursor(QPixmap *cursor)
 {
-    QApplication::setOverrideCursor(QCursor( *m_cursor, 0, 0 ));
-    m_isActive = true;
+    cursor->fill(QColor(255,255,255,0));
+    QPainter painter( cursor );
+    auto size = cursorSize();
+
+    auto pen = QPen(Qt::DashLine);
+    QVector<qreal> dashPattern;
+    dashPattern << 4 << 4;
+    pen.setDashPattern(dashPattern);
+    pen.setColor(QColor(0,0,0));
+    painter.setPen(pen);
+    painter.drawRect( QRect( 0, 0, size, size ) );
+
+    pen.setColor(QColor(255,255,255));
+    pen.setDashOffset(4);
+    painter.setPen(pen);
+    painter.drawRect( QRect( 0, 0, size, size ) );
 }
 
-void InputControllerErase::leaveEvent(QEvent *)
+void InputControllerErase::setPosition(const QPoint &pos)
 {
-    QApplication::restoreOverrideCursor();
-    m_isActive = false;
+  m_rect.moveTopLeft(pos);
+}
+
+void InputControllerErase::resize()
+{
+    auto size = cursorSize();
+    m_rect.setSize( QSize(size, size) );
+}
+
+//--------------------------------------------------------------------------------
+
+InputControllerDrawAndErase::InputControllerDrawAndErase(QObject *parent): InputControllerDraw(parent),
+  m_pos(0,0), m_rect(8), m_creating(false)
+{
+  makePolygon();
+}
+
+void InputControllerDrawAndErase::makePolygon()
+{
+  auto r = double(cursorSize()) / 2.0;
+  double a = 2.0 * M_PI / double(m_rect.size());
+  for(int i = 0; i < m_rect.size(); ++i)
+  {
+    double ia = double(i) * a;
+    auto x = r + static_cast<int>(r * cos(ia));
+    auto y = r + static_cast<int>(r * sin(ia));
+    m_rect[i] = QPointF(x, y);
+  }
+}
+
+void InputControllerDrawAndErase::signalLeftClick()
+{
+  auto poly = m_rect.translated(m_pos);
+  if (m_creating)
+  {
+    m_creating = false;
+    emit addShape(poly, m_borderColor, m_fillColor);
+  }
+  else
+  {
+    emit draw(poly);
+  }
+}
+
+void InputControllerDrawAndErase::signalRightClick()
+{
+  auto poly = m_rect.translated(m_pos);
+  emit erase(poly);
 }
 
-void InputControllerErase::drawCursor()
+void InputControllerDrawAndErase::drawCursor(QPixmap *cursor)
 {
-    m_cursor->fill(QColor(255,255,255,0));
-    QPainter painter( m_cursor );
+    cursor->fill(QColor(255,255,255,0));
+    QPainter painter( cursor );
+
+    auto bRect = m_rect.boundingRect();
+    auto poly = m_rect.translated(-bRect.topLeft());
 
     auto pen = QPen(Qt::DashLine);
     QVector<qreal> dashPattern;
-    dashPattern << 4 << 4;
+    qreal dashLength = cursorSize() < 10 ? 1 : 2;
+    dashPattern << dashLength << dashLength;
     pen.setDashPattern(dashPattern);
     pen.setColor(QColor(0,0,0));
     painter.setPen(pen);
-    painter.drawRect( QRect( 0, 0, m_size, m_size ) );
+    painter.drawPolygon(poly);
 
     pen.setColor(QColor(255,255,255));
-    pen.setDashOffset(4);
+    pen.setDashOffset(dashLength);
     painter.setPen(pen);
-    painter.drawRect( QRect( 0, 0, m_size, m_size ) );
+    painter.drawPolygon(poly);
+}
 
-    m_rect.setSize( QSize(m_size,m_size) );
+void InputControllerDrawAndErase::setPosition(const QPoint &pos)
+{
+  m_pos = pos;
+}
+
+void InputControllerDrawAndErase::resize()
+{
+  makePolygon();
 }
+
+void InputControllerDrawAndErase::startCreatingShape2D(const QColor &borderColor, const QColor &fillColor)
+{
+  m_borderColor = borderColor;
+  m_fillColor = fillColor;
+  m_creating = true;
+}
+
 }
 }
 
diff --git a/images/brush.png b/images/brush.png
new file mode 100644
index 0000000000000000000000000000000000000000..328d01196160c1bc534ac5bada51431445c612e6
Binary files /dev/null and b/images/brush.png differ
diff --git a/images/images.qrc b/images/images.qrc
index d68c46cd1be169a22d4f1458ecf80e0c6898c893..f574b14d849722bdb4ae85bdc201873be4d0d521 100644
--- a/images/images.qrc
+++ b/images/images.qrc
@@ -67,6 +67,7 @@
         <file>eraser.png</file>
         <file>selection-box-ring.png</file>
         <file>selection-circle-ring.png</file>
+        <file>brush.png</file>
     </qresource>
     <qresource prefix="/MaskTools">
         <file>selection-circle.png</file>
@@ -74,5 +75,6 @@
         <file>selection-box-ring.png</file>
         <file>selection-circle-ring.png</file>
         <file>selection-edit.png</file>
+        <file>brush.png</file>
     </qresource>
 </RCC>