hugin_executor.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00002 
00012 /*  This program is free software; you can redistribute it and/or
00013  *  modify it under the terms of the GNU General Public
00014  *  License as published by the Free Software Foundation; either
00015  *  version 2 of the License, or (at your option) any later version.
00016  *
00017  *  This software is distributed in the hope that it will be useful,
00018  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020  *  General Public License for more details.
00021  *
00022  *  You should have received a copy of the GNU General Public
00023  *  License along with this software. If not, see
00024  *  <http://www.gnu.org/licenses/>.
00025  *
00026  */
00027 
00028 #include <hugin_config.h>
00029 
00030 #include <fstream>
00031 #include <sstream>
00032 
00033 #include <wx/app.h>
00034 #include <wx/cmdline.h>
00035 #include <wx/arrstr.h>
00036 #include <wx/stdpaths.h>
00037 #if defined _WIN32
00038 // undefine DIFFERENCE defined in windows.h (included by wx/app.h)
00039 #undef DIFFERENCE
00040 #endif
00041 
00042 #include "base_wx/huginConfig.h"
00043 #include "base_wx/platform.h"
00044 #include "panodata/Panorama.h"
00045 #include "hugin/config_defaults.h"
00046 
00047 #include "base_wx/Executor.h"
00048 #include "base_wx/AssistantExecutor.h"
00049 #include "base_wx/StitchingExecutor.h"
00050 
00051 #ifdef __WXMAC__
00052 // on wxMac wxAppConsole stores the settings in another folder, so we have to use wxApp to
00053 // retrieve our settings which are stored by Hugin
00054 // wxAppConsole is accessing preferences in $HOME/appname Preferences
00055 // wxApp        is accessing preferences in  $HOME/Library/Preferences/appname Preferences
00056 #define APP wxApp
00057 #else
00058 #define APP wxAppConsole
00059 #endif
00060 
00061 class HuginExecutor : public APP
00062 {
00064     virtual bool OnInit()
00065     {
00066         wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
00067         m_utilsBinDir=exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
00068 #if defined __WXMSW__
00069         // locale setup
00070         exePath.RemoveLastDir();
00071         m_locale.AddCatalogLookupPathPrefix(exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + wxT("share\\locale"));
00072 #elif defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
00073         // nothing to do
00074 #else
00075         // add the locale directory specified during configure
00076         m_locale.AddCatalogLookupPathPrefix(wxT(INSTALL_LOCALE_DIR));
00077 #endif
00078         // init our config settings
00079         wxConfig* config = new wxConfig(wxT("hugin"));
00080         wxConfigBase::Set(config);
00081 
00082         // need to explicitly initialize locale for C++ library/runtime
00083         setlocale(LC_ALL, "");
00084         // initialize i18n
00085         int localeID = config->Read(wxT("language"), (long)HUGIN_LANGUAGE);
00086         m_locale.Init(localeID);
00087         // set the name of locale recource to look for
00088         m_locale.AddCatalog(wxT("hugin"));
00089         
00090         return APP::OnInit();
00091     };
00093     virtual int OnRun()
00094     {
00095         HuginBase::Panorama pano;
00096         wxFileName inputFile(m_input);
00097         inputFile.Normalize();
00098         std::string input(inputFile.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
00099         std::ifstream prjfile(input.c_str());
00100         if (!prjfile.good())
00101         {
00102             std::cerr << "could not open script : " << input << std::endl;
00103             return -1;
00104         }
00105         pano.setFilePrefix(hugin_utils::getPathPrefix(input));
00106         AppBase::DocumentData::ReadWriteError err = pano.readData(prjfile);
00107         if (err != AppBase::DocumentData::SUCCESSFUL)
00108         {
00109             std::cerr << "error while parsing panos tool script: " << input << std::endl;
00110             std::cerr << "DocumentData::ReadWriteError code: " << err << std::endl;
00111             return -1;
00112         }
00113         prjfile.close();
00114 
00115         HuginQueue::CommandQueue* commands;
00116         wxArrayString tempfiles;
00117         wxString oldCwd;
00118         if (m_runAssistant)
00119         {
00120             if (m_userAssistant.IsEmpty())
00121             {
00122                 commands = HuginQueue::GetAssistantCommandQueue(pano, m_utilsBinDir, m_input);
00123             }
00124             else
00125             {
00126                 commands = HuginQueue::GetAssistantCommandQueueUserDefined(pano, m_utilsBinDir, m_input, m_userAssistant);
00127             };
00128         }
00129         else
00130         {
00131             wxFileName outputPrefix;
00132             if (m_prefix.IsEmpty())
00133             {
00134                 outputPrefix = getDefaultOutputName(m_input, pano);
00135                 outputPrefix.Normalize();
00136             }
00137             else
00138             {
00139                 outputPrefix = m_prefix;
00140                 outputPrefix.MakeAbsolute();
00141             };
00142             oldCwd = wxFileName::GetCwd();
00143             wxFileName::SetCwd(outputPrefix.GetPath());
00144             wxString statusText;
00145             wxArrayString outputFiles;
00146             if (m_userOutput.IsEmpty())
00147             {
00148                 commands = HuginQueue::GetStitchingCommandQueue(pano, m_utilsBinDir, inputFile.GetFullPath(), outputPrefix.GetName(), statusText, outputFiles, tempfiles);
00149             }
00150             else
00151             {
00152                 commands = HuginQueue::GetStitchingCommandQueueUserOutput(pano, m_utilsBinDir, inputFile.GetFullPath(), outputPrefix.GetName(), m_userOutput, statusText, outputFiles, tempfiles);
00153             };
00154             if (!m_dryRun)
00155             {
00156                 std::cout << statusText.mb_str(wxConvLocal) << std::endl;
00157             }
00158         };
00159 
00160         if (commands->empty())
00161         {
00162             std::cout << "ERROR: Queue is empty." << std::endl;
00163             return 1;
00164         };
00165 
00166         if (m_threads == -1)
00167         {
00168             m_threads = wxConfigBase::Get()->Read(wxT("/output/NumberOfThreads"), 0l);
00169         };
00170 
00171         const bool success = HuginQueue::RunCommandsQueue(commands, m_threads, m_dryRun);
00172         if (!tempfiles.IsEmpty())
00173         {
00174             if (m_dryRun)
00175             {
00176 #ifdef __WXMSW__
00177                 std::cout << "del ";
00178 #else
00179                 std::cout << "rm ";
00180 #endif
00181                 std::cout << HuginQueue::GetQuotedFilenamesString(tempfiles).mb_str(wxConvLocal) << std::endl;
00182             }
00183             else
00184             {
00185                 // short waiting time to write all files to disc
00186                 wxMilliSleep(100);
00187                 std::cout << _("Removing temporary files...") << std::endl;
00188                 for (size_t i = 0; i < tempfiles.size(); ++i)
00189                 {
00190                     wxRemoveFile(tempfiles[i]);
00191                 };
00192             };
00193         };
00194         // restore current working dir
00195         if (!oldCwd.IsEmpty())
00196         {
00197             wxFileName::SetCwd(oldCwd);
00198         }
00199         return success ? 0 : 1;
00200     };
00201 
00203     virtual void OnInitCmdLine(wxCmdLineParser &parser)
00204     {
00205         parser.AddSwitch(wxT("h"), wxT("help"), _("shows this help message"), wxCMD_LINE_OPTION_HELP);
00206         parser.AddSwitch(wxT("a"), wxT("assistant"), _("execute assistant"));
00207         parser.AddSwitch(wxT("s"), wxT("stitching"), _("execute stitching with given project"));
00208         parser.AddOption(wxT("t"), wxT("threads"), _("number of used threads"), wxCMD_LINE_VAL_NUMBER);
00209         parser.AddOption(wxT("p"), wxT("prefix"), _("prefix used for stitching"), wxCMD_LINE_VAL_STRING);
00210         parser.AddOption(wxT("u"), wxT("user-defined-output"), _("use user defined commands in given file"), wxCMD_LINE_VAL_STRING);
00211         parser.AddLongOption(wxT("user-defined-assistant"), _("use user defined assistant commands in given file"), wxCMD_LINE_VAL_STRING);
00212         parser.AddSwitch(wxT("d"), wxT("dry-run"), _("only print commands"));
00213         parser.AddParam(wxT("input.pto"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY);
00214         m_runAssistant = false;
00215         m_runStitching = false;
00216         m_dryRun = false;
00217         m_threads = -1;
00218     }
00219 
00221     virtual bool OnCmdLineParsed(wxCmdLineParser &parser)
00222     {
00223         // we don't call the parents method of OnCmdLineParse, this will pull in other options we don't want
00224         m_runAssistant = parser.Found(wxT("a"));
00225         m_runStitching = parser.Found(wxT("s"));
00226         m_dryRun = parser.Found(wxT("d"));
00227         long threads;
00228         if (parser.Found(wxT("t"), &threads))
00229         {
00230             m_threads = threads;
00231         };
00232         parser.Found(wxT("p"), &m_prefix);
00233         parser.Found(wxT("u"), &m_userOutput);
00234         if (!m_userOutput.IsEmpty() && m_runStitching)
00235         {
00236             wxFileName userOutputFile(m_userOutput);
00237             if (!userOutputFile.FileExists())
00238             {
00239                 if (userOutputFile.GetDirCount() == 0)
00240                 {
00241                     // file not found, search now in data dir
00242                     userOutputFile.SetPath(wxString(hugin_utils::GetDataDir().c_str(), HUGIN_CONV_FILENAME));
00243                     if (!userOutputFile.FileExists())
00244                     {
00245                         std::cerr << "ERROR: File \"" << m_userOutput.mb_str(wxConvLocal) << "\" does not exists." << std::endl
00246                             << "       Also tried file \"" << userOutputFile.GetFullPath().mb_str(wxConvLocal) << "\", which does also not exists." << std::endl;
00247                         return false;
00248                     }
00249                     m_userOutput = userOutputFile.GetFullPath();
00250                 }
00251                 else
00252                 {
00253                     std::cerr << "ERROR: File \"" << m_userOutput.mb_str(wxConvLocal) << "\" does not exists." << std::endl;
00254                     return false;
00255                 };
00256             };
00257         }
00258         parser.Found(wxT("user-defined-assistant"), &m_userAssistant);
00259         if (!m_userAssistant.IsEmpty() && m_runAssistant)
00260         {
00261             wxFileName userAssistantFile(m_userAssistant);
00262             if (!userAssistantFile.FileExists())
00263             {
00264                 if (userAssistantFile.GetDirCount() == 0)
00265                 {
00266                     // file not found, search now in data dir
00267                     userAssistantFile.SetPath(wxString(hugin_utils::GetDataDir().c_str(), HUGIN_CONV_FILENAME));
00268                     if (!userAssistantFile.FileExists())
00269                     {
00270                         std::cerr << "ERROR: File \"" << m_userAssistant.mb_str(wxConvLocal) << "\" does not exists." << std::endl
00271                             << "       Also tried file \"" << userAssistantFile.GetFullPath().mb_str(wxConvLocal) << "\", which does also not exists." << std::endl;
00272                         return false;
00273                     }
00274                     m_userAssistant = userAssistantFile.GetFullPath();
00275                 }
00276                 else
00277                 {
00278                     std::cerr << "ERROR: File \"" << m_userAssistant.mb_str(wxConvLocal) << "\" does not exists." << std::endl;
00279                     return false;
00280                 };
00281             };
00282         }
00283         m_input = parser.GetParam();
00284         if (!m_runAssistant && !m_runStitching)
00285         {
00286             std::cerr << "ERROR: Switch --assistant or --stitching is required." << std::endl;
00287             return false;
00288         };
00289         if (m_runAssistant == m_runStitching)
00290         {
00291             std::cerr << "ERROR: Switches --assistant and --stitching are mutually excluse." << std::endl;
00292             return false;
00293         }
00294         return true;
00295     };
00296 
00297 private:
00299     bool m_runAssistant;
00301     bool m_runStitching;
00303     wxString m_userOutput;
00305     wxString m_userAssistant;
00307     bool m_dryRun;
00309     wxString m_input;
00311     wxString m_prefix;
00313     long m_threads;
00315     wxString m_utilsBinDir;
00317     wxLocale m_locale;
00318 };
00319 
00320 DECLARE_APP(HuginExecutor)
00321 
00322 IMPLEMENT_APP_CONSOLE(HuginExecutor)

Generated on 23 Jan 2018 for Hugintrunk by  doxygen 1.4.7