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  vigra::ImageImportInfo::ICCProfile iccProfile;
508  // ignore icc profile for float images, because we have already color remapped image
509  if (cacheEntry->imageFloat->width() == 0)
510  {
511  iccProfile = *(cacheEntry->iccProfile);
512  }
514  };
515  wxBitmap scaledBitmap(scaled);
516  // set the DPI scale factor in wxBitmap, otherwise wxStaticBitmap scales the wxBitmap also
517  scaledBitmap.SetScaleFactor(m_smallImgCtrl->GetDPIScaleFactor());
518  m_smallImgCtrl->SetBitmap(scaledBitmap);
519  m_smallImgCtrl->GetParent()->Layout();
520  m_smallImgCtrl->Refresh();
521  }
522 }
523 
525 {
528  m_CPDetectorChoice->InvalidateBestSize();
529  m_CPDetectorChoice->GetParent()->Layout();
530  Refresh();
531 };
532 
533 void ImagesPanel::OnLensTypeChanged (wxCommandEvent & e)
534 {
535  size_t var = GetSelectedValue(m_lenstype);
537  if(!images.empty())
538  {
539  const HuginBase::SrcPanoImage & img = m_pano->getImage(*(images.begin()));
540  double focal_length = HuginBase::SrcPanoImage::calcFocalLength(img.getProjection(), img.getHFOV(), img.getCropFactor(), img.getSize());
541  std::vector<PanoCommand::PanoCommand*> commands;
542  commands.push_back(new PanoCommand::ChangeImageProjectionCmd(*m_pano, images,(HuginBase::SrcPanoImage::Projection) var));
543  commands.push_back(new PanoCommand::UpdateFocalLengthCmd(*m_pano, images, focal_length));
546  );
547  // check if fisheye projections is selected
548  if (wxConfig::Get()->Read("/ShowFisheyeCropHint", 1l) == 1 &&
553  {
554  // if so, show hint about crop and open tab when requested
555  wxDialog dlg;
556  wxXmlResource::Get()->LoadDialog(&dlg, NULL, "fisheye_show_crop_dlg");
557  if (dlg.ShowModal() == wxID_OK)
558  {
559  MainFrame::Get()->ShowMaskEditor(*(images.begin()), true);
560  };
561  if (XRCCTRL(dlg, "fisheye_crop_dont_ask_checkbox", wxCheckBox)->IsChecked())
562  {
563  wxConfig::Get()->Write("/ShowFisheyeCropHint", 0l);
564  };
565  };
566  };
567 };
568 
569 void ImagesPanel::OnFocalLengthChanged(wxCommandEvent & e)
570 {
571  if (m_pano->getNrOfImages() == 0)
572  {
573  return;
574  };
575 
576  wxString text = m_focallength->GetValue();
577  if(text.IsEmpty())
578  {
579  return;
580  };
581  double val;
582  if (!hugin_utils::str2double(text, val))
583  {
584  return;
585  }
586  //no negative values, no zero input please
587  if (val<0.1)
588  {
589  wxBell();
590  return;
591  };
592 
594  const HuginBase::SrcPanoImage& srcImg = m_pano->getImage(*(images.begin()));
595  if (srcImg.getProjection() == HuginBase::SrcPanoImage::FISHEYE_ORTHOGRAPHIC)
596  {
597  double hfov=srcImg.calcHFOV(srcImg.getProjection(), val, srcImg.getCropFactor(), srcImg.getSize());
598  if(hfov>190)
599  {
601  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),
602  _("Hugin"), wxICON_EXCLAMATION | wxYES_NO, this) == wxNO)
603  {
604  wxTreeEvent dummy;
605  OnSelectionChanged(dummy);
606  return;
607  };
608  };
609  };
611  new PanoCommand::UpdateFocalLengthCmd(*m_pano, images, val)
612  );
613 }
614 
615 void ImagesPanel::OnCropFactorChanged(wxCommandEvent & e)
616 {
617  if (m_pano->getNrOfImages() == 0)
618  {
619  return;
620  };
621 
622  wxString text = m_cropfactor->GetValue();
623  if(text.IsEmpty())
624  {
625  return;
626  };
627  double val;
628  if (!hugin_utils::str2double(text, val))
629  {
630  return;
631  }
632  //no negative values, no zero input please
633  if (val<0.1)
634  {
635  wxBell();
636  return;
637  };
638 
642  );
643 }
644 
645 void ImagesPanel::OnMinimumOverlapChanged(wxCommandEvent & e)
646 {
647  wxString text = m_overlap->GetValue();
648  if(text.IsEmpty())
649  {
650  return;
651  };
652  double val;
653  if (!hugin_utils::str2double(text, val))
654  {
655  return;
656  }
657  if(fabs(val)<0.001 || val>1)
658  {
659  hugin_utils::HuginMessageBox(_("The minimum overlap has to be greater than 0 and smaller than 1."),
660  _("Hugin"), wxOK | wxICON_INFORMATION, this);
661  return;
662  };
663  if (val < 0)
664  {
665  val = -1;
666  };
668  opt.outputStacksMinOverlap=val;
671  );
672 };
673 
674 void ImagesPanel::OnMaxEvDiffChanged(wxCommandEvent& e)
675 {
676  wxString text = m_maxEv->GetValue();
677  if(text.IsEmpty())
678  {
679  return;
680  };
681  double val;
682  if (!hugin_utils::str2double(text, val))
683  {
684  return;
685  }
686  if(val<0)
687  {
688  hugin_utils::HuginMessageBox(_("The maximum Ev difference has to be greater than 0."), _("Hugin"), wxOK | wxICON_INFORMATION, this);
689  return;
690  };
692  opt.outputLayersExposureDiff=val;
695  );
696 };
697 
699 {
700  size_t sel=m_groupModeChoice->GetSelection();
702  m_groupModeChoice->Clear();
703  int* i=new int;
705  m_groupModeChoice->Append(_("None"), i);
706  i=new int;
708  m_groupModeChoice->Append(_("Lens"), i);
710  {
711  i=new int;
713  m_groupModeChoice->Append(_("Stacks"), i);
715  {
716  i=new int;
718  m_groupModeChoice->Append(_("Output layers"), i);
719  i=new int;
721  m_groupModeChoice->Append(_("Output stacks"), i);
722  };
723  };
724  if((m_guiLevel==GUI_ADVANCED && sel>2) || (m_guiLevel==GUI_SIMPLE && sel>1))
725  {
726  sel=0;
727  };
728  m_groupModeChoice->SetSelection(sel);
729  wxCommandEvent dummy;
730  OnGroupModeChanged(dummy);
731 };
732 
734 {
736  m_optChoice->Clear();
737  int* i=new int;
739  m_optChoice->Append(_("Positions (incremental, starting from anchor)"), i);
740  i=new int;
742  m_optChoice->Append(_("Positions (y,p,r)"), i);
743  i=new int;
745  m_optChoice->Append(_("Positions and View (y,p,r,v)"), i);
746  i=new int;
748  m_optChoice->Append(_("Positions and Barrel Distortion (y,p,r,b)"), i);
749  i=new int;
751  m_optChoice->Append(_("Positions, View and Barrel (y,p,r,v,b)"), i);
752  i=new int;
755  {
756  m_optChoice->Append(_("Everything without translation"), i);
757  }
758  else
759  {
760  m_optChoice->Append(_("Everything"), i);
761  };
763  {
764  i=new int;
766  m_optChoice->Append(_("Positions and Translation (y,p,r,x,y,z)"), i);
767  i=new int;
769  m_optChoice->Append(_("Positions, Translation and View (y,p,r,x,y,z,v)"), i);
770  i=new int;
772  m_optChoice->Append(_("Positions, Translation and Barrel (y,p,r,x,y,z,b)"), i);
773  i=new int;
775  m_optChoice->Append(_("Positions, Translation, View and Barrel (y,p,r,x,y,z,v,b)"), i);
776  };
777  i=new int;
778  *i=0;
779  m_optChoice->Append(_("Custom parameters"), i);
780 
782  m_optPhotoChoice->Clear();
783  i=new int;
785  m_optPhotoChoice->Append(_("Low dynamic range"), i);
786  i=new int;
788  m_optPhotoChoice->Append(_("Low dynamic range, variable white balance"), i);
790  {
791  i=new int;
793  m_optPhotoChoice->Append(_("High dynamic range, fixed exposure"), i);
794  i=new int;
796  m_optPhotoChoice->Append(_("High dynamic range, variable white balance, fixed exposure"), i);
797  };
798  i=new int;
799  *i=0;
800  m_optPhotoChoice->Append(_("Custom parameters"), i);
801  m_optChoice->GetParent()->Layout();
802  Refresh();
803 };
804 
806 {
807  return m_optChoice->GetString(m_optChoice->GetSelection());
808 };
809 
810 void ImagesPanel::OnGroupModeChanged(wxCommandEvent & e)
811 {
812  ImagesTreeCtrl::GroupMode mode=ImagesTreeCtrl::GroupMode(*static_cast<int*>(m_groupModeChoice->GetClientData(m_groupModeChoice->GetSelection())));
814  XRCCTRL(*this, "images_text_overlap", wxStaticText)->Show(mode==ImagesTreeCtrl::GROUP_OUTPUTSTACK);
817  XRCCTRL(*this, "images_text_maxev", wxStaticText)->Show(mode==ImagesTreeCtrl::GROUP_OUTPUTLAYERS);
820  Layout();
821  Refresh();
822 };
823 
824 void ImagesPanel::OnDisplayModeChanged(wxCommandEvent & e)
825 {
826  wxRadioBox* display=XRCCTRL(*this,"images_column_radiobox", wxRadioBox);
827  m_images_tree->SetDisplayMode((ImagesTreeCtrl::DisplayMode)display->GetSelection());
828 };
829 
831 {
832  int optSwitch=*static_cast<int*>(m_optChoice->GetClientData(m_optChoice->GetSelection()));
833  if(optSwitch!=m_pano->getOptimizerSwitch())
834  {
837  );
838  };
839 };
840 
842 {
843  int optSwitch=*static_cast<int*>(m_optPhotoChoice->GetClientData(m_optPhotoChoice->GetSelection()));
844  if(optSwitch!=m_pano->getPhotometricOptimizerSwitch())
845  {
848  );
849  };
850 };
851 
853 {
854  m_guiLevel=newGuiLevel;
855  m_images_tree->SetGuiLevel(newGuiLevel);
856  FillGroupChoice();
858  wxStaticText* textlabel=XRCCTRL(*this, "images_mode_text", wxStaticText);
859  switch(m_guiLevel)
860  {
861  case GUI_SIMPLE:
862  textlabel->SetLabel(_("Simple interface"));
863  break;
864  case GUI_ADVANCED:
865  textlabel->SetLabel(_("Advanced interface"));
866  break;
867  case GUI_EXPERT:
868  textlabel->SetLabel(_("Expert interface"));
869  break;
870  };
871  textlabel->GetParent()->Layout();
872  textlabel->Refresh();
874 };
875 
876 void ImagesPanel::OnOptimizeButton(wxCommandEvent &e)
877 {
878  hugin_utils::DisableWindow disableButton(XRCCTRL(*this, "images_optimize", wxButton));
880 };
881 
883 {
884  hugin_utils::DisableWindow disableButton(XRCCTRL(*this, "images_photo_optimize", wxButton));
886 };
887 
889 
891  : wxXmlResourceHandler()
892 {
893  AddWindowStyles();
894 }
895 
897 {
898  XRC_MAKE_INSTANCE(cp, ImagesPanel)
899 
900  cp->Create(m_parentAsWindow,
901  GetID(),
902  GetPosition(), GetSize(),
903  GetStyle("style"),
904  GetName());
905 
906  SetupWindow( cp);
907  return cp;
908 }
909 
910 bool ImagesPanelXmlHandler::CanHandle(wxXmlNode *node)
911 {
912  return IsOfClass(node, "ImagesPanel");
913 }
914 
915 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
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 GetMonitorProfile(wxString &profileName, cmsHPROFILE &profile)
Definition: wxcms.cpp:195
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:2130
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:2001
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)