Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ImagesPanel.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
2 
28 #include "hugin_config.h"
29 #include "panoinc_WX.h"
30 #include "panoinc.h"
31 #include <time.h>
32 
33 #include "base_wx/platform.h"
34 #include "base_wx/wxPlatform.h"
35 #include "base_wx/wxcms.h"
36 #include <vector>
37 #include <map>
38 #include <functional> // std::bind
39 
40 #include "hugin/ImagesPanel.h"
41 #include "base_wx/CommandHistory.h"
43 #include "hugin/CPEditorPanel.h"
44 #include "hugin/MainFrame.h"
45 #include "hugin/huginApp.h"
47 #include "hugin/config_defaults.h"
48 #include "base_wx/PTWXDlg.h"
49 #include "base_wx/LensTools.h"
50 #include "hugin/ImagesTree.h"
52 #include "base_wx/PanoCommand.h"
53 
55 
57 {
58  m_pano = 0;
60 }
61 
62 bool ImagesPanel::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
63  long style, const wxString& name)
64 {
65  if (! wxPanel::Create(parent, id, pos, size, style, name)) {
66  return false;
67  }
68 
69  wxXmlResource::Get()->LoadPanel(this, wxT("images_panel"));
70  wxPanel * panel = XRCCTRL(*this, "images_panel", wxPanel);
71  wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
72  topsizer->Add(panel, 1, wxEXPAND, 0);
73  SetSizer(topsizer);
74 
75  m_images_tree = XRCCTRL(*this, "images_tree_ctrl", ImagesTreeCtrl);
77  m_images_tree->Bind(wxEVT_TREE_SEL_CHANGED, &ImagesPanel::OnSelectionChanged, this);
78 
79  m_showImgNr = INT_MAX;
80 
81  m_matchingButton = XRCCTRL(*this, "images_feature_matching", wxButton);
83  m_matchingButton->Bind(wxEVT_BUTTON, &ImagesPanel::CPGenerate, this);
84 
85  m_CPDetectorChoice = XRCCTRL(*this, "cpdetector_settings", wxChoice);
86 
87  // Image Preview
88  m_smallImgCtrl = XRCCTRL(*this, "images_selected_image", wxStaticBitmap);
90 
91  // empty bitmap with size (0,0) is not valid for wxStaticBitmap
92  // so we create a bitmap with the background color of the static bitmap control
93  wxImage image(1, 1, true);
94  const wxColour imageBackgroundColor = m_smallImgCtrl->GetBackgroundColour();
95  image.SetRGB(0, 0, imageBackgroundColor.Red(), imageBackgroundColor.Green(), imageBackgroundColor.Blue());
96  m_empty = wxBitmap(image);
97  m_smallImgCtrl->SetBitmap(m_empty);
98 
99  m_lenstype = XRCCTRL(*this, "images_lens_type", wxChoice);
101  m_lenstype->Bind(wxEVT_CHOICE, &ImagesPanel::OnLensTypeChanged, this);
103  m_lenstype->SetSelection(0);
104 
105  m_focallength = XRCCTRL(*this, "images_focal_length", wxTextCtrl);
107  m_focallength->PushEventHandler(new TextKillFocusHandler(this));
108  m_focallength->Bind(wxEVT_TEXT_ENTER, &ImagesPanel::OnFocalLengthChanged, this);
109 
110  m_cropfactor = XRCCTRL(*this, "images_crop_factor", wxTextCtrl);
112  m_cropfactor->PushEventHandler(new TextKillFocusHandler(this));
113  m_cropfactor->Bind(wxEVT_TEXT_ENTER, &ImagesPanel::OnCropFactorChanged, this);
114 
115  m_overlap = XRCCTRL(*this, "images_overlap", wxTextCtrl);
117  m_overlap->PushEventHandler(new TextKillFocusHandler(this));
118  m_overlap->Bind(wxEVT_TEXT_ENTER, &ImagesPanel::OnMinimumOverlapChanged, this);
119 
120  m_maxEv = XRCCTRL(*this, "images_maxev", wxTextCtrl);
122  m_maxEv->PushEventHandler(new TextKillFocusHandler(this));
123  m_maxEv->Bind(wxEVT_TEXT_ENTER, &ImagesPanel::OnMaxEvDiffChanged, this);
124 
125  wxTreeEvent ev;
126  OnSelectionChanged(ev);
127  DEBUG_TRACE("end");
128 
129  m_optChoice = XRCCTRL(*this, "images_optimize_mode", wxChoice);
131  m_optChoice->Bind(wxEVT_CHOICE, &ImagesPanel::OnOptimizerSwitchChanged, this);
132 
133  m_optPhotoChoice = XRCCTRL(*this, "images_photo_optimize_mode", wxChoice);
136 
138 
139  m_groupModeChoice = XRCCTRL(*this, "images_group_mode", wxChoice);
140  m_groupModeChoice->Bind(wxEVT_CHOICE, &ImagesPanel::OnGroupModeChanged, this);
141  FillGroupChoice();
142 
143  wxConfigBase* config=wxConfigBase::Get();
144  m_degDigits = config->Read(wxT("/General/DegreeFractionalDigitsEdit"),3);
145  //read autopano generator settings
146  cpdetector_config.Read(config,huginApp::Get()->GetDataPath()+wxT("default.setting"));
147  //write current autopano generator settings
148  cpdetector_config.Write(config);
149  config->Flush();
151  Layout();
152 #ifdef __WXGTK__
153  // explicitly set focus to propogate correctly key presses/shortcuts
155 #endif
156  Bind(wxEVT_RADIOBOX, &ImagesPanel::OnDisplayModeChanged, this, XRCID("images_column_radiobox"));
157  Bind(wxEVT_BUTTON, &ImagesPanel::OnOptimizeButton, this, XRCID("images_optimize"));
158  Bind(wxEVT_BUTTON, &ImagesPanel::OnPhotometricOptimizeButton, this, XRCID("images_photo_optimize"));
159  return true;
160 }
161 
163 {
164  m_pano = panorama;
166  // observe the panorama
167  m_pano->addObserver(this);
168 }
169 
170 void DeleteClientData(wxChoice* cb)
171 {
172  if(cb->HasClientUntypedData())
173  {
174  for(size_t i = 0; i < cb->GetCount(); i++)
175  {
176  delete static_cast<int*>(cb->GetClientData(i));
177  };
178  };
179 };
180 
182 {
183  DEBUG_TRACE("dtor");
184  m_focallength->PopEventHandler(true);
185  m_cropfactor->PopEventHandler(true);
186  m_overlap->PopEventHandler(true);
187  m_maxEv->PopEventHandler(true);
188  m_pano->removeObserver(this);
192  DEBUG_TRACE("dtor end");
193 }
194 
195 // We need to override the default handling of size events because the
196 // sizers set the virtual size but not the actual size. We reverse
197 // the standard handling and fit the child to the parent rather than
198 // fitting the parent around the child
199 
200 void ImagesPanel::OnSize( wxSizeEvent & e )
201 {
202  int winWidth, winHeight;
203  GetClientSize(&winWidth, &winHeight);
204  DEBUG_INFO( "image panel: " << winWidth <<"x"<< winHeight );
206 
207  e.Skip();
208 }
209 
211 {
212  //update optimizer choice selection
213  int optSwitch=m_pano->getOptimizerSwitch();
214  int found=wxNOT_FOUND;
215  for(size_t i=0;i<m_optChoice->GetCount();i++)
216  {
217  if(optSwitch==*static_cast<int*>(m_optChoice->GetClientData(i)))
218  {
219  found=i;
220  break;
221  };
222  };
223  if(found==wxNOT_FOUND)
224  {
227  );
228  }
229  else
230  {
231  m_optChoice->SetSelection(found);
232  };
233 
234  //update photometric optimizer choice selection
236  found=wxNOT_FOUND;
237  for(size_t i=0;i<m_optPhotoChoice->GetCount();i++)
238  {
239  if(optSwitch==*static_cast<int*>(m_optPhotoChoice->GetClientData(i)))
240  {
241  found=i;
242  break;
243  };
244  };
245  if(found==wxNOT_FOUND)
246  {
249  );
250  }
251  else
252  {
253  m_optPhotoChoice->SetSelection(found);
254  };
258 }
259 
261 {
262  DEBUG_TRACE("");
263 
264  // update text field if selected
265  const HuginBase::UIntSet & selected = m_images_tree->GetSelectedImages();
266  DEBUG_DEBUG("nr of sel Images: " << selected.size());
267  if (pano.getNrOfImages() == 0)
268  {
270  m_matchingButton->Disable();
271  }
272  else
273  {
274  m_matchingButton->Enable();
275  wxTreeEvent ev;
276  OnSelectionChanged(ev);
277  };
278  //enable/disable optimize buttons
279  XRCCTRL(*this, "images_optimize", wxButton)->Enable(pano.getNrOfImages()>0);
280  XRCCTRL(*this, "images_photo_optimize", wxButton)->Enable(pano.getNrOfImages()>1);
281 }
282 
283 // ##### Here start the eventhandlers #####
284 
286 void ImagesPanel::CPGenerate(wxCommandEvent & e)
287 {
289  //if only one image is selected, run detector on all images, except for linefind
290  wxString progName = cpdetector_config.settings[m_CPDetectorChoice->GetSelection()].GetProg().Lower();
291  if ((selImg.empty()) || (selImg.size() == 1 && progName.Find(wxT("linefind")) == wxNOT_FOUND))
292  {
293  // add all images.
294  selImg.clear();
295  fill_set(selImg, 0, m_pano->getNrOfImages() - 1);
296  }
297 
298  if (selImg.empty())
299  {
300  return;
301  }
303 };
304 
306 {
308 }
309 
311 {
312  wxConfigBase* config=wxConfigBase::Get();
313  long nFeatures = HUGIN_ASS_NCONTROLPOINTS;
314  if(wxGetKeyState(WXK_COMMAND))
315  {
316  nFeatures = config->Read(wxT("/MainFrame/nControlPoints"), HUGIN_ASS_NCONTROLPOINTS);
317  nFeatures = wxGetNumberFromUser(
318  _("Enter maximal number of control points per image pair"),
319  _("Points per Overlap"),
320  _("Control point detector option"),
321  nFeatures, 1, 10000
322  );
323  if(nFeatures<1)
324  {
325  return;
326  };
327  config->Write(wxT("/MainFrame/nControlPoints"), nFeatures);
328  }
329  else
330  {
331  nFeatures = config->Read(wxT("/Assistant/nControlPoints"), HUGIN_ASS_NCONTROLPOINTS);
332  };
333 
334  AutoCtrlPointCreator matcher;
335  HuginBase::CPVector cps = matcher.automatch(setting, *m_pano, img, nFeatures, this);
336  wxString msg;
337  wxMessageBox(wxString::Format(_("Added %lu control points"), (unsigned long) cps.size()), _("Control point detector result"),wxOK|wxICON_INFORMATION,this);
340  );
341 
342 };
343 
345 {
346  return cpdetector_config.settings[m_CPDetectorChoice->GetSelection()].GetCPDetectorDesc();
347 };
348 
349 void ImagesPanel::OnSelectionChanged(wxTreeEvent & e)
350 {
352  DEBUG_DEBUG("selected Images: " << sel.size());
353  if (sel.empty())
354  {
355  // nothing to edit
357  }
358  else
359  {
360  // enable edit
362  const HuginBase::SrcPanoImage& img = m_pano->getImage(*sel.begin());
363  bool identical_projection=true;
364  HuginBase::SrcPanoImage::Projection proj = img.getProjection();
365  double focallength = HuginBase::SrcPanoImage::calcFocalLength(img.getProjection(), img.getHFOV(),
366  img.getCropFactor(),img.getSize());;
367  double cropFactor=img.getCropFactor();
368  for (HuginBase::UIntSet::const_iterator it = sel.begin(); it != sel.end(); ++it)
369  {
370  const HuginBase::SrcPanoImage& img2 = m_pano->getImage(*it);
371  if(proj!=img2.getProjection())
372  {
373  identical_projection=false;
374  };
375  double focallength2 = HuginBase::SrcPanoImage::calcFocalLength(img2.getProjection(), img2.getHFOV(),
376  img2.getCropFactor(),img2.getSize());
377  if(focallength>0 && fabs(focallength-focallength2)>0.05)
378  {
379  focallength=-1;
380  };
381  if(fabs(cropFactor-img2.getCropFactor())>0.1)
382  {
383  cropFactor=-1;
384  };
385  };
386 
387  if(identical_projection)
388  {
390  }
391  else
392  {
393  m_lenstype->Select(wxNOT_FOUND);
394  };
395  if(focallength>0)
396  {
397  // use ChangeValue explicit, SetValue would create EVT_TEXT event which collides with our TextKillFocusHandler
398  m_focallength->ChangeValue(hugin_utils::doubleTowxString(focallength,m_degDigits));
399  }
400  else
401  {
402  m_focallength->Clear();
403  };
404  if(cropFactor>0)
405  {
406  m_cropfactor->ChangeValue(hugin_utils::doubleTowxString(cropFactor,m_degDigits));
407  }
408  else
409  {
410  m_cropfactor->Clear();
411  };
412 
413  if (sel.size() == 1)
414  {
415  ShowImage(*(sel.begin()));
416  }
417  else
418  {
419  m_smallImgCtrl->SetBitmap(m_empty);
420  m_smallImgCtrl->GetParent()->Layout();
421  m_smallImgCtrl->Refresh();
422  };
423  }
424 }
425 
427 {
428  // disable controls
429  m_lenstype->Disable();
430  m_focallength->Disable();
431  m_cropfactor->Disable();
432  m_smallImgCtrl->SetBitmap(m_empty);
433  m_smallImgCtrl->GetParent()->Layout();
434  m_smallImgCtrl->Refresh();
435 }
436 
438 {
439  // enable control if not already enabled
440  m_lenstype->Enable();
441  m_focallength->Enable();
442  m_cropfactor->Enable();
443 }
444 
445 void ImagesPanel::ShowImage(unsigned int imgNr)
446 {
447  m_showImgNr = imgNr;
449 }
450 
452 {
453  if (m_showImgNr < 0 || m_showImgNr >= m_pano->getNrOfImages())
454  {
455  return;
456  }
457  ImageCache::EntryPtr cacheEntry = ImageCache::getInstance().getSmallImageIfAvailable(
458  m_pano->getImage(m_showImgNr).getFilename());
459  if (!cacheEntry.get())
460  {
461  // image currently isn't loaded.
462  // Instead of loading and displaying the image now, request it for
463  // later. Then the user can switch between images in the list quickly,
464  // even when not all images previews are in the cache.
465  thumbnail_request = ImageCache::getInstance().requestAsyncSmallImage(
466  m_pano->getImage(m_showImgNr).getFilename());
467  // When the image is ready, try this function again.
468  thumbnail_request->ready.push_back(
469  std::bind(&ImagesPanel::UpdatePreviewImage, this)
470  );
471  } else {
472  // forget any request now the image has loaded.
473  thumbnail_request = ImageCache::RequestPtr();
474  wxImage img = imageCacheEntry2wxImage(cacheEntry);
475 
476  double iRatio = img.GetWidth() / (double) img.GetHeight();
477 
478  wxSize sz;
479  // estimate image size
480 
481  sz = m_smallImgCtrl->GetContainingSizer()->GetSize();
482  double sRatio = (double)sz.GetWidth() / sz.GetHeight();
483  if (iRatio > sRatio) {
484  // image is wider than screen, display landscape
485  sz.SetHeight((int) (sz.GetWidth() / iRatio));
486  } else {
487  // portrait
488  sz.SetWidth((int) (sz.GetHeight() * iRatio));
489  }
490  // Make sure the size is positive:
491  // on a small window, m_smallImgCtrl can have 0 width.
492  sz.IncTo(wxSize(1,1));
493  wxImageResizeQuality resizeQuality = wxIMAGE_QUALITY_NORMAL;
494  if (std::max(img.GetWidth(), img.GetHeight()) > (ULONG_MAX >> 16))
495  {
496  // wxIMAGE_QUALITY_NORMAL resizes the image with ResampleNearest
497  // this algorithm works only if image dimensions are smaller then
498  // ULONG_MAX >> 16 (actual size of unsigned long differ from system
499  // to system)
500  resizeQuality = wxIMAGE_QUALITY_BOX_AVERAGE;
501  };
502  wxImage scaled = img.Scale(sz.GetWidth(),sz.GetHeight(), resizeQuality);
503  // now apply color profile
504  if (!cacheEntry->iccProfile->empty() || huginApp::Get()->HasMonitorProfile())
505  {
506  HuginBase::Color::CorrectImage(scaled, *(cacheEntry->iccProfile), huginApp::Get()->GetMonitorProfile());
507  };
508  wxBitmap scaledBitmap(scaled);
509  // set the DPI scale factor in wxBitmap, otherwise wxStaticBitmap scales the wxBitmap also
510  scaledBitmap.SetScaleFactor(m_smallImgCtrl->GetDPIScaleFactor());
511  m_smallImgCtrl->SetBitmap(scaledBitmap);
512  m_smallImgCtrl->GetParent()->Layout();
513  m_smallImgCtrl->Refresh();
514  }
515 }
516 
518 {
521  m_CPDetectorChoice->InvalidateBestSize();
522  m_CPDetectorChoice->GetParent()->Layout();
523  Refresh();
524 };
525 
526 void ImagesPanel::OnLensTypeChanged (wxCommandEvent & e)
527 {
528  size_t var = GetSelectedValue(m_lenstype);
530  if(!images.empty())
531  {
532  const HuginBase::SrcPanoImage & img = m_pano->getImage(*(images.begin()));
533  double focal_length = HuginBase::SrcPanoImage::calcFocalLength(img.getProjection(), img.getHFOV(), img.getCropFactor(), img.getSize());
534  std::vector<PanoCommand::PanoCommand*> commands;
535  commands.push_back(new PanoCommand::ChangeImageProjectionCmd(*m_pano, images,(HuginBase::SrcPanoImage::Projection) var));
536  commands.push_back(new PanoCommand::UpdateFocalLengthCmd(*m_pano, images, focal_length));
539  );
540  // check if fisheye projections is selected
541  if (wxConfig::Get()->Read(wxT("/ShowFisheyeCropHint"), 1l) == 1 &&
546  {
547  // if so, show hint about crop and open tab when requested
548  wxDialog dlg;
549  wxXmlResource::Get()->LoadDialog(&dlg, NULL, wxT("fisheye_show_crop_dlg"));
550  if (dlg.ShowModal() == wxID_OK)
551  {
552  MainFrame::Get()->ShowMaskEditor(*(images.begin()), true);
553  };
554  if (XRCCTRL(dlg, "fisheye_crop_dont_ask_checkbox", wxCheckBox)->IsChecked())
555  {
556  wxConfig::Get()->Write(wxT("/ShowFisheyeCropHint"), 0l);
557  };
558  };
559  };
560 };
561 
562 void ImagesPanel::OnFocalLengthChanged(wxCommandEvent & e)
563 {
564  if (m_pano->getNrOfImages() == 0)
565  {
566  return;
567  };
568 
569  wxString text = m_focallength->GetValue();
570  if(text.IsEmpty())
571  {
572  return;
573  };
574  double val;
575  if (!hugin_utils::str2double(text, val))
576  {
577  return;
578  }
579  //no negative values, no zero input please
580  if (val<0.1)
581  {
582  wxBell();
583  return;
584  };
585 
587  const HuginBase::SrcPanoImage& srcImg = m_pano->getImage(*(images.begin()));
588  if (srcImg.getProjection() == HuginBase::SrcPanoImage::FISHEYE_ORTHOGRAPHIC)
589  {
590  double hfov=srcImg.calcHFOV(srcImg.getProjection(), val, srcImg.getCropFactor(), srcImg.getSize());
591  if(hfov>190)
592  {
593  if(wxMessageBox(
594  wxString::Format(_("You have given a field of view of %.2f degrees.\n But the orthographic projection is limited to a field of view of 180 degress.\nDo you want still use that high value?"), hfov),
595 #ifdef __WXMSW__
596  _("Hugin"),
597 #else
598  wxT(""),
599 #endif
600  wxICON_EXCLAMATION | wxYES_NO)==wxNO)
601  {
602  wxTreeEvent dummy;
603  OnSelectionChanged(dummy);
604  return;
605  };
606  };
607  };
609  new PanoCommand::UpdateFocalLengthCmd(*m_pano, images, val)
610  );
611 }
612 
613 void ImagesPanel::OnCropFactorChanged(wxCommandEvent & e)
614 {
615  if (m_pano->getNrOfImages() == 0)
616  {
617  return;
618  };
619 
620  wxString text = m_cropfactor->GetValue();
621  if(text.IsEmpty())
622  {
623  return;
624  };
625  double val;
626  if (!hugin_utils::str2double(text, val))
627  {
628  return;
629  }
630  //no negative values, no zero input please
631  if (val<0.1)
632  {
633  wxBell();
634  return;
635  };
636 
640  );
641 }
642 
643 void ImagesPanel::OnMinimumOverlapChanged(wxCommandEvent & e)
644 {
645  wxString text = m_overlap->GetValue();
646  if(text.IsEmpty())
647  {
648  return;
649  };
650  double val;
651  if (!hugin_utils::str2double(text, val))
652  {
653  return;
654  }
655  if(fabs(val)<0.001 || val>1)
656  {
657  wxMessageBox(_("The minimum overlap has to be greater than 0 and smaller than 1."),
658 #ifdef _WIN32
659  _("Hugin"),
660 #else
661  wxT(""),
662 #endif
663  wxOK | wxICON_INFORMATION, this);
664  return;
665  };
666  if (val < 0)
667  {
668  val = -1;
669  };
671  opt.outputStacksMinOverlap=val;
674  );
675 };
676 
677 void ImagesPanel::OnMaxEvDiffChanged(wxCommandEvent& e)
678 {
679  wxString text = m_maxEv->GetValue();
680  if(text.IsEmpty())
681  {
682  return;
683  };
684  double val;
685  if (!hugin_utils::str2double(text, val))
686  {
687  return;
688  }
689  if(val<0)
690  {
691  wxMessageBox(_("The maximum Ev difference has to be greater than 0."),
692 #ifdef _WIN32
693  _("Hugin"),
694 #else
695  wxT(""),
696 #endif
697  wxOK | wxICON_INFORMATION, this);
698  return;
699  };
701  opt.outputLayersExposureDiff=val;
704  );
705 };
706 
708 {
709  size_t sel=m_groupModeChoice->GetSelection();
711  m_groupModeChoice->Clear();
712  int* i=new int;
714  m_groupModeChoice->Append(_("None"), i);
715  i=new int;
717  m_groupModeChoice->Append(_("Lens"), i);
719  {
720  i=new int;
722  m_groupModeChoice->Append(_("Stacks"), i);
724  {
725  i=new int;
727  m_groupModeChoice->Append(_("Output layers"), i);
728  i=new int;
730  m_groupModeChoice->Append(_("Output stacks"), i);
731  };
732  };
733  if((m_guiLevel==GUI_ADVANCED && sel>2) || (m_guiLevel==GUI_SIMPLE && sel>1))
734  {
735  sel=0;
736  };
737  m_groupModeChoice->SetSelection(sel);
738  wxCommandEvent dummy;
739  OnGroupModeChanged(dummy);
740 };
741 
743 {
745  m_optChoice->Clear();
746  int* i=new int;
748  m_optChoice->Append(_("Positions (incremental, starting from anchor)"), i);
749  i=new int;
751  m_optChoice->Append(_("Positions (y,p,r)"), i);
752  i=new int;
754  m_optChoice->Append(_("Positions and View (y,p,r,v)"), i);
755  i=new int;
757  m_optChoice->Append(_("Positions and Barrel Distortion (y,p,r,b)"), i);
758  i=new int;
760  m_optChoice->Append(_("Positions, View and Barrel (y,p,r,v,b)"), i);
761  i=new int;
764  {
765  m_optChoice->Append(_("Everything without translation"), i);
766  }
767  else
768  {
769  m_optChoice->Append(_("Everything"), i);
770  };
772  {
773  i=new int;
775  m_optChoice->Append(_("Positions and Translation (y,p,r,x,y,z)"), i);
776  i=new int;
778  m_optChoice->Append(_("Positions, Translation and View (y,p,r,x,y,z,v)"), i);
779  i=new int;
781  m_optChoice->Append(_("Positions, Translation and Barrel (y,p,r,x,y,z,b)"), i);
782  i=new int;
784  m_optChoice->Append(_("Positions, Translation, View and Barrel (y,p,r,x,y,z,v,b)"), i);
785  };
786  i=new int;
787  *i=0;
788  m_optChoice->Append(_("Custom parameters"), i);
789 
791  m_optPhotoChoice->Clear();
792  i=new int;
794  m_optPhotoChoice->Append(_("Low dynamic range"), i);
795  i=new int;
797  m_optPhotoChoice->Append(_("Low dynamic range, variable white balance"), i);
799  {
800  i=new int;
802  m_optPhotoChoice->Append(_("High dynamic range, fixed exposure"), i);
803  i=new int;
805  m_optPhotoChoice->Append(_("High dynamic range, variable white balance, fixed exposure"), i);
806  };
807  i=new int;
808  *i=0;
809  m_optPhotoChoice->Append(_("Custom parameters"), i);
810  m_optChoice->GetParent()->Layout();
811  Refresh();
812 };
813 
815 {
816  return m_optChoice->GetString(m_optChoice->GetSelection());
817 };
818 
819 void ImagesPanel::OnGroupModeChanged(wxCommandEvent & e)
820 {
821  ImagesTreeCtrl::GroupMode mode=ImagesTreeCtrl::GroupMode(*static_cast<int*>(m_groupModeChoice->GetClientData(m_groupModeChoice->GetSelection())));
823  XRCCTRL(*this, "images_text_overlap", wxStaticText)->Show(mode==ImagesTreeCtrl::GROUP_OUTPUTSTACK);
826  XRCCTRL(*this, "images_text_maxev", wxStaticText)->Show(mode==ImagesTreeCtrl::GROUP_OUTPUTLAYERS);
829  Layout();
830  Refresh();
831 };
832 
833 void ImagesPanel::OnDisplayModeChanged(wxCommandEvent & e)
834 {
835  wxRadioBox* display=XRCCTRL(*this,"images_column_radiobox", wxRadioBox);
836  m_images_tree->SetDisplayMode((ImagesTreeCtrl::DisplayMode)display->GetSelection());
837 };
838 
840 {
841  int optSwitch=*static_cast<int*>(m_optChoice->GetClientData(m_optChoice->GetSelection()));
842  if(optSwitch!=m_pano->getOptimizerSwitch())
843  {
846  );
847  };
848 };
849 
851 {
852  int optSwitch=*static_cast<int*>(m_optPhotoChoice->GetClientData(m_optPhotoChoice->GetSelection()));
853  if(optSwitch!=m_pano->getPhotometricOptimizerSwitch())
854  {
857  );
858  };
859 };
860 
862 {
863  m_guiLevel=newGuiLevel;
864  m_images_tree->SetGuiLevel(newGuiLevel);
865  FillGroupChoice();
867  wxStaticText* textlabel=XRCCTRL(*this, "images_mode_text", wxStaticText);
868  switch(m_guiLevel)
869  {
870  case GUI_SIMPLE:
871  textlabel->SetLabel(_("Simple interface"));
872  break;
873  case GUI_ADVANCED:
874  textlabel->SetLabel(_("Advanced interface"));
875  break;
876  case GUI_EXPERT:
877  textlabel->SetLabel(_("Expert interface"));
878  break;
879  };
880  textlabel->GetParent()->Layout();
881  textlabel->Refresh();
883 };
884 
885 void ImagesPanel::OnOptimizeButton(wxCommandEvent &e)
886 {
888 };
889 
891 {
893 };
894 
896 
898  : wxXmlResourceHandler()
899 {
900  AddWindowStyles();
901 }
902 
904 {
905  XRC_MAKE_INSTANCE(cp, ImagesPanel)
906 
907  cp->Create(m_parentAsWindow,
908  GetID(),
909  GetPosition(), GetSize(),
910  GetStyle(wxT("style")),
911  GetName());
912 
913  SetupWindow( cp);
914  return cp;
915 }
916 
917 bool ImagesPanelXmlHandler::CanHandle(wxXmlNode *node)
918 {
919  return IsOfClass(node, wxT("ImagesPanel"));
920 }
921 
922 IMPLEMENT_DYNAMIC_CLASS(ImagesPanelXmlHandler, wxXmlResourceHandler)
void UpdatePreviewImage()
#define DEBUG_INFO(msg)
Definition: utils.h:69
virtual void panoramaImagesChanged(HuginBase::Panorama &pano, const HuginBase::UIntSet &imgNr)
notifies about changes to images
wxTextCtrl * m_focallength
the text input control for focal length
Definition: ImagesPanel.h:154
implementation of huginApp Class
virtual wxObject * DoCreateResource()
void SetGroupMode(GroupMode newMode)
sets the group mode to given mode
wxString GetDataPath()
return path to data directory, it depends on operating system
void Read(wxConfigBase *config=wxConfigBase::Get(), wxString loadFromFile=wxEmptyString)
read the settings of different cp generators from config
virtual HuginBase::CPVector automatch(CPDetectorSetting &setting, HuginBase::Panorama &pano, const HuginBase::UIntSet &imgs, int nFeatures, int &ret_value, wxWindow *parent=NULL)
Do cp matching, calles the right routines, based on the matcher selected.
bool str2double(const wxString &s, double &d)
Definition: wxPlatform.cpp:37
wxChoice * m_groupModeChoice
Definition: ImagesPanel.h:165
declaration of main image tree control
bool removeObserver(PanoramaObserver *observer)
remove a panorama observer.
Definition: Panorama.cpp:1551
wxStaticBitmap * m_smallImgCtrl
pointer to the preview image control
Definition: ImagesPanel.h:146
#define DEBUG_TRACE(msg)
Definition: utils.h:67
Somewhere to specify what variables belong to what.
wxChoice * m_CPDetectorChoice
Definition: ImagesPanel.h:164
void RunCPGenerator(CPDetectorSetting &setting, const HuginBase::UIntSet &img)
run the cp generator with the given setting on selected images
some helper classes for graphes
const cmsHPROFILE GetMonitorProfile() const
returns the monitor profile, if no monitor profile was found the sRGB profile is used instead ...
Definition: huginApp.h:129
wxChoice * m_lenstype
pointer to lens type selector
Definition: ImagesPanel.h:148
size_t m_showImgNr
Definition: ImagesPanel.h:161
wxString doubleTowxString(double d, int digits)
Definition: wxPlatform.cpp:31
#define DEBUG_ASSERT(cond)
Definition: utils.h:80
void OnPhotometricOptimizerSwitchChanged(wxCommandEvent &e)
event handler, when photometric optimizer master switch was changed
void OnPhotometricOptimize(wxCommandEvent &e)
Definition: MainFrame.cpp:1669
HuginBase::Panorama * m_pano
the model
Definition: ImagesPanel.h:97
include file for the hugin project
void ShowImage(unsigned int imgNr)
show a bigger thumbnail
update the photometric optimizer master switch
Definition: PanoCommand.h:225
void OnDisplayModeChanged(wxCommandEvent &e)
event handler when display mode (which information should be shown) was changed
void EnableImageCtrls()
void OnLensTypeChanged(wxCommandEvent &e)
updates the lens type for the selected images
wxBitmap m_empty
bitmap with default image
Definition: ImagesPanel.h:138
static huginApp * Get()
hack.. kind of a pseudo singleton...
Definition: huginApp.cpp:645
void Init(HuginBase::Panorama *pano)
initialization, connects all control with Panorama, register observer
Definition: ImagesTree.cpp:204
PanoCommand to combine other PanoCommands.
Definition: PanoCommand.h:39
ImagesTreeCtrl * m_images_tree
pointer to the main control
Definition: ImagesPanel.h:144
void OnOptimizeButton(wxCommandEvent &e)
event handler for geometric optimizer
Base class for control point creators.
Hugin&#39;s first panel.
Definition: ImagesPanel.h:40
std::set< unsigned int > UIntSet
Definition: PanoramaData.h:51
ArraySettings settings
array which stores the different autopano settings
set the panorama options
Definition: PanoCommand.h:418
void FillControl(wxControlWithItems *control, bool select_default=false, bool show_default=false)
fills a wxControlWithItems with the available generators
DisplayMode
enumeration for display mode, limits the displayed columns
Definition: ImagesTree.h:49
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL, const wxString &name=wxT("panel"))
Definition: ImagesPanel.cpp:62
Model for a panorama.
Definition: Panorama.h:152
void OnMaxEvDiffChanged(wxCommandEvent &e)
updates the max ev difference
some definitions to work with optimizer master switches
size_t GetSelectedValue(wxControlWithItems *list)
Returns the client value of the selected item from list.
Definition: LensTools.cpp:102
class, which stores all settings of one cp detector
void SetDisplayMode(DisplayMode newMode)
sets the display mode to given mode
void CorrectImage(wxImage &image, const vigra::ImageImportInfo::ICCProfile &iccProfile, const cmsHPROFILE &monitorProfile)
apply color correction to given image using input iccProfile and monitor profile
Definition: wxcms.cpp:218
void CPGenerate(wxCommandEvent &e)
control point detection event handler
std::size_t getNrOfImages() const
number of images.
Definition: Panorama.h:205
static MainFrame * Get()
hack.. kind of a pseudo singleton...
Definition: MainFrame.cpp:2153
GroupMode
enumeration for grouping mode
Definition: ImagesTree.h:40
update the optimizer master switch
Definition: PanoCommand.h:214
wxTextCtrl * m_maxEv
the text input control for max ev difference
Definition: ImagesPanel.h:160
wxImage imageCacheEntry2wxImage(ImageCache::EntryPtr e)
GuiLevel m_guiLevel
Definition: ImagesPanel.h:169
Update the focal length.
Definition: PanoCommand.h:476
IMPLEMENT_DYNAMIC_CLASS(wxTreeListHeaderWindow, wxWindow)
void FillGroupChoice()
fills the grouping wxChoice with values depending on GuiLevel
bool HasMonitorProfile() const
return true if we found a suitable monitor profile and could loading it
Definition: huginApp.h:134
static GlobalCmdHist & getInstance()
void ShowMaskEditor(size_t imgNr, bool switchToCropMode=false)
opens the mask/crop editor with the given image selected
Definition: MainFrame.cpp:2024
void Init(HuginBase::Panorama *pano)
void addCommand(PanoCommand *command, bool execute=true)
Adds a command to the history.
wxTextCtrl * m_cropfactor
the text input control for crop factor
Definition: ImagesPanel.h:156
static double calcFocalLength(SrcPanoImage::Projection proj, double hfov, double crop, vigra::Size2D imageSize)
calcualte focal length, given crop factor and hfov
void OnSelectionChanged(wxTreeEvent &e)
change displayed variables if the selection has changed.
void OnOptimize(wxCommandEvent &e)
Definition: MainFrame.cpp:1613
void SetGuiLevel(GuiLevel newSetting)
sets the GuiLevel of the control
Definition: ImagesTree.cpp:943
void ReloadCPDetectorSettings()
Reloads the cp detector settings from config, necessary after edit preferences.
wxTextCtrl * m_overlap
the text input control for minimum overlap
Definition: ImagesPanel.h:158
void OnMinimumOverlapChanged(wxCommandEvent &e)
updates the minimum overlap
void OnCropFactorChanged(wxCommandEvent &e)
updates the crop factor for the selected images
void OnOptimizerSwitchChanged(wxCommandEvent &e)
event handler, when optimizer master switch was changed
void OnPhotometricOptimizeButton(wxCommandEvent &e)
event handler for photometric optimizer
HuginBase::UIntSet GetSelectedImages()
returns the selected images
Definition: ImagesTree.cpp:899
void addObserver(PanoramaObserver *o)
add a panorama observer.
Definition: Panorama.cpp:1546
include file for the hugin project
const PanoramaOptions & getOptions() const
returns the options for this panorama
Definition: Panorama.h:481
HuginBase::ImageCache::RequestPtr thumbnail_request
Request for thumbnail image.
Definition: ImagesPanel.h:141
Handle EVT_KILL_FOCUS and convert it to a EVT_TEXT_ENTER event.
wxChoice * m_optPhotoChoice
pointer to photometric optimizer switch selector
Definition: ImagesPanel.h:152
the main images tree control, used on images and optimizer tabs
Definition: ImagesTree.h:36
const int getPhotometricOptimizerSwitch() const
return the photometric optimizer master switch
Definition: Panorama.h:467
void SelectListValue(wxControlWithItems *list, size_t newValue)
Selects the given value (stored in the client data) in the given list item.
Definition: LensTools.cpp:89
static T max(T x, T y)
Definition: svm.cpp:65
const int getOptimizerSwitch() const
returns optimizer master switch
Definition: Panorama.h:461
CPDetectorConfig cpdetector_config
Definition: ImagesPanel.h:167
#define DEBUG_DEBUG(msg)
Definition: utils.h:68
void OnFocalLengthChanged(wxCommandEvent &e)
updates the focal length for the selected images
void OnGroupModeChanged(wxCommandEvent &e)
event handler when grouping selection was changed
std::vector< ControlPoint > CPVector
Definition: ControlPoint.h:99
static double calcHFOV(SrcPanoImage::Projection proj, double fl, double crop, vigra::Size2D imageSize)
calculate hfov of an image given focal length, image size and crop factor
platform/compiler specific stuff.
wxString GetCurrentOptimizerString()
return the currently selected optimizer setting as string from the drop down list box ...
wxButton * m_matchingButton
Definition: ImagesPanel.h:163
Update the crop factor.
Definition: PanoCommand.h:491
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
Definition: Panorama.h:211
GuiLevel
Definition: GuiLevel.h:31
void fill_set(_Container &c, typename _Container::key_type begin, typename _Container::key_type end)
Definition: stl_utils.h:81
void Write(wxConfigBase *config=wxConfigBase::Get())
writes the settings of different cp generators to config
virtual void panoramaChanged(HuginBase::Panorama &pano)
this is called whenever the panorama has changed.
void OnSize(wxSizeEvent &e)
#define HUGIN_ASS_NCONTROLPOINTS
add multiple control points
Definition: PanoCommand.h:281
wxChoice * m_optChoice
pointer to optimizer switch selector
Definition: ImagesPanel.h:150
void SetGuiLevel(GuiLevel newGuiLevel)
sets the GuiLevel for all controls on this panel
void DisableImageCtrls()
All variables of a source image.
Definition: SrcPanoImage.h:194
Panorama image options.
void FillLensProjectionList(wxControlWithItems *list)
Fills a wxControlWithItem with all input projection formats, the client data contains the associated ...
Definition: LensTools.cpp:35
const wxString GetSelectedCPGenerator()
return the currently selected cp generator description
void FillOptimizerChoice()
fills the optmizer wxChoices with values depending on GuiLevel
virtual bool CanHandle(wxXmlNode *node)
void DeleteClientData(wxChoice *cb)