ImagesPanel.cpp

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

Generated on Wed Jun 19 01:25:36 2013 for Hugintrunk by  doxygen 1.3.9.1