Commit [96f930] hugin_parallel_openmp Maximize Restore History

Allow cp generation in pano space for overlapping images in fast preview window

This extends the delete cp tool to a more general edit cp tool.

tmodes tmodes 2014-02-16

changed src/hugin1/hugin/xrc/preview_frame.xrc
changed src/hugin1/hugin/ImagesPanel.h
changed src/hugin1/hugin/MainFrame.h
changed src/hugin1/hugin/GLPreviewFrame.cpp
changed src/hugin1/hugin/MainFrame.cpp
changed src/hugin1/hugin/GLPreviewFrame.h
changed src/hugin1/hugin/CMakeLists.txt
changed src/hugin1/hugin/ImagesPanel.cpp
copied src/hugin1/hugin/PreviewDeleteCPTool.h -> src/hugin1/hugin/PreviewEditCPTool.h
copied src/hugin1/hugin/PreviewDeleteCPTool.cpp -> src/hugin1/hugin/PreviewEditCPTool.cpp
src/hugin1/hugin/xrc/preview_frame.xrc Diff Switch to side-by-side view
Loading...
src/hugin1/hugin/ImagesPanel.h Diff Switch to side-by-side view
Loading...
src/hugin1/hugin/MainFrame.h Diff Switch to side-by-side view
Loading...
src/hugin1/hugin/GLPreviewFrame.cpp Diff Switch to side-by-side view
Loading...
src/hugin1/hugin/MainFrame.cpp Diff Switch to side-by-side view
Loading...
src/hugin1/hugin/GLPreviewFrame.h Diff Switch to side-by-side view
Loading...
src/hugin1/hugin/CMakeLists.txt Diff Switch to side-by-side view
Loading...
src/hugin1/hugin/ImagesPanel.cpp Diff Switch to side-by-side view
Loading...
src/hugin1/hugin/PreviewDeleteCPTool.h to src/hugin1/hugin/PreviewEditCPTool.h
--- a/src/hugin1/hugin/PreviewDeleteCPTool.h
+++ b/src/hugin1/hugin/PreviewEditCPTool.h
@@ -1,6 +1,6 @@
 // -*- c-basic-offset: 4 -*-
 
-/** @file PreviewDeleteCPTool.h
+/** @file PreviewEditCPTool.h
  *
  *  @author T. Modes
  *
@@ -24,20 +24,26 @@
  *
  */
 
-#ifndef _PREVIEWDELETECPTOOL_H
-#define _PREVIEWDELETECPTOOL_H
+#ifndef _PREVIEWEDITCPTOOL_H
+#define _PREVIEWEDITCPTOOL_H
 
 #include "Tool.h"
 #include "hugin_utils/utils.h"
 
 #include <panotools/PanoToolsInterface.h>
 
+/** id for context menu */
+enum{
+    ID_CREATE_CP=wxID_HIGHEST + 301,
+    ID_REMOVE_CP
+};
+
 /** Tool to delete all cp in a selected rectangle
  */
-class PreviewDeleteCPTool : public Tool
+class PreviewEditCPTool : public Tool
 {
 public:
-    PreviewDeleteCPTool(ToolHelper *helper) : Tool(helper), m_mouse_down(false) {};
+    PreviewEditCPTool(ToolHelper *helper) : Tool(helper), m_mouseDown(false), m_menuPopup(false) {};
     /** activate the tool */
     void Activate();
     /** draw selection rectangle */
@@ -46,11 +52,25 @@
     void MouseMoveEvent(double x, double y, wxMouseEvent & e);
     /** mouse button handling */
     void MouseButtonEvent(wxMouseEvent &e);
+    /** return set of found control points */
+    HuginBase::UIntSet GetFoundCPs() { return m_CPinROI; };
+    /** returns selected ROI */
+    vigra::Rect2D GetSelectedROI();
+    /** reset popup menu status */
+    void SetMenuProcessed();
 private:
-    void DeleteCP(const hugin_utils::FDiff2D& pos1, const hugin_utils::FDiff2D& pos2);
-    bool m_mouse_down;
-    hugin_utils::FDiff2D m_start_pos;
-    hugin_utils::FDiff2D m_current_pos;
+    /** search for control points in selected rectangle */
+    void FindCPInRect(const hugin_utils::FDiff2D& pos1, const hugin_utils::FDiff2D& pos2);
+    /** mouse down status */
+    bool m_mouseDown;
+    /** true, when popup menu is shown, this is to ignore a mouse event when the popup menu is closed */
+    bool m_menuPopup;
+    /** position where the marking starts */
+    hugin_utils::FDiff2D m_startPos;
+    /** current position of selection */
+    hugin_utils::FDiff2D m_currentPos;
+    /** contains the found cp */
+    HuginBase::UIntSet m_CPinROI;
 };
 
 #endif
src/hugin1/hugin/PreviewDeleteCPTool.cpp to src/hugin1/hugin/PreviewEditCPTool.cpp
--- a/src/hugin1/hugin/PreviewDeleteCPTool.cpp
+++ b/src/hugin1/hugin/PreviewEditCPTool.cpp
@@ -1,10 +1,10 @@
 // -*- c-basic-offset: 4 -*-
 
-/** @file PreviewDeleteCPTool.cpp
+/** @file PreviewEditCPTool.cpp
  *
  *  @author T. Modes
  *
- *  @brief implementation of ToolHelper for deleting control points in the pano space
+ *  @brief implementation of ToolHelper for editing control points in the pano space
  *
  */
 
@@ -25,10 +25,9 @@
  *
  */
 
-#include "hugin/PreviewDeleteCPTool.h"
+#include "hugin/PreviewEditCPTool.h"
 #include "panoinc_WX.h"
 #include "panoinc.h"
-#include "hugin/CommandHistory.h"
 #include <map>
 
 #include <wx/platform.h>
@@ -41,81 +40,120 @@
 #include <GL/gl.h>
 #endif
 
-// we want to draw over the panorama when in use, so make sure we get notice.
-void PreviewDeleteCPTool::Activate()
+#include "GLPreviewFrame.h"
+
+// we want to handle the mouse events and to draw over the panorama when in use, so make sure we get notice.
+void PreviewEditCPTool::Activate()
 {
     helper->NotifyMe(PreviewToolHelper::MOUSE_PRESS, this);
     helper->NotifyMe(PreviewToolHelper::MOUSE_MOVE, this);
     helper->NotifyMe(PreviewToolHelper::REALLY_DRAW_OVER_IMAGES, this);
-    m_mouse_down = false;
-    helper->SetStatusMessage(_("Drag a rectangle to select which control points should be deleted."));
-};
-
-// The panorama has been drawn the selection rectangle.
-void PreviewDeleteCPTool::ReallyAfterDrawImagesEvent()
-{
-    if (m_mouse_down)
+    m_mouseDown = false;
+    helper->SetStatusMessage(_("Drag a rectangle and select the desired action for the control points in the selected rectangle."));
+};
+
+// The panorama has been drawn, now draw the selection rectangle.
+void PreviewEditCPTool::ReallyAfterDrawImagesEvent()
+{
+    if (m_mouseDown)
     {
         glDisable(GL_TEXTURE_2D);
-        glColor3f(1, 0, 0);
+        hugin_utils::FDiff2D dist = m_currentPos - m_startPos;
+        // select color depending on size
+        if (fabs(dist.x) > 100 && fabs(dist.y) > 100)
+        {
+            glColor3f(1, 1, 0);
+        }
+        else
+        {
+            // selection is too small, use a gray color
+            glColor3f(0.7, 0.7, 0.7);
+        }
         glBegin(GL_LINES);
-        glVertex2f(m_start_pos.x, m_start_pos.y);
-        glVertex2f(m_current_pos.x, m_start_pos.y);
-        glVertex2f(m_current_pos.x, m_start_pos.y);
-        glVertex2f(m_current_pos.x, m_current_pos.y);
-        glVertex2f(m_current_pos.x, m_current_pos.y);
-        glVertex2f(m_start_pos.x, m_current_pos.y);
-        glVertex2f(m_start_pos.x, m_current_pos.y);
-        glVertex2f(m_start_pos.x, m_start_pos.y);
+        glVertex2f(m_startPos.x, m_startPos.y);
+        glVertex2f(m_currentPos.x, m_startPos.y);
+        glVertex2f(m_currentPos.x, m_startPos.y);
+        glVertex2f(m_currentPos.x, m_currentPos.y);
+        glVertex2f(m_currentPos.x, m_currentPos.y);
+        glVertex2f(m_startPos.x, m_currentPos.y);
+        glVertex2f(m_startPos.x, m_currentPos.y);
+        glVertex2f(m_startPos.x, m_startPos.y);
         glEnd();
         glEnable(GL_TEXTURE_2D);
     };
 };
 
-void PreviewDeleteCPTool::MouseMoveEvent(double x, double y, wxMouseEvent & e)
-{
-    if (m_mouse_down)
-    {
-        m_current_pos = helper->GetMousePanoPosition();
+// update selection rectangle
+void PreviewEditCPTool::MouseMoveEvent(double x, double y, wxMouseEvent & e)
+{
+    if (m_mouseDown)
+    {
+        m_currentPos = helper->GetMousePanoPosition();
         // force redrawing
         helper->GetVisualizationStatePtr()->ForceRequireRedraw();
         helper->GetVisualizationStatePtr()->Redraw();
     };
 }
 
-
-void PreviewDeleteCPTool::MouseButtonEvent(wxMouseEvent &e)
-{
-    if (e.GetButton() == wxMOUSE_BTN_LEFT)
-    {
-        if (e.ButtonDown())
-        {
-            m_mouse_down = true;
-            m_start_pos = helper->GetMousePanoPosition();
+// handle mouse buttons
+void PreviewEditCPTool::MouseButtonEvent(wxMouseEvent &e)
+{
+    if (e.GetButton() && m_menuPopup)
+    {
+        // catch first mouse click after menu popup
+        // to correctly handle dismiss of popup menu
+        m_menuPopup = false;
+    }
+    else
+    {
+        if (e.ButtonDown(wxMOUSE_BTN_LEFT) && !m_mouseDown)
+        {
+            // start selecting rectangle
+            m_mouseDown = true;
+            m_startPos = helper->GetMousePanoPosition();
+            m_CPinROI.clear();
         }
         else
         {
-            m_mouse_down = false;
-            m_current_pos = helper->GetMousePanoPosition();
-            if (m_current_pos.squareDistance(m_start_pos) > 5)
+            if (e.ButtonUp(wxMOUSE_BTN_LEFT) && m_mouseDown)
             {
-                DeleteCP(m_start_pos, m_current_pos);
-            }
-            else
-            {
-                wxBell();
+                // finish selecting
+                m_mouseDown = false;
+                m_currentPos = helper->GetMousePanoPosition();
+                hugin_utils::FDiff2D dist = m_currentPos - m_startPos;
+                if (fabs(dist.x)>100 && fabs(dist.y)>100)
+                {
+                    // build menu
+                    wxMenu menu;
+                    FindCPInRect(m_startPos, m_currentPos);
+                    menu.Append(ID_CREATE_CP, _("Create control points here"));
+                    if (!m_CPinROI.empty())
+                    {
+                        menu.Append(ID_REMOVE_CP, wxString::Format(_("Remove %lu control points"), static_cast<unsigned long int>(m_CPinROI.size())));
+                    }
+                    m_menuPopup = true;
+                    helper->GetPreviewFrame()->PopupMenu(&menu);
+                }
+                else
+                {
+                    wxBell();
+                    // we need to redraw so that the selection rectangle vanishes
+                    helper->GetVisualizationStatePtr()->ForceRequireRedraw();
+                    helper->GetVisualizationStatePtr()->Redraw();
+                };
             };
         };
     };
 };
 
-void PreviewDeleteCPTool::DeleteCP(const hugin_utils::FDiff2D& pos1, const hugin_utils::FDiff2D& pos2)
+// find all cp in the given rectangle
+void PreviewEditCPTool::FindCPInRect(const hugin_utils::FDiff2D& pos1, const hugin_utils::FDiff2D& pos2)
 {
     PT::Panorama* pano = helper->GetPanoramaPtr();
     HuginBase::UIntSet activeImages = pano->getActiveImages();
     const hugin_utils::FDiff2D panoPos1(pos1.x < pos2.x ? pos1.x : pos2.x, pos1.y < pos2.y ? pos1.y : pos2.y);
     const hugin_utils::FDiff2D panoPos2(pos1.x > pos2.x ? pos1.x : pos2.x, pos1.y > pos2.y ? pos1.y : pos2.y);
-    HuginBase::UIntSet cpsToDelete;
+    m_CPinROI.clear();
     if (!activeImages.empty())
     {
         // create transformation objects
@@ -142,7 +180,7 @@
                     if (panoPos1.x <= pos1.x && pos1.x <= panoPos2.x && panoPos1.y <= pos1.y && pos1.y <= panoPos2.y &&
                         panoPos1.x <= pos2.x && pos2.x <= panoPos2.x && panoPos1.y <= pos2.y && pos2.y <= panoPos2.y)
                     {
-                        cpsToDelete.insert(cpIt - cps.begin());
+                        m_CPinROI.insert(cpIt - cps.begin());
                     };
                 };
             };
@@ -152,31 +190,24 @@
             delete it->second;
         };
     };
-    if (cpsToDelete.empty())
-    {
-        wxMessageBox(_("Selected rectangle does not contain any control points.\nNo control point removed."),
-#ifdef _WINDOWS
-            _("Hugin"),
-#else
-            wxT(""),
-#endif
-            wxOK | wxICON_INFORMATION, (wxWindow*)helper->GetPreviewFrame());
-    }
-    else
-    {
-        int r = wxMessageBox(wxString::Format(_("Really delete %lu control points?"), static_cast<unsigned long int>(cpsToDelete.size())),
-#ifdef _WINDOWS
-            _("Hugin"),
-#else
-            wxT(""),
-#endif
-            wxICON_INFORMATION | wxYES_NO, (wxWindow*)helper->GetPreviewFrame());
-        if (r == wxYES)
-        {
-            GlobalCmdHist::getInstance().addCommand(new PT::RemoveCtrlPointsCmd(*pano, cpsToDelete));
-        };
-    };
-    // force redrawing
-    helper->GetVisualizationStatePtr()->ForceRequireRedraw();
-    helper->GetVisualizationStatePtr()->Redraw();
-};+};
+
+// return the selected ROI
+vigra::Rect2D PreviewEditCPTool::GetSelectedROI()
+{
+    vigra::Point2D p1;
+    p1.x = std::min(m_startPos.x, m_currentPos.x);
+    p1.y = std::min(m_startPos.y, m_currentPos.y);
+    vigra::Point2D p2;
+    p2.x = std::max(m_startPos.x, m_currentPos.x);
+    p2.y = std::max(m_startPos.y, m_currentPos.y);
+    return vigra::Rect2D(p1, p2);
+};
+
+// for correctly handling the popup menu 
+// when selecting the popup menu or dismiss the popup menu we get an additional mouse
+// click, we need to ignore this one, this function sets the state back
+void PreviewEditCPTool::SetMenuProcessed()
+{
+    m_menuPopup = false;
+};