Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PreviewEditCPTool.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
2 
11 /*
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public
14  * License as published by the Free Software Foundation; either
15  * version 2 of the License, or (at your option) any later version.
16  *
17  * This software is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20  * General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public
23  * License along with this software. If not, see
24  * <http://www.gnu.org/licenses/>.
25  *
26  */
27 
28 #include "panoinc_WX.h"
29 #include "panoinc.h"
31 #include <map>
32 #include "base_wx/CommandHistory.h"
33 #include "base_wx/wxPanoCommand.h"
34 
35 #include <wx/platform.h>
36 #ifdef __WXMAC__
37 #include <OpenGL/gl.h>
38 #else
39 #ifdef __WXMSW__
40 #include <vigra/windows.h>
41 #endif
42 #include <GL/gl.h>
43 #endif
44 
45 #include "GLPreviewFrame.h"
46 
47 // we want to handle the mouse events and to draw over the panorama when in use, so make sure we get notice.
49 {
53  m_mouseDown = false;
54  helper->SetStatusMessage(_("Drag a rectangle and select the desired action for the control points in the selected rectangle. Alt + drag to create a line control point."));
55 };
56 
57 // The panorama has been drawn, now draw the selection rectangle.
59 {
60  if (m_mouseDown)
61  {
62  glDisable(GL_TEXTURE_2D);
64  // select color depending on size
65  if (m_line || (fabs(dist.x) > 10 && fabs(dist.y) > 10))
66  {
67  glColor3f(1.0f, 1.0f, 0.0f);
68  }
69  else
70  {
71  // selection is too small, use a gray color
72  glColor3f(0.7f, 0.7f, 0.7f);
73  }
74  if (m_line)
75  {
76  glBegin(GL_LINES);
77  glVertex2f(m_startPos.x, m_startPos.y);
78  glVertex2f(m_currentPos.x, m_currentPos.y);
79  glEnd();
80  }
81  else
82  {
83  glBegin(GL_LINES);
84  glVertex2f(m_startPos.x, m_startPos.y);
85  glVertex2f(m_currentPos.x, m_startPos.y);
86  glVertex2f(m_currentPos.x, m_startPos.y);
87  glVertex2f(m_currentPos.x, m_currentPos.y);
88  glVertex2f(m_currentPos.x, m_currentPos.y);
89  glVertex2f(m_startPos.x, m_currentPos.y);
90  glVertex2f(m_startPos.x, m_currentPos.y);
91  glVertex2f(m_startPos.x, m_startPos.y);
92  glEnd();
93  };
94  glEnable(GL_TEXTURE_2D);
95  };
96 };
97 
98 // update selection rectangle
99 void PreviewEditCPTool::MouseMoveEvent(double x, double y, wxMouseEvent & e)
100 {
101  if (m_mouseDown)
102  {
105  // force redrawing
108  };
109 }
110 
111 // handle mouse buttons
113 {
114  if (e.GetButton() && m_menuPopup)
115  {
116  // catch first mouse click after menu popup
117  // to correctly handle dismiss of popup menu
118  m_menuPopup = false;
119  }
120  else
121  {
122  if (e.ButtonDown(wxMOUSE_BTN_LEFT) && !m_mouseDown)
123  {
124  // start selecting rectangle
125  m_mouseDown = true;
128  m_CPinROI.clear();
129  m_line = e.AltDown();
130  }
131  else
132  {
133  if (e.ButtonUp(wxMOUSE_BTN_LEFT) && m_mouseDown)
134  {
135  // finish selecting
136  m_mouseDown = false;
139  if (m_line)
140  {
141  // now add the line cp
143  }
144  else
145  {
147  if (fabs(dist.x) > 10 && fabs(dist.y) > 10)
148  {
149  // build menu
150  wxMenu menu;
151  const vigra::Rect2D roi = GetSelectedROI();
152  // selected roi should have at least 10 pixel width and height in pano space
153  if (!roi.isEmpty() && roi.width() > 10 && roi.height() > 10)
154  {
155  menu.Append(ID_CREATE_CP, _("Create control points here"));
156  };
158  if (!m_CPinROI.empty())
159  {
160  menu.Append(ID_REMOVE_CP, wxString::Format(_("Remove %lu control points"), static_cast<unsigned long int>(m_CPinROI.size())));
161  };
162  if (!menu.GetMenuItems().IsEmpty())
163  {
164  m_menuPopup = true;
165  helper->GetPreviewFrame()->PopupMenu(&menu);
166  }
167  else
168  {
169  wxBell();
172  };
173  }
174  else
175  {
176  wxBell();
177  // we need to redraw so that the selection rectangle vanishes
180  };
181  };
182  };
183  };
184  };
185 };
186 
187 // find all cp in the given rectangle
189 {
191  HuginBase::UIntSet activeImages = pano->getActiveImages();
192  const hugin_utils::FDiff2D panoPos1(pos1.x < pos2.x ? pos1.x : pos2.x, pos1.y < pos2.y ? pos1.y : pos2.y);
193  const hugin_utils::FDiff2D panoPos2(pos1.x > pos2.x ? pos1.x : pos2.x, pos1.y > pos2.y ? pos1.y : pos2.y);
194  m_CPinROI.clear();
195  if (!activeImages.empty())
196  {
197  // create transformation objects
198  typedef std::map<size_t, HuginBase::PTools::Transform*> TransformMap;
199  TransformMap transformations;
200  for (HuginBase::UIntSet::iterator it = activeImages.begin(); it != activeImages.end(); ++it)
201  {
203  trans->createInvTransform(pano->getImage(*it), pano->getOptions());
204  transformations.insert(std::make_pair(*it, trans));
205  };
206  HuginBase::CPVector cps = pano->getCtrlPoints();
207  for (HuginBase::CPVector::const_iterator cpIt = cps.begin(); cpIt != cps.end(); ++cpIt)
208  {
209  // check cp only if both images are visible
210  if (set_contains(activeImages, cpIt->image1Nr) && set_contains(activeImages, cpIt->image2Nr))
211  {
214  // remove all control points, where both points are inside the given rectangle
215  if (transformations[cpIt->image1Nr]->transformImgCoord(pos1, hugin_utils::FDiff2D(cpIt->x1, cpIt->y1)) &&
216  transformations[cpIt->image2Nr]->transformImgCoord(pos2, hugin_utils::FDiff2D(cpIt->x2, cpIt->y2)))
217  {
218  if (panoPos1.x <= pos1.x && pos1.x <= panoPos2.x && panoPos1.y <= pos1.y && pos1.y <= panoPos2.y &&
219  panoPos1.x <= pos2.x && pos2.x <= panoPos2.x && panoPos1.y <= pos2.y && pos2.y <= panoPos2.y)
220  {
221  m_CPinROI.insert(cpIt - cps.begin());
222  };
223  };
224  };
225  };
226  for (TransformMap::iterator it = transformations.begin(); it != transformations.end(); ++it)
227  {
228  delete it->second;
229  };
230  };
231 };
232 
233 // return the selected ROI
235 {
236  vigra::Point2D p1;
239  vigra::Point2D p2;
242  return vigra::Rect2D(p1, p2) & vigra::Rect2D(helper->GetPanoramaPtr()->getOptions().getSize());
243 };
244 
245 // for correctly handling the popup menu
246 // when selecting the popup menu or dismiss the popup menu we get an additional mouse
247 // click, we need to ignore this one, this function sets the state back
249 {
250  m_menuPopup = false;
251 };
252 
254 {
257  HuginBase::UIntSet imgIntersection;
258  std::set_intersection(imgs1.begin(), imgs1.end(), imgs2.begin(), imgs2.end(), std::inserter(imgIntersection, imgIntersection.begin()));
259  if (!imgIntersection.empty())
260  {
261  // start and end point are on the same image
264  cp.image1Nr = *imgIntersection.begin();
265 
267  transform.createTransform(pano->getImage(cp.image1Nr), pano->getOptions());
268  double image_x, image_y;
269  transform.transformImgCoord(image_x, image_y, pos1.x, pos1.y);
270  cp.x1 = image_x;
271  cp.y1 = image_y;
272  transform.transformImgCoord(image_x, image_y, pos2.x, pos2.y);
273  cp.image2Nr = cp.image1Nr;
274  cp.x2 = image_x;
275  cp.y2 = image_y;
276  if (abs(pos1.x - pos2.x) < abs(pos1.y - pos2.y))
277  {
279  }
280  else
281  {
283  };
285  }
286  else
287  {
288  wxBell();
289  // we need to redraw so that the selection vanishes
292  };
293 }
implementation of huginApp Class
hugin_utils::FDiff2D GetMousePanoPosition()
Definition: ToolHelper.cpp:295
void ReallyAfterDrawImagesEvent()
draw selection rectangle
HuginBase::Panorama * GetPanoramaPtr()
Definition: ToolHelper.cpp:310
bool set_contains(const _Container &c, const typename _Container::key_type &key)
Definition: stl_utils.h:74
include file for the hugin project
void SetMenuProcessed()
reset popup menu status
void ForceRequireRedraw()
Definition: ViewState.cpp:439
void NotifyMe(Event event, Tool *tool)
Definition: ToolHelper.cpp:315
const CPVector & getCtrlPoints() const
get all control point of this Panorama
Definition: Panorama.h:319
hugin_utils::FDiff2D m_currentPosScreen
current position of selection in screen coordinates
add a control point
Definition: PanoCommand.h:268
represents a control point
Definition: ControlPoint.h:38
void AddLineCP(const hugin_utils::FDiff2D &pos1, const hugin_utils::FDiff2D &pos2)
called to add line control point
void MouseMoveEvent(double x, double y, wxMouseEvent &e)
mouse move handling
VisualizationState * GetVisualizationStatePtr()
Definition: ToolHelper.cpp:300
hugin_utils::FDiff2D GetMouseScreenPosition()
Definition: ToolHelper.cpp:290
std::set< unsigned int > UIntSet
Definition: PanoramaData.h:51
ToolHelper * helper
The PreviewToolHelper that uses the same preview window and panorama as the tool should.
Definition: Tool.h:102
Model for a panorama.
Definition: Panorama.h:152
void MouseButtonEvent(wxMouseEvent &e)
mouse button handling
void createInvTransform(const vigra::Diff2D &srcSize, VariableMap srcVars, Lens::LensProjectionFormat srcProj, const vigra::Diff2D &destSize, PanoramaOptions::ProjectionFormat destProj, const std::vector< double > &destProjParam, double destHFOV, const vigra::Diff2D &origSrcSize)
create image-&gt;pano transformation
hugin_utils::FDiff2D m_currentPos
current position of selection
bool m_line
if selecting a rectangle or a line
wxwindows specific panorama commands
bool m_menuPopup
true, when popup menu is shown, this is to ignore a mouse event when the popup menu is closed ...
evaluate x, points are on a vertical line
Definition: ControlPoint.h:47
static GlobalCmdHist & getInstance()
void addCommand(PanoCommand *command, bool execute=true)
Adds a command to the history.
void Activate()
activate the tool
UIntSet getActiveImages() const
get active images
Definition: Panorama.cpp:1585
bool m_mouseDown
mouse down status
include file for the hugin project
bool transformImgCoord(double &x_dest, double &y_dest, double x_src, double y_src) const
like transform, but return image coordinates, not cartesian coordinates
const PanoramaOptions & getOptions() const
returns the options for this panorama
Definition: Panorama.h:481
hugin_utils::FDiff2D m_startPos
position where the marking starts
static T max(T x, T y)
Definition: svm.cpp:65
Holds transformations for Image -&gt; Pano and the other way.
void SetStatusMessage(wxString message)
Definition: ToolHelper.cpp:409
std::vector< ControlPoint > CPVector
Definition: ControlPoint.h:99
interface of ToolHelper for deleting control points in the pano space
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
Definition: Panorama.h:211
HuginBase::UIntSet m_CPinROI
contains the found cp
vigra::Size2D getSize() const
get size of output image
void FindCPInRect(const hugin_utils::FDiff2D &pos1, const hugin_utils::FDiff2D &pos2)
search for control points in selected rectangle
vigra::Rect2D GetSelectedROI()
returns selected ROI
evaluate y, points are on a horizontal line
Definition: ControlPoint.h:48
static T min(T x, T y)
Definition: svm.cpp:62
GLPreviewFrame * GetPreviewFrame()
Definition: ToolHelper.h:139
void createTransform(const vigra::Diff2D &srcSize, VariableMap srcVars, Lens::LensProjectionFormat srcProj, const vigra::Diff2D &destSize, PanoramaOptions::ProjectionFormat destProj, const std::vector< double > &destProjParam, double destHFOV, const vigra::Diff2D &origSrcSize)
initialize pano-&gt;image transformation
HuginBase::UIntSet GetImagesUnderPos(const hugin_utils::FDiff2D &pos)
Definition: ToolHelper.cpp:121
hugin_utils::FDiff2D m_startPosScreen
position where the marking starts in screen coordinates