Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

[3ff100]: src / hugin1 / hugin / PreviewEditCPTool.cpp Maximize Restore History

Download this file

PreviewEditCPTool.cpp    214 lines (201 with data), 7.9 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
// -*- c-basic-offset: 4 -*-
/** @file PreviewEditCPTool.cpp
*
* @author T. Modes
*
* @brief implementation of ToolHelper for editing control points in the pano space
*
*/
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This software 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "hugin/PreviewEditCPTool.h"
#include "panoinc_WX.h"
#include "panoinc.h"
#include <map>
#include <wx/platform.h>
#ifdef __WXMAC__
#include <OpenGL/gl.h>
#else
#ifdef __WXMSW__
#include <vigra/windows.h>
#endif
#include <GL/gl.h>
#endif
#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_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);
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_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);
};
};
// 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();
};
}
// 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
{
if (e.ButtonUp(wxMOUSE_BTN_LEFT) && m_mouseDown)
{
// 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();
};
};
};
};
};
// 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);
m_CPinROI.clear();
if (!activeImages.empty())
{
// create transformation objects
typedef std::map<size_t, HuginBase::PTools::Transform*> TransformMap;
TransformMap transformations;
for (HuginBase::UIntSet::iterator it = activeImages.begin(); it != activeImages.end(); ++it)
{
HuginBase::PTools::Transform* trans = new HuginBase::PTools::Transform();
trans->createInvTransform(pano->getImage(*it), pano->getOptions());
transformations.insert(std::make_pair(*it, trans));
};
HuginBase::CPVector cps = pano->getCtrlPoints();
for (HuginBase::CPVector::const_iterator cpIt = cps.begin(); cpIt != cps.end(); ++cpIt)
{
// check cp only if both images are visible
if (set_contains(activeImages, cpIt->image1Nr) && set_contains(activeImages, cpIt->image2Nr))
{
hugin_utils::FDiff2D pos1;
hugin_utils::FDiff2D pos2;
// remove all control points, where both points are inside the given rectangle
if (transformations[cpIt->image1Nr]->transformImgCoord(pos1, hugin_utils::FDiff2D(cpIt->x1, cpIt->y1)) &&
transformations[cpIt->image2Nr]->transformImgCoord(pos2, hugin_utils::FDiff2D(cpIt->x2, cpIt->y2)))
{
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)
{
m_CPinROI.insert(cpIt - cps.begin());
};
};
};
};
for (TransformMap::iterator it = transformations.begin(); it != transformations.end(); ++it)
{
delete it->second;
};
};
};
// 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;
};