ImagesPanel.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00002 
00028 #include <config.h>
00029 #include "panoinc_WX.h"
00030 #include "panoinc.h"
00031 #include <time.h>
00032 
00033 #include "base_wx/platform.h"
00034 #include "base_wx/wxPlatform.h"
00035 #include <vector>
00036 #include <map>
00037 
00038 #include "hugin/ImagesPanel.h"
00039 #include "hugin/CommandHistory.h"
00040 #include "hugin/TextKillFocusHandler.h"
00041 #include "hugin/CPEditorPanel.h"
00042 #include "hugin/ImagesList.h"
00043 #include "hugin/MainFrame.h"
00044 #include "hugin/huginApp.h"
00045 #include "icpfind/AutoCtrlPointCreator.h"
00046 #include "hugin/config_defaults.h"
00047 #include "base_wx/MyProgressDialog.h"
00048 #include "base_wx/PTWXDlg.h"
00049 #include <PT/PTOptimise.h>
00050 #include "base_wx/LensTools.h"
00051 #include "hugin/ImagesTree.h"
00052 #include "panodata/OptimizerSwitches.h"
00053 
00054 #include <panodata/StandardImageVariableGroups.h>
00055 
00056 using namespace PT;
00057 using namespace hugin_utils;
00058 using namespace vigra;
00059 using namespace vigra_ext;
00060 using namespace std;
00061 
00062 BEGIN_EVENT_TABLE(ImagesPanel, wxPanel)
00063     EVT_TREE_SEL_CHANGED(XRCID("images_tree_ctrl"), ImagesPanel::OnSelectionChanged )
00064     EVT_CHOICE     ( XRCID("images_lens_type"), ImagesPanel::OnLensTypeChanged)
00065     EVT_CHOICE     ( XRCID("images_group_mode"), ImagesPanel::OnGroupModeChanged)
00066     EVT_RADIOBOX   ( XRCID("images_column_radiobox"), ImagesPanel::OnDisplayModeChanged)
00067     EVT_CHOICE     ( XRCID("images_optimize_mode"), ImagesPanel::OnOptimizerSwitchChanged)
00068     EVT_CHOICE     ( XRCID("images_photo_optimize_mode"), ImagesPanel::OnPhotometricOptimizerSwitchChanged)
00069     EVT_TEXT_ENTER ( XRCID("images_focal_length"), ImagesPanel::OnFocalLengthChanged)
00070     EVT_TEXT_ENTER ( XRCID("images_crop_factor"),  ImagesPanel::OnCropFactorChanged)
00071     EVT_TEXT_ENTER ( XRCID("images_overlap"), ImagesPanel::OnMinimumOverlapChanged)
00072     EVT_TEXT_ENTER ( XRCID("images_maxev"), ImagesPanel::OnMaxEvDiffChanged)
00073     EVT_BUTTON     ( XRCID("images_feature_matching"), ImagesPanel::CPGenerate)
00074     EVT_BUTTON     ( XRCID("images_optimize"), ImagesPanel::OnOptimizeButton)
00075     EVT_BUTTON     ( XRCID("images_photo_optimize"), ImagesPanel::OnPhotometricOptimizeButton)
00076 END_EVENT_TABLE()
00077 
00078 ImagesPanel::ImagesPanel()
00079 {
00080     m_pano = 0;
00081     m_guiLevel=GUI_SIMPLE;
00082 }
00083 
00084 bool ImagesPanel::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
00085                       long style, const wxString& name)
00086 {
00087     if (! wxPanel::Create(parent, id, pos, size, style, name)) {
00088         return false;
00089     }
00090 
00091     wxXmlResource::Get()->LoadPanel(this, wxT("images_panel"));
00092     wxPanel * panel = XRCCTRL(*this, "images_panel", wxPanel);
00093     wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
00094     topsizer->Add(panel, 1, wxEXPAND, 0);
00095     SetSizer(topsizer);
00096 
00097     m_images_tree = XRCCTRL(*this, "images_tree_ctrl", ImagesTreeCtrl);
00098     DEBUG_ASSERT(m_images_tree);
00099 
00100     m_showImgNr = INT_MAX;
00101 
00102     m_matchingButton = XRCCTRL(*this, "images_feature_matching", wxButton);
00103     DEBUG_ASSERT(m_matchingButton);
00104 
00105     m_CPDetectorChoice = XRCCTRL(*this, "cpdetector_settings", wxChoice);
00106 
00107     // Image Preview
00108     m_smallImgCtrl = XRCCTRL(*this, "images_selected_image", wxStaticBitmap);
00109     DEBUG_ASSERT(m_smallImgCtrl);
00110 
00111     m_empty.Create(0,0);
00112     m_smallImgCtrl->SetBitmap(m_empty);
00113 
00114     m_lenstype = XRCCTRL(*this, "images_lens_type", wxChoice);
00115     DEBUG_ASSERT(m_lenstype);
00116     FillLensProjectionList(m_lenstype);
00117     m_lenstype->SetSelection(0);
00118 
00119     m_focallength = XRCCTRL(*this, "images_focal_length", wxTextCtrl);
00120     DEBUG_ASSERT(m_focallength);
00121     m_focallength->PushEventHandler(new TextKillFocusHandler(this));
00122 
00123     m_cropfactor = XRCCTRL(*this, "images_crop_factor", wxTextCtrl);
00124     DEBUG_ASSERT(m_cropfactor);
00125     m_cropfactor->PushEventHandler(new TextKillFocusHandler(this));
00126 
00127     m_overlap = XRCCTRL(*this, "images_overlap", wxTextCtrl);
00128     DEBUG_ASSERT(m_overlap);
00129     m_overlap->PushEventHandler(new TextKillFocusHandler(this));
00130 
00131     m_maxEv = XRCCTRL(*this, "images_maxev", wxTextCtrl);
00132     DEBUG_ASSERT(m_maxEv);
00133     m_maxEv->PushEventHandler(new TextKillFocusHandler(this));
00134 
00135     FillGroupChoice();
00136 
00137     wxTreeEvent ev;
00138     OnSelectionChanged(ev);
00139     DEBUG_TRACE("end");
00140 
00141     m_optChoice = XRCCTRL(*this, "images_optimize_mode", wxChoice);
00142     DEBUG_ASSERT(m_optChoice);
00143 
00144     m_optPhotoChoice = XRCCTRL(*this, "images_photo_optimize_mode", wxChoice);
00145     DEBUG_ASSERT(m_optPhotoChoice);
00146 
00147     FillOptimizerChoice();
00148 
00149     wxConfigBase* config=wxConfigBase::Get();
00150     m_degDigits = config->Read(wxT("/General/DegreeFractionalDigitsEdit"),3);
00151     //read autopano generator settings
00152     cpdetector_config.Read(config,huginApp::Get()->GetDataPath()+wxT("default.setting"));
00153     //write current autopano generator settings
00154     cpdetector_config.Write(config);
00155     config->Flush();
00156     cpdetector_config.FillControl(m_CPDetectorChoice,true);
00157     Layout();
00158 
00159     return true;
00160 }
00161 
00162 void ImagesPanel::Init(Panorama * panorama)
00163 {
00164     m_pano = panorama;
00165     m_images_tree->Init(m_pano);
00166     // observe the panorama
00167     m_pano->addObserver(this);
00168 }
00169 
00170 void DeleteClientData(wxChoice* cb)
00171 {
00172     if(cb->HasClientUntypedData())
00173     {
00174         for(size_t i = 0; i < cb->GetCount(); i++)
00175         {
00176             delete static_cast<int*>(cb->GetClientData(i));
00177         };
00178     };
00179 };
00180 
00181 ImagesPanel::~ImagesPanel()
00182 {
00183     DEBUG_TRACE("dtor");
00184     m_focallength->PopEventHandler(true);
00185     m_cropfactor->PopEventHandler(true);
00186     m_overlap->PopEventHandler(true);
00187     m_maxEv->PopEventHandler(true);
00188     m_pano->removeObserver(this);
00189     wxChoice* group=XRCCTRL(*this,"images_group_mode", wxChoice);
00190     size_t sel=group->GetSelection();
00191     DeleteClientData(group);
00192     DeleteClientData(m_optChoice);
00193     DeleteClientData(m_optPhotoChoice);
00194     DEBUG_TRACE("dtor end");
00195 }
00196 
00197 // We need to override the default handling of size events because the
00198 // sizers set the virtual size but not the actual size. We reverse
00199 // the standard handling and fit the child to the parent rather than
00200 // fitting the parent around the child
00201 
00202 void ImagesPanel::OnSize( wxSizeEvent & e )
00203 {
00204     int winWidth, winHeight;
00205     GetClientSize(&winWidth, &winHeight);
00206     DEBUG_INFO( "image panel: " << winWidth <<"x"<< winHeight );
00207     UpdatePreviewImage();
00208 
00209     e.Skip();
00210 }
00211 
00212 void ImagesPanel::panoramaChanged(PT::Panorama & pano)
00213 {
00214     //update optimizer choice selection
00215     int optSwitch=m_pano->getOptimizerSwitch();
00216     int found=wxNOT_FOUND;
00217     for(size_t i=0;i<m_optChoice->GetCount();i++)
00218     {
00219         if(optSwitch==*static_cast<int*>(m_optChoice->GetClientData(i)))
00220         {
00221             found=i;
00222             break;
00223         };
00224     };
00225     if(found==wxNOT_FOUND)
00226     {
00227         GlobalCmdHist::getInstance().addCommand(
00228             new PT::UpdateOptimizerSwitchCmd(*m_pano, 0)
00229         );
00230     }
00231     else
00232     {
00233         m_optChoice->SetSelection(found);
00234     };
00235 
00236     //update photometric optimizer choice selection
00237     optSwitch=m_pano->getPhotometricOptimizerSwitch();
00238     found=wxNOT_FOUND;
00239     for(size_t i=0;i<m_optPhotoChoice->GetCount();i++)
00240     {
00241         if(optSwitch==*static_cast<int*>(m_optPhotoChoice->GetClientData(i)))
00242         {
00243             found=i;
00244             break;
00245         };
00246     };
00247     if(found==wxNOT_FOUND)
00248     {
00249         GlobalCmdHist::getInstance().addCommand(
00250             new PT::UpdatePhotometricOptimizerSwitchCmd(*m_pano, 0)
00251         );
00252     }
00253     else
00254     {
00255         m_optPhotoChoice->SetSelection(found);
00256     };
00257     const PanoramaOptions opts=m_pano->getOptions();
00258     m_overlap->SetValue(hugin_utils::doubleTowxString(opts.outputStacksMinOverlap,3));
00259     m_maxEv->SetValue(hugin_utils::doubleTowxString(opts.outputLayersExposureDiff,2));
00260 }
00261 
00262 void ImagesPanel::panoramaImagesChanged(PT::Panorama &pano, const PT::UIntSet & _imgNr)
00263 {
00264     DEBUG_TRACE("");
00265 
00266     // update text field if selected
00267     const UIntSet & selected = m_images_tree->GetSelectedImages();
00268     DEBUG_DEBUG("nr of sel Images: " << selected.size());
00269     if (pano.getNrOfImages() == 0)
00270     {
00271         DisableImageCtrls();
00272         m_matchingButton->Disable();
00273     }
00274     else
00275     {
00276         m_matchingButton->Enable();
00277         wxTreeEvent ev;
00278         OnSelectionChanged(ev);
00279     };
00280     //enable/disable optimize buttons
00281     XRCCTRL(*this, "images_optimize", wxButton)->Enable(pano.getNrOfImages()>0);
00282     XRCCTRL(*this, "images_photo_optimize", wxButton)->Enable(pano.getNrOfImages()>1);
00283 }
00284 
00285 // #####  Here start the eventhandlers  #####
00286 
00288 void ImagesPanel::CPGenerate(wxCommandEvent & e)
00289 {
00290     UIntSet selImg = m_images_tree->GetSelectedImages();
00291     //if only one image is selected, run detector on all images, except for linefind
00292     wxString progName=cpdetector_config.settings[m_CPDetectorChoice->GetSelection()].GetProg().Lower();
00293     if ((selImg.size()==0) || (selImg.size()==1 && progName.Find(wxT("linefind"))==wxNOT_FOUND))
00294     {
00295         // add all images.
00296         selImg.clear();
00297         fill_set(selImg,0,m_pano->getNrOfImages()-1);
00298     }
00299 
00300     if (selImg.size() == 0)
00301     {
00302         return;
00303     }
00304 
00305     wxConfigBase* config=wxConfigBase::Get();
00306     long nFeatures = HUGIN_ASS_NCONTROLPOINTS;
00307 #if wxCHECK_VERSION(2,9,4)
00308     if(wxGetKeyState(WXK_COMMAND))
00309 #else
00310     if(wxGetKeyState(WXK_CONTROL))
00311 #endif
00312     {
00313         nFeatures = config->Read(wxT("/MainFrame/nControlPoints"), HUGIN_ASS_NCONTROLPOINTS);
00314         nFeatures = wxGetNumberFromUser(
00315                             _("Enter maximal number of control points per image pair"),
00316                             _("Points per Overlap"),
00317                             _("Control point detector option"), 
00318                             nFeatures, 1, 10000
00319                                  );
00320         if(nFeatures<1)
00321         {
00322             return;
00323         };
00324         config->Write(wxT("/MainFrame/nControlPoints"), nFeatures);
00325     }
00326     else
00327     {
00328         nFeatures = config->Read(wxT("/Assistant/nControlPoints"), HUGIN_ASS_NCONTROLPOINTS);
00329     };
00330 
00331     AutoCtrlPointCreator matcher;
00332     CPVector cps = matcher.automatch(cpdetector_config.settings[m_CPDetectorChoice->GetSelection()],
00333         *m_pano, selImg, nFeatures,this);
00334     wxString msg;
00335     wxMessageBox(wxString::Format(_("Added %lu control points"), (unsigned long) cps.size()), _("Control point detector result"),wxOK|wxICON_INFORMATION,this);
00336     GlobalCmdHist::getInstance().addCommand(
00337             new PT::AddCtrlPointsCmd(*m_pano, cps)
00338                                            );
00339 
00340 };
00341 
00342 void ImagesPanel::OnSelectionChanged(wxTreeEvent & e)
00343 {
00344     const UIntSet & sel = m_images_tree->GetSelectedImages();
00345     DEBUG_DEBUG("selected Images: " << sel.size());
00346     if (sel.size() == 0)
00347     {
00348         // nothing to edit
00349         DisableImageCtrls();
00350     }
00351     else
00352     {
00353         // enable edit
00354         EnableImageCtrls();
00355         const SrcPanoImage& img=m_pano->getImage(*sel.begin());
00356         bool identical_projection=true;
00357         SrcPanoImage::Projection proj=img.getProjection();
00358         double focallength=SrcPanoImage::calcFocalLength(img.getProjection(),img.getHFOV(),
00359                 img.getExifCropFactor(),img.getSize());;
00360         double cropFactor=img.getExifCropFactor();
00361         for(UIntSet::const_iterator it=sel.begin(); it!=sel.end(); it++)
00362         {
00363             const SrcPanoImage& img2=m_pano->getImage(*it);
00364             if(proj!=img2.getProjection())
00365             {
00366                 identical_projection=false;
00367             };
00368             double focallength2 = SrcPanoImage::calcFocalLength(img2.getProjection(),img2.getHFOV(),
00369                 img2.getExifCropFactor(),img2.getSize());
00370             if(focallength>0 && fabs(focallength-focallength2)>0.05)
00371             {
00372                 focallength=-1;
00373             };
00374             if(fabs(cropFactor-img2.getExifCropFactor())>0.1)
00375             {
00376                 cropFactor=-1;
00377             };
00378         };
00379 
00380         if(identical_projection)
00381         {
00382             SelectProjection(m_lenstype, proj);
00383         }
00384         else
00385         {
00386             m_lenstype->Select(wxNOT_FOUND);
00387         };
00388         if(focallength>0)
00389         {
00390             m_focallength->SetValue(hugin_utils::doubleTowxString(focallength,m_degDigits));
00391         }
00392         else
00393         {
00394             m_focallength->Clear();
00395         };
00396         if(cropFactor>0)
00397         {
00398             m_cropfactor->SetValue(doubleTowxString(cropFactor,m_degDigits));
00399         }
00400         else
00401         {
00402             m_cropfactor->Clear();
00403         };
00404 
00405         if (sel.size() == 1)
00406         {
00407             ShowImage(*(sel.begin()));
00408         }
00409         else
00410         {
00411             m_smallImgCtrl->SetBitmap(m_empty);
00412             m_smallImgCtrl->GetParent()->Layout();
00413             m_smallImgCtrl->Refresh();
00414         };
00415     }
00416 }
00417 
00418 void ImagesPanel::DisableImageCtrls()
00419 {
00420     // disable controls
00421     m_lenstype->Disable();
00422     m_focallength->Disable();
00423     m_cropfactor->Disable();
00424     m_smallImgCtrl->SetBitmap(m_empty);
00425     m_smallImgCtrl->GetParent()->Layout();
00426     m_smallImgCtrl->Refresh();
00427 }
00428 
00429 void ImagesPanel::EnableImageCtrls()
00430 {
00431     // enable control if not already enabled
00432     m_lenstype->Enable();
00433     m_focallength->Enable();
00434     m_cropfactor->Enable();
00435 }
00436 
00437 void ImagesPanel::ShowImage(unsigned int imgNr)
00438 {
00439     m_showImgNr = imgNr;
00440     UpdatePreviewImage();
00441 }
00442 
00443 void ImagesPanel::UpdatePreviewImage()
00444 {
00445     if (m_showImgNr < 0 || m_showImgNr >= m_pano->getNrOfImages())
00446     {
00447         return;
00448     }
00449     ImageCache::EntryPtr cacheEntry = ImageCache::getInstance().getSmallImageIfAvailable(
00450             m_pano->getImage(m_showImgNr).getFilename());
00451     if (!cacheEntry.get())
00452     {
00453         // image currently isn't loaded.
00454         // Instead of loading and displaying the image now, request it for
00455         // later. Then the user can switch between images in the list quickly,
00456         // even when not all images previews are in the cache.
00457         thumbnail_request = ImageCache::getInstance().requestAsyncSmallImage(
00458                 m_pano->getImage(m_showImgNr).getFilename());
00459         // When the image is ready, try this function again.
00460         thumbnail_request->ready.connect(
00461             boost::bind(&ImagesPanel::UpdatePreviewImage, this));
00462     } else {
00463         // forget any request now the image has loaded.
00464         thumbnail_request = ImageCache::RequestPtr();
00465         wxImage img = imageCacheEntry2wxImage(cacheEntry); 
00466 
00467         double iRatio = img.GetWidth() / (double) img.GetHeight();
00468 
00469         wxSize sz;
00470         // estimate image size
00471         
00472         sz = m_smallImgCtrl->GetContainingSizer()->GetSize();
00473         double sRatio = (double)sz.GetWidth() / sz.GetHeight();
00474         if (iRatio > sRatio) {
00475             // image is wider than screen, display landscape
00476             sz.SetHeight((int) (sz.GetWidth() / iRatio));
00477         } else {
00478             // portrait
00479             sz.SetWidth((int) (sz.GetHeight() * iRatio));
00480         }
00481         // Make sure the size is positive:
00482         // on a small window, m_smallImgCtrl can have 0 width.
00483         sz.IncTo(wxSize(1,1));
00484         wxImage scaled = img.Scale(sz.GetWidth(),sz.GetHeight());
00485         m_smallImgCtrl->SetBitmap(wxBitmap(scaled));
00486         m_smallImgCtrl->GetParent()->Layout();
00487         m_smallImgCtrl->Refresh();
00488     }
00489 }
00490 
00491 void ImagesPanel::ReloadCPDetectorSettings()
00492 {
00493     cpdetector_config.Read(); 
00494     cpdetector_config.FillControl(m_CPDetectorChoice,true);
00495     m_CPDetectorChoice->InvalidateBestSize();
00496     m_CPDetectorChoice->GetParent()->Layout();
00497     Refresh();
00498 };
00499 
00500 void ImagesPanel::OnLensTypeChanged (wxCommandEvent & e)
00501 {
00502     size_t var = GetSelectedProjection(m_lenstype);
00503     UIntSet images=m_images_tree->GetSelectedImages();
00504     if(images.size()>0)
00505     {
00506         const SrcPanoImage & img=m_pano->getImage(*(images.begin()));
00507         double focal_length = SrcPanoImage::calcFocalLength(img.getProjection(),img.getHFOV(),img.getExifCropFactor(),img.getSize());
00508         std::vector<PanoCommand*> commands;
00509         commands.push_back(new PT::ChangeImageProjectionCmd(*m_pano, images,(HuginBase::SrcPanoImage::Projection) var));
00510         commands.push_back(new PT::UpdateFocalLengthCmd(*m_pano, images, focal_length));
00511         GlobalCmdHist::getInstance().addCommand(
00512             new PT::CombinedPanoCommand(*m_pano, commands)
00513         );
00514     };
00515 };
00516 
00517 void ImagesPanel::OnFocalLengthChanged(wxCommandEvent & e)
00518 {
00519     if (m_pano->getNrOfImages() == 0)
00520     {
00521         return;
00522     };
00523 
00524     wxString text = m_focallength->GetValue();
00525     if(text.IsEmpty())
00526     {
00527         return;
00528     };
00529     double val;
00530     if (!str2double(text, val))
00531     {
00532         return;
00533     }
00534     //no negative values, no zero input please
00535     if (val<0.1)
00536     {
00537         wxBell();
00538         return;
00539     };
00540     
00541     UIntSet images=m_images_tree->GetSelectedImages();
00542     const SrcPanoImage& srcImg=m_pano->getImage(*(images.begin()));
00543     if(srcImg.getProjection()==SrcPanoImage::FISHEYE_ORTHOGRAPHIC)
00544     {
00545         double hfov=srcImg.calcHFOV(srcImg.getProjection(), val, srcImg.getExifCropFactor(), srcImg.getSize());
00546         if(hfov>190)
00547         {
00548             if(wxMessageBox(
00549                 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),
00550 #ifdef __WXMSW__
00551                 _("Hugin"),
00552 #else
00553                 wxT(""),
00554 #endif
00555                 wxICON_EXCLAMATION | wxYES_NO)==wxNO)
00556             {
00557                 wxTreeEvent dummy;
00558                 OnSelectionChanged(dummy);
00559                 return;
00560             };
00561         };
00562     };
00563     GlobalCmdHist::getInstance().addCommand(
00564         new PT::UpdateFocalLengthCmd(*m_pano, images, val)
00565     );
00566 }
00567 
00568 void ImagesPanel::OnCropFactorChanged(wxCommandEvent & e)
00569 {
00570     if (m_pano->getNrOfImages() == 0)
00571     {
00572         return;
00573     };
00574 
00575     wxString text = m_cropfactor->GetValue();
00576     if(text.IsEmpty())
00577     {
00578         return;
00579     };
00580     double val;
00581     if (!str2double(text, val))
00582     {
00583         return;
00584     }
00585     //no negative values, no zero input please
00586     if (val<0.1)
00587     {
00588         wxBell();
00589         return;
00590     };
00591 
00592     UIntSet images=m_images_tree->GetSelectedImages();
00593     GlobalCmdHist::getInstance().addCommand(
00594         new PT::UpdateCropFactorCmd(*m_pano,images,val)
00595     );
00596 }
00597 
00598 void ImagesPanel::OnMinimumOverlapChanged(wxCommandEvent & e)
00599 {
00600     wxString text = m_overlap->GetValue();
00601     if(text.IsEmpty())
00602     {
00603         return;
00604     };
00605     double val;
00606     if (!str2double(text, val))
00607     {
00608         return;
00609     }
00610     if(val<=0 || val>1)
00611     {
00612         wxMessageBox(_("The minimum overlap has to be greater than 0 and smaller than 1."),
00613 #ifdef _WINDOWS
00614             _("Hugin"),
00615 #else
00616             wxT(""),
00617 #endif
00618             wxOK | wxICON_INFORMATION, this);
00619         return;
00620     };
00621     PanoramaOptions opt=m_pano->getOptions();
00622     opt.outputStacksMinOverlap=val;
00623     GlobalCmdHist::getInstance().addCommand(
00624         new PT::SetPanoOptionsCmd(*m_pano,opt)
00625     );
00626 };
00627 
00628 void ImagesPanel::OnMaxEvDiffChanged(wxCommandEvent& e)
00629 {
00630     wxString text = m_maxEv->GetValue();
00631     if(text.IsEmpty())
00632     {
00633         return;
00634     };
00635     double val;
00636     if (!str2double(text, val))
00637     {
00638         return;
00639     }
00640     if(val<0)
00641     {
00642         wxMessageBox(_("The maximum Ev difference has to be greater than 0."),
00643 #ifdef _WINDOWS
00644             _("Hugin"),
00645 #else
00646             wxT(""),
00647 #endif
00648             wxOK | wxICON_INFORMATION, this);
00649         return;
00650     };
00651     PanoramaOptions opt=m_pano->getOptions();
00652     opt.outputLayersExposureDiff=val;
00653     GlobalCmdHist::getInstance().addCommand(
00654         new PT::SetPanoOptionsCmd(*m_pano,opt)
00655     );
00656 };
00657 
00658 void ImagesPanel::FillGroupChoice()
00659 {
00660     wxChoice* group=XRCCTRL(*this,"images_group_mode", wxChoice);
00661     size_t sel=group->GetSelection();
00662     DeleteClientData(group);
00663     group->Clear();
00664     int* i=new int;
00665     *i=ImagesTreeCtrl::GROUP_NONE;
00666     group->Append(_("None"), i);
00667     i=new int;
00668     *i=ImagesTreeCtrl::GROUP_LENS;
00669     group->Append(_("Lens"), i);
00670     if(m_guiLevel>GUI_SIMPLE)
00671     {
00672         i=new int;
00673         *i=ImagesTreeCtrl::GROUP_STACK;
00674         group->Append(_("Stacks"), i);
00675         if(m_guiLevel==GUI_EXPERT)
00676         {
00677             i=new int;
00678             *i=ImagesTreeCtrl::GROUP_OUTPUTLAYERS;
00679             group->Append(_("Output layers"), i);
00680             i=new int;
00681             *i=ImagesTreeCtrl::GROUP_OUTPUTSTACK;
00682             group->Append(_("Output stacks"), i);
00683         };
00684     };
00685     if((m_guiLevel==GUI_ADVANCED && sel>2) || (m_guiLevel==GUI_SIMPLE && sel>1))
00686     {
00687         sel=0;
00688     };
00689     group->SetSelection(sel);
00690     wxCommandEvent dummy;
00691     OnGroupModeChanged(dummy);
00692 };
00693 
00694 void ImagesPanel::FillOptimizerChoice()
00695 {
00696     DeleteClientData(m_optChoice);
00697     m_optChoice->Clear();
00698     int* i=new int;
00699     *i=HuginBase::OPT_PAIR;
00700     m_optChoice->Append(_("Positions (incremental, starting from anchor)"), i);
00701     i=new int;
00702     *i=HuginBase::OPT_POSITION;
00703     m_optChoice->Append(_("Positions (y,p,r)"), i);
00704     i=new int;
00705     *i=(HuginBase::OPT_POSITION | HuginBase::OPT_VIEW);
00706     m_optChoice->Append(_("Positions and View (y,p,r,v)"), i);
00707     i=new int;
00708     *i=(HuginBase::OPT_POSITION | HuginBase::OPT_BARREL);
00709     m_optChoice->Append(_("Positions and Barrel Distortion (y,p,r,b)"), i);
00710     i=new int;
00711     *i=(HuginBase::OPT_POSITION | HuginBase::OPT_VIEW | HuginBase::OPT_BARREL);
00712     m_optChoice->Append(_("Positions, View and Barrel (y,p,r,v,b)"), i);
00713     i=new int;
00714     *i=HuginBase::OPT_ALL;
00715     if(m_guiLevel==GUI_EXPERT)
00716     {
00717         m_optChoice->Append(_("Everything without translation"), i);
00718     }
00719     else
00720     {
00721         m_optChoice->Append(_("Everything"), i);
00722     };
00723     if(m_guiLevel==GUI_EXPERT)
00724     {
00725         i=new int;
00726         *i=(HuginBase::OPT_POSITION | HuginBase::OPT_TRANSLATION);
00727         m_optChoice->Append(_("Positions and Translation (y,p,r,x,y,z)"), i);
00728         i=new int;
00729         *i=(HuginBase::OPT_POSITION | HuginBase::OPT_TRANSLATION | HuginBase::OPT_VIEW);
00730         m_optChoice->Append(_("Positions, Translation and View (y,p,r,x,y,z,v)"), i);
00731         i=new int;
00732         *i=(HuginBase::OPT_POSITION | HuginBase::OPT_TRANSLATION | HuginBase::OPT_BARREL);
00733         m_optChoice->Append(_("Positions, Translation and Barrel (y,p,r,x,y,z,b)"), i);
00734         i=new int;
00735         *i=(HuginBase::OPT_POSITION | HuginBase::OPT_TRANSLATION | HuginBase::OPT_VIEW | HuginBase::OPT_BARREL);
00736         m_optChoice->Append(_("Positions, Translation, View and Barrel (y,p,r,x,y,z,v,b)"), i);
00737     };
00738     i=new int;
00739     *i=0;
00740     m_optChoice->Append(_("Custom parameters"), i);
00741 
00742     DeleteClientData(m_optPhotoChoice);
00743     m_optPhotoChoice->Clear();
00744     i=new int;
00745     *i=(HuginBase::OPT_EXPOSURE | HuginBase::OPT_VIGNETTING | HuginBase::OPT_RESPONSE);
00746     m_optPhotoChoice->Append(_("Low dynamic range"), i);
00747     i=new int;
00748     *i=(HuginBase::OPT_EXPOSURE | HuginBase::OPT_VIGNETTING | HuginBase::OPT_RESPONSE | HuginBase::OPT_WHITEBALANCE);
00749     m_optPhotoChoice->Append(_("Low dynamic range, variable white balance"), i);
00750     if(m_guiLevel>GUI_SIMPLE)
00751     {
00752         i=new int;
00753         *i=(HuginBase::OPT_VIGNETTING | HuginBase::OPT_RESPONSE);
00754         m_optPhotoChoice->Append(_("High dynamic range, fixed exposure"), i);
00755         i=new int;
00756         *i=(HuginBase::OPT_WHITEBALANCE | HuginBase::OPT_VIGNETTING | HuginBase::OPT_RESPONSE);
00757         m_optPhotoChoice->Append(_("High dynamic range, variable white balance, fixed exposure"), i);
00758     };
00759     i=new int;
00760     *i=0;
00761     m_optPhotoChoice->Append(_("Custom parameters"), i);
00762     m_optChoice->GetParent()->Layout();
00763     Refresh();
00764 };
00765 
00766 void ImagesPanel::OnGroupModeChanged(wxCommandEvent & e)
00767 {
00768     wxChoice* group=XRCCTRL(*this,"images_group_mode", wxChoice);
00769     ImagesTreeCtrl::GroupMode mode=ImagesTreeCtrl::GroupMode(*static_cast<int*>(group->GetClientData(group->GetSelection())));
00770     m_images_tree->SetGroupMode(mode);
00771     XRCCTRL(*this, "images_text_overlap", wxStaticText)->Show(mode==ImagesTreeCtrl::GROUP_OUTPUTSTACK);
00772     m_overlap->Show(mode==ImagesTreeCtrl::GROUP_OUTPUTSTACK);
00773     m_overlap->Enable(mode==ImagesTreeCtrl::GROUP_OUTPUTSTACK);
00774     XRCCTRL(*this, "images_text_maxev", wxStaticText)->Show(mode==ImagesTreeCtrl::GROUP_OUTPUTLAYERS);
00775     m_maxEv->Show(mode==ImagesTreeCtrl::GROUP_OUTPUTLAYERS);
00776     m_maxEv->Enable(mode==ImagesTreeCtrl::GROUP_OUTPUTLAYERS);
00777     Layout();
00778     Refresh();
00779 };
00780 
00781 void ImagesPanel::OnDisplayModeChanged(wxCommandEvent & e)
00782 {
00783     wxRadioBox* display=XRCCTRL(*this,"images_column_radiobox", wxRadioBox);
00784     m_images_tree->SetDisplayMode((ImagesTreeCtrl::DisplayMode)display->GetSelection());
00785 };
00786 
00787 void ImagesPanel::OnOptimizerSwitchChanged(wxCommandEvent &e)
00788 {
00789     int optSwitch=*static_cast<int*>(m_optChoice->GetClientData(m_optChoice->GetSelection()));
00790     if(optSwitch!=m_pano->getOptimizerSwitch())
00791     {
00792         GlobalCmdHist::getInstance().addCommand(
00793             new PT::UpdateOptimizerSwitchCmd(*m_pano,optSwitch)
00794         );
00795     };
00796 };
00797 
00798 void ImagesPanel::OnPhotometricOptimizerSwitchChanged(wxCommandEvent &e)
00799 {
00800     int optSwitch=*static_cast<int*>(m_optPhotoChoice->GetClientData(m_optPhotoChoice->GetSelection()));
00801     if(optSwitch!=m_pano->getPhotometricOptimizerSwitch())
00802     {
00803         GlobalCmdHist::getInstance().addCommand(
00804             new PT::UpdatePhotometricOptimizerSwitchCmd(*m_pano,optSwitch)
00805         );
00806     };
00807 };
00808 
00809 void ImagesPanel::SetGuiLevel(GuiLevel newGuiLevel)
00810 {
00811     m_guiLevel=newGuiLevel;
00812     m_images_tree->SetGuiLevel(newGuiLevel);
00813     FillGroupChoice();
00814     FillOptimizerChoice();
00815     wxStaticText* textlabel=XRCCTRL(*this, "images_mode_text", wxStaticText);
00816     switch(m_guiLevel)
00817     {
00818         case GUI_SIMPLE:
00819             textlabel->SetLabel(_("Simple interface"));
00820             break;
00821         case GUI_ADVANCED:
00822             textlabel->SetLabel(_("Advanced interface"));
00823             break;
00824         case GUI_EXPERT:
00825             textlabel->SetLabel(_("Expert interface"));
00826             break;
00827     };
00828     textlabel->GetParent()->Layout();
00829     textlabel->Refresh();
00830     panoramaChanged(*m_pano);
00831 };
00832 
00833 void ImagesPanel::OnOptimizeButton(wxCommandEvent &e)
00834 {
00835     MainFrame::Get()->OnOptimize(e);
00836 };
00837 
00838 void ImagesPanel::OnPhotometricOptimizeButton(wxCommandEvent &e)
00839 {
00840     MainFrame::Get()->OnPhotometricOptimize(e);
00841 };
00842 
00843 IMPLEMENT_DYNAMIC_CLASS(ImagesPanel, wxPanel)
00844 
00845 ImagesPanelXmlHandler::ImagesPanelXmlHandler()
00846                 : wxXmlResourceHandler()
00847 {
00848     AddWindowStyles();
00849 }
00850 
00851 wxObject *ImagesPanelXmlHandler::DoCreateResource()
00852 {
00853     XRC_MAKE_INSTANCE(cp, ImagesPanel)
00854 
00855     cp->Create(m_parentAsWindow,
00856                    GetID(),
00857                    GetPosition(), GetSize(),
00858                    GetStyle(wxT("style")),
00859                    GetName());
00860 
00861     SetupWindow( cp);
00862     return cp;
00863 }
00864 
00865 bool ImagesPanelXmlHandler::CanHandle(wxXmlNode *node)
00866 {
00867     return IsOfClass(node, wxT("ImagesPanel"));
00868 }
00869 
00870 IMPLEMENT_DYNAMIC_CLASS(ImagesPanelXmlHandler, wxXmlResourceHandler)

Generated on 26 Oct 2014 for Hugintrunk by  doxygen 1.4.7