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

Generated on 1 Sep 2015 for Hugintrunk by  doxygen 1.4.7