Hugin trunk 0.1
Loading...
Searching...
No Matches
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>
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#include "GLViewer.h"
47
48// we want to handle the mouse events and to draw over the panorama when in use, so make sure we get notice.
50{
54 m_mouseDown = false;
55 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."));
56 // set cursor to cross on preview
58}
59
61{
62 // reset cursor back to default
64}
65
66// The panorama has been drawn, now draw the selection rectangle.
68{
69 if (m_mouseDown)
70 {
73 // select color depending on size
74 if (m_line || (fabs(dist.x) > 10 && fabs(dist.y) > 10))
75 {
76 glColor3f(1.0f, 1.0f, 0.0f);
77 }
78 else
79 {
80 // selection is too small, use a gray color
81 glColor3f(0.7f, 0.7f, 0.7f);
82 }
83 if (m_line)
84 {
88 glEnd();
89 }
90 else
91 {
101 glEnd();
102 };
104 };
105};
106
107// update selection rectangle
119
120// handle mouse buttons
122{
123 if (e.GetButton() && m_menuPopup)
124 {
125 // catch first mouse click after menu popup
126 // to correctly handle dismiss of popup menu
127 m_menuPopup = false;
128 }
129 else
130 {
131 if (e.ButtonDown(wxMOUSE_BTN_LEFT) && !m_mouseDown)
132 {
133 // start selecting rectangle
134 m_mouseDown = true;
137 m_CPinROI.clear();
138 m_line = e.AltDown();
139 }
140 else
141 {
142 if (e.ButtonUp(wxMOUSE_BTN_LEFT) && m_mouseDown)
143 {
144 // finish selecting
145 m_mouseDown = false;
148 if (m_line)
149 {
150 // now add the line cp
152 }
153 else
154 {
156 if (fabs(dist.x) > 10 && fabs(dist.y) > 10)
157 {
158 // build menu
159 wxMenu menu;
160 const vigra::Rect2D roi = GetSelectedROI();
161 // selected roi should have at least 10 pixel width and height in pano space
162 if (!roi.isEmpty() && roi.width() > 10 && roi.height() > 10)
163 {
164 menu.Append(ID_CREATE_CP, _("Create control points here"));
165 };
167 if (!m_CPinROI.empty())
168 {
169 menu.Append(ID_REMOVE_CP, wxString::Format(_("Remove %lu control points"), static_cast<unsigned long int>(m_CPinROI.size())));
170 };
171 if (!menu.GetMenuItems().IsEmpty())
172 {
173 m_menuPopup = true;
174 helper->GetPreviewFrame()->PopupMenu(&menu);
175 }
176 else
177 {
178 wxBell();
181 };
182 }
183 else
184 {
185 wxBell();
186 // we need to redraw so that the selection rectangle vanishes
189 };
190 };
191 };
192 };
193 };
194};
195
196// find all cp in the given rectangle
198{
200 HuginBase::UIntSet activeImages = pano->getActiveImages();
201 const hugin_utils::FDiff2D panoPos1(pos1.x < pos2.x ? pos1.x : pos2.x, pos1.y < pos2.y ? pos1.y : pos2.y);
202 const hugin_utils::FDiff2D panoPos2(pos1.x > pos2.x ? pos1.x : pos2.x, pos1.y > pos2.y ? pos1.y : pos2.y);
203 m_CPinROI.clear();
204 if (!activeImages.empty())
205 {
206 // create transformation objects
207 typedef std::map<size_t, HuginBase::PTools::Transform*> TransformMap;
209 for (HuginBase::UIntSet::iterator it = activeImages.begin(); it != activeImages.end(); ++it)
210 {
212 trans->createInvTransform(pano->getImage(*it), pano->getOptions());
213 transformations.insert(std::make_pair(*it, trans));
214 };
216 for (HuginBase::CPVector::const_iterator cpIt = cps.begin(); cpIt != cps.end(); ++cpIt)
217 {
218 // check cp only if both images are visible
219 if (set_contains(activeImages, cpIt->image1Nr) && set_contains(activeImages, cpIt->image2Nr))
220 {
223 // remove all control points, where both points are inside the given rectangle
224 if (transformations[cpIt->image1Nr]->transformImgCoord(pos1, hugin_utils::FDiff2D(cpIt->x1, cpIt->y1)) &&
225 transformations[cpIt->image2Nr]->transformImgCoord(pos2, hugin_utils::FDiff2D(cpIt->x2, cpIt->y2)))
226 {
227 if (panoPos1.x <= pos1.x && pos1.x <= panoPos2.x && panoPos1.y <= pos1.y && pos1.y <= panoPos2.y &&
228 panoPos1.x <= pos2.x && pos2.x <= panoPos2.x && panoPos1.y <= pos2.y && pos2.y <= panoPos2.y)
229 {
230 m_CPinROI.insert(cpIt - cps.begin());
231 };
232 };
233 };
234 };
235 for (TransformMap::iterator it = transformations.begin(); it != transformations.end(); ++it)
236 {
237 delete it->second;
238 };
239 };
240};
241
242// return the selected ROI
244{
245 vigra::Point2D p1;
246 p1.x = std::min(m_startPos.x, m_currentPos.x);
247 p1.y = std::min(m_startPos.y, m_currentPos.y);
248 vigra::Point2D p2;
249 p2.x = std::max(m_startPos.x, m_currentPos.x);
250 p2.y = std::max(m_startPos.y, m_currentPos.y);
251 return vigra::Rect2D(p1, p2) & vigra::Rect2D(helper->GetPanoramaPtr()->getOptions().getSize());
252};
253
254// for correctly handling the popup menu
255// when selecting the popup menu or dismiss the popup menu we get an additional mouse
256// click, we need to ignore this one, this function sets the state back
261
263{
266 if (imgs1.empty() || imgs2.empty())
267 {
268 // start or end point are not above any image
269 wxBell();
270 // we need to redraw so that the selection vanishes
273 }
274 else
275 {
277 std::set_intersection(imgs1.begin(), imgs1.end(), imgs2.begin(), imgs2.end(), std::inserter(imgIntersection, imgIntersection.begin()));
280 if (!imgIntersection.empty())
281 {
282 // start and end point are on the same image
283 cp.image1Nr = *imgIntersection.begin();
285 transform.createTransform(pano->getImage(cp.image1Nr), pano->getOptions());
286 double image_x, image_y;
287 transform.transformImgCoord(image_x, image_y, pos1.x, pos1.y);
288 cp.x1 = image_x;
289 cp.y1 = image_y;
290 transform.transformImgCoord(image_x, image_y, pos2.x, pos2.y);
291 cp.image2Nr = cp.image1Nr;
292 cp.x2 = image_x;
293 cp.y2 = image_y;
294 }
295 else
296 {
297 // start and end point are on different images
298 cp.image1Nr = *imgs1.begin();
299 cp.image2Nr = *imgs2.begin();
300
302 transform.createTransform(pano->getImage(cp.image1Nr), pano->getOptions());
303 double image_x, image_y;
304 transform.transformImgCoord(image_x, image_y, pos1.x, pos1.y);
305 cp.x1 = image_x;
306 cp.y1 = image_y;
307 transform.createTransform(pano->getImage(cp.image2Nr), pano->getOptions());
308 transform.transformImgCoord(image_x, image_y, pos2.x, pos2.y);
309 cp.x2 = image_x;
310 cp.y2 = image_y;
311 }
312 if (abs(pos1.x - pos2.x) < abs(pos1.y - pos2.y))
313 {
315 }
316 else
317 {
319 };
321 }
322}
interface of ToolHelper for deleting control points in the pano space
@ ID_CREATE_CP
@ ID_REMOVE_CP
GLPreview * getPreview()
represents a control point
@ X
evaluate x, points are on a vertical line
@ Y
evaluate y, points are on a horizontal line
Holds transformations for Image -> Pano and the other way.
bool transformImgCoord(double &x_dest, double &y_dest, double x_src, double y_src) const
like transform, but return image coordinates, not cartesian coordinates
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->image transformation
vigra::Size2D getSize() const
get size of output image
Model for a panorama.
Definition Panorama.h:153
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
Definition Panorama.h:211
const PanoramaOptions & getOptions() const
returns the options for this panorama
Definition Panorama.h:481
const CPVector & getCtrlPoints() const
get all control point of this Panorama
Definition Panorama.h:319
UIntSet getActiveImages() const
get active images
add a control point
void addCommand(PanoCommand *command, bool execute=true)
Adds a command to the history.
static GlobalCmdHist & getInstance()
void ReallyAfterDrawImagesEvent() override
draw selection rectangle
void Activate() override
activate the tool
void MouseButtonEvent(wxMouseEvent &e) override
mouse button handling
void Deactivate() override
deactivate the tool, reset the cursor
void MouseMoveEvent(double x, double y, wxMouseEvent &e) override
mouse move handling
vigra::Rect2D GetSelectedROI()
returns selected ROI
void SetMenuProcessed()
reset popup menu status
void AddLineCP(const hugin_utils::FDiff2D &pos1, const hugin_utils::FDiff2D &pos2)
called to add line control point
bool m_menuPopup
true, when popup menu is shown, this is to ignore a mouse event when the popup menu is closed
hugin_utils::FDiff2D m_currentPos
current position of selection
bool m_line
if selecting a rectangle or a line
bool m_mouseDown
mouse down status
void FindCPInRect(const hugin_utils::FDiff2D &pos1, const hugin_utils::FDiff2D &pos2)
search for control points in selected rectangle
HuginBase::UIntSet m_CPinROI
contains the found cp
hugin_utils::FDiff2D m_startPosScreen
position where the marking starts in screen coordinates
hugin_utils::FDiff2D m_currentPosScreen
current position of selection in screen coordinates
hugin_utils::FDiff2D m_startPos
position where the marking starts
hugin_utils::FDiff2D GetMousePanoPosition()
GLPreviewFrame * GetPreviewFrame()
Definition ToolHelper.h:139
HuginBase::Panorama * GetPanoramaPtr()
void NotifyMe(Event event, Tool *tool)
HuginBase::UIntSet GetImagesUnderPos(const hugin_utils::FDiff2D &pos)
VisualizationState * GetVisualizationStatePtr()
hugin_utils::FDiff2D GetMouseScreenPosition()
@ REALLY_DRAW_OVER_IMAGES
Definition ToolHelper.h:83
void SetStatusMessage(wxString message)
ToolHelper * helper
The PreviewToolHelper that uses the same preview window and panorama as the tool should.
Definition Tool.h:109
implementation of huginApp Class
std::vector< ControlPoint > CPVector
std::set< unsigned int > UIntSet
include file for the hugin project
include file for the hugin project
bool set_contains(const _Container &c, const typename _Container::key_type &key)
Definition stl_utils.h:74
std::vector< deghosting::BImagePtr > threshold(const std::vector< deghosting::FImagePtr > &inputImages, const double threshold, const uint16_t flags)
Threshold function used for creating alpha masks for images.
Definition threshold.h:41
wxwindows specific panorama commands