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

Generated on 29 Apr 2016 for Hugintrunk by  doxygen 1.4.7