00001
00002
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
00051
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
00080 wxConfigBase* config = wxConfigBase::Get();
00081
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
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
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
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
00219 m_stopped=true;
00220 m_button_start->SetLabel(_("Accepted"));
00221 }
00222 else
00223 {
00224
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
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
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
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
00371 delete img;
00372 };
00373 };
00374
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
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
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
00489
00490 if(GetMaxExposureDifference()<1.2)
00491 {
00492 return false;
00493 }
00494
00495 if((*m_images.begin())->getExifExposureMode()==0)
00496 {
00497 return false;
00498 }
00499
00500 std::set<int> evValues;
00501 for(ImageSet::const_iterator it=m_images.begin(); it!=m_images.end(); it++)
00502 {
00503
00504 evValues.insert(int((*it)->getExposureValue()*10));
00505 };
00506
00507 if(evValues.size()<2)
00508 {
00509 return false;
00510 }
00511
00512 if(evValues.size()==m_images.size())
00513 {
00514 return false;
00515 }
00516
00517
00518 if(m_images.size() % evValues.size()!=0)
00519 {
00520 return false;
00521 }
00522
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
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
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
00691 HuginBase::Panorama pano;
00692 for(ImageSet::iterator it=m_images.begin(); it!=m_images.end(); it++)
00693 {
00694 pano.addImage(*(*it));
00695 };
00696
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
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
00740 PanoramaOptions opts = pano.getOptions();
00741
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
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