FindPanoDialog.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00002 
00011 /*  This is free software; you can redistribute it and/or
00012  *  modify it under the terms of the GNU General Public
00013  *  License as published by the Free Software Foundation; either
00014  *  version 2 of the License, or (at your option) any later version.
00015  *
00016  *  This software is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019  *  Lesser General Public License for more details.
00020  *
00021  *  You should have received a copy of the GNU General Public
00022  *  License along with this software; if not, write to the Free Software
00023  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024  *
00025  */
00026 
00027 #include "FindPanoDialog.h"
00028 #include "base_wx/wxPlatform.h"
00029 #include "panoinc.h"
00030 #include "panodata/OptimizerSwitches.h"
00031 #include "PTBatcherGUI.h"
00032 #include "hugin_utils/alphanum.h"
00033 #include "hugin/config_defaults.h"
00034 
00035 BEGIN_EVENT_TABLE(FindPanoDialog,wxDialog)
00036     EVT_BUTTON(XRCID("find_pano_close"), FindPanoDialog::OnButtonClose)
00037     EVT_BUTTON(XRCID("find_pano_select_dir"), FindPanoDialog::OnButtonChoose)
00038     EVT_BUTTON(XRCID("find_pano_start_stop"), FindPanoDialog::OnButtonStart)
00039     EVT_BUTTON(XRCID("find_pano_add_queue"), FindPanoDialog::OnButtonSend)
00040     EVT_CLOSE(FindPanoDialog::OnClose)
00041 END_EVENT_TABLE()
00042 
00043 bool SortFilename::operator()(const SrcPanoImage* img1, const SrcPanoImage* img2)
00044 {
00045     return doj::alphanum_comp(img1->getFilename(),img2->getFilename())<0;
00046 };
00047 
00048 FindPanoDialog::FindPanoDialog(BatchFrame* batchframe, wxString xrcPrefix)
00049 {
00050     // load our children. some children might need special
00051     // initialization. this will be done later.
00052     wxXmlResource::Get()->LoadDialog(this,batchframe,wxT("find_pano_dialog"));
00053 
00054 #ifdef __WXMSW__
00055     wxIcon myIcon(xrcPrefix+ wxT("data/ptbatcher.ico"),wxBITMAP_TYPE_ICO);
00056 #else
00057     wxIcon myIcon(xrcPrefix + wxT("data/ptbatcher.png"),wxBITMAP_TYPE_PNG);
00058 #endif
00059     SetIcon(myIcon);
00060     m_batchframe=batchframe;
00061     m_isRunning=false;
00062     m_stopped=false;
00063 
00064     m_button_start=XRCCTRL(*this,"find_pano_start_stop",wxButton);
00065     m_button_choose=XRCCTRL(*this,"find_pano_select_dir",wxButton);
00066     m_button_send=XRCCTRL(*this,"find_pano_add_queue",wxButton);
00067     m_button_close=XRCCTRL(*this,"find_pano_close",wxButton);
00068     m_textctrl_dir=XRCCTRL(*this,"find_pano_dir",wxTextCtrl);
00069     m_cb_subdir=XRCCTRL(*this,"find_pano_subdir",wxCheckBox);
00070     m_statustext=XRCCTRL(*this,"find_pano_label",wxStaticText);
00071     m_list_pano=XRCCTRL(*this,"find_pano_list",wxCheckListBox);
00072     m_ch_naming=XRCCTRL(*this,"find_pano_naming",wxChoice);
00073     m_cb_createLinks=XRCCTRL(*this,"find_pano_create_links",wxCheckBox);
00074     m_cb_loadDistortion=XRCCTRL(*this,"find_pano_load_distortion",wxCheckBox);
00075     m_cb_loadVignetting=XRCCTRL(*this,"find_pano_load_vignetting",wxCheckBox);
00076     m_sc_minNumberImages=XRCCTRL(*this, "find_pano_min_number_images", wxSpinCtrl);
00077     m_sc_maxTimeDiff=XRCCTRL(*this, "find_pano_max_time_diff", wxSpinCtrl);
00078 
00079     //set parameters
00080     wxConfigBase* config = wxConfigBase::Get();
00081     // restore position and size
00082     int dx,dy;
00083     wxDisplaySize(&dx,&dy);
00084     bool maximized = config->Read(wxT("/FindPanoDialog/maximized"), 0l) != 0;
00085     if (maximized)
00086     {
00087         this->Maximize();
00088     }
00089     else
00090     {
00091         //size
00092         int w = config->Read(wxT("/FindPanoDialog/width"),-1l);
00093         int h = config->Read(wxT("/FindPanoDialog/height"),-1l);
00094         if (w > 0 && w <= dx)
00095         {
00096             this->SetClientSize(w,h);
00097         }
00098         else
00099         {
00100             this->Fit();
00101         }
00102         //position
00103         int x = config->Read(wxT("/FindPanoDialog/positionX"),-1l);
00104         int y = config->Read(wxT("/FindPanoDialog/positionY"),-1l);
00105         if ( y >= 0 && x >= 0 && x < dx && y < dy)
00106         {
00107             this->Move(x, y);
00108         }
00109         else
00110         {
00111             this->Move(0, 44);
00112         }
00113     }
00114     wxString path=config->Read(wxT("/FindPanoDialog/actualPath"),wxEmptyString);
00115     if(!path.IsEmpty())
00116     {
00117         m_textctrl_dir->SetValue(path);
00118     }
00119     bool val;
00120     config->Read(wxT("/FindPanoDialog/includeSubDirs"),&val,false);
00121     m_cb_subdir->SetValue(val);
00122     long i=config->Read(wxT("/FindPanoDialog/Naming"),0l);
00123     m_ch_naming->SetSelection(i);
00124     config->Read(wxT("/FindPanoDialog/linkStacks"),&val,true);
00125     m_cb_createLinks->SetValue(val);
00126     config->Read(wxT("/FindPanoDialog/loadDistortion"),&val,false);
00127     m_cb_loadDistortion->SetValue(val);
00128     config->Read(wxT("/FindPanoDialog/loadVignetting"),&val,false);
00129     m_cb_loadVignetting->SetValue(val);
00130     i=config->Read(wxT("/FindPanoDialog/MinNumberImages"), 2l);
00131     m_sc_minNumberImages->SetValue(i);
00132     i=config->Read(wxT("/FindPanoDialog/MaxTimeDiff"), 30l);
00133     m_sc_maxTimeDiff->SetValue(i);
00134     m_button_send->Disable();
00135 };
00136 
00137 FindPanoDialog::~FindPanoDialog()
00138 {
00139     wxConfigBase* config=wxConfigBase::Get();
00140     if(!this->IsMaximized())
00141     {
00142         wxSize sz = this->GetClientSize();
00143         config->Write(wxT("/FindPanoDialog/width"), sz.GetWidth());
00144         config->Write(wxT("/FindPanoDialog/height"), sz.GetHeight());
00145         wxPoint ps = this->GetPosition();
00146         config->Write(wxT("/FindPanoDialog/positionX"), ps.x);
00147         config->Write(wxT("/FindPanoDialog/positionY"), ps.y);
00148         config->Write(wxT("/FindPanoDialog/maximized"), 0);
00149     }
00150     else
00151     {
00152         config->Write(wxT("/FindPanoDialog/maximized"), 1l);
00153     };
00154     config->Write(wxT("/FindPanoDialog/actualPath"),m_textctrl_dir->GetValue());
00155     config->Write(wxT("/FindPanoDialog/includeSubDirs"),m_cb_subdir->GetValue());
00156     config->Write(wxT("/FindPanoDialog/Naming"),m_ch_naming->GetSelection());
00157     config->Write(wxT("/FindPanoDialog/linkStacks"),m_cb_createLinks->GetValue());
00158     config->Write(wxT("/FindPanoDialog/loadDistortion"),m_cb_loadDistortion->GetValue());
00159     config->Write(wxT("/FindPanoDialog/loadVignetting"),m_cb_loadDistortion->GetValue());
00160     config->Write(wxT("/FindPanoDialog/MinNumberImages"), m_sc_minNumberImages->GetValue());
00161     config->Write(wxT("/FindPanoDialog/MaxTimeDiff"), m_sc_maxTimeDiff->GetValue());
00162     CleanUpPanolist();
00163 };
00164 
00165 void FindPanoDialog::CleanUpPanolist()
00166 {
00167     if(m_panos.size()>0)
00168     {
00169         while(!m_panos.empty())
00170         {
00171             delete m_panos.back();
00172             m_panos.pop_back();
00173         };
00174     };
00175 };
00176 
00177 //prevent closing window when running detection
00178 void FindPanoDialog::OnClose(wxCloseEvent& e)
00179 {
00180     if(e.CanVeto() && m_isRunning)
00181     {
00182         wxBell();
00183         e.Veto();
00184     }
00185     else
00186     {
00187         e.Skip();
00188     };
00189 };
00190 
00191 void FindPanoDialog::OnButtonClose(wxCommandEvent& e)
00192 {
00193     if(m_panos.size()>0)
00194     {
00195         if(wxMessageBox(_("The list contains possibly unprocessed panoramas.\nIf you close the dialog, you will lose them.\nContinue anyway?"),
00196                         _("Question"),wxYES_NO|wxICON_QUESTION,this)==wxNO)
00197         {
00198             return;
00199         };
00200     };
00201     this->Close();
00202 };
00203 
00204 void FindPanoDialog::OnButtonChoose(wxCommandEvent& e)
00205 {
00206     wxDirDialog dlg(this, _("Specify a directory to search for projects in"),
00207                     m_textctrl_dir->GetValue(), wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST);
00208     if (dlg.ShowModal()==wxID_OK)
00209     {
00210         m_textctrl_dir->SetValue(dlg.GetPath());
00211     };
00212 };
00213 
00214 void FindPanoDialog::OnButtonStart(wxCommandEvent& e)
00215 {
00216     if(m_isRunning)
00217     {
00218         //stop detection
00219         m_stopped=true;
00220         m_button_start->SetLabel(_("Accepted"));
00221     }
00222     else
00223     {
00224         //start detection
00225         m_start_dir=m_textctrl_dir->GetValue();
00226         if(wxDir::Exists(m_start_dir))
00227         {
00228             if(m_panos.size()>0)
00229             {
00230                 if(wxMessageBox(_("The list contains still not yet processed panoramas.\nIf you continue, they will be disregarded.\nDo you still want to continue?"),
00231                                 _("Question"),wxYES_NO|wxICON_QUESTION,this)==wxNO)
00232                 {
00233                     return;
00234                 };
00235             };
00236             m_isRunning=true;
00237             m_stopped=false;
00238             //deactivate TIFF warning message boxes
00239             m_oldtiffwarning=TIFFSetWarningHandler(NULL);
00240             m_button_start->SetLabel(_("Stop"));
00241             CleanUpPanolist();
00242             m_list_pano->Clear();
00243             EnableButtons(false);
00244             SearchInDir(m_start_dir,m_cb_subdir->GetValue(), m_cb_loadDistortion->GetValue(), m_cb_loadVignetting->GetValue(), 
00245                 m_sc_minNumberImages->GetValue(), m_sc_maxTimeDiff->GetValue());
00246         }
00247         else
00248         {
00249             wxMessageBox(wxString::Format(_("Directory %s does not exist.\nPlease give an existing directory."),m_start_dir.c_str()),
00250                          _("Warning"),wxOK | wxICON_EXCLAMATION,this);
00251         };
00252     };
00253 }
00254 
00255 void FindPanoDialog::OnButtonSend(wxCommandEvent& e)
00256 {
00257     if(m_panos.size()==0)
00258     {
00259         return;
00260     }
00261     unsigned int nr=0;
00262     for(unsigned int i=0; i<m_list_pano->GetCount(); i++)
00263     {
00264         if(m_list_pano->IsChecked(i))
00265         {
00266             nr++;
00267         };
00268     };
00269     if(nr==0)
00270     {
00271         wxMessageBox(_("You have selected no possible panorama.\nPlease select at least one panorama and try again."),_("Warning"),wxOK|wxICON_EXCLAMATION,this);
00272         return;
00273     }
00274     bool failed=false;
00275     bool createLinks=m_cb_createLinks->GetValue();
00276     for(unsigned int i=0; i<m_list_pano->GetCount(); i++)
00277     {
00278         if(m_list_pano->IsChecked(i))
00279         {
00280             wxString filename=m_panos[i]->GeneratePanorama((PossiblePano::NamingConvention)(m_ch_naming->GetSelection()),createLinks);
00281             if(!filename.IsEmpty())
00282             {
00283                 m_batchframe->AddToList(filename,Project::DETECTING);
00284             }
00285             else
00286             {
00287                 failed=true;
00288             };
00289         };
00290     };
00291     if(failed)
00292     {
00293         wxMessageBox(_("Not all project files could be written successfully.\nMaybe you have no write permission for these directories or your disc is full."),_("Error"),wxOK,this);
00294     };
00295     this->Close();
00296 };
00297 
00298 void FindPanoDialog::EnableButtons(const bool state)
00299 {
00300     m_textctrl_dir->Enable(state);
00301     m_button_choose->Enable(state);
00302     m_cb_subdir->Enable(state);
00303     m_ch_naming->Enable(state);
00304     m_cb_createLinks->Enable(state);
00305     m_button_close->Enable(state);
00306     m_button_send->Enable(state);
00307 };
00308 
00309 int SortWxFilenames(const wxString& s1,const wxString& s2)
00310 {
00311     return doj::alphanum_comp(std::string(s1.mb_str(wxConvLocal)),std::string(s2.mb_str(wxConvLocal)));
00312 };
00313 
00314 void FindPanoDialog::SearchInDir(wxString dirstring, const bool includeSubdir, const bool loadDistortion, const bool loadVignetting, const size_t minNumberImages, const size_t maxTimeDiff)
00315 {
00316     std::vector<PossiblePano*> newPanos;
00317     wxTimeSpan max_diff(0, 0, maxTimeDiff, 0); 
00318     wxString filename;
00319     wxArrayString fileList;
00320     wxDir::GetAllFiles(dirstring,&fileList,wxEmptyString,wxDIR_FILES|wxDIR_HIDDEN);
00321     fileList.Sort(SortWxFilenames);
00322     //map for caching projection information to prevent reading from database for each image
00323     typedef std::map<std::string,HuginBase::BaseSrcPanoImage::Projection> projMap;
00324     projMap lensProjMap;
00325     for(size_t j=0; j<fileList.size() && !m_stopped; j++)
00326     {
00327         m_statustext->SetLabel(wxString::Format(_("Reading file %s"),fileList[j].c_str()));
00328         wxFileName file(fileList[j]);
00329         file.MakeAbsolute();
00330         wxString ext=file.GetExt();
00331         if(ext.CmpNoCase(wxT("jpg"))==0 || ext.CmpNoCase(wxT("jpeg"))==0 ||
00332                 ext.CmpNoCase(wxT("tif"))==0 || ext.CmpNoCase(wxT("tiff"))==0)
00333         {
00334             std::string filenamestr(file.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
00335             SrcPanoImage* img=new SrcPanoImage(filenamestr);
00336             if(img->hasEXIFread())
00337             {
00338                 img->readProjectionFromDB();
00339                 if(loadDistortion)
00340                 {
00341                     img->readDistortionFromDB();
00342                 };
00343                 if(loadVignetting)
00344                 {
00345                     img->readVignettingFromDB();
00346                 };
00347                 bool found=false;
00348                 for(unsigned int i=0; i<newPanos.size() && !m_stopped && !found; i++)
00349                 {
00350                     //compare with all other image groups
00351                     if(newPanos[i]->BelongsTo(img,max_diff))
00352                     {
00353                         newPanos[i]->AddSrcPanoImage(img);
00354                         found=true;
00355                     };
00356                     if(i%10==0)
00357                     {
00358                         wxGetApp().Yield(true);
00359                     };
00360                 };
00361                 if(!found)
00362                 {
00363                     PossiblePano* newPano=new PossiblePano();
00364                     newPano->AddSrcPanoImage(img);
00365                     newPanos.push_back(newPano);
00366                 };
00367             }
00368             else
00369             {
00370                 //could not read exif infos, disregard this image
00371                 delete img;
00372             };
00373         };
00374         //allow processing events
00375         wxGetApp().Yield(true);
00376     };
00377     if(!m_stopped && newPanos.size()>0)
00378     {
00379         for(size_t i=0; i<newPanos.size(); i++)
00380         {
00381             if(newPanos[i]->GetImageCount()>=minNumberImages)
00382             {
00383                 m_panos.push_back(newPanos[i]);
00384                 int newItem=m_list_pano->Append(m_panos[m_panos.size()-1]->GetItemString(m_start_dir));
00385                 m_list_pano->Check(newItem,true);
00386             }
00387             else
00388             {
00389                 delete newPanos[i];
00390             };
00391         };
00392     };
00393 
00394     if(includeSubdir && !m_stopped)
00395     {
00396         //now we go into all directories
00397         wxDir dir(dirstring);
00398         bool cont=dir.GetFirst(&filename,wxEmptyString,wxDIR_DIRS);
00399         while(cont && !m_stopped)
00400         {
00401             SearchInDir(dir.GetName()+wxFileName::GetPathSeparator()+filename,includeSubdir, loadDistortion, loadVignetting, minNumberImages, maxTimeDiff);
00402             cont=dir.GetNext(&filename);
00403         }
00404     };
00405     if(m_start_dir.Cmp(dirstring)==0)
00406     {
00407         m_stopped=false;
00408         m_isRunning=false;
00409         m_button_start->SetLabel(_("Start"));
00410         EnableButtons(true);
00411         //enable send button if at least one panorama found
00412         m_button_send->Enable(m_panos.size()>0);
00413         if(m_panos.size()>0)
00414         {
00415             m_statustext->SetLabel(wxString::Format(_("Found %d possible panoramas."),m_panos.size()));
00416         }
00417         else
00418         {
00419             m_statustext->SetLabel(_("No possible panoramas found."));
00420         };
00421         TIFFSetWarningHandler(m_oldtiffwarning);
00422     };
00423 };
00424 
00425 PossiblePano::~PossiblePano()
00426 {
00427     if(m_images.size()>0)
00428     {
00429         for(ImageSet::reverse_iterator it=m_images.rbegin(); it!=m_images.rend(); it++)
00430         {
00431             delete (*it);
00432         }
00433     };
00434 };
00435 
00436 bool PossiblePano::BelongsTo(SrcPanoImage* img, const wxTimeSpan max_time_diff)
00437 {
00438     if(m_make.compare(img->getExifMake())!=0)
00439     {
00440         return false;
00441     }
00442     if(m_camera.compare(img->getExifModel())!=0)
00443     {
00444         return false;
00445     }
00446     if(m_lens.compare(img->getExifLens())!=0)
00447     {
00448         return false;
00449     }
00450     if(fabs(m_focallength-img->getExifFocalLength())>0.01)
00451     {
00452         return false;
00453     }
00454     if(m_size!=img->getSize())
00455     {
00456         return false;
00457     }
00458     if(!GetDateTime(img).IsBetween(m_dt_start-max_time_diff,m_dt_end+max_time_diff))
00459     {
00460         return false;
00461     };
00462     return true;
00463 };
00464 
00465 double PossiblePano::GetMaxExposureDifference()
00466 {
00467     if(m_images.empty())
00468     {
00469         return 0;
00470     }
00471     double minEv=1000;
00472     double maxEv=-1000;
00473     for(ImageSet::const_iterator it=m_images.begin(); it!=m_images.end(); it++)
00474     {
00475         double ev=(*it)->getExposureValue();
00476         minEv=std::min(minEv,ev);
00477         maxEv=std::max(maxEv,ev);
00478     };
00479     return maxEv-minEv;
00480 };
00481 
00482 bool PossiblePano::IsStacked()
00483 {
00484     if(m_images.empty())
00485     {
00486         return false;
00487     }
00488     // this algorithm is based on panostart by Bruno Postle
00489     // bracketed pano has at least a dynamic range of 1.2 ev values (corresponds to bracket with +-2/3)
00490     if(GetMaxExposureDifference()<1.2)
00491     {
00492         return false;
00493     }
00494     //if image is shooted in auto exposure mode then it is not a bracket pano
00495     if((*m_images.begin())->getExifExposureMode()==0)
00496     {
00497         return false;
00498     }
00499     //now collect all unique exposure values
00500     std::set<int> evValues;
00501     for(ImageSet::const_iterator it=m_images.begin(); it!=m_images.end(); it++)
00502     {
00503         //we multiply with 10 to don't get fooled by rounded double values
00504         evValues.insert(int((*it)->getExposureValue()*10));
00505     };
00506     //if there is only one unique exposure value then there are no stacks
00507     if(evValues.size()<2)
00508     {
00509         return false;
00510     }
00511     //if number of unique exposure values is equal the number of images then there are no stacks
00512     if(evValues.size()==m_images.size())
00513     {
00514         return false;
00515     }
00516     //if number of images is not a multiple of number of unique exposure values
00517     //then the stacks are incomplete, skipping
00518     if(m_images.size() % evValues.size()!=0)
00519     {
00520         return false;
00521     }
00522     //check if exposure value is repeated with step size of bracket size
00523     ImageSet::const_iterator it=m_images.begin();
00524     for(unsigned int i=0; i<evValues.size(); i++)
00525     {
00526         it++;
00527     };
00528     if(abs((*m_images.begin())->getExposureValue()-(*it)->getExposureValue())<0.1)
00529     {
00530         return true;
00531     }
00532     else
00533     {
00534         return false;
00535     };
00536 };
00537 
00538 const wxDateTime PossiblePano::GetDateTime(const SrcPanoImage* img)
00539 {
00540     struct tm exifdatetime;
00541     if(img->getExifDateTime(&exifdatetime)==0)
00542     {
00543         return wxDateTime(exifdatetime);
00544     }
00545     else
00546     {
00547         wxFileName file(wxString(img->getFilename().c_str(),HUGIN_CONV_FILENAME));
00548         return file.GetModificationTime();
00549     };
00550 };
00551 
00552 void PossiblePano::AddSrcPanoImage(HuginBase::SrcPanoImage* img)
00553 {
00554     if(m_images.size()==0)
00555     {
00556         //fill all values from first image
00557         m_make=img->getExifMake();
00558         m_camera=img->getExifModel();
00559         m_lens=img->getExifLens();
00560         m_focallength=img->getExifFocalLength();
00561         m_size=img->getSize();
00562         m_dt_start=GetDateTime(img);
00563         m_dt_end=m_dt_start;
00564     }
00565     else
00566     {
00567         wxDateTime dt=GetDateTime(img);
00568         if(dt.IsEarlierThan(m_dt_start))
00569         {
00570             m_dt_start=dt;
00571         }
00572         if(dt.IsLaterThan(m_dt_end))
00573         {
00574             m_dt_end=dt;
00575         };
00576     };
00577     m_images.insert(img);
00578 };
00579 
00580 const wxString PossiblePano::GetFilestring(const wxString BasePath, const bool stripExtension) const
00581 {
00582     ImageSet::const_iterator it=m_images.begin();
00583     wxFileName f1(wxString((*it)->getFilename().c_str(),HUGIN_CONV_FILENAME));
00584     f1.MakeRelativeTo(BasePath);
00585     ImageSet::const_reverse_iterator rit=m_images.rbegin();
00586     wxFileName f2(wxString((*rit)->getFilename().c_str(),HUGIN_CONV_FILENAME));
00587     if(stripExtension)
00588     {
00589         return f1.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR)+f1.GetName()+wxT("-")+f2.GetName();
00590     }
00591     else
00592     {
00593         return f1.GetFullPath()+wxT(" - ")+f2.GetFullName();
00594     };
00595 };
00596 
00597 const wxString PossiblePano::GetItemString(const wxString BasePath) const
00598 {
00599     return wxString::Format(_("%d images: %s"),m_images.size(),GetFilestring(BasePath).c_str());
00600 };
00601 
00602 bool PossiblePano::GetNewProjectFilename(NamingConvention nc,const wxString basePath, wxFileName& projectFile)
00603 {
00604     wxString mask;
00605     unsigned int i=1;
00606     projectFile.SetPath(basePath);
00607     projectFile.SetName(wxT("pano"));
00608     projectFile.SetExt(wxT("pto"));
00609     if(!projectFile.IsDirWritable())
00610     {
00611         return false;
00612     };
00613     switch(nc)
00614     {
00615         case NAMING_PANO:
00616             mask=wxT("panorama%d");
00617             break;
00618         case NAMING_FIRST_LAST:
00619             mask=GetFilestring(basePath,true);
00620             projectFile.SetName(mask);
00621             if(!projectFile.FileExists())
00622             {
00623                 return true;
00624             };
00625             mask=mask+wxT("_%d");
00626             break;
00627         case NAMING_FOLDER:
00628             {
00629                 wxArrayString folders=projectFile.GetDirs();
00630                 if(folders.GetCount()==0)
00631                 {
00632                     return false;
00633                 }
00634                 mask=folders.Last();
00635                 projectFile.SetName(mask);
00636                 if(!projectFile.FileExists())
00637                 {
00638                     return true;
00639                 }
00640                 mask=mask+wxT("_%d");
00641             }
00642             break;
00643         case NAMING_TEMPLATE:
00644             {
00645                 HuginBase::Panorama tempPano;
00646                 tempPano.addImage(**m_images.begin());
00647                 tempPano.addImage(**m_images.rbegin());
00648                 wxFileName newProject(getDefaultProjectName(tempPano));
00649                 mask=newProject.GetName();
00650                 projectFile.SetName(mask);
00651                 if(!projectFile.FileExists())
00652                 {
00653                     return true;
00654                 }
00655                 mask=mask+wxT("_%d");
00656             };
00657             break;
00658         default:
00659             mask=wxT("panorama%d");
00660     };
00661 
00662     projectFile.SetName(wxString::Format(mask,i));
00663     while(projectFile.FileExists())
00664     {
00665         i++;
00666         projectFile.SetName(wxString::Format(mask,i));
00667         //security fall through
00668         if(i>1000)
00669         {
00670             return false;
00671         };
00672     }
00673     return true;
00674 };
00675 
00676 wxString PossiblePano::GeneratePanorama(NamingConvention nc,bool createLinks)
00677 {
00678     if(m_images.size()==0)
00679     {
00680         return wxEmptyString;
00681     };
00682     ImageSet::const_iterator it=m_images.begin();
00683     wxFileName firstFile(wxString((*it)->getFilename().c_str(),HUGIN_CONV_FILENAME));
00684     firstFile.MakeAbsolute();
00685     wxFileName projectFile;
00686     if(!GetNewProjectFilename(nc,firstFile.GetPath(),projectFile))
00687     {
00688         return wxEmptyString;
00689     };
00690     //generate panorama
00691     HuginBase::Panorama pano;
00692     for(ImageSet::iterator it=m_images.begin(); it!=m_images.end(); it++)
00693     {
00694         pano.addImage(*(*it));
00695     };
00696     //assign all images the same lens number
00697     HuginBase::StandardImageVariableGroups variable_groups(pano);
00698     HuginBase::ImageVariableGroup& lenses = variable_groups.getLenses();
00699     if(pano.getNrOfImages()>1)
00700     {
00701         for(unsigned int i=1; i<pano.getNrOfImages(); i++)
00702         {
00703             SrcPanoImage img=pano.getSrcImage(i);
00704             double ev=img.getExposureValue();
00705             lenses.switchParts(i,lenses.getPartNumber(0));
00706             lenses.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_ExposureValue, i);
00707             img.setExposureValue(ev);
00708             lenses.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_WhiteBalanceRed, i);
00709             lenses.unlinkVariableImage(HuginBase::ImageVariableGroup::IVE_WhiteBalanceBlue, i);
00710             img.setWhiteBalanceRed(1);
00711             img.setWhiteBalanceBlue(1);
00712             pano.setSrcImage(i, img);
00713         };
00714     };
00715     if(IsStacked())
00716     {
00717         //if it is a stacked pano, create the stacks and link position if desired
00718         unsigned int imgNr=0;
00719         double ev=pano.getImage(imgNr).getExposureValue();
00720         for(unsigned int i=1; i<pano.getNrOfImages(); i++)
00721         {
00722             if(abs(pano.getImage(i).getExposureValue()-ev)<0.1)
00723             {
00724                 imgNr=i;
00725                 ev=pano.getImage(imgNr).getExposureValue();
00726             }
00727             else
00728             {
00729                 pano.linkImageVariableStack(imgNr,i);
00730                 if(createLinks)
00731                 {
00732                     pano.linkImageVariableYaw(imgNr,i);
00733                     pano.linkImageVariablePitch(imgNr,i);
00734                     pano.linkImageVariableRoll(imgNr,i);
00735                 };
00736             };
00737         };
00738     };
00739     // Setup pano with options from preferences
00740     PanoramaOptions opts = pano.getOptions();
00741     //set default exposure value
00742     opts.outputExposureValue = pano.getImage(0).getExposureValue();
00743     wxConfigBase* config = wxConfigBase::Get();
00744     opts.quality = config->Read(wxT("/output/jpeg_quality"),HUGIN_JPEG_QUALITY);
00745     switch(config->Read(wxT("/output/tiff_compression"), HUGIN_TIFF_COMPRESSION))
00746     {
00747         case 0:
00748         default:
00749             opts.outputImageTypeCompression = "NONE";
00750             opts.tiffCompression = "NONE";
00751             break;
00752         case 1:
00753             opts.outputImageTypeCompression = "PACKBITS";
00754             opts.tiffCompression = "PACKBITS";
00755             break;
00756         case 2:
00757             opts.outputImageTypeCompression = "LZW";
00758             opts.tiffCompression = "LZW";
00759             break;
00760         case 3:
00761             opts.outputImageTypeCompression = "DEFLATE";
00762             opts.tiffCompression = "DEFLATE";
00763             break;
00764     }
00765     switch (config->Read(wxT("/output/ldr_format"), HUGIN_LDR_OUTPUT_FORMAT))
00766     {
00767         case 1:
00768             opts.outputImageType ="jpg";
00769             break;
00770         case 2:
00771             opts.outputImageType ="png";
00772             break;
00773         case 3:
00774             opts.outputImageType ="exr";
00775             break;
00776         default:
00777         case 0:
00778             opts.outputImageType ="tif";
00779             break;
00780     }
00781     opts.outputFormat = PanoramaOptions::TIFF_m;
00782     opts.blendMode = PanoramaOptions::ENBLEND_BLEND;
00783     opts.enblendOptions = config->Read(wxT("Enblend/Args"),wxT(HUGIN_ENBLEND_ARGS)).mb_str(wxConvLocal);
00784     opts.enfuseOptions = config->Read(wxT("Enfuse/Args"),wxT(HUGIN_ENFUSE_ARGS)).mb_str(wxConvLocal);
00785     opts.interpolator = (vigra_ext::Interpolator)config->Read(wxT("Nona/Interpolator"),HUGIN_NONA_INTERPOLATOR);
00786     opts.tiff_saveROI = config->Read(wxT("Nona/CroppedImages"),HUGIN_NONA_CROPPEDIMAGES)!=0;
00787     opts.hdrMergeMode = PanoramaOptions::HDRMERGE_AVERAGE;
00788     opts.hdrmergeOptions = HUGIN_HDRMERGE_ARGS;
00789     pano.setOptions(opts);
00790     // set optimizer switches
00791     pano.setOptimizerSwitch(HuginBase::OPT_POSITION);
00792     pano.setPhotometricOptimizerSwitch(HuginBase::OPT_EXPOSURE | HuginBase::OPT_VIGNETTING | HuginBase::OPT_RESPONSE);
00793 
00794     std::ofstream script(projectFile.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
00795     script.exceptions ( std::ofstream::eofbit | std::ofstream::failbit | std::ofstream::badbit );
00796     if(!script.good())
00797     {
00798         return wxEmptyString;
00799     };
00800     PT::UIntSet all;
00801     fill_set(all, 0, pano.getNrOfImages()-1);
00802     try
00803     {
00804         std::string Pathprefix(projectFile.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR).mb_str(HUGIN_CONV_FILENAME));
00805         pano.printPanoramaScript(script, pano.getOptimizeVector(), pano.getOptions(), all, false, Pathprefix);
00806     }
00807     catch (...)
00808     {
00809         return wxEmptyString;
00810     };
00811     script.close();
00812     return projectFile.GetFullPath();
00813 };
00814 

Generated on 31 Oct 2014 for Hugintrunk by  doxygen 1.4.7