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

Generated on 12 Feb 2016 for Hugintrunk by  doxygen 1.4.7