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 #include "base_wx/wxutils.h"
54 
56 
58 {
59  m_pano = 0;
61 }
62 
63 bool ImagesPanel::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
64  long style, const wxString& name)
65 {
66  if (! wxPanel::Create(parent, id, pos, size, style, name)) {
67  return false;
68  }
69 
70  wxXmlResource::Get()->LoadPanel(this, "images_panel");
71  wxPanel * panel = XRCCTRL(*this, "images_panel", wxPanel);
72  wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
73  topsizer->Add(panel, 1, wxEXPAND, 0);
74  SetSizer(topsizer);
75 
76  m_images_tree = XRCCTRL(*this, "images_tree_ctrl", ImagesTreeCtrl);
78  m_images_tree->Bind(wxEVT_TREE_SEL_CHANGED, &ImagesPanel::OnSelectionChanged, this);
79 
80  m_showImgNr = INT_MAX;
81 
82  m_matchingButton = XRCCTRL(*this, "images_feature_matching", wxButton);
84  m_matchingButton->Bind(wxEVT_BUTTON, &ImagesPanel::CPGenerate, this);
85 
86  m_CPDetectorChoice = XRCCTRL(*this, "cpdetector_settings", wxChoice);
87 
88  // Image Preview
89  m_smallImgCtrl = XRCCTRL(*this, "images_selected_image", wxStaticBitmap);
91 
92  // empty bitmap with size (0,0) is not valid for wxStaticBitmap
93  // so we create a bitmap with the background color of the static bitmap control
94  wxImage image(1, 1, true);
95  const wxColour imageBackgroundColor = m_smallImgCtrl->GetBackgroundColour();
96  image.SetRGB(0, 0, imageBackgroundColor.Red(), imageBackgroundColor.Green(), imageBackgroundColor.Blue());
97  m_empty = wxBitmap(image);
98  m_smallImgCtrl->SetBitmap(m_empty);
99 
100  m_lenstype = XRCCTRL(*this, "images_lens_type", wxChoice);
102  m_lenstype->Bind(wxEVT_CHOICE, &ImagesPanel::OnLensTypeChanged, this);
104  m_lenstype->SetSelection(0);
105 
106  m_focallength = XRCCTRL(*this, "images_focal_length", wxTextCtrl);
108  m_focallength->PushEventHandler(new TextKillFocusHandler(this));
109  m_focallength->Bind(wxEVT_TEXT_ENTER, &ImagesPanel::OnFocalLengthChanged, this);
110 
111  m_cropfactor = XRCCTRL(*this, "images_crop_factor", wxTextCtrl);
113  m_cropfactor->PushEventHandler(new TextKillFocusHandler(this));
114  m_cropfactor->Bind(wxEVT_TEXT_ENTER, &ImagesPanel::OnCropFactorChanged, this);
115 
116  m_overlap = XRCCTRL(*this, "images_overlap", wxTextCtrl);
118  m_overlap->PushEventHandler(new TextKillFocusHandler(this));
119  m_overlap->Bind(wxEVT_TEXT_ENTER, &ImagesPanel::OnMinimumOverlapChanged, this);
120 
121  m_maxEv = XRCCTRL(*this, "images_maxev", wxTextCtrl);
123  m_maxEv->PushEventHandler(new TextKillFocusHandler(this));
124  m_maxEv->Bind(wxEVT_TEXT_ENTER, &ImagesPanel::OnMaxEvDiffChanged, this);
125 
126  wxTreeEvent ev;
127  OnSelectionChanged(ev);
128  DEBUG_TRACE("end");
129 
130  m_optChoice = XRCCTRL(*this, "images_optimize_mode", wxChoice);
132  m_optChoice->Bind(wxEVT_CHOICE, &ImagesPanel::OnOptimizerSwitchChanged, this);
133 
134  m_optPhotoChoice = XRCCTRL(*this, "images_photo_optimize_mode", wxChoice);
137 
139 
140  m_groupModeChoice = XRCCTRL(*this, "images_group_mode", wxChoice);
141  m_groupModeChoice->Bind(wxEVT_CHOICE, &ImagesPanel::OnGroupModeChanged, this);
142  FillGroupChoice();
143 
144  wxConfigBase* config=wxConfigBase::Get();
145  m_degDigits = config->Read("/General/DegreeFractionalDigitsEdit",3);
146  //read autopano generator settings
147  cpdetector_config.Read(config,huginApp::Get()->GetDataPath()+"default.setting");
148  //write current autopano generator settings
149  cpdetector_config.Write(config);
150  config->Flush();
152  Layout();
153 #ifdef __WXGTK__
154  // explicitly set focus to propogate correctly key presses/shortcuts
156 #endif
157  Bind(wxEVT_RADIOBOX, &ImagesPanel::OnDisplayModeChanged, this, XRCID("images_column_radiobox"));
158  Bind(wxEVT_BUTTON, &ImagesPanel::OnOptimizeButton, this, XRCID("images_optimize"));
159  Bind(wxEVT_BUTTON, &ImagesPanel::OnPhotometricOptimizeButton, this, XRCID("images_photo_optimize"));
160  return true;
161 }
162 
164 {
165  m_pano = panorama;
167  // observe the panorama
168  m_pano->addObserver(this);
169 }
170 
171 void DeleteClientData(wxChoice* cb)
172 {
173  if(cb->HasClientUntypedData())
174  {
175  for(size_t i = 0; i < cb->GetCount(); i++)
176  {
177  delete static_cast<int*>(cb->GetClientData(i));
178  };
179  };
180 };
181 
183 {
184  DEBUG_TRACE("dtor");
185  m_focallength->PopEventHandler(true);
186  m_cropfactor->PopEventHandler(true);
187  m_overlap->PopEventHandler(true);
188  m_maxEv->PopEventHandler(true);
189  m_pano->removeObserver(this);
193  DEBUG_TRACE("dtor end");
194 }
195 
196 // We need to override the default handling of size events because the
197 // sizers set the virtual size but not the actual size. We reverse
198 // the standard handling and fit the child to the parent rather than
199 // fitting the parent around the child
200 
201 void ImagesPanel::OnSize( wxSizeEvent & e )
202 {
203  int winWidth, winHeight;
204  GetClientSize(&winWidth, &winHeight);
205  DEBUG_INFO( "image panel: " << winWidth <<"x"<< winHeight );
207 
208  e.Skip();
209 }
210 
212 {
213  //update optimizer choice selection
214  int optSwitch=m_pano->getOptimizerSwitch();
215  int found=wxNOT_FOUND;
216  for(size_t i=0;i<m_optChoice->GetCount();i++)
217  {
218  if(optSwitch==*static_cast<int*>(m_optChoice->GetClientData(i)))
219  {
220  found=i;
221  break;
222  };
223  };
224  if(found==wxNOT_FOUND)
225  {
228  );
229  }
230  else
231  {
232  m_optChoice->SetSelection(found);
233  };
234 
235  //update photometric optimizer choice selection
237  found=wxNOT_FOUND;
238  for(size_t i=0;i<m_optPhotoChoice->GetCount();i++)
239  {
240  if(optSwitch==*static_cast<int*>(m_optPhotoChoice->GetClientData(i)))
241  {
242  found=i;
243  break;
244  };
245  };
246  if(found==wxNOT_FOUND)
247  {
250  );
251  }
252  else
253  {
254  m_optPhotoChoice->SetSelection(found);
255  };
259 }
260 
262 {
263  DEBUG_TRACE("");
264 
265  // update text field if selected
266  const HuginBase::UIntSet & selected = m_images_tree->GetSelectedImages();
267  DEBUG_DEBUG("nr of sel Images: " << selected.size());
268  if (pano.getNrOfImages() == 0)
269  {
271  m_matchingButton->Disable();
272  }
273  else
274  {
275  m_matchingButton->Enable();
276  wxTreeEvent ev;
277  OnSelectionChanged(ev);
278  };
279  //enable/disable optimize buttons
280  XRCCTRL(*this, "images_optimize", wxButton)->Enable(pano.getNrOfImages()>0);
281  XRCCTRL(*this, "images_photo_optimize", wxButton)->Enable(pano.getNrOfImages()>1);
282 }
283 
284 // ##### Here start the eventhandlers #####
285 
287 void ImagesPanel::CPGenerate(wxCommandEvent & e)
288 {
290  //if only one image is selected, run detector on all images, except for linefind
291  wxString progName = cpdetector_config.settings[m_CPDetectorChoice->GetSelection()].GetProg().Lower();
292  if ((selImg.empty()) || (selImg.size() == 1 && progName.Find("linefind") == wxNOT_FOUND))
293  {
294  // add all images.
295  selImg.clear();
296  fill_set(selImg, 0, m_pano->getNrOfImages() - 1);
297  }
298 
299  if (selImg.empty())
300  {
301  return;
302  }
304 };
305 
307 {
309 }
310 
312 {
313  wxConfigBase* config=wxConfigBase::Get();
314  long nFeatures = HUGIN_ASS_NCONTROLPOINTS;
315  if(wxGetKeyState(WXK_COMMAND))
316  {
317  nFeatures = config->Read("/MainFrame/nControlPoints", HUGIN_ASS_NCONTROLPOINTS);
318  nFeatures = wxGetNumberFromUser(
319  _("Enter maximal number of control points per image pair"),
320  _("Points per Overlap"),
321  _("Control point detector option"),
322  nFeatures, 1, 10000
323  );
324  if(nFeatures<1)
325  {
326  return;
327  };
328  config->Write("/MainFrame/nControlPoints", nFeatures);
329  }
330  else
331  {
332  nFeatures = config->Read("/Assistant/nControlPoints", HUGIN_ASS_NCONTROLPOINTS);
333  };
334 
335  AutoCtrlPointCreator matcher;
336  HuginBase::CPVector cps = matcher.automatch(setting, *m_pano, img, nFeatures, this);
337  wxString msg;
338  hugin_utils::HuginMessageBox(wxString::Format(_("Added %lu control points"), (unsigned long)cps.size()), _("Hugin"), wxOK | wxICON_INFORMATION, this);
341  );
342 
343 };
344 
346 {
347  return cpdetector_config.settings[m_CPDetectorChoice->GetSelection()].GetCPDetectorDesc();
348 };
349 
350 void ImagesPanel::OnSelectionChanged(wxTreeEvent & e)
351 {
353  DEBUG_DEBUG("selected Images: " << sel.size());
354  if (sel.empty())
355  {
356  // nothing to edit
358  }
359  else
360  {
361  // enable edit
363  const HuginBase::SrcPanoImage& img = m_pano->getImage(*sel.begin());
364  bool identical_projection=true;
365  HuginBase::SrcPanoImage::Projection proj = img.getProjection();
366  double focallength = HuginBase::SrcPanoImage::calcFocalLength(img.getProjection(), img.getHFOV(),
367  img.getCropFactor(),img.getSize());;
368  double cropFactor=img.getCropFactor();
369  for (HuginBase::UIntSet::const_iterator it = sel.begin(); it != sel.end(); ++it)
370  {
371  const HuginBase::SrcPanoImage& img2 = m_pano->getImage(*it);
372  if(proj!=img2.getProjection())
373  {
374  identical_projection=false;
375  };
376  double focallength2 = HuginBase::SrcPanoImage::calcFocalLength(img2.getProjection(), img2.getHFOV(),
377  img2.getCropFactor(),img2.getSize());
378  if(focallength>0 && fabs(focallength-focallength2)>0.05)
379  {
380  focallength=-1;
381  };
382  if(fabs(cropFactor-img2.getCropFactor())>0.1)
383  {
384  cropFactor=-1;
385  };
386  };
387 
388  if(identical_projection)
389  {
391  }
392  else
393  {
394  m_lenstype->Select(wxNOT_FOUND);
395  };
396  if(focallength>0)
397  {
398  // use ChangeValue explicit, SetValue would create EVT_TEXT event which collides with our TextKillFocusHandler
399  m_focallength->ChangeValue(hugin_utils::doubleTowxString(focallength,m_degDigits));
400  }
401  else
402  {
403  m_focallength->Clear();
404  };
405  if(cropFactor>0)
406  {
407  m_cropfactor->ChangeValue(hugin_utils::doubleTowxString(cropFactor,m_degDigits));
408  }
409  else
410  {
411  m_cropfactor->Clear();
412  };
413 
414  if (sel.size() == 1)
415  {
416  ShowImage(*(sel.begin()));
417  }
418  else
419  {
420  m_smallImgCtrl->SetBitmap(m_empty);
421  m_smallImgCtrl->GetParent()->Layout();
422  m_smallImgCtrl->Refresh();
423  };
424  }
425 }
426 
428 {
429  // disable controls
430  m_lenstype->Disable();
431  m_focallength->Disable();
432  m_cropfactor->Disable();
433  m_smallImgCtrl->SetBitmap(m_empty);
434  m_smallImgCtrl->GetParent()->Layout();
435  m_smallImgCtrl->Refresh();
436 }
437 
439 {
440  // enable control if not already enabled
441  m_lenstype->Enable();
442  m_focallength->Enable();
443  m_cropfactor->Enable();
444 }
445 
446 void ImagesPanel::ShowImage(unsigned int imgNr)
447 {
448  m_showImgNr = imgNr;
450 }
451 
453 {
454  if (m_showImgNr < 0 || m_showImgNr >= m_pano->getNrOfImages())
455  {
456  return;
457  }
458  ImageCache::EntryPtr cacheEntry = ImageCache::getInstance().getSmallImageIfAvailable(
459  m_pano->getImage(m_showImgNr).getFilename());
460  if (!cacheEntry.get())
461  {
462  // image currently isn't loaded.
463  // Instead of loading and displaying the image now, request it for
464  // later. Then the user can switch between images in the list quickly,
465  // even when not all images previews are in the cache.
466  thumbnail_request = ImageCache::getInstance().requestAsyncSmallImage(
467  m_pano->getImage(m_showImgNr).getFilename());
468  // When the image is ready, try this function again.
469  thumbnail_request->ready.push_back(
470  std::bind(&ImagesPanel::UpdatePreviewImage, this)
471  );
472  } else {
473  // forget any request now the image has loaded.
474  thumbnail_request = ImageCache::RequestPtr();
475  wxImage img = imageCacheEntry2wxImage(cacheEntry);
476 
477  double iRatio = img.GetWidth() / (double) img.GetHeight();
478 
479  wxSize sz;
480  // estimate image size
481 
482  sz = m_smallImgCtrl->GetContainingSizer()->GetSize();
483  double sRatio = (double)sz.GetWidth() / sz.GetHeight();
484  if (iRatio > sRatio) {
485  // image is wider than screen, display landscape
486  sz.SetHeight((int) (sz.GetWidth() / iRatio));
487  } else {
488  // portrait
489  sz.SetWidth((int) (sz.GetHeight() * iRatio));
490  }
491  // Make sure the size is positive:
492  // on a small window, m_smallImgCtrl can have 0 width.
493  sz.IncTo(wxSize(1,1));
494  wxImageResizeQuality resizeQuality = wxIMAGE_QUALITY_NORMAL;
495  if (std::max(img.GetWidth(), img.GetHeight()) > (ULONG_MAX >> 16))
496  {
497  // wxIMAGE_QUALITY_NORMAL resizes the image with ResampleNearest
498  // this algorithm works only if image dimensions are smaller then
499  // ULONG_MAX >> 16 (actual size of unsigned long differ from system
500  // to system)
501  resizeQuality = wxIMAGE_QUALITY_BOX_AVERAGE;
502  };
503  wxImage scaled = img.Scale(sz.GetWidth(),sz.GetHeight(), resizeQuality);
504  // now apply color profile
505  if (!cacheEntry->iccProfile->empty() || huginApp::Get()->HasMonitorProfile())
506  {
507  HuginBase::Color::CorrectImage(scaled, *(cacheEntry->iccProfile), huginApp::Get()->GetMonitorProfile());
508  };
509  wxBitmap scaledBitmap(scaled);
510  // set the DPI scale factor in wxBitmap, otherwise wxStaticBitmap scales the wxBitmap also
511  scaledBitmap.SetScaleFactor(m_smallImgCtrl->GetDPIScaleFactor());
512  m_smallImgCtrl->SetBitmap(scaledBitmap);
513  m_smallImgCtrl->GetParent()->Layout();
514  m_smallImgCtrl->Refresh();
515  }
516 }
517 
519 {
522  m_CPDetectorChoice->InvalidateBestSize();
523  m_CPDetectorChoice->GetParent()->Layout();
524  Refresh();
525 };
526 
527 void ImagesPanel::OnLensTypeChanged (wxCommandEvent & e)
528 {
529  size_t var = GetSelectedValue(m_lenstype);
531  if(!images.empty())
532  {
533  const HuginBase::SrcPanoImage & img = m_pano->getImage(*(images.begin()));
534  double focal_length = HuginBase::SrcPanoImage::calcFocalLength(img.getProjection(), img.getHFOV(), img.getCropFactor(), img.getSize());
535  std::vector<PanoCommand::PanoCommand*> commands;
536  commands.push_back(new PanoCommand::ChangeImageProjectionCmd(*m_pano, images,(HuginBase::SrcPanoImage::Projection) var));
537  commands.push_back(new PanoCommand::UpdateFocalLengthCmd(*m_pano, images, focal_length));
540  );
541  // check if fisheye projections is selected
542  if (wxConfig::Get()->Read("/ShowFisheyeCropHint", 1l) == 1 &&
547  {
548  // if so, show hint about crop and open tab when requested
549  wxDialog dlg;
550  wxXmlResource::Get()->LoadDialog(&dlg, NULL, "fisheye_show_crop_dlg");
551  if (dlg.ShowModal() == wxID_OK)
552  {
553  MainFrame::Get()->ShowMaskEditor(*(images.begin()), true);
554  };
555  if (XRCCTRL(dlg, "fisheye_crop_dont_ask_checkbox", wxCheckBox)->IsChecked())
556  {
557  wxConfig::Get()->Write("/ShowFisheyeCropHint", 0l);
558  };
559  };
560  };
561 };
562 
563 void ImagesPanel::OnFocalLengthChanged(wxCommandEvent & e)
564 {
565  if (m_pano->getNrOfImages() == 0)
566  {
567  return;
568  };
569 
570  wxString text = m_focallength->GetValue();
571  if(text.IsEmpty())
572  {
573  return;
574  };
575  double val;
576  if (!hugin_utils::str2double(text, val))
577  {
578  return;
579  }
580  //no negative values, no zero input please
581  if (val<0.1)
582  {
583  wxBell();
584  return;
585  };
586 
588  const HuginBase::SrcPanoImage& srcImg = m_pano->getImage(*(images.begin()));
589  if (srcImg.getProjection() == HuginBase::SrcPanoImage::FISHEYE_ORTHOGRAPHIC)
590  {
591  double hfov=srcImg.calcHFOV(srcImg.getProjection(), val, srcImg.getCropFactor(), srcImg.getSize());
592  if(hfov>190)
593  {
595  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),
596  _("Hugin"), wxICON_EXCLAMATION | wxYES_NO, this) == wxNO)
597  {
598  wxTreeEvent dummy;
599  OnSelectionChanged(dummy);
600  return;
601  };
602  };
603  };
605  new PanoCommand::UpdateFocalLengthCmd(*m_pano, images, val)
606  );
607 }
608 
609 void ImagesPanel::OnCropFactorChanged(wxCommandEvent & e)
610 {
611  if (m_pano->getNrOfImages() == 0)
612  {
613  return;
614  };
615 
616  wxString text = m_cropfactor->GetValue();
617  if(text.IsEmpty())
618  {
619  return;
620  };
621  double val;
622  if (!hugin_utils::str2double(text, val))
623  {
624  return;
625  }
626  //no negative values, no zero input please
627  if (val<0.1)
628  {
629  wxBell();
630  return;
631  };
632 
636  );
637 }
638 
639 void ImagesPanel::OnMinimumOverlapChanged(wxCommandEvent & e)
640 {
641  wxString text = m_overlap->GetValue();
642  if(text.IsEmpty())
643  {
644  return;
645  };
646  double val;
647  if (!hugin_utils::str2double(text, val))
648  {
649  return;
650  }
651  if(fabs(val)<0.001 || val>1)
652  {
653  hugin_utils::HuginMessageBox(_("The minimum overlap has to be greater than 0 and smaller than 1."),
654  _("Hugin"), wxOK | wxICON_INFORMATION, this);
655  return;
656  };
657  if (val < 0)
658  {
659  val = -1;
660  };
662  opt.outputStacksMinOverlap=val;
665  );
666 };
667 
668 void ImagesPanel::OnMaxEvDiffChanged(wxCommandEvent& e)
669 {
670  wxString text = m_maxEv->GetValue();
671  if(text.IsEmpty())
672  {
673  return;
674  };
675  double val;
676  if (!hugin_utils::str2double(text, val))
677  {
678  return;
679  }
680  if(val<0)
681  {
682  hugin_utils::HuginMessageBox(_("The maximum Ev difference has to be greater than 0."), _("Hugin"), wxOK | wxICON_INFORMATION, this);
683  return;
684  };
686  opt.outputLayersExposureDiff=val;
689  );
690 };
691 
693 {
694  size_t sel=m_groupModeChoice->GetSelection();
696  m_groupModeChoice->Clear();
697  int* i=new int;
699  m_groupModeChoice->Append(_("None"), i);
700  i=new int;
702  m_groupModeChoice->Append(_("Lens"), i);
704  {
705  i=new int;
707  m_groupModeChoice->Append(_("Stacks"), i);
709  {
710  i=new int;
712  m_groupModeChoice->Append(_("Output layers"), i);
713  i=new int;
715  m_groupModeChoice->Append(_("Output stacks"), i);
716  };
717  };
718  if((m_guiLevel==GUI_ADVANCED && sel>2) || (m_guiLevel==GUI_SIMPLE && sel>1))
719  {
720  sel=0;
721  };
722  m_groupModeChoice->SetSelection(sel);
723  wxCommandEvent dummy;
724  OnGroupModeChanged(dummy);
725 };
726 
728 {
730  m_optChoice->Clear();
731  int* i=new int;
733  m_optChoice->Append(_("Positions (incremental, starting from anchor)"), i);
734  i=new int;
736  m_optChoice->Append(_("Positions (y,p,r)"), i);
737  i=new int;
739  m_optChoice->Append(_("Positions and View (y,p,r,v)"), i);
740  i=new int;
742  m_optChoice->Append(_("Positions and Barrel Distortion (y,p,r,b)"), i);
743  i=new int;
745  m_optChoice->Append(_("Positions, View and Barrel (y,p,r,v,b)"), i);
746  i=new int;
749  {
750  m_optChoice->Append(_("Everything without translation"), i);
751  }
752  else
753  {
754  m_optChoice->Append(_("Everything"), i);
755  };
757  {
758  i=new int;
760  m_optChoice->Append(_("Positions and Translation (y,p,r,x,y,z)"), i);
761  i=new int;
763  m_optChoice->Append(_("Positions, Translation and View (y,p,r,x,y,z,v)"), i);
764  i=new int;
766  m_optChoice->Append(_("Positions, Translation and Barrel (y,p,r,x,y,z,b)"), i);
767  i=new int;
769  m_optChoice->Append(_("Positions, Translation, View and Barrel (y,p,r,x,y,z,v,b)"), i);
770  };
771  i=new int;
772  *i=0;
773  m_optChoice->Append(_("Custom parameters"), i);
774 
776  m_optPhotoChoice->Clear();
777  i=new int;
779  m_optPhotoChoice->Append(_("Low dynamic range"), i);
780  i=new int;
782  m_optPhotoChoice->Append(_("Low dynamic range, variable white balance"), i);
784  {
785  i=new int;
787  m_optPhotoChoice->Append(_("High dynamic range, fixed exposure"), i);
788  i=new int;
790  m_optPhotoChoice->Append(_("High dynamic range, variable white balance, fixed exposure"), i);
791  };
792  i=new int;
793  *i=0;
794  m_optPhotoChoice->Append(_("Custom parameters"), i);
795  m_optChoice->GetParent()->Layout();
796  Refresh();
797 };
798 
800 {
801  return m_optChoice->GetString(m_optChoice->GetSelection());
802 };
803 
804 void ImagesPanel::OnGroupModeChanged(wxCommandEvent & e)
805 {
806  ImagesTreeCtrl::GroupMode mode=ImagesTreeCtrl::GroupMode(*static_cast<int*>(m_groupModeChoice->GetClientData(m_groupModeChoice->GetSelection())));
808  XRCCTRL(*this, "images_text_overlap", wxStaticText)->Show(mode==ImagesTreeCtrl::GROUP_OUTPUTSTACK);
811  XRCCTRL(*this, "images_text_maxev", wxStaticText)->Show(mode==ImagesTreeCtrl::GROUP_OUTPUTLAYERS);
814  Layout();
815  Refresh();
816 };
817 
818 void ImagesPanel::OnDisplayModeChanged(wxCommandEvent & e)
819 {
820  wxRadioBox* display=XRCCTRL(*this,"images_column_radiobox", wxRadioBox);
821  m_images_tree->SetDisplayMode((ImagesTreeCtrl::DisplayMode)display->GetSelection());
822 };
823 
825 {
826  int optSwitch=*static_cast<int*>(m_optChoice->GetClientData(m_optChoice->GetSelection()));
827  if(optSwitch!=m_pano->getOptimizerSwitch())
828  {
831  );
832  };
833 };
834 
836 {
837  int optSwitch=*static_cast<int*>(m_optPhotoChoice->GetClientData(m_optPhotoChoice->GetSelection()));
838  if(optSwitch!=m_pano->getPhotometricOptimizerSwitch())
839  {
842  );
843  };
844 };
845 
847 {
848  m_guiLevel=newGuiLevel;
849  m_images_tree->SetGuiLevel(newGuiLevel);
850  FillGroupChoice();
852  wxStaticText* textlabel=XRCCTRL(*this, "images_mode_text", wxStaticText);
853  switch(m_guiLevel)
854  {
855  case GUI_SIMPLE:
856  textlabel->SetLabel(_("Simple interface"));
857  break;
858  case GUI_ADVANCED:
859  textlabel->SetLabel(_("Advanced interface"));
860  break;
861  case GUI_EXPERT:
862  textlabel->SetLabel(_("Expert interface"));
863  break;
864  };
865  textlabel->GetParent()->Layout();
866  textlabel->Refresh();
868 };
869 
870 void ImagesPanel::OnOptimizeButton(wxCommandEvent &e)
871 {
872  hugin_utils::DisableWindow disableButton(XRCCTRL(*this, "images_optimize", wxButton));
874 };
875 
877 {
878  hugin_utils::DisableWindow disableButton(XRCCTRL(*this, "images_photo_optimize", wxButton));
880 };
881 
883 
885  : wxXmlResourceHandler()
886 {
887  AddWindowStyles();
888 }
889 
891 {
892  XRC_MAKE_INSTANCE(cp, ImagesPanel)
893 
894  cp->Create(m_parentAsWindow,
895  GetID(),
896  GetPosition(), GetSize(),
897  GetStyle("style"),
898  GetName());
899 
900  SetupWindow( cp);
901  return cp;
902 }
903 
904 bool ImagesPanelXmlHandler::CanHandle(wxXmlNode *node)
905 {
906  return IsOfClass(node, "ImagesPanel");
907 }
908 
909 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:115
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:1645
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:651
void Init(HuginBase::Panorama *pano)
initialization, connects all control with Panorama, register observer
Definition: ImagesTree.cpp:205
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
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:103
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:2129
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:120
static GlobalCmdHist & getInstance()
void ShowMaskEditor(size_t imgNr, bool switchToCropMode=false)
opens the mask/crop editor with the given image selected
Definition: MainFrame.cpp:2000
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:1589
void SetGuiLevel(GuiLevel newSetting)
sets the GuiLevel of the control
Definition: ImagesTree.cpp:952
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:908
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:90
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
helper class, it disables the control/window in the constructor and automatically enables it back in ...
Definition: wxutils.h:97
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
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL, const wxString &name="panel")
Definition: ImagesPanel.cpp:63
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:36
const wxString GetSelectedCPGenerator()
return the currently selected cp generator description
int HuginMessageBox(const wxString &message, const wxString &caption, int style, wxWindow *parent)
Definition: wxutils.cpp:176
void FillOptimizerChoice()
fills the optmizer wxChoices with values depending on GuiLevel
virtual bool CanHandle(wxXmlNode *node)
void DeleteClientData(wxChoice *cb)