changeset 1020:ac88989817e3 toa2019093001

TrackerCommand --> MeasureCommand + fuse against exception in MeasureTool dtor + added DeleteMeasureCommand + moved the various concrete measuring tool-related classes to their pre-assigned file locations (everything was crammed into MeasureCommands.* files up to this commit) + added double-click handler to GuiAdapter (for TOA implementation of "delete measuring tool on double-click")
author Benjamin Golinvaux <bgo@osimis.io>
date Mon, 30 Sep 2019 10:41:06 +0200
parents 29f5f2031310
children 2f22e3086a5b
files Applications/Generic/GuiAdapter.cpp Applications/Generic/GuiAdapter.h Framework/Scene2DViewport/AngleMeasureTool.cpp Framework/Scene2DViewport/AngleMeasureTool.h Framework/Scene2DViewport/CreateAngleMeasureCommand.cpp Framework/Scene2DViewport/CreateAngleMeasureCommand.h Framework/Scene2DViewport/CreateAngleMeasureTracker.cpp Framework/Scene2DViewport/CreateLineMeasureCommand.cpp Framework/Scene2DViewport/CreateLineMeasureCommand.h Framework/Scene2DViewport/CreateLineMeasureTracker.cpp Framework/Scene2DViewport/CreateLineMeasureTracker.h Framework/Scene2DViewport/EditAngleMeasureCommand.cpp Framework/Scene2DViewport/EditAngleMeasureCommand.h Framework/Scene2DViewport/EditAngleMeasureTracker.cpp Framework/Scene2DViewport/EditAngleMeasureTracker.h Framework/Scene2DViewport/EditLineMeasureCommand.cpp Framework/Scene2DViewport/EditLineMeasureCommand.h Framework/Scene2DViewport/EditLineMeasureTracker.cpp Framework/Scene2DViewport/EditLineMeasureTracker.h Framework/Scene2DViewport/LineMeasureTool.cpp Framework/Scene2DViewport/LineMeasureTool.h Framework/Scene2DViewport/MeasureCommands.cpp Framework/Scene2DViewport/MeasureCommands.h Framework/Scene2DViewport/MeasureTool.cpp Framework/Scene2DViewport/MeasureTool.h Framework/Scene2DViewport/MeasureTrackers.h Framework/Scene2DViewport/PredeclaredTypes.h Framework/Scene2DViewport/UndoStack.cpp Framework/Scene2DViewport/UndoStack.h Framework/Scene2DViewport/ViewportController.cpp Framework/Scene2DViewport/ViewportController.h Framework/Toolbox/CoordinateSystem3D.cpp
diffstat 32 files changed, 548 insertions(+), 204 deletions(-) [+]
line wrap: on
line diff
--- a/Applications/Generic/GuiAdapter.cpp	Fri Sep 27 13:32:05 2019 +0200
+++ b/Applications/Generic/GuiAdapter.cpp	Mon Sep 30 10:41:06 2019 +0200
@@ -78,6 +78,9 @@
     case EMSCRIPTEN_EVENT_MOUSEDOWN:
       dest.type = GUIADAPTER_EVENT_MOUSEDOWN;
       break;
+    case EMSCRIPTEN_EVENT_DBLCLICK:
+      dest.type = GUIADAPTER_EVENT_MOUSEDBLCLICK;
+      break;
     case EMSCRIPTEN_EVENT_MOUSEMOVE:
       dest.type = GUIADAPTER_EVENT_MOUSEMOVE;
       break;
@@ -287,6 +290,19 @@
       func);
   }
 
+  
+  void GuiAdapter::SetMouseDblClickCallback(
+      std::string canvasId, void* userData, bool capture, OnMouseEventFunc func)
+  {
+    SetCallback<OnMouseEventFunc, GuiAdapterMouseEvent, EmscriptenMouseEvent>(
+      &emscripten_set_dblclick_callback_on_thread,
+      canvasId,
+      userData,
+      capture,
+      func);
+  }
+
+
   void GuiAdapter::SetMouseDownCallback(
     std::string canvasId, void* userData, bool capture, OnMouseEventFunc func)
   {
@@ -401,7 +417,14 @@
     switch (source.type)
     {
     case SDL_MOUSEBUTTONDOWN:
-      dest.type = GUIADAPTER_EVENT_MOUSEDOWN;
+      if (source.button.clicks == 1) {
+        dest.type = GUIADAPTER_EVENT_MOUSEDOWN;
+      } else if (source.button.clicks == 2) {
+        dest.type = GUIADAPTER_EVENT_MOUSEDBLCLICK;
+      } else {
+        dest.type = GUIADAPTER_EVENT_MOUSEDBLCLICK;
+        LOG(WARNING) << "Multiple-click ignored.";
+      }
       break;
     case SDL_MOUSEMOTION:
       dest.type = GUIADAPTER_EVENT_MOUSEMOVE;
@@ -513,6 +536,13 @@
   }
 
   // SDL ONLY
+  void GuiAdapter::SetMouseDblClickCallback(
+    std::string canvasId, void* userData, bool capture, OnMouseEventFunc func)
+  {
+    mouseDblCickHandlers_.push_back(EventHandlerData<OnMouseEventFunc>(canvasId, func, userData));
+  }
+
+  // SDL ONLY
   void GuiAdapter::SetMouseMoveCallback(
     std::string canvasId, void* userData, bool capture, OnMouseEventFunc  func)
   {
@@ -674,6 +704,13 @@
             (*(mouseDownHandlers_[i].func))(windowTitle, &event, mouseDownHandlers_[i].userData);
         }
         break;
+      case GUIADAPTER_EVENT_MOUSEDBLCLICK:
+        for (size_t i = 0; i < mouseDblCickHandlers_.size(); i++)
+        {
+          if (mouseDblCickHandlers_[i].canvasName == windowTitle)
+            (*(mouseDblCickHandlers_[i].func))(windowTitle, &event, mouseDblCickHandlers_[i].userData);
+        }
+        break;
       case GUIADAPTER_EVENT_MOUSEMOVE:
         for (size_t i = 0; i < mouseMoveHandlers_.size(); i++)
         {
--- a/Applications/Generic/GuiAdapter.h	Fri Sep 27 13:32:05 2019 +0200
+++ b/Applications/Generic/GuiAdapter.h	Mon Sep 30 10:41:06 2019 +0200
@@ -77,12 +77,13 @@
 
   enum GuiAdapterHidEventType
   {
-    GUIADAPTER_EVENT_MOUSEDOWN = 1973,
-    GUIADAPTER_EVENT_MOUSEMOVE = 1974,
-    GUIADAPTER_EVENT_MOUSEUP   = 1975,
-    GUIADAPTER_EVENT_WHEEL     = 1976,
-    GUIADAPTER_EVENT_KEYDOWN   = 1977,
-    GUIADAPTER_EVENT_KEYUP     = 1978,
+    GUIADAPTER_EVENT_MOUSEDOWN      = 1973,
+    GUIADAPTER_EVENT_MOUSEMOVE      = 1974,
+    GUIADAPTER_EVENT_MOUSEDBLCLICK  = 1975,
+    GUIADAPTER_EVENT_MOUSEUP        = 1976,
+    GUIADAPTER_EVENT_WHEEL          = 1977,
+    GUIADAPTER_EVENT_KEYDOWN        = 1978,
+    GUIADAPTER_EVENT_KEYUP          = 1979,
   };
 
   const unsigned int GUIADAPTER_DELTA_PIXEL = 2973;
@@ -253,12 +254,13 @@
 
     */
 
-    void SetMouseDownCallback(std::string canvasId, void* userData, bool capture, OnMouseEventFunc   func);
-    void SetMouseMoveCallback(std::string canvasId, void* userData, bool capture, OnMouseEventFunc   func);
-    void SetMouseUpCallback  (std::string canvasId, void* userData, bool capture, OnMouseEventFunc   func);
-    void SetWheelCallback    (std::string canvasId, void* userData, bool capture, OnMouseWheelFunc   func);
-    void SetKeyDownCallback  (std::string canvasId, void* userData, bool capture, OnKeyDownFunc      func);
-    void SetKeyUpCallback    (std::string canvasId, void* userData, bool capture, OnKeyUpFunc        func);
+    void SetMouseDownCallback     (std::string canvasId, void* userData, bool capture, OnMouseEventFunc   func);
+    void SetMouseDblClickCallback (std::string canvasId, void* userData, bool capture, OnMouseEventFunc   func);
+    void SetMouseMoveCallback     (std::string canvasId, void* userData, bool capture, OnMouseEventFunc   func);
+    void SetMouseUpCallback       (std::string canvasId, void* userData, bool capture, OnMouseEventFunc   func);
+    void SetWheelCallback         (std::string canvasId, void* userData, bool capture, OnMouseWheelFunc   func);
+    void SetKeyDownCallback       (std::string canvasId, void* userData, bool capture, OnKeyDownFunc      func);
+    void SetKeyUpCallback         (std::string canvasId, void* userData, bool capture, OnKeyUpFunc        func);
     
     // if you pass "#window", under SDL, then any Window resize will trigger the callback
     void SetResizeCallback (std::string canvasId, void* userData, bool capture, OnWindowResizeFunc func);
@@ -330,6 +332,7 @@
     };
     std::vector<EventHandlerData<OnWindowResizeFunc> > resizeHandlers_;
     std::vector<EventHandlerData<OnMouseEventFunc  > > mouseDownHandlers_;
+    std::vector<EventHandlerData<OnMouseEventFunc  > > mouseDblCickHandlers_;
     std::vector<EventHandlerData<OnMouseEventFunc  > > mouseMoveHandlers_;
     std::vector<EventHandlerData<OnMouseEventFunc  > > mouseUpHandlers_;
     std::vector<EventHandlerData<OnMouseWheelFunc  > > mouseWheelHandlers_;
--- a/Framework/Scene2DViewport/AngleMeasureTool.cpp	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/AngleMeasureTool.cpp	Mon Sep 30 10:41:06 2019 +0200
@@ -115,6 +115,13 @@
     RefreshScene();
   }
 
+  std::string AngleMeasureTool::GetDescription()
+  {
+    std::stringstream ss;
+    ss << "AngleMeasureTool. Center = " << center_ << " Side1End = " << side1End_ << " Side2End = " << side2End_;
+    return ss.str();
+  }
+
   void AngleMeasureTool::Highlight(ScenePoint2D p)
   {
     AngleHighlightArea angleHighlightArea = AngleHitTest(p);
--- a/Framework/Scene2DViewport/AngleMeasureTool.h	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/AngleMeasureTool.h	Mon Sep 30 10:41:06 2019 +0200
@@ -54,6 +54,7 @@
     virtual boost::shared_ptr<IFlexiblePointerTracker> CreateEditionTracker(const PointerEvent& e) ORTHANC_OVERRIDE;
     virtual boost::shared_ptr<MeasureToolMemento> GetMemento() const ORTHANC_OVERRIDE;
     virtual void SetMemento(boost::shared_ptr<MeasureToolMemento>) ORTHANC_OVERRIDE;
+    virtual std::string GetDescription() ORTHANC_OVERRIDE;
 
     enum AngleHighlightArea
     {
--- a/Framework/Scene2DViewport/CreateAngleMeasureCommand.cpp	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/CreateAngleMeasureCommand.cpp	Mon Sep 30 10:41:06 2019 +0200
@@ -0,0 +1,53 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2019 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 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
+ * Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "CreateAngleMeasureCommand.h"
+
+#include <boost/make_shared.hpp>
+#include <boost/ref.hpp>
+
+namespace OrthancStone
+{
+  CreateAngleMeasureCommand::CreateAngleMeasureCommand(
+    MessageBroker& broker,
+    boost::weak_ptr<ViewportController> controllerW,
+    ScenePoint2D           point)
+    : CreateMeasureCommand(controllerW)
+    , measureTool_(
+      boost::make_shared<AngleMeasureTool>(boost::ref(broker), controllerW))
+  {
+    GetController()->AddMeasureTool(measureTool_);
+    measureTool_->SetSide1End(point);
+    measureTool_->SetCenter(point);
+    measureTool_->SetSide2End(point);
+  }
+
+  /** This method sets center*/
+  void CreateAngleMeasureCommand::SetCenter(ScenePoint2D scenePos)
+  {
+    measureTool_->SetCenter(scenePos);
+  }
+
+  /** This method sets end of side 2*/
+  void CreateAngleMeasureCommand::SetSide2End(ScenePoint2D scenePos)
+  {
+    measureTool_->SetSide2End(scenePos);
+  }
+}
--- a/Framework/Scene2DViewport/CreateAngleMeasureCommand.h	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/CreateAngleMeasureCommand.h	Mon Sep 30 10:41:06 2019 +0200
@@ -0,0 +1,48 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2019 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 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
+ * Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+#pragma once
+
+#include "MeasureCommands.h"
+
+namespace OrthancStone
+{
+  class CreateAngleMeasureCommand : public CreateMeasureCommand
+  {
+  public:
+    /** Ctor sets end of side 1*/
+    CreateAngleMeasureCommand(
+      MessageBroker& broker,
+      boost::weak_ptr<ViewportController> controllerW,
+      ScenePoint2D           point);
+
+    /** This method sets center*/
+    void SetCenter(ScenePoint2D scenePos);
+
+    /** This method sets end of side 2*/
+    void SetSide2End(ScenePoint2D scenePos);
+
+  private:
+    virtual boost::shared_ptr<MeasureTool> GetMeasureTool() ORTHANC_OVERRIDE
+    {
+      return measureTool_;
+    }
+    boost::shared_ptr<AngleMeasureTool> measureTool_;
+  };
+}
--- a/Framework/Scene2DViewport/CreateAngleMeasureTracker.cpp	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/CreateAngleMeasureTracker.cpp	Mon Sep 30 10:41:06 2019 +0200
@@ -19,6 +19,8 @@
  **/
 
 #include "CreateAngleMeasureTracker.h"
+#include "CreateAngleMeasureCommand.h"
+
 #include <Core/OrthancException.h>
 
 namespace OrthancStone
--- a/Framework/Scene2DViewport/CreateLineMeasureCommand.cpp	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/CreateLineMeasureCommand.cpp	Mon Sep 30 10:41:06 2019 +0200
@@ -0,0 +1,44 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2019 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 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
+ * Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "CreateLineMeasureCommand.h"
+
+#include <boost/make_shared.hpp>
+#include <boost/ref.hpp>
+
+namespace OrthancStone
+{
+  CreateLineMeasureCommand::CreateLineMeasureCommand(
+    MessageBroker& broker,
+    boost::weak_ptr<ViewportController> controllerW,
+    ScenePoint2D           point)
+    : CreateMeasureCommand(controllerW)
+    , measureTool_(
+      boost::make_shared<LineMeasureTool>(boost::ref(broker), controllerW))
+  {
+    GetController()->AddMeasureTool(measureTool_);
+    measureTool_->Set(point, point);
+  }
+
+  void CreateLineMeasureCommand::SetEnd(ScenePoint2D scenePos)
+  {
+    measureTool_->SetEnd(scenePos);
+  }
+}
--- a/Framework/Scene2DViewport/CreateLineMeasureCommand.h	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/CreateLineMeasureCommand.h	Mon Sep 30 10:41:06 2019 +0200
@@ -0,0 +1,46 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2019 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 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
+ * Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+#pragma once
+
+#include "MeasureCommands.h"
+
+namespace OrthancStone
+{
+  class CreateLineMeasureCommand : public CreateMeasureCommand
+  {
+  public:
+    CreateLineMeasureCommand(
+      MessageBroker& broker,
+      boost::weak_ptr<ViewportController> controllerW,
+      ScenePoint2D           point);
+
+    // the starting position is set in the ctor
+    void SetEnd(ScenePoint2D scenePos);
+
+  private:
+    virtual boost::shared_ptr<MeasureTool> GetMeasureTool() ORTHANC_OVERRIDE
+    {
+      return measureTool_;
+    }
+    boost::shared_ptr<LineMeasureTool> measureTool_;
+  };
+}
+
+
--- a/Framework/Scene2DViewport/CreateLineMeasureTracker.cpp	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/CreateLineMeasureTracker.cpp	Mon Sep 30 10:41:06 2019 +0200
@@ -19,6 +19,8 @@
  **/
 
 #include "CreateLineMeasureTracker.h"
+#include "CreateLineMeasureCommand.h"
+
 #include <Core/OrthancException.h>
 
 namespace OrthancStone
--- a/Framework/Scene2DViewport/CreateLineMeasureTracker.h	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/CreateLineMeasureTracker.h	Mon Sep 30 10:41:06 2019 +0200
@@ -22,6 +22,9 @@
 
 #include "MeasureTrackers.h"
 
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+
 namespace OrthancStone
 {
   class CreateLineMeasureTracker : public CreateMeasureTracker
--- a/Framework/Scene2DViewport/EditAngleMeasureCommand.cpp	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/EditAngleMeasureCommand.cpp	Mon Sep 30 10:41:06 2019 +0200
@@ -0,0 +1,53 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2019 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 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
+ * Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "EditAngleMeasureCommand.h"
+
+namespace OrthancStone
+{
+  EditAngleMeasureCommand::EditAngleMeasureCommand(
+    boost::shared_ptr<AngleMeasureTool>  measureTool,
+    MessageBroker& broker,
+    boost::weak_ptr<ViewportController> controllerW)
+    : EditMeasureCommand(measureTool, controllerW)
+    , measureTool_(measureTool)
+  {
+  }
+
+  void EditAngleMeasureCommand::SetCenter(ScenePoint2D scenePos)
+  {
+    measureTool_->SetCenter(scenePos);
+    mementoModified_ = measureTool_->GetMemento();
+  }
+
+
+  void EditAngleMeasureCommand::SetSide1End(ScenePoint2D scenePos)
+  {
+    measureTool_->SetSide1End(scenePos);
+    mementoModified_ = measureTool_->GetMemento();
+  }
+
+
+  void EditAngleMeasureCommand::SetSide2End(ScenePoint2D scenePos)
+  {
+    measureTool_->SetSide2End(scenePos);
+    mementoModified_ = measureTool_->GetMemento();
+  }
+}
--- a/Framework/Scene2DViewport/EditAngleMeasureCommand.h	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/EditAngleMeasureCommand.h	Mon Sep 30 10:41:06 2019 +0200
@@ -0,0 +1,51 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2019 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 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
+ * Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+#pragma once
+
+#include "MeasureCommands.h"
+
+namespace OrthancStone
+{
+  class EditAngleMeasureCommand : public EditMeasureCommand
+  {
+  public:
+    /** Ctor sets end of side 1*/
+    EditAngleMeasureCommand(
+      boost::shared_ptr<AngleMeasureTool>  measureTool,
+      MessageBroker& broker,
+      boost::weak_ptr<ViewportController> controllerW);
+
+    /** This method sets center*/
+    void SetCenter(ScenePoint2D scenePos);
+
+    /** This method sets end of side 1*/
+    void SetSide1End(ScenePoint2D scenePos);
+
+    /** This method sets end of side 2*/
+    void SetSide2End(ScenePoint2D scenePos);
+
+  private:
+    virtual boost::shared_ptr<MeasureTool> GetMeasureTool() ORTHANC_OVERRIDE
+    {
+      return measureTool_;
+    }
+    boost::shared_ptr<AngleMeasureTool> measureTool_;
+  };
+}
--- a/Framework/Scene2DViewport/EditAngleMeasureTracker.cpp	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/EditAngleMeasureTracker.cpp	Mon Sep 30 10:41:06 2019 +0200
@@ -19,6 +19,7 @@
  **/
 
 #include "EditAngleMeasureTracker.h"
+#include "EditAngleMeasureCommand.h"
 
 namespace OrthancStone
 {
--- a/Framework/Scene2DViewport/EditAngleMeasureTracker.h	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/EditAngleMeasureTracker.h	Mon Sep 30 10:41:06 2019 +0200
@@ -24,6 +24,8 @@
 
 namespace OrthancStone
 {
+  class EditAngleMeasureCommand;
+
   class EditAngleMeasureTracker : public EditMeasureTracker
   {
   public:
--- a/Framework/Scene2DViewport/EditLineMeasureCommand.cpp	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/EditLineMeasureCommand.cpp	Mon Sep 30 10:41:06 2019 +0200
@@ -0,0 +1,47 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2019 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 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
+ * Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "EditLineMeasureCommand.h"
+
+namespace OrthancStone
+{
+  EditLineMeasureCommand::EditLineMeasureCommand(
+    boost::shared_ptr<LineMeasureTool>  measureTool,
+    MessageBroker& broker,
+    boost::weak_ptr<ViewportController> controllerW)
+    : EditMeasureCommand(measureTool, controllerW)
+    , measureTool_(measureTool)
+  {
+  }
+
+
+  void EditLineMeasureCommand::SetStart(ScenePoint2D scenePos)
+  {
+    measureTool_->SetStart(scenePos);
+    mementoModified_ = measureTool_->GetMemento();
+  }
+
+
+  void EditLineMeasureCommand::SetEnd(ScenePoint2D scenePos)
+  {
+    measureTool_->SetEnd(scenePos);
+    mementoModified_ = measureTool_->GetMemento();
+  }
+}
--- a/Framework/Scene2DViewport/EditLineMeasureCommand.h	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/EditLineMeasureCommand.h	Mon Sep 30 10:41:06 2019 +0200
@@ -0,0 +1,45 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2019 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 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
+ * Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+#pragma once
+
+#include "MeasureCommands.h"
+
+namespace OrthancStone
+{
+  class EditLineMeasureCommand : public EditMeasureCommand
+  {
+  public:
+    EditLineMeasureCommand(
+      boost::shared_ptr<LineMeasureTool>  measureTool,
+      MessageBroker& broker,
+      boost::weak_ptr<ViewportController> controllerW);
+
+    void SetStart(ScenePoint2D scenePos);
+    void SetEnd(ScenePoint2D scenePos);
+
+  private:
+    virtual boost::shared_ptr<MeasureTool> GetMeasureTool() ORTHANC_OVERRIDE
+    {
+      return measureTool_;
+    }
+    boost::shared_ptr<LineMeasureTool> measureTool_;
+  };
+}
+
--- a/Framework/Scene2DViewport/EditLineMeasureTracker.cpp	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/EditLineMeasureTracker.cpp	Mon Sep 30 10:41:06 2019 +0200
@@ -19,6 +19,8 @@
  **/
 
 #include "EditLineMeasureTracker.h"
+#include "EditLineMeasureCommand.h"
+
 
 namespace OrthancStone
 {
--- a/Framework/Scene2DViewport/EditLineMeasureTracker.h	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/EditLineMeasureTracker.h	Mon Sep 30 10:41:06 2019 +0200
@@ -24,6 +24,8 @@
 
 namespace OrthancStone
 {
+  class EditLineMeasureCommand;
+
   class EditLineMeasureTracker : public EditMeasureTracker
   {
   public:
--- a/Framework/Scene2DViewport/LineMeasureTool.cpp	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/LineMeasureTool.cpp	Mon Sep 30 10:41:06 2019 +0200
@@ -87,6 +87,13 @@
     }
   }
 
+  std::string LineMeasureTool::GetDescription()
+  {
+    std::stringstream ss;
+    ss << "LineMeasureTool. Start = " << start_ << " End = " << end_;
+    return ss.str();
+  }
+
   void LineMeasureTool::ResetHighlightState()
   {
     SetLineHighlightArea(LineHighlightArea_None);
--- a/Framework/Scene2DViewport/LineMeasureTool.h	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/LineMeasureTool.h	Mon Sep 30 10:41:06 2019 +0200
@@ -53,6 +53,7 @@
     virtual boost::shared_ptr<IFlexiblePointerTracker> CreateEditionTracker(const PointerEvent& e) ORTHANC_OVERRIDE;
     virtual boost::shared_ptr<MeasureToolMemento> GetMemento() const ORTHANC_OVERRIDE;
     virtual void SetMemento(boost::shared_ptr<MeasureToolMemento>) ORTHANC_OVERRIDE;
+    virtual std::string GetDescription() ORTHANC_OVERRIDE;
 
     enum LineHighlightArea
     {
--- a/Framework/Scene2DViewport/MeasureCommands.cpp	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/MeasureCommands.cpp	Mon Sep 30 10:41:06 2019 +0200
@@ -39,7 +39,7 @@
   }
 
   CreateMeasureCommand::CreateMeasureCommand(boost::weak_ptr<ViewportController> controllerW)
-    : TrackerCommand(controllerW)
+    : MeasureCommand(controllerW)
   {
 
   }
@@ -50,8 +50,37 @@
     // we thus leave it as is
   }
 
+  void DeleteMeasureCommand::Redo()
+  {
+    // simply disable the measure tool upon undo
+    GetMeasureTool()->Disable();
+    GetController()->RemoveMeasureTool(GetMeasureTool());
+  }
+
+  void DeleteMeasureCommand::Undo()
+  {
+    GetMeasureTool()->Enable();
+    GetController()->AddMeasureTool(GetMeasureTool());
+  }
+
+  DeleteMeasureCommand::~DeleteMeasureCommand()
+  {
+    // deleting the command should not change the model state
+    // we thus leave it as is
+  }
+
+  DeleteMeasureCommand::DeleteMeasureCommand(boost::shared_ptr<MeasureTool> measureTool, boost::weak_ptr<ViewportController> controllerW)
+    : MeasureCommand(controllerW)
+    , measureTool_(measureTool)
+    , mementoOriginal_(measureTool->GetMemento())
+    , mementoModified_(measureTool->GetMemento())
+  {
+    GetMeasureTool()->Disable();
+    GetController()->RemoveMeasureTool(GetMeasureTool());
+  }
+
   EditMeasureCommand::EditMeasureCommand(boost::shared_ptr<MeasureTool> measureTool, boost::weak_ptr<ViewportController> controllerW)
-    : TrackerCommand(controllerW)
+    : MeasureCommand(controllerW)
     , mementoOriginal_(measureTool->GetMemento())
     , mementoModified_(measureTool->GetMemento())
   {
@@ -74,106 +103,10 @@
     GetMeasureTool()->SetMemento(mementoModified_);
   }
 
-  CreateLineMeasureCommand::CreateLineMeasureCommand(
-    MessageBroker&         broker, 
-    boost::weak_ptr<ViewportController> controllerW,
-    ScenePoint2D           point)
-    : CreateMeasureCommand(controllerW)
-    , measureTool_(
-        boost::make_shared<LineMeasureTool>(boost::ref(broker), controllerW))
-  {
-    GetController()->AddMeasureTool(measureTool_);
-    measureTool_->Set(point, point);
-  }
-
-  void CreateLineMeasureCommand::SetEnd(ScenePoint2D scenePos)
-  {
-    measureTool_->SetEnd(scenePos);
-  }
-
-  EditLineMeasureCommand::EditLineMeasureCommand(
-    boost::shared_ptr<LineMeasureTool>  measureTool,
-    MessageBroker& broker,
-    boost::weak_ptr<ViewportController> controllerW)
-    : EditMeasureCommand(measureTool,controllerW)
-    , measureTool_(measureTool)
-  {
-  }
-
-
-  void EditLineMeasureCommand::SetStart(ScenePoint2D scenePos)
-  {
-    measureTool_->SetStart(scenePos);
-    mementoModified_ = measureTool_->GetMemento();
-  }
-
-
-  void EditLineMeasureCommand::SetEnd(ScenePoint2D scenePos)
-  {
-    measureTool_->SetEnd(scenePos);
-    mementoModified_ = measureTool_->GetMemento();
-  }
-    
-  CreateAngleMeasureCommand::CreateAngleMeasureCommand(
-    MessageBroker&         broker, 
-    boost::weak_ptr<ViewportController> controllerW,
-    ScenePoint2D           point)
-    : CreateMeasureCommand(controllerW)
-    , measureTool_(
-      boost::make_shared<AngleMeasureTool>(boost::ref(broker), controllerW))
-  {
-    GetController()->AddMeasureTool(measureTool_);
-    measureTool_->SetSide1End(point);
-    measureTool_->SetCenter(point);
-    measureTool_->SetSide2End(point);
-  }
-
-  /** This method sets center*/
-  void CreateAngleMeasureCommand::SetCenter(ScenePoint2D scenePos)
-  {
-    measureTool_->SetCenter(scenePos);
-  }
-
-  /** This method sets end of side 2*/
-  void CreateAngleMeasureCommand::SetSide2End(ScenePoint2D scenePos)
-  {
-    measureTool_->SetSide2End(scenePos);
-  }
-
-  boost::shared_ptr<ViewportController> TrackerCommand::GetController()
+  boost::shared_ptr<ViewportController> MeasureCommand::GetController()
   {
     boost::shared_ptr<ViewportController> controller = controllerW_.lock();
     assert(controller); // accessing dead object?
     return controller;
   }
-
-  EditAngleMeasureCommand::EditAngleMeasureCommand(
-    boost::shared_ptr<AngleMeasureTool>  measureTool,
-    MessageBroker& broker,
-    boost::weak_ptr<ViewportController> controllerW)
-    : EditMeasureCommand(measureTool, controllerW)
-    , measureTool_(measureTool)
-  {
-  }
-
-  void EditAngleMeasureCommand::SetCenter(ScenePoint2D scenePos)
-  {
-    measureTool_->SetCenter(scenePos);
-    mementoModified_ = measureTool_->GetMemento();
-  }
-
-
-  void EditAngleMeasureCommand::SetSide1End(ScenePoint2D scenePos)
-  {
-    measureTool_->SetSide1End(scenePos);
-    mementoModified_ = measureTool_->GetMemento();
-  }
-
-
-  void EditAngleMeasureCommand::SetSide2End(ScenePoint2D scenePos)
-  {
-    measureTool_->SetSide2End(scenePos);
-    mementoModified_ = measureTool_->GetMemento();
-  }
-
 }
--- a/Framework/Scene2DViewport/MeasureCommands.h	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/MeasureCommands.h	Mon Sep 30 10:41:06 2019 +0200
@@ -32,10 +32,10 @@
 
 namespace OrthancStone
 {
-  class TrackerCommand : public boost::noncopyable
+  class MeasureCommand : public boost::noncopyable
   {
   public:
-    TrackerCommand(boost::weak_ptr<ViewportController> controllerW) 
+    MeasureCommand(boost::weak_ptr<ViewportController> controllerW) 
       : controllerW_(controllerW)
     {
 
@@ -43,14 +43,14 @@
     virtual void Undo() = 0;
     virtual void Redo() = 0;
     
-    virtual ~TrackerCommand() {};
+    virtual ~MeasureCommand() {};
 
   protected:
     boost::shared_ptr<ViewportController>  GetController();
     boost::weak_ptr<ViewportController> controllerW_;
   };
 
-  class CreateMeasureCommand : public TrackerCommand
+  class CreateMeasureCommand : public MeasureCommand
   {
   public:
     CreateMeasureCommand(boost::weak_ptr<ViewportController> controllerW);
@@ -62,7 +62,7 @@
     virtual boost::shared_ptr<MeasureTool> GetMeasureTool() = 0;
   };
   
-  class EditMeasureCommand : public TrackerCommand
+  class EditMeasureCommand : public MeasureCommand
   {
   public:
     EditMeasureCommand(boost::shared_ptr<MeasureTool> measureTool, boost::weak_ptr<ViewportController> controllerW);
@@ -83,94 +83,30 @@
     boost::shared_ptr<MeasureToolMemento> mementoModified_;
   };
 
-  class CreateLineMeasureCommand : public CreateMeasureCommand
+  class DeleteMeasureCommand : public MeasureCommand
   {
   public:
-    CreateLineMeasureCommand(
-      MessageBroker&         broker, 
-      boost::weak_ptr<ViewportController> controllerW,
-      ScenePoint2D           point);
-    
-    // the starting position is set in the ctor
-    void SetEnd(ScenePoint2D scenePos);
+    DeleteMeasureCommand(boost::shared_ptr<MeasureTool> measureTool, boost::weak_ptr<ViewportController> controllerW);
+    virtual ~DeleteMeasureCommand();
+    virtual void Undo() ORTHANC_OVERRIDE;
+    virtual void Redo() ORTHANC_OVERRIDE;
+
+    /** This memento is the original object state */
+    boost::shared_ptr<MeasureToolMemento> mementoOriginal_;
 
   private:
-    virtual boost::shared_ptr<MeasureTool> GetMeasureTool() ORTHANC_OVERRIDE
-    {
-      return measureTool_;
-    }
-    boost::shared_ptr<LineMeasureTool> measureTool_;
-  };
-
-
-  class EditLineMeasureCommand : public EditMeasureCommand
-  {
-  public:
-    EditLineMeasureCommand(
-      boost::shared_ptr<LineMeasureTool>  measureTool,
-      MessageBroker&                      broker,
-      boost::weak_ptr<ViewportController> controllerW);
-
-    void SetStart(ScenePoint2D scenePos);
-    void SetEnd(ScenePoint2D scenePos);
-
-  private:
-    virtual boost::shared_ptr<MeasureTool> GetMeasureTool() ORTHANC_OVERRIDE
+    /** Must be implemented by the subclasses that edit the actual tool */
+    virtual boost::shared_ptr<MeasureTool> GetMeasureTool()
     {
       return measureTool_;
     }
-    boost::shared_ptr<LineMeasureTool> measureTool_;
-  };
 
-
-  class CreateAngleMeasureCommand : public CreateMeasureCommand
-  {
-  public:
-    /** Ctor sets end of side 1*/
-    CreateAngleMeasureCommand(
-      MessageBroker&         broker, 
-      boost::weak_ptr<ViewportController> controllerW,
-      ScenePoint2D           point);
-
-    /** This method sets center*/
-    void SetCenter(ScenePoint2D scenePos);
-
-    /** This method sets end of side 2*/
-    void SetSide2End(ScenePoint2D scenePos);
-
-  private:
-    virtual boost::shared_ptr<MeasureTool> GetMeasureTool() ORTHANC_OVERRIDE
-    {
-      return measureTool_;
-    }
-    boost::shared_ptr<AngleMeasureTool> measureTool_;
-  };
+    boost::shared_ptr<MeasureTool> measureTool_;
 
-  class EditAngleMeasureCommand : public EditMeasureCommand
-  {
-  public:
-    /** Ctor sets end of side 1*/
-    EditAngleMeasureCommand(
-      boost::shared_ptr<AngleMeasureTool>  measureTool,
-      MessageBroker& broker,
-      boost::weak_ptr<ViewportController> controllerW);
-
-    /** This method sets center*/
-    void SetCenter(ScenePoint2D scenePos);
+  protected:
 
-    /** This method sets end of side 1*/
-    void SetSide1End(ScenePoint2D scenePos);
-
-    /** This method sets end of side 2*/
-    void SetSide2End(ScenePoint2D scenePos);
-
-  private:
-    virtual boost::shared_ptr<MeasureTool> GetMeasureTool() ORTHANC_OVERRIDE
-    {
-      return measureTool_;
-    }
-    boost::shared_ptr<AngleMeasureTool> measureTool_;
+    /** This memento is updated by the subclasses upon modifications */
+    boost::shared_ptr<MeasureToolMemento> mementoModified_;
   };
-
 }
 
--- a/Framework/Scene2DViewport/MeasureTool.cpp	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/MeasureTool.cpp	Mon Sep 30 10:41:06 2019 +0200
@@ -30,7 +30,10 @@
 {
   MeasureTool::~MeasureTool()
   {
-    GetController()->Unregister(this);
+    // if the controller is dead, let's not bother.
+    boost::shared_ptr<ViewportController> controller = controllerW_.lock();
+    if (controller)
+      controller->Unregister(this);
   }
 
   void MeasureTool::Enable()
--- a/Framework/Scene2DViewport/MeasureTool.h	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/MeasureTool.h	Mon Sep 30 10:41:06 2019 +0200
@@ -105,6 +105,11 @@
     */
     virtual void ResetHighlightState() = 0;
 
+    /**
+    A description of the measuring tool, useful in debug logs
+    */
+    virtual std::string GetDescription() = 0;
+
   protected:
     MeasureTool(MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW);
 
--- a/Framework/Scene2DViewport/MeasureTrackers.h	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/MeasureTrackers.h	Mon Sep 30 10:41:06 2019 +0200
@@ -27,6 +27,9 @@
 #include "MeasureTool.h"
 #include "MeasureCommands.h"
 
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+
 #include <vector>
 
 namespace OrthancStone
--- a/Framework/Scene2DViewport/PredeclaredTypes.h	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/PredeclaredTypes.h	Mon Sep 30 10:41:06 2019 +0200
@@ -35,7 +35,7 @@
   class CreateMeasureCommand;
   class CreateLineMeasureCommand;
   class CreateAngleMeasureCommand;
-  class TrackerCommand;
+  class MeasureCommand;
   class ViewportController;
   class LayerHolder;
 }
--- a/Framework/Scene2DViewport/UndoStack.cpp	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/UndoStack.cpp	Mon Sep 30 10:41:06 2019 +0200
@@ -29,7 +29,7 @@
   UndoStack::UndoStack() : numAppliedCommands_(0)
   {}
 
-  void UndoStack::PushCommand(boost::shared_ptr<TrackerCommand> command)
+  void UndoStack::PushCommand(boost::shared_ptr<MeasureCommand> command)
   {
     commandStack_.erase(
       commandStack_.begin() + numAppliedCommands_,
--- a/Framework/Scene2DViewport/UndoStack.h	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/UndoStack.h	Mon Sep 30 10:41:06 2019 +0200
@@ -26,7 +26,7 @@
 
 namespace OrthancStone
 {
-  class TrackerCommand;
+  class MeasureCommand;
 
   class UndoStack
   {
@@ -41,7 +41,7 @@
     In other words, when a new command is pushed, all the undone (and not
     redone) commands are removed.
     */
-    void PushCommand(boost::shared_ptr<TrackerCommand> command);
+    void PushCommand(boost::shared_ptr<MeasureCommand> command);
 
     /**
     Undoes the command at the top of the undo stack, or throws if there is no
@@ -64,7 +64,7 @@
     bool CanRedo() const;
   
   private:
-    std::vector<boost::shared_ptr<TrackerCommand> > commandStack_;
+    std::vector<boost::shared_ptr<MeasureCommand> > commandStack_;
 
     /**
     This is always between >= 0 and <= undoStack_.size() and gives the
--- a/Framework/Scene2DViewport/ViewportController.cpp	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/ViewportController.cpp	Mon Sep 30 10:41:06 2019 +0200
@@ -38,6 +38,11 @@
     , viewport_(viewport)
   {
   }
+ 
+  ViewportController::~ViewportController()
+  {
+
+  }
 
   boost::shared_ptr<UndoStack> ViewportController::GetUndoStack()
   {
@@ -49,7 +54,7 @@
     return undoStackW_.lock();
   }
 
-  void ViewportController::PushCommand(boost::shared_ptr<TrackerCommand> command)
+  void ViewportController::PushCommand(boost::shared_ptr<MeasureCommand> command)
   {
     boost::shared_ptr<UndoStack> undoStack = undoStackW_.lock();
     if(undoStack.get() != NULL)
--- a/Framework/Scene2DViewport/ViewportController.h	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Scene2DViewport/ViewportController.h	Mon Sep 30 10:41:06 2019 +0200
@@ -84,6 +84,9 @@
                        MessageBroker& broker,
                        IViewport& viewport);
 
+
+    ~ViewportController();
+
     /** 
     This method is called by the GUI system and should update/delete the
     current tracker
@@ -156,7 +159,7 @@
 
 
     /** forwarded to the UndoStack */
-    void PushCommand(boost::shared_ptr<TrackerCommand> command);
+    void PushCommand(boost::shared_ptr<MeasureCommand> command);
 
     /** forwarded to the UndoStack */
     void Undo();
--- a/Framework/Toolbox/CoordinateSystem3D.cpp	Fri Sep 27 13:32:05 2019 +0200
+++ b/Framework/Toolbox/CoordinateSystem3D.cpp	Mon Sep 30 10:41:06 2019 +0200
@@ -198,7 +198,6 @@
     offsetY = boost::numeric::ublas::inner_prod(axisY_, projection - origin_);
   }
 
-
   bool CoordinateSystem3D::IntersectSegment(Vector& p,
                                             const Vector& edgeFrom,
                                             const Vector& edgeTo) const