Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GenerateSequenceDialog.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
10 /* This is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This software is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public
21  * License along with this software. If not, see
22  * <http://www.gnu.org/licenses/>.
23  *
24  */
25 
26 #include "GenerateSequenceDialog.h"
27 #include "base_wx/wxPlatform.h"
28 #if wxCHECK_VERSION(3,1,0)
29 #include <wx/busyinfo.h>
30 #endif
31 #include "panoinc.h"
32 
34 wxArrayString GetAllSubDirectories(const wxString baseDir)
35 {
36  wxArrayString subDirs;
37  wxDir dir(baseDir);
38  if (!dir.IsOpened())
39  {
40  // could not open given directories
41  return subDirs;
42  }
43  wxString filename;
44  bool cont = dir.GetFirst(&filename, wxEmptyString, wxDIR_DIRS);
45  while (cont)
46  {
47  subDirs.Add(filename);
48  cont = dir.GetNext(&filename);
49  };
50  return subDirs;
51 }
52 
54 wxString GetNumberString(size_t x, size_t width)
55 {
56  const wxString formatString = wxString::Format("%%0%dd", width);
57  return wxString::Format(formatString, x);
58 }
59 
60 BEGIN_EVENT_TABLE(GenerateSequenceDialog, wxDialog)
61  EVT_BUTTON(XRCID("sequence_select_base_path"), GenerateSequenceDialog::OnSelectBasePath)
62  EVT_CHOICE(XRCID("sequence_choice_subdirectory"), GenerateSequenceDialog::OnSelectSubDir)
63  EVT_LIST_ITEM_SELECTED(XRCID("sequence_images_list"), GenerateSequenceDialog::OnImageListSelected)
64  EVT_LIST_ITEM_DESELECTED(XRCID("sequence_images_list"), GenerateSequenceDialog::OnImageListSelected)
65  EVT_BUTTON(XRCID("sequence_change_image"), GenerateSequenceDialog::OnUpdateImageTemplate)
66  EVT_BUTTON(XRCID("sequence_change_all_images"), GenerateSequenceDialog::OnUpdateAllImagesTemplate)
67  EVT_SPINCTRL(XRCID("sequence_p_offset"), GenerateSequenceDialog::OnUpdateCounters)
68  EVT_SPINCTRL(XRCID("sequence_p_step"), GenerateSequenceDialog::OnUpdateCounters)
69  EVT_SPINCTRL(XRCID("sequence_p_end"), GenerateSequenceDialog::OnUpdateCounters)
70  EVT_SPINCTRL(XRCID("sequence_i_offset"), GenerateSequenceDialog::OnUpdateCounters)
71  EVT_SPINCTRL(XRCID("sequence_i_step"), GenerateSequenceDialog::OnUpdateCounters)
72  EVT_SPINCTRL(XRCID("sequence_i_end"), GenerateSequenceDialog::OnUpdateCounters)
73  EVT_SPINCTRL(XRCID("sequence_x_offset"), GenerateSequenceDialog::OnUpdateCounters)
74  EVT_SPINCTRL(XRCID("sequence_x_step"), GenerateSequenceDialog::OnUpdateCounters)
75  EVT_SPINCTRL(XRCID("sequence_x_end"), GenerateSequenceDialog::OnUpdateCounters)
76  EVT_BUTTON(XRCID("sequence_generate_preview"), GenerateSequenceDialog::OnGeneratePreview)
77  EVT_BUTTON(XRCID("sequence_generate_stitching"), GenerateSequenceDialog::OnGenerateStitchingPanorama)
78  EVT_BUTTON(XRCID("sequence_generate_assistant"), GenerateSequenceDialog::OnGenerateAssistantPanorama)
80 
81 GenerateSequenceDialog::GenerateSequenceDialog(BatchFrame* batchframe, wxString xrcPrefix, wxString ptoFilename)
82 {
83  // load our children. some children might need special
84  // initialization. this will be done later.
85  wxXmlResource::Get()->LoadDialog(this,batchframe, "generate_sequence_dialog");
86 
87 #ifdef __WXMSW__
88  wxIconBundle myIcons(xrcPrefix+ "data/ptbatcher.ico",wxBITMAP_TYPE_ICO);
89  SetIcons(myIcons);
90 #else
91  wxIcon myIcon(xrcPrefix + "data/ptbatcher.png",wxBITMAP_TYPE_PNG);
92  SetIcon(myIcon);
93 #endif
94  m_batchframe=batchframe;
95  m_filename = ptoFilename;
96  ReadPTOFile();
97  if (IsValidPanorama())
98  {
99  this->SetLabel(wxString::Format(_("Generating sequence from %s"), m_filename.c_str()));
100  m_basepath = XRCCTRL(*this, "sequence_base_path", wxTextCtrl);
101  m_basepath->SetValue(wxPathOnly(m_filename));
102 
103  m_choiceSubDir = XRCCTRL(*this, "sequence_choice_subdirectory", wxChoice);
104  m_subDirTextCtrl = XRCCTRL(*this, "sequence_directory_name", wxTextCtrl);
105 
106  m_imagesListCtrl = XRCCTRL(*this, "sequence_images_list", wxListCtrl);
107  m_imagesListCtrl->InsertColumn(0, _("Template image name"));
108  m_imagesListCtrl->InsertColumn(1, _("Sequence image name"));
109  FillImagesList();
110 
111  m_originalImage = XRCCTRL(*this, "sequence_orignal_image_text", wxStaticText);
112  m_imageTemplate = XRCCTRL(*this, "sequence_image_text", wxTextCtrl);
113  m_changeImageTemplate = XRCCTRL(*this, "sequence_change_image", wxButton);
114  m_changeAllImagesTemplate = XRCCTRL(*this, "sequence_change_all_images", wxButton);
115 
116  m_spinCounterP_offset = XRCCTRL(*this, "sequence_p_offset", wxSpinCtrl);
117  m_spinCounterP_step = XRCCTRL(*this, "sequence_p_step", wxSpinCtrl);
118  m_spinCounterP_end = XRCCTRL(*this, "sequence_p_end", wxSpinCtrl);
119  m_spinCounterI_offset = XRCCTRL(*this, "sequence_i_offset", wxSpinCtrl);
120  m_spinCounterI_step = XRCCTRL(*this, "sequence_i_step", wxSpinCtrl);
121  m_spinCounterI_end = XRCCTRL(*this, "sequence_i_end", wxSpinCtrl);
122  m_spinCounterX_offset = XRCCTRL(*this, "sequence_x_offset", wxSpinCtrl);
123  m_spinCounterX_step = XRCCTRL(*this, "sequence_x_step", wxSpinCtrl);
124  m_spinCounterX_end = XRCCTRL(*this, "sequence_x_end", wxSpinCtrl);
125 
126  wxCommandEvent dummy;
127  OnSelectSubDir(dummy);
128  // UpdateCounters();
129 
130  //set parameters
131  wxConfigBase* config = wxConfigBase::Get();
132  // restore position and size
133  int dx, dy;
134  wxDisplaySize(&dx, &dy);
135  bool maximized = config->Read("/GenerateSequenceDialog/maximized", 0l) != 0;
136  if (maximized)
137  {
138  this->Maximize();
139  }
140  else
141  {
142  //size
143  int w = config->Read("/GenerateSequenceDialog/width", -1l);
144  int h = config->Read("/GenerateSequenceDialog/height", -1l);
145  if (w > 0 && w <= dx)
146  {
147  this->SetClientSize(w, h);
148  }
149  else
150  {
151  this->Fit();
152  }
153  //position
154  int x = config->Read("/GenerateSequenceDialog/positionX", -1l);
155  int y = config->Read("/GenerateSequenceDialog/positionY", -1l);
156  if (y >= 0 && x >= 0 && x < dx && y < dy)
157  {
158  this->Move(x, y);
159  }
160  else
161  {
162  this->Move(0, 44);
163  }
164  }
165 
166  m_imagesListCtrl->SetColumnWidth(0, config->Read("/GenerateSequenceDialog/ImageListColumn0Width", 200l));
167  m_imagesListCtrl->SetColumnWidth(1, config->Read("/GenerateSequenceDialog/ImageListColumn1Width", 200l));
168  XRCCTRL(*this, "sequence_naming", wxChoice)->SetSelection(config->Read("/GenerateSequenceDialog/NamingConvention", 0l));
169  };
170  XRCCTRL(*this, "sequence_counter_help", wxTextCtrl)->SetBackgroundColour(this->GetBackgroundColour());
171 };
172 
174 {
175  wxConfigBase* config=wxConfigBase::Get();
176  if(!this->IsMaximized())
177  {
178  wxSize sz = this->GetClientSize();
179  config->Write("/GenerateSequenceDialog/width", sz.GetWidth());
180  config->Write("/GenerateSequenceDialog/height", sz.GetHeight());
181  wxPoint ps = this->GetPosition();
182  config->Write("/GenerateSequenceDialog/positionX", ps.x);
183  config->Write("/GenerateSequenceDialog/positionY", ps.y);
184  config->Write("/GenerateSequenceDialog/maximized", 0);
185  }
186  else
187  {
188  config->Write(wxT("/GenerateSequenceDialog/maximized"), 1l);
189  };
190  config->Write("/GenerateSequenceDialog/ImageListColumn0Width", m_imagesListCtrl->GetColumnWidth(0));
191  config->Write("/GenerateSequenceDialog/ImageListColumn1Width", m_imagesListCtrl->GetColumnWidth(1));
192  config->Write("/GenerateSequenceDialog/NamingConvention", XRCCTRL(*this, "sequence_naming", wxChoice)->GetSelection());
193 }
194 
196 {
197  return m_validPTO && m_pano.getNrOfImages() > 0;
198 }
199 
201 {
202  std::ifstream prjfile((const char*)m_filename.mb_str(HUGIN_CONV_FILENAME));
203  if (prjfile.good())
204  {
206  int ptoVersion = 0;
207  if (newPano.loadPTScript(prjfile, ptoVersion, ""))
208  {
209  m_pano.setMemento(newPano);
210  m_validPTO = true;
211  for (size_t i = 0; i < m_pano.getNrOfImages(); ++i)
212  {
213  const wxString imageFilename(wxString(m_pano.getImage(i).getFilename().c_str(), HUGIN_CONV_FILENAME));
214  m_orignalFilenames.Add(imageFilename);
215  m_mappedFilenames.Add(imageFilename);
216  };
217  };
218  };
219 }
220 
222 {
223  long selItem = -1;
224  if (m_imagesListCtrl->GetSelectedItemCount() > 0)
225  {
226  // remember selected item
227  selItem = m_imagesListCtrl->GetNextItem(selItem, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
228  };
229  m_imagesListCtrl->DeleteAllItems();
231  for (size_t i = 0; i < m_orignalFilenames.size(); ++i)
232  {
233  const size_t index = m_imagesListCtrl->GetItemCount();
234  m_imagesListCtrl->InsertItem(index, m_orignalFilenames[i]);
235  m_imagesListCtrl->SetItem(index, 1, m_mappedFilenames[i]);
236  };
237  // restore selected item
238  if (selItem != -1)
239  {
240  m_imagesListCtrl->SetItemState(selItem, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
241  };
242 }
243 
245 {
246  wxDirDialog dlg(this, _("Specify a directory to search for projects in"),
247  m_basepath->GetValue(), wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST);
248  if (dlg.ShowModal() == wxID_OK)
249  {
250  m_basepath->SetValue(dlg.GetPath());
251  OnSelectSubDir(e);
252  };
253 }
254 
256 {
257  // show text ctrl only when "use name template" use selected
258  m_subDirTextCtrl->Enable(m_choiceSubDir->GetSelection() == 2);
259  if (m_choiceSubDir->GetSelection() != 2)
260  {
261  // clear input wxTextCtrl if not used
262  m_subDirTextCtrl->Clear();
263  };
264  if (m_choiceSubDir->GetSelection() == 1)
265  {
266  // get list of all sub-directories
267  wxArrayString subDirs = GetAllSubDirectories(m_basepath->GetValue());
268  m_subDirCount = subDirs.size();
269  }
270  else
271  {
272  m_subDirCount = 0;
273  };
274  UpdateCounters();
275 }
276 
278 {
279  if (m_imagesListCtrl->GetSelectedItemCount() > 0)
280  {
281  // enable all controls
282  // if one image is selected in list control
283  m_imageTemplate->Enable(true);
284  m_changeImageTemplate->Enable(true);
285  m_changeAllImagesTemplate->Enable(true);
286  // set text
287  long item = -1;
288  item = m_imagesListCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
289  m_originalImage->SetLabel(m_orignalFilenames[item]);
290  m_imageTemplate->SetValue(m_mappedFilenames[item]);
291  }
292  else
293  {
294  // no item selected, disable all related ctrl
295  m_imageTemplate->Enable(false);
296  m_changeImageTemplate->Enable(false);
297  m_changeAllImagesTemplate->Enable(false);
298  }
299 }
300 
302 {
303  if (m_imagesListCtrl->GetSelectedItemCount() > 0)
304  {
305  // find selected item
306  long item = -1;
307  item = m_imagesListCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
308  // now update value
309  m_mappedFilenames[item] = m_imageTemplate->GetValue();
310  FillImagesList();
311  }
312  else
313  {
314  wxBell();
315  };
316 }
317 
319 {
320  for (size_t i = 0; i < m_mappedFilenames.size(); ++i)
321  {
322  // update values
323  m_mappedFilenames[i] = m_imageTemplate->GetValue();
324  };
325  FillImagesList();
326 }
327 
329 {
330  UpdateCounters();
331 }
332 
334 {
335  // update %p counter
336  size_t pano_count;
337  if (m_choiceSubDir->GetSelection() == 1)
338  {
339  // iterate all sub-directories selected
340  m_spinCounterP_end->Enable(false);
341  pano_count = m_subDirCount;
342  if (pano_count > 0)
343  {
344  m_spinCounterP_end->SetValue(m_spinCounterP_offset->GetValue() + m_spinCounterI_step->GetValue() * (pano_count - 1));
345  }
346  else
347  {
348  m_spinCounterP_end->SetValue(m_spinCounterP_offset->GetValue());
349  };
350  }
351  else
352  {
353  m_spinCounterP_end->Enable(true);
354  m_spinCounterP_end->SetRange(m_spinCounterP_offset->GetValue(), m_spinCounterP_end->GetMax());
355  if (m_spinCounterP_end->GetValue() < m_spinCounterP_offset->GetValue())
356  {
357  m_spinCounterP_end->SetValue(m_spinCounterP_offset->GetValue());
358  };
359  pano_count = (m_spinCounterP_end->GetValue() - m_spinCounterP_offset->GetValue()) / m_spinCounterP_step->GetValue() + 1;
360  };
361  // update end value for image counter
362  m_spinCounterI_end->Enable(false);
363  m_spinCounterI_end->SetValue(m_spinCounterI_offset->GetValue() + m_spinCounterI_step->GetValue() * (m_pano.getNrOfImages() - 1));
364  // update end value for x counter
365  m_spinCounterX_end->Enable(false);
366  m_spinCounterX_end->SetValue(m_spinCounterX_offset->GetValue() + m_spinCounterX_step->GetValue() * (m_pano.getNrOfImages() * pano_count - 1));
367 }
368 
369 void GenerateSequenceDialog::GenerateFileList(wxArrayString& panoSubDirs, std::vector<wxArrayString>& fileList)
370 {
371  // read all counter values
372  // first update all counters if necessary
373  UpdateCounters();
374  const size_t pano_offset = m_spinCounterP_offset->GetValue();
375  const size_t pano_step = m_spinCounterP_step->GetValue();
376  const size_t pano_end = m_spinCounterP_end->GetValue();
377  const size_t pano_width = XRCCTRL(*this, "sequence_p_width", wxSpinCtrl)->GetValue();
378  const size_t img_offset = m_spinCounterI_offset->GetValue();
379  const size_t img_step = m_spinCounterI_step->GetValue();
380  const size_t img_width = XRCCTRL(*this, "sequence_i_width", wxSpinCtrl)->GetValue();
381  const size_t x_offset = m_spinCounterX_offset->GetValue();
382  const size_t x_step = m_spinCounterX_step->GetValue();
383  const size_t x_width = XRCCTRL(*this, "sequence_x_width", wxSpinCtrl)->GetValue();
384  const size_t pano_count = (pano_end - pano_offset) / pano_step + 1;
385  const size_t img_count = m_pano.getNrOfImages();
386  // generate list of all sub-directories
387  if (m_choiceSubDir->GetSelection() == 1)
388  {
389  panoSubDirs = GetAllSubDirectories(m_basepath->GetValue());
390  if (panoSubDirs.IsEmpty())
391  {
392  wxBell();
393  return;
394  };
395  }
396  else
397  {
398  wxString panoNameTemplate = m_subDirTextCtrl->GetValue();
399  panoSubDirs.resize(pano_count);
400  if (!panoNameTemplate.IsEmpty())
401  {
402  size_t panoCounter = pano_offset;
403  for (size_t i = 0; i < pano_count; ++i, panoCounter += pano_step)
404  {
405  panoSubDirs[i] = panoNameTemplate;
406  // replace placeholder
407  panoSubDirs[i].Replace("%p", GetNumberString(panoCounter, pano_width), true);
408  };
409  };
410  };
411  // now iterate all panoramas and generate file list
412  size_t panoCounter = pano_offset;
413  size_t xCounter = x_offset;
414  for (size_t i = 0; i < pano_count; ++i, panoCounter += pano_step)
415  {
416  wxFileName currentPath;
417  currentPath.SetPath(m_basepath->GetValue());
418  if (!panoSubDirs[i].IsEmpty())
419  {
420  currentPath.AppendDir(panoSubDirs[i]);
421  };
422  size_t imgCounter = img_offset;
423  wxArrayString panoFileList;
424  for (size_t j = 0; j < m_pano.getNrOfImages(); ++j, imgCounter += img_step, xCounter += x_step)
425  {
426  // replace all counter variables
427  wxString file = m_mappedFilenames[j];
428  // replace all placeholders
429  file.Replace("%p", GetNumberString(panoCounter, pano_width), true);
430  file.Replace("%i", GetNumberString(imgCounter, img_width), true);
431  file.Replace("%x", GetNumberString(xCounter, x_width), true);
432  wxFileName fileName(file);
433  fileName.MakeAbsolute(currentPath.GetPath());
434  panoFileList.Add(fileName.GetFullPath());
435  }
436  fileList.push_back(panoFileList);
437  };
438 }
439 
441 {
442  wxWindowDisabler winDisable;
443 #if wxCHECK_VERSION(3,1,0)
444  wxBusyInfo waitInfo(
445  wxBusyInfoFlags()
446  .Parent(this)
447  .Text(_("Generating preview list. Please wait..."))
448  .Icon(GetIcon())
449  );
450 #else
451  wxBusyCursor waitCursor;
452 #endif
453  // generate a preview of all images in text form
454  wxArrayString subDirList;
455  std::vector<wxArrayString> fileList;
456  GenerateFileList(subDirList, fileList);
457  wxTextCtrl* preview = XRCCTRL(*this, "sequence_preview", wxTextCtrl);
458  preview->Clear();
459  wxString text;
460 #ifdef __WXMSW__
461  const wxString linebreak("\r\n");
462 #else
463  const wxString linebreak("\n");
464 #endif
465  if (fileList.empty())
466  {
467  text.Append(_("No matching sub-directories found."));
468  }
469  else
470  {
471  // iterate above all panoramas
472  for (size_t i = 0; i < fileList.size(); ++i)
473  {
474  text.Append(wxString::Format(_("Panorama %d"), i));
475  text.Append(linebreak);
476  if (!subDirList[i].IsEmpty())
477  {
478  text.Append(wxString::Format(_("Sub-directory: %s"), subDirList[i].c_str()));
479  text.Append(linebreak);
480  };
481  // iterate above all files in current pano
482  bool missingFiles = false;
483  for (size_t j = 0; j < m_pano.getNrOfImages(); ++j)
484  {
485  text.Append("\t");
486  text.Append(fileList[i][j]);
487  if (!wxFileName::FileExists(fileList[i][j]))
488  {
489  missingFiles = true;
490  text.Append(" <-- ");
491  text.Append(_("File not found"));
492  };
493  text.Append(linebreak);
494  };
495  if (missingFiles)
496  {
497  text.Append("\t");
498  text.Append(_("This panorama will be skipped becaused of missing files."));
499  text.Append(linebreak);
500  };
501  };
502  };
503  preview->SetValue(text);
504 }
505 
510 {
511  // check image sizes, and correct parameters if required.
513  for (unsigned int i = 0; i < newPano.getNrOfImages(); i++)
514  {
515  // check if image size is correct
516  const HuginBase::SrcPanoImage& oldSrcImg = pano.getImage(i);
517  HuginBase::SrcPanoImage newSrcImg = newPano.getSrcImage(i);
518 
519  // just keep the file name
520  newSrcImg.setFilename(oldSrcImg.getFilename());
521  if (oldSrcImg.getSize() != newSrcImg.getSize())
522  {
523  // adjust size properly.
524  newSrcImg.resize(oldSrcImg.getSize(), &vars[i]);
525  }
526  newPano.setSrcImage(i, newSrcImg);
527  }
528  // now update all possible linked variables
529  for (unsigned int i = 0; i < newPano.getNrOfImages(); ++i)
530  {
531  if (!vars[i].empty())
532  {
533  newPano.updateVariables(i, vars[i]);
534  };
535  };
536  // remove all control points, they are only valid for the original template
538 }
539 
542 bool GetNewProjectFilename(long index, const HuginBase::Panorama& pano, const wxString basePath, wxFileName& projectFile, unsigned int currentIndex)
543 {
544  wxString mask;
545  projectFile.SetPath(basePath);
546  projectFile.SetExt(wxT("pto"));
547  if (!projectFile.IsDirWritable())
548  {
549  return false;
550  };
551  switch (index)
552  {
553  case 0:
554  // panoramaXX.pto
555  mask = wxString::Format("panorama%d", currentIndex);
556  break;
557  case 1:
558  // First file - last file.pto
559  {
560  const wxFileName f1(wxString(pano.getImage(0).getFilename().c_str(), HUGIN_CONV_FILENAME));
561  const wxFileName f2(wxString(pano.getImage(pano.getNrOfImages() - 1).getFilename().c_str(), HUGIN_CONV_FILENAME));
562  mask = f1.GetName() + wxT("-") + f2.GetName();
563  }
564  break;
565  case 2:
566  // Foldername.pto
567  {
568  wxArrayString folders = projectFile.GetDirs();
569  if (folders.GetCount() == 0)
570  {
571  return false;
572  }
573  mask = folders.Last();
574  }
575  break;
576  case 3:
577  // Template from preferences
578  {
579  wxFileName newProject(getDefaultProjectName(pano));
580  mask = newProject.GetName();
581  projectFile.SetName(mask);
582  };
583  break;
584  default:
585  mask = wxString::Format("panorama%d", currentIndex);
586  };
587 
588  projectFile.SetName(mask);
589  if (projectFile.FileExists())
590  {
591  unsigned int i = 1;
592  mask = mask.Append("_%d");
593  projectFile.SetName(wxString::Format(mask, i));
594  while (projectFile.FileExists())
595  {
596  i++;
597  projectFile.SetName(wxString::Format(mask, i));
598  //security fall through
599  if (i > 1000)
600  {
601  return false;
602  };
603  };
604  };
605  return true;
606 }
607 
609 {
610  wxWindowDisabler winDisable;
611 #if wxCHECK_VERSION(3,1,0)
612  wxBusyInfo waitInfo(
613  wxBusyInfoFlags()
614  .Parent(this)
615  .Text(_("Generating panorama files. Please wait..."))
616  .Icon(GetIcon())
617  );
618 #else
619  wxBusyCursor waitCursor;
620 #endif
621  wxArrayString subDirList;
622  std::vector<wxArrayString> fileList;
623  GenerateFileList(subDirList, fileList);
624  if (fileList.empty())
625  {
626  wxMessageBox(_("No matching sub-directories found."),
627 #ifdef __WXMSW__
628  wxT("PTBatcherGUI"),
629 #else
630  wxEmptyString,
631 #endif
632  wxOK | wxICON_EXCLAMATION, NULL);
633  }
634  else
635  {
636  const wxString basePath = m_basepath->GetValue();
637  wxArrayString ptoFileList;
638 
639  for (size_t i = 0; i < fileList.size(); ++i)
640  {
641  // check that all files exists
642  bool missingFiles = false;
643  for (size_t j = 0; j < m_pano.getNrOfImages(); ++j)
644  {
645  if (!wxFileName::FileExists(fileList[i][j]))
646  {
647  missingFiles = true;
648  break;
649  };
650  };
651  if (!missingFiles)
652  {
653  // now build the new panorama object
654  HuginBase::Panorama newPano;
655  bool allFilesReadable = true;
656  for (size_t j = 0; j < m_pano.getNrOfImages(); ++j)
657  {
659  image.setFilename(std::string(fileList[i][j].mb_str(HUGIN_CONV_FILENAME)));
660  if (!image.checkImageSizeKnown())
661  {
662  allFilesReadable = false;
663  break;
664  };
665  newPano.addImage(image);
666  };
667  if (allFilesReadable)
668  {
669  HuginBase::Panorama newGeneratedPano = m_pano.duplicate();
670  ApplyTemplate(newPano, newGeneratedPano);
671  // write to disc
672  wxFileName projectFile;
673  if (!GetNewProjectFilename(XRCCTRL(*this, "sequence_naming", wxChoice)->GetSelection(), newGeneratedPano, basePath, projectFile, i))
674  {
675  break;
676  };
677  const std::string scriptString(projectFile.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
678  newGeneratedPano.WritePTOFile(scriptString, hugin_utils::getPathPrefix(scriptString));
679  // all done, remember pto file name
680  ptoFileList.Add(projectFile.GetFullPath());
681  };
682  };
683  };
684  // all done, now add the pto files to queue
685  if (!ptoFileList.IsEmpty())
686  {
687  m_batchframe->AddArrayToList(ptoFileList, target);
688  };
689  EndModal(wxID_OK);
690  };
691 }
692 
694 {
696 }
697 
699 {
701 }
bool FileExists(const std::string &filename)
checks if file exists
Definition: utils.cpp:362
wxString GetNumberString(size_t x, size_t width)
return given number as string with given number of digits
Definition of GenerateSequenceDialog class.
void setMemento(const PanoramaMemento &memento)
set the internal state
Definition: Panorama.cpp:1507
void OnGenerateAssistantPanorama(wxCommandEvent &e)
generate assistant sequence button
SrcPanoImage getSrcImage(unsigned imgNr) const
get a description of a source image
Definition: Panorama.cpp:1620
HuginBase::Panorama m_pano
#define HUGIN_CONV_FILENAME
Definition: platform.h:40
bool checkImageSizeKnown()
check if the image size is known, if try to load the information from the file
void OnUpdateImageTemplate(wxCommandEvent &e)
update image filename template on selected image
Dialog for generate panoramas from a sequence of images.
void OnGenerateStitchingPanorama(wxCommandEvent &e)
generate stitching sequence button
#define DEBUG_ASSERT(cond)
Definition: utils.h:80
END_EVENT_TABLE()
include file for the hugin project
void ApplyTemplate(const HuginBase::Panorama &pano, HuginBase::Panorama &newPano)
copy the image files from pano to newPano -&gt; this corresponds to apply the template newPano to pano t...
virtual void updateVariables(const VariableMapVector &vars)
Set the variables.
Definition: Panorama.cpp:171
Panorama duplicate() const
duplicate the panorama
Definition: Panorama.cpp:1653
std::vector< VariableMap > VariableMapVector
Model for a panorama.
Definition: Panorama.h:152
std::string getPathPrefix(const std::string &filename)
Get the path to a filename.
Definition: utils.cpp:184
bool loadPTScript(std::istream &i, int &ptoVersion, const std::string &prefix="")
load a Hugin file
std::size_t getNrOfImages() const
number of images.
Definition: Panorama.h:205
void setCtrlPoints(const CPVector &points)
set all control points (Ippei: Is this supposed to be &#39;add&#39; method?)
Definition: Panorama.cpp:449
void OnSelectBasePath(wxCommandEvent &e)
show select directory dialog
void OnUpdateAllImagesTemplate(wxCommandEvent &e)
update images filename template for all images
void FillImagesList()
fill the images list with current values
void GenerateFileList(wxArrayString &panoSubDirs, std::vector< wxArrayString > &fileList)
generate a list of all panorama and images in panoramas
void OnImageListSelected(wxListEvent &e)
image in list ctrl selected
void resize(const vigra::Size2D &size, VariableMap *potentialLinkedVars)
&quot;resize&quot; image, adjusts all distortion coefficients for usage with a source image of size size potent...
IMPEX double h[25][1024]
Definition: emor.cpp:169
void OnUpdateCounters(wxSpinEvent &e)
update all spin controls with current numbers
unsigned int addImage(const SrcPanoImage &img)
the the number for a specific image
Definition: Panorama.cpp:319
bool GetNewProjectFilename(long index, const HuginBase::Panorama &pano, const wxString basePath, wxFileName &projectFile, unsigned int currentIndex)
generate filename from given settings and panorama append a number if file already exists ...
wxArrayString GetAllSubDirectories(const wxString baseDir)
return a list of all sub-directories
void DoGeneratePanorama(const Project::Target target)
generates all panoramas and add them to the batch queue with given queue target
void OnSelectSubDir(wxCommandEvent &e)
select which sub-directory should be used
void UpdateCounters()
update all counters, enable/disable end value and calculate end values
~GenerateSequenceDialog()
destructor, saves size and position
Memento class for a Panorama object.
Definition: Panorama.h:49
void OnGeneratePreview(wxCommandEvent &e)
generate preview
void ReadPTOFile()
read pto template from file
std::vector< ControlPoint > CPVector
Definition: ControlPoint.h:99
platform/compiler specific stuff.
bool WritePTOFile(const std::string &filename, const std::string &prefix="")
write data to given pto file
Definition: Panorama.cpp:2059
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
Definition: Panorama.h:211
bool IsValidPanorama() const
return true if given template is a valid pto file, if not the dialog should not be used ...
void setSrcImage(unsigned int nr, const SrcPanoImage &img)
set input image parameters
All variables of a source image.
Definition: SrcPanoImage.h:194
wxString getDefaultProjectName(const HuginBase::Panorama &pano, const wxString filenameTemplate)
gets the default project name, as defined in the preferences
void AddArrayToList(const wxArrayString &fileList, Project::Target target)
Definition: BatchFrame.cpp:507