Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CPListFrame.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
2 
27 #include "hugin_config.h"
28 #include "panoinc_WX.h"
29 #include "panoinc.h"
30 
31 #include <algorithm>
32 #include <utility>
33 #include <functional>
34 
35 #include "base_wx/wxPlatform.h"
36 #include "hugin/CPListFrame.h"
37 #include "hugin/MainFrame.h"
38 #include "base_wx/CommandHistory.h"
39 #include "base_wx/PanoCommand.h"
40 #include "hugin/huginApp.h"
41 #include "hugin/config_defaults.h"
44 
45 BEGIN_EVENT_TABLE(CPListCtrl, wxListCtrl)
46  EVT_CHAR(CPListCtrl::OnChar)
47  EVT_LIST_ITEM_SELECTED(wxID_ANY, CPListCtrl::OnCPListSelectionChanged)
48  EVT_LIST_ITEM_DESELECTED(wxID_ANY, CPListCtrl::OnCPListSelectionChanged)
49  EVT_LIST_COL_CLICK(wxID_ANY, CPListCtrl::OnCPListHeaderClick)
50  EVT_LIST_COL_END_DRAG(wxID_ANY, CPListCtrl::OnColumnWidthChange)
52 
53 std::string makePairId(unsigned int id1, unsigned int id2)
54 {
55  // Control points from same image pair, regardless of which is left or right
56  // are counted the same so return the identical hash id.
57  std::ostringstream oss;
58 
59  if (id1 < id2) {
60  oss << id1 << "_" << id2;
61  }
62  else if (id2 < id1) {
63  oss << id2 << "_" << id1;
64  }
65  else {
66  // Control points are from same image.
67  oss << id1;
68  }
69  return oss.str();
70 }
71 
72 CPListCtrl::CPListCtrl() : m_pano(NULL)
73 {
74  m_sortCol = 0;
75  m_sortAscend = true;
76 };
77 
79 {
80  wxConfigBase* config = wxConfig::Get();
81  config->Write(wxT("/CPListFrame/SortColumn"), m_sortCol);
82  config->Write(wxT("/CPListFrame/SortAscending"), m_sortAscend ? 1 : 0);
83  config->Flush();
84  if (m_pano)
85  {
86  m_pano->removeObserver(this);
87  };
88 };
89 
90 bool CPListCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos,
91  const wxSize& size, long style, const wxValidator& validator, const wxString& name)
92 {
93  if (!wxListCtrl::Create(parent, id, pos, size, style))
94  {
95  return false;
96  };
97  InsertColumn(0, _("G CP#"), wxLIST_FORMAT_RIGHT, 25);
98  InsertColumn(1, _("Left Img."), wxLIST_FORMAT_RIGHT, 65);
99  InsertColumn(2, _("Right Img."), wxLIST_FORMAT_RIGHT, 65);
100  InsertColumn(3, _("P CP#"), wxLIST_FORMAT_RIGHT, 25);
101  InsertColumn(4, _("Alignment"), wxLIST_FORMAT_LEFT, 80);
102  InsertColumn(5, MainFrame::Get()->IsShowingCorrelation() ? _("Correlation") : _("Distance"), wxLIST_FORMAT_RIGHT, 80);
103 
104  //get saved width
105  for (int j = 0; j < GetColumnCount(); j++)
106  {
107  // -1 is auto
108  int width = wxConfigBase::Get()->Read(wxString::Format(wxT("/CPListFrame/ColumnWidth%d"), j), -1);
109  if (width != -1)
110  {
111  SetColumnWidth(j, width);
112  };
113  };
114  EnableAlternateRowColours(true);
115 
116  wxConfigBase* config = wxConfig::Get();
117  m_sortCol=config->Read(wxT("/CPListFrame/SortColumn"), 0l);
118  m_sortAscend = config->Read(wxT("/CPListFrame/SortAscending"), 1l) == 1;
119  config->Flush();
120  ShowSortIndicator(m_sortCol, m_sortAscend);
121  return true;
122 };
123 
125 {
126  m_pano = pano;
127  m_pano->addObserver(this);
128  panoramaChanged(*pano);
129 };
130 
131 wxString CPListCtrl::OnGetItemText(long item, long column) const
132 {
133  if (item > m_internalCPList.size())
134  {
135  return wxEmptyString;
136  };
137  const HuginBase::ControlPoint& cp = m_pano->getCtrlPoint(m_internalCPList[item].globalIndex);
138  switch (column)
139  {
140  case 0:
141  return wxString::Format(wxT("%lu"), static_cast<unsigned long>(m_internalCPList[item].globalIndex));
142  break;
143  case 1:
144  return wxString::Format(wxT("%u"), cp.image1Nr);
145  break;
146  case 2:
147  return wxString::Format(wxT("%u"), cp.image2Nr);
148  break;
149  case 3:
150  return wxString::Format(wxT("%lu"), static_cast<unsigned long>(m_internalCPList[item].localNumber));
151  break;
152  case 4:
153  switch (cp.mode)
154  {
156  return wxString(_("normal"));
157  break;
159  return wxString(_("vert. Line"));
160  break;
162  return wxString(_("horiz. Line"));
163  break;
164  default:
165  return wxString::Format(_("Line %d"), cp.mode);
166  break;
167  };
168  break;
169  case 5:
170  return wxString::Format(wxT("%.2f"), cp.error);
171  break;
172  default:
173  return wxEmptyString;
174  };
175  return wxEmptyString;
176 };
177 
178 int CPListCtrl::OnGetItemImage(long item) const
179 {
180  return -1;
181 };
182 
184 {
186  const bool isShowingCorrelation = MainFrame::Get()->IsShowingCorrelation();
187  wxListItem item;
188  if (GetColumn(5, item))
189  {
190  if (isShowingCorrelation)
191  {
192  item.SetText(_("Correlation"));
193  }
194  else
195  {
196  item.SetText(_("Distance"));
197  }
198  SetColumn(5, item);
199  };
200  XRCCTRL(*GetParent(), "cp_list_select", wxButton)->SetLabel(isShowingCorrelation ? _("Select by Correlation") : _("Select by Distance"));
202  SetItemCount(m_internalCPList.size());
203  Refresh();
204 };
205 
207 {
208  const HuginBase::CPVector& cps = m_pano->getCtrlPoints();
209  const HuginBase::UIntSet activeImgs = m_pano->getActiveImages();
210  // Rebuild the global->local CP map on each update as CPs might have been
211  // removed.
212  m_localIds.clear();
213  m_internalCPList.clear();
214  m_internalCPList.reserve(cps.size());
215  for (size_t i = 0; i < cps.size(); i++)
216  {
217  const HuginBase::ControlPoint& cp = cps[i];
218  if (m_onlyActiveImages && (!set_contains(activeImgs, cp.image1Nr) || !set_contains(activeImgs, cp.image2Nr)))
219  {
220  continue;
221  };
222  CPListItem cpListItem;
223  cpListItem.globalIndex = i;
224  std::string pairId = makePairId(cp.image1Nr, cp.image2Nr);
225  std::map<std::string, int>::iterator it = m_localIds.find(pairId);
226  if (it != m_localIds.end())
227  {
228  ++(it->second);
229  }
230  else
231  {
232  m_localIds[pairId] = 0;
233  }
234  cpListItem.localNumber=m_localIds[pairId];
235  m_internalCPList.push_back(cpListItem);
236  };
237  SortInternalList(true);
238 };
239 
240 // sort helper function
241 // sort by global or local number only
242 #define CompareStruct(VAR, TYPESUFFIX, OP) \
243 struct Compare##TYPESUFFIX\
244 {\
245  bool operator()(const CPListItem& item1, const CPListItem& item2)\
246  {\
247  return item1.VAR OP item2.VAR;\
248  };\
249 };
250 CompareStruct(globalIndex, globalIndex, <)
251 CompareStruct(globalIndex, globalIndexGreater, >)
252 CompareStruct(localNumber, localNumber, <)
253 CompareStruct(localNumber, localNumberGreater, >)
254 #undef CompareStruct
255 
256 // sort by image number, take second image number as second criterion and local number as third
257 #define CompareStruct(VAR1, VAR2, TYPESUFFIX, OP)\
258 struct Compare##TYPESUFFIX\
259 {\
260  explicit Compare##TYPESUFFIX(const HuginBase::CPVector& cps) : m_cps(cps) {};\
261  bool operator()(const CPListItem& item1, const CPListItem& item2)\
262  {\
263  return m_cps[item1.globalIndex].VAR1 * 1e4 + m_cps[item1.globalIndex].VAR2 + item1.localNumber * 1.0 / m_cps.size() OP\
264  m_cps[item2.globalIndex].VAR1 * 1e4 + m_cps[item2.globalIndex].VAR2 + item2.localNumber * 1.0 / m_cps.size();\
265  }\
266 private:\
267  const HuginBase::CPVector& m_cps;\
268 };
269 CompareStruct(image1Nr, image2Nr, image1Nr, <)
270 CompareStruct(image1Nr, image2Nr, image1NrGreater, >)
271 CompareStruct(image2Nr, image1Nr, image2Nr, <)
272 CompareStruct(image2Nr, image1Nr, image2NrGreater, >)
273 #undef CompareStruct
274 
275 // sort by mode or error
276 #define CompareStruct(VAR, TYPESUFFIX, OP)\
277 struct Compare##TYPESUFFIX\
278 {\
279  explicit Compare##TYPESUFFIX(const HuginBase::CPVector& cps) : m_cps(cps) {};\
280  bool operator()(const CPListItem& item1, const CPListItem& item2)\
281  {\
282  return m_cps[item1.globalIndex].VAR OP m_cps[item2.globalIndex].VAR;\
283  }\
284 private:\
285  const HuginBase::CPVector& m_cps;\
286 };
287 CompareStruct(mode, mode, <)
288 CompareStruct(mode, modeGreater, >)
289 CompareStruct(error, error, <)
290 CompareStruct(error, errorGreater, >)
291 #undef CompareStruct
292 
293 void CPListCtrl::SortInternalList(bool isAscending)
294 {
295  // nothing to sort
296  if (m_internalCPList.empty())
297  {
298  return;
299  };
300 
301  switch (m_sortCol)
302  {
303  case 0:
304  if (m_sortAscend)
305  {
306  if (!isAscending)
307  {
308  std::sort(m_internalCPList.begin(), m_internalCPList.end(), CompareglobalIndex());
309  };
310  }
311  else
312  {
313  std::sort(m_internalCPList.begin(), m_internalCPList.end(), CompareglobalIndexGreater());
314  };
315  break;
316  case 1:
317  if (m_sortAscend)
318  {
319  std::sort(m_internalCPList.begin(), m_internalCPList.end(), Compareimage1Nr(m_pano->getCtrlPoints()));
320  }
321  else
322  {
323  std::sort(m_internalCPList.begin(), m_internalCPList.end(), Compareimage1NrGreater(m_pano->getCtrlPoints()));
324  };
325  break;
326  case 2:
327  if (m_sortAscend)
328  {
329  std::sort(m_internalCPList.begin(), m_internalCPList.end(), Compareimage2Nr(m_pano->getCtrlPoints()));
330  }
331  else
332  {
333  std::sort(m_internalCPList.begin(), m_internalCPList.end(), Compareimage2NrGreater(m_pano->getCtrlPoints()));
334  };
335  break;
336  case 3:
337  if (m_sortAscend)
338  {
339  std::sort(m_internalCPList.begin(), m_internalCPList.end(), ComparelocalNumber());
340  }
341  else
342  {
343  std::sort(m_internalCPList.begin(), m_internalCPList.end(), ComparelocalNumberGreater());
344  };
345  break;
346  case 4:
347  if (m_sortAscend)
348  {
349  std::sort(m_internalCPList.begin(), m_internalCPList.end(), Comparemode(m_pano->getCtrlPoints()));
350  }
351  else
352  {
353  std::sort(m_internalCPList.begin(), m_internalCPList.end(), ComparemodeGreater(m_pano->getCtrlPoints()));
354  };
355  break;
356  case 5:
357  if (m_sortAscend)
358  {
359  std::sort(m_internalCPList.begin(), m_internalCPList.end(), Compareerror(m_pano->getCtrlPoints()));
360  }
361  else
362  {
363  std::sort(m_internalCPList.begin(), m_internalCPList.end(), CompareerrorGreater(m_pano->getCtrlPoints()));
364  };
365  break;
366  };
367 };
368 
370 {
371  if (GetSelectedItemCount() == 1)
372  {
373  if (e.GetIndex() < m_internalCPList.size())
374  {
375  MainFrame::Get()->ShowCtrlPoint(m_internalCPList[e.GetIndex()].globalIndex);
376  };
377  };
378 };
379 
381 {
382  const int newCol = e.GetColumn();
383  if (m_sortCol == newCol)
384  {
386  }
387  else
388  {
389  m_sortCol = newCol;
390  m_sortAscend = true;
391  };
392  ShowSortIndicator(m_sortCol, m_sortAscend);
393  SortInternalList(false);
394  Refresh();
395 };
396 
398 {
399  const int colNum = e.GetColumn();
400  wxConfigBase::Get()->Write(wxString::Format(wxT("/CPListFrame/ColumnWidth%d"), colNum), GetColumnWidth(colNum));
401 };
402 
404 {
405  // no selected item.
406  const int nSelected = GetSelectedItemCount();
407  if (nSelected == 0)
408  {
409  wxBell();
410  return;
411  };
412 
413  HuginBase::UIntSet selected;
414  long item = GetFirstSelected();
415  long newSelection = -1;
416  if (m_internalCPList.size() - nSelected > 0)
417  {
418  newSelection = item;
419  if (item >= m_internalCPList.size() - nSelected)
420  {
421  newSelection = m_internalCPList.size() - nSelected - 1;
422  };
423  };
424  while (item>=0)
425  {
426  // deselect item
427  Select(item, false);
428  selected.insert(m_internalCPList[item].globalIndex);
429  item = GetNextSelected(item);
430  }
431  DEBUG_DEBUG("about to delete " << selected.size() << " points");
433 
434  if (newSelection >= 0)
435  {
436  MainFrame::Get()->ShowCtrlPoint(m_internalCPList[newSelection].globalIndex);
437  Select(newSelection, true);
438  };
439 };
440 
442 {
443  const bool invert = threshold < 0;
444  if (invert)
445  {
446  threshold = -threshold;
447  };
448  const HuginBase::CPVector& cps = m_pano->getCtrlPoints();
449  Freeze();
450  for (size_t i = 0; i < m_internalCPList.size(); i++)
451  {
452  const double error = cps[m_internalCPList[i].globalIndex].error;
453  Select(i, ((error > threshold) && (!invert)) || ((error < threshold) && (invert)));
454  };
455  Thaw();
456 };
457 
459 {
460  for (long i = 0; i < m_internalCPList.size(); i++)
461  {
462  Select(i, true);
463  };
464 };
465 
466 void CPListCtrl::OnChar(wxKeyEvent& e)
467 {
468  switch (e.GetKeyCode())
469  {
470  case WXK_DELETE:
471  case WXK_NUMPAD_DELETE:
472  DeleteSelected();
473  break;
474  case WXK_CONTROL_A:
475  SelectAll();
476  break;
477  default:
478  e.Skip();
479  };
480 };
481 
482 
484 
485 IMPLEMENT_DYNAMIC_CLASS(CPListCtrlXmlHandler, wxListCtrlXmlHandler)
486 
487 CPListCtrlXmlHandler::CPListCtrlXmlHandler()
488 : wxListCtrlXmlHandler()
489 {
490  AddWindowStyles();
491 }
492 
494 {
495  XRC_MAKE_INSTANCE(cp, CPListCtrl)
496  cp->Create(m_parentAsWindow, GetID(), GetPosition(), GetSize(), GetStyle(wxT("style")), wxDefaultValidator, GetName());
497  SetupWindow(cp);
498  return cp;
499 }
500 
501 bool CPListCtrlXmlHandler::CanHandle(wxXmlNode *node)
502 {
503  return IsOfClass(node, wxT("CPListCtrl"));
504 }
505 
506 
507 BEGIN_EVENT_TABLE(CPListFrame, wxFrame)
508  EVT_CLOSE(CPListFrame::OnClose)
509  EVT_BUTTON(XRCID("cp_list_delete"), CPListFrame::OnDeleteButton)
510  EVT_BUTTON(XRCID("cp_list_select"), CPListFrame::OnSelectButton)
512 
513 CPListFrame::CPListFrame(wxFrame* parent, HuginBase::Panorama& pano) : m_pano(pano)
514 {
515  DEBUG_TRACE("");
516  bool ok = wxXmlResource::Get()->LoadFrame(this, parent, wxT("cp_list_frame"));
517  DEBUG_ASSERT(ok);
518  m_list = XRCCTRL(*this, "cp_list_frame_list", CPListCtrl);
519  DEBUG_ASSERT(m_list);
520  m_list->Init(&m_pano);
521 
522 #ifdef __WXMSW__
523  // wxFrame does have a strange background color on Windows, copy color from a child widget
524  this->SetBackgroundColour(XRCCTRL(*this, "cp_list_select", wxButton)->GetBackgroundColour());
525 #endif
526 #ifdef __WXMSW__
527  wxIconBundle myIcons(huginApp::Get()->GetXRCPath() + wxT("data/hugin.ico"),wxBITMAP_TYPE_ICO);
528  SetIcons(myIcons);
529 #else
530  wxIcon myIcon(huginApp::Get()->GetXRCPath() + wxT("data/hugin.png"),wxBITMAP_TYPE_PNG);
531  SetIcon(myIcon);
532 #endif
533 
534 
535  //set minumum size
536  SetSizeHints(200, 300);
537  //size
538  RestoreFramePosition(this, wxT("CPListFrame"));
539 }
540 
542 {
543  DEBUG_TRACE("dtor");
544  StoreFramePosition(this, wxT("CPListFrame"));
545  DEBUG_TRACE("dtor end");
546 }
547 
548 void CPListFrame::OnClose(wxCloseEvent& event)
549 {
550  DEBUG_DEBUG("OnClose");
552  DEBUG_DEBUG("closing");
553  Destroy();
554 }
555 
556 void CPListFrame::OnDeleteButton(wxCommandEvent & e)
557 {
559 }
560 
561 void CPListFrame::OnSelectButton(wxCommandEvent & e)
562 {
563  double threshold;
564  const bool isShowingCorrelation = MainFrame::Get()->IsShowingCorrelation();
565  if(isShowingCorrelation)
566  {
567  threshold = HUGIN_FT_CORR_THRESHOLD;
568  wxConfig::Get()->Read(wxT("/Finetune/CorrThreshold"), &threshold, HUGIN_FT_CORR_THRESHOLD);;
569  }
570  else
571  {
572  // calculate the mean error and the standard deviation
574  double min, max, mean, var;
576 
577  // select points whos distance is greater than the mean
578  // hmm, maybe some theory would be nice.. this is just a
579  // guess.
580  threshold = mean + sqrt(var);
581  };
582  wxString t;
583  do
584  {
585  t = wxGetTextFromUser(isShowingCorrelation ?
586  _("Enter minimum control point correlation.\nAll points with lower correlation will be selected.") :
587  _("Enter minimum control point error.\nAll points with a higher error will be selected"),
588  _("Select Control Points"),
589  hugin_utils::doubleTowxString(threshold, 2));
590  if (t == wxEmptyString) {
591  // do not select anything
592  return;
593  }
594  }
595  while (!hugin_utils::str2double(t, threshold));
596 
597  m_list->SelectDistanceThreshold(isShowingCorrelation ? -threshold : threshold);
598 };
const bool GetOptimizeOnlyActiveImages() const
Definition: MainFrame.cpp:1655
void OnColumnWidthChange(wxListEvent &e)
column width changed
void DeleteSelected()
Delete the selected points.
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxLC_REPORT|wxLC_VIRTUAL, const wxValidator &validator=wxDefaultValidator, const wxString &name=wxListCtrlNameStr)
Definition: CPListFrame.cpp:90
void UpdateInternalCPList()
helper class for virtual listview control
Definition: CPListFrame.h:33
bool str2double(const wxString &s, double &d)
Definition: wxPlatform.cpp:37
bool removeObserver(PanoramaObserver *observer)
remove a panorama observer.
Definition: Panorama.cpp:1551
virtual int OnGetItemImage(long item) const
show no images
std::vector< CPListItem > m_internalCPList
Definition: CPListFrame.h:87
#define DEBUG_TRACE(msg)
Definition: utils.h:67
int m_sortCol
Definition: CPListFrame.h:84
void OnDeleteButton(wxCommandEvent &e)
static void calcCtrlPntsErrorStats(const PanoramaData &pano, double &min, double &max, double &mean, double &var, const int &imgNr=-1, const bool onlyActive=false, const bool ignoreLineCp=false)
void Init(HuginBase::Panorama *pano)
void OnClose(wxCloseEvent &event)
void OnSelectButton(wxCommandEvent &e)
void SortInternalList(bool isAscending)
wxString doubleTowxString(double d, int digits)
Definition: wxPlatform.cpp:31
virtual wxString OnGetItemText(long item, long column) const
create labels for virtual list control
bool set_contains(const _Container &c, const typename _Container::key_type &key)
Definition: stl_utils.h:74
#define CompareStruct(VAR, TYPESUFFIX, OP)
#define DEBUG_ASSERT(cond)
Definition: utils.h:80
END_EVENT_TABLE()
include file for the hugin project
const CPVector & getCtrlPoints() const
get all control point of this Panorama
Definition: Panorama.h:319
remove several control points
Definition: PanoCommand.h:307
represents a control point
Definition: ControlPoint.h:38
static huginApp * Get()
hack.. kind of a pseudo singleton...
Definition: huginApp.cpp:641
std::set< unsigned int > UIntSet
Definition: PanoramaData.h:51
void OnChar(wxKeyEvent &e)
handle keystrokes
void ShowCtrlPoint(unsigned int cpNr)
Definition: MainFrame.cpp:2021
void calcCtrlPointErrors(PanoramaData &pano)
Update the Ctrl Point errors without optimizing.
Model for a panorama.
Definition: Panorama.h:152
void SelectAll()
select all items
List all control points of this project.
Definition: CPListFrame.h:43
static MainFrame * Get()
hack.. kind of a pseudo singleton...
Definition: MainFrame.cpp:2169
void StoreFramePosition(wxTopLevelWindow *frame, const wxString &basename)
Store window size and position in configfile/registry.
Definition: LensCalApp.cpp:212
HuginBase::Panorama * m_pano
Definition: CPListFrame.h:82
void OnCPListFrameClosed()
Definition: MainFrame.cpp:1624
const ControlPoint & getCtrlPoint(std::size_t nr) const
get a control point, counting starts with 0
Definition: Panorama.h:312
IMPLEMENT_DYNAMIC_CLASS(wxTreeListHeaderWindow, wxWindow)
evaluate x, points are on a vertical line
Definition: ControlPoint.h:47
void RestoreFramePosition(wxTopLevelWindow *frame, const wxString &basename)
Restore window size and position from configfile/registry.
Definition: LensCalApp.cpp:158
xrc handler for CPImagesComboBox
Definition: CPListFrame.h:95
static GlobalCmdHist & getInstance()
void OnCPListSelectionChanged(wxListEvent &e)
selection event handler
size_t globalIndex
Definition: CPListFrame.h:35
virtual wxObject * DoCreateResource()
Create CPImagesComboBox from resource.
virtual ~CPListFrame()
dtor.
void addCommand(PanoCommand *command, bool execute=true)
Adds a command to the history.
bool m_sortAscend
Definition: CPListFrame.h:85
void SelectDistanceThreshold(double threshold)
select all cp with the given error bigger than the threshold
UIntSet getActiveImages() const
get active images
Definition: Panorama.cpp:1585
void OnCPListHeaderClick(wxListEvent &e)
sort criterium changed
Utility calls into PanoTools using CPP interface.
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
void addObserver(PanoramaObserver *o)
add a panorama observer.
Definition: Panorama.cpp:1546
CPListCtrl * m_list
Definition: CPListFrame.h:124
include file for the hugin project
#define HUGIN_FT_CORR_THRESHOLD
size_t localNumber
Definition: CPListFrame.h:36
static T max(T x, T y)
Definition: svm.cpp:65
#define DEBUG_DEBUG(msg)
Definition: utils.h:68
std::string makePairId(unsigned int id1, unsigned int id2)
Definition: CPListFrame.cpp:53
std::vector< ControlPoint > CPVector
Definition: ControlPoint.h:99
platform/compiler specific stuff.
std::map< std::string, int > m_localIds
Definition: CPListFrame.h:88
bool m_onlyActiveImages
Definition: CPListFrame.h:86
virtual bool CanHandle(wxXmlNode *node)
Internal use to identify right xml handler.
bool IsShowingCorrelation() const
Definition: MainFrame.cpp:2185
virtual void panoramaChanged(HuginBase::Panorama &pano)
Notification about a Panorama change.
evaluate y, points are on a horizontal line
Definition: ControlPoint.h:48
static T min(T x, T y)
Definition: svm.cpp:62
HuginBase::Panorama & m_pano
Definition: CPListFrame.h:125