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