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  // set the DPI scale factor in wxBitmap, otherwise wxStaticBitmap scales the wxBitmap also
514  scaledBitmap.SetScaleFactor(m_smallImgCtrl->GetDPIScaleFactor());
515  m_smallImgCtrl->SetBitmap(scaledBitmap);
516  m_smallImgCtrl->GetParent()->Layout();
517  m_smallImgCtrl->Refresh();
518  }
519 }
520 
522 {
525  m_CPDetectorChoice->InvalidateBestSize();
526  m_CPDetectorChoice->GetParent()->Layout();
527  Refresh();
528 };
529 
530 void ImagesPanel::OnLensTypeChanged (wxCommandEvent & e)
531 {
532  size_t var = GetSelectedValue(m_lenstype);
534  if(!images.empty())
535  {
536  const HuginBase::SrcPanoImage & img = m_pano->getImage(*(images.begin()));
537  double focal_length = HuginBase::SrcPanoImage::calcFocalLength(img.getProjection(), img.getHFOV(), img.getCropFactor(), img.getSize());
538  std::vector<PanoCommand::PanoCommand*> commands;
539  commands.push_back(new PanoCommand::ChangeImageProjectionCmd(*m_pano, images,(HuginBase::SrcPanoImage::Projection) var));
540  commands.push_back(new PanoCommand::UpdateFocalLengthCmd(*m_pano, images, focal_length));
543  );
544  // check if fisheye projections is selected
545  if (wxConfig::Get()->Read(wxT("/ShowFisheyeCropHint"), 1l) == 1 &&
550  {
551  // if so, show hint about crop and open tab when requested
552  wxDialog dlg;
553  wxXmlResource::Get()->LoadDialog(&dlg, NULL, wxT("fisheye_show_crop_dlg"));
554  if (dlg.ShowModal() == wxID_OK)
555  {
556  MainFrame::Get()->ShowMaskEditor(*(images.begin()), true);
557  };
558  if (XRCCTRL(dlg, "fisheye_crop_dont_ask_checkbox", wxCheckBox)->IsChecked())
559  {
560  wxConfig::Get()->Write(wxT("/ShowFisheyeCropHint"), 0l);
561  };
562  };
563  };
564 };
565 
566 void ImagesPanel::OnFocalLengthChanged(wxCommandEvent & e)
567 {
568  if (m_pano->getNrOfImages() == 0)
569  {
570  return;
571  };
572 
573  wxString text = m_focallength->GetValue();
574  if(text.IsEmpty())
575  {
576  return;
577  };
578  double val;
579  if (!hugin_utils::str2double(text, val))
580  {
581  return;
582  }
583  //no negative values, no zero input please
584  if (val<0.1)
585  {
586  wxBell();
587  return;
588  };
589 
591  const HuginBase::SrcPanoImage& srcImg = m_pano->getImage(*(images.begin()));
592  if (srcImg.getProjection() == HuginBase::SrcPanoImage::FISHEYE_ORTHOGRAPHIC)
593  {
594  double hfov=srcImg.calcHFOV(srcImg.getProjection(), val, srcImg.getCropFactor(), srcImg.getSize());
595  if(hfov>190)
596  {
597  if(wxMessageBox(
598  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),
599 #ifdef __WXMSW__
600  _("Hugin"),
601 #else
602  wxT(""),
603 #endif
604  wxICON_EXCLAMATION | wxYES_NO)==wxNO)
605  {
606  wxTreeEvent dummy;
607  OnSelectionChanged(dummy);
608  return;
609  };
610  };
611  };
613  new PanoCommand::UpdateFocalLengthCmd(*m_pano, images, val)
614  );
615 }
616 
617 void ImagesPanel::OnCropFactorChanged(wxCommandEvent & e)
618 {
619  if (m_pano->getNrOfImages() == 0)
620  {
621  return;
622  };
623 
624  wxString text = m_cropfactor->GetValue();
625  if(text.IsEmpty())
626  {
627  return;
628  };
629  double val;
630  if (!hugin_utils::str2double(text, val))
631  {
632  return;
633  }
634  //no negative values, no zero input please
635  if (val<0.1)
636  {
637  wxBell();
638  return;
639  };
640 
644  );
645 }
646 
647 void ImagesPanel::OnMinimumOverlapChanged(wxCommandEvent & e)
648 {
649  wxString text = m_overlap->GetValue();
650  if(text.IsEmpty())
651  {
652  return;
653  };
654  double val;
655  if (!hugin_utils::str2double(text, val))
656  {
657  return;
658  }
659  if(fabs(val)<0.001 || val>1)
660  {
661  wxMessageBox(_("The minimum overlap has to be greater than 0 and smaller than 1."),
662 #ifdef _WIN32
663  _("Hugin"),
664 #else
665  wxT(""),
666 #endif
667  wxOK | wxICON_INFORMATION, this);
668  return;
669  };
670  if (val < 0)
671  {
672  val = -1;
673  };
675  opt.outputStacksMinOverlap=val;
678  );
679 };
680 
681 void ImagesPanel::OnMaxEvDiffChanged(wxCommandEvent& e)
682 {
683  wxString text = m_maxEv->GetValue();
684  if(text.IsEmpty())
685  {
686  return;
687  };
688  double val;
689  if (!hugin_utils::str2double(text, val))
690  {
691  return;
692  }
693  if(val<0)
694  {
695  wxMessageBox(_("The maximum Ev difference has to be greater than 0."),
696 #ifdef _WIN32
697  _("Hugin"),
698 #else
699  wxT(""),
700 #endif
701  wxOK | wxICON_INFORMATION, this);
702  return;
703  };
705  opt.outputLayersExposureDiff=val;
708  );
709 };
710 
712 {
713  wxChoice* group=XRCCTRL(*this,"images_group_mode", wxChoice);
714  size_t sel=group->GetSelection();
715  DeleteClientData(group);
716  group->Clear();
717  int* i=new int;
719  group->Append(_("None"), i);
720  i=new int;
722  group->Append(_("Lens"), i);
724  {
725  i=new int;
727  group->Append(_("Stacks"), i);
729  {
730  i=new int;
732  group->Append(_("Output layers"), i);
733  i=new int;
735  group->Append(_("Output stacks"), i);
736  };
737  };
738  if((m_guiLevel==GUI_ADVANCED && sel>2) || (m_guiLevel==GUI_SIMPLE && sel>1))
739  {
740  sel=0;
741  };
742  group->SetSelection(sel);
743  wxCommandEvent dummy;
744  OnGroupModeChanged(dummy);
745 };
746 
748 {
750  m_optChoice->Clear();
751  int* i=new int;
753  m_optChoice->Append(_("Positions (incremental, starting from anchor)"), i);
754  i=new int;
756  m_optChoice->Append(_("Positions (y,p,r)"), i);
757  i=new int;
759  m_optChoice->Append(_("Positions and View (y,p,r,v)"), i);
760  i=new int;
762  m_optChoice->Append(_("Positions and Barrel Distortion (y,p,r,b)"), i);
763  i=new int;
765  m_optChoice->Append(_("Positions, View and Barrel (y,p,r,v,b)"), i);
766  i=new int;
769  {
770  m_optChoice->Append(_("Everything without translation"), i);
771  }
772  else
773  {
774  m_optChoice->Append(_("Everything"), i);
775  };
777  {
778  i=new int;
780  m_optChoice->Append(_("Positions and Translation (y,p,r,x,y,z)"), i);
781  i=new int;
783  m_optChoice->Append(_("Positions, Translation and View (y,p,r,x,y,z,v)"), i);
784  i=new int;
786  m_optChoice->Append(_("Positions, Translation and Barrel (y,p,r,x,y,z,b)"), i);
787  i=new int;
789  m_optChoice->Append(_("Positions, Translation, View and Barrel (y,p,r,x,y,z,v,b)"), i);
790  };
791  i=new int;
792  *i=0;
793  m_optChoice->Append(_("Custom parameters"), i);
794 
796  m_optPhotoChoice->Clear();
797  i=new int;
799  m_optPhotoChoice->Append(_("Low dynamic range"), i);
800  i=new int;
802  m_optPhotoChoice->Append(_("Low dynamic range, variable white balance"), i);
804  {
805  i=new int;
807  m_optPhotoChoice->Append(_("High dynamic range, fixed exposure"), i);
808  i=new int;
810  m_optPhotoChoice->Append(_("High dynamic range, variable white balance, fixed exposure"), i);
811  };
812  i=new int;
813  *i=0;
814  m_optPhotoChoice->Append(_("Custom parameters"), i);
815  m_optChoice->GetParent()->Layout();
816  Refresh();
817 };
818 
820 {
821  return m_optChoice->GetString(m_optChoice->GetSelection());
822 };
823 
824 void ImagesPanel::OnGroupModeChanged(wxCommandEvent & e)
825 {
826  wxChoice* group=XRCCTRL(*this,"images_group_mode", wxChoice);
827  ImagesTreeCtrl::GroupMode mode=ImagesTreeCtrl::GroupMode(*static_cast<int*>(group->GetClientData(group->GetSelection())));
829  XRCCTRL(*this, "images_text_overlap", wxStaticText)->Show(mode==ImagesTreeCtrl::GROUP_OUTPUTSTACK);
832  XRCCTRL(*this, "images_text_maxev", wxStaticText)->Show(mode==ImagesTreeCtrl::GROUP_OUTPUTLAYERS);
835  Layout();
836  Refresh();
837 };
838 
839 void ImagesPanel::OnDisplayModeChanged(wxCommandEvent & e)
840 {
841  wxRadioBox* display=XRCCTRL(*this,"images_column_radiobox", wxRadioBox);
842  m_images_tree->SetDisplayMode((ImagesTreeCtrl::DisplayMode)display->GetSelection());
843 };
844 
846 {
847  int optSwitch=*static_cast<int*>(m_optChoice->GetClientData(m_optChoice->GetSelection()));
848  if(optSwitch!=m_pano->getOptimizerSwitch())
849  {
852  );
853  };
854 };
855 
857 {
858  int optSwitch=*static_cast<int*>(m_optPhotoChoice->GetClientData(m_optPhotoChoice->GetSelection()));
859  if(optSwitch!=m_pano->getPhotometricOptimizerSwitch())
860  {
863  );
864  };
865 };
866 
868 {
869  m_guiLevel=newGuiLevel;
870  m_images_tree->SetGuiLevel(newGuiLevel);
871  FillGroupChoice();
873  wxStaticText* textlabel=XRCCTRL(*this, "images_mode_text", wxStaticText);
874  switch(m_guiLevel)
875  {
876  case GUI_SIMPLE:
877  textlabel->SetLabel(_("Simple interface"));
878  break;
879  case GUI_ADVANCED:
880  textlabel->SetLabel(_("Advanced interface"));
881  break;
882  case GUI_EXPERT:
883  textlabel->SetLabel(_("Expert interface"));
884  break;
885  };
886  textlabel->GetParent()->Layout();
887  textlabel->Refresh();
889 };
890 
891 void ImagesPanel::OnOptimizeButton(wxCommandEvent &e)
892 {
894 };
895 
897 {
899 };
900 
902 
904  : wxXmlResourceHandler()
905 {
906  AddWindowStyles();
907 }
908 
910 {
911  XRC_MAKE_INSTANCE(cp, ImagesPanel)
912 
913  cp->Create(m_parentAsWindow,
914  GetID(),
915  GetPosition(), GetSize(),
916  GetStyle(wxT("style")),
917  GetName());
918 
919  SetupWindow( cp);
920  return cp;
921 }
922 
923 bool ImagesPanelXmlHandler::CanHandle(wxXmlNode *node)
924 {
925  return IsOfClass(node, wxT("ImagesPanel"));
926 }
927 
928 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:147
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:1685
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:641
void Init(HuginBase::Panorama *pano)
initialization, connects all control with Panorama, register observer
Definition: ImagesTree.cpp:213
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:2169
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:152
static GlobalCmdHist & getInstance()
void ShowMaskEditor(size_t imgNr, bool switchToCropMode=false)
opens the mask/crop editor with the given image selected
Definition: MainFrame.cpp:2040
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:1629
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: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)