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 #if defined __WXGTK__ && wxCHECK_VERSION(3,1,1)
00080         CheckConfigFilename();
00081 #endif
00082         wxConfig* config = new wxConfig(wxT("hugin"));
00083         wxConfigBase::Set(config);
00084 
00085         // need to explicitly initialize locale for C++ library/runtime
00086         setlocale(LC_ALL, "");
00087         // initialize i18n
00088         int localeID = config->Read(wxT("language"), (long)HUGIN_LANGUAGE);
00089         m_locale.Init(localeID);
00090         // set the name of locale recource to look for
00091         m_locale.AddCatalog(wxT("hugin"));
00092         
00093         return APP::OnInit();
00094     };
00096     virtual int OnRun()
00097     {
00098         HuginBase::Panorama pano;
00099         wxFileName inputFile(m_input);
00100         inputFile.Normalize();
00101         std::string input(inputFile.GetFullPath().mb_str(HUGIN_CONV_FILENAME));
00102         std::ifstream prjfile(input.c_str());
00103         if (!prjfile.good())
00104         {
00105             std::cerr << "could not open script : " << input << std::endl;
00106             return -1;
00107         }
00108         pano.setFilePrefix(hugin_utils::getPathPrefix(input));
00109         AppBase::DocumentData::ReadWriteError err = pano.readData(prjfile);
00110         if (err != AppBase::DocumentData::SUCCESSFUL)
00111         {
00112             std::cerr << "error while parsing panos tool script: " << input << std::endl;
00113             std::cerr << "DocumentData::ReadWriteError code: " << err << std::endl;
00114             return -1;
00115         }
00116         prjfile.close();
00117 
00118         HuginQueue::CommandQueue* commands;
00119         wxArrayString tempfiles;
00120         wxString oldCwd;
00121         if (m_runAssistant)
00122         {
00123             if (m_userAssistant.IsEmpty())
00124             {
00125                 commands = HuginQueue::GetAssistantCommandQueue(pano, m_utilsBinDir, m_input);
00126             }
00127             else
00128             {
00129                 commands = HuginQueue::GetAssistantCommandQueueUserDefined(pano, m_utilsBinDir, m_input, m_userAssistant);
00130             };
00131         }
00132         else
00133         {
00134             wxFileName outputPrefix;
00135             if (m_prefix.IsEmpty())
00136             {
00137                 outputPrefix = getDefaultOutputName(m_input, pano);
00138                 outputPrefix.Normalize();
00139             }
00140             else
00141             {
00142                 outputPrefix = m_prefix;
00143                 outputPrefix.MakeAbsolute();
00144             };
00145             oldCwd = wxFileName::GetCwd();
00146             wxFileName::SetCwd(outputPrefix.GetPath());
00147             wxString statusText;
00148             wxArrayString outputFiles;
00149             if (m_userOutput.IsEmpty())
00150             {
00151                 commands = HuginQueue::GetStitchingCommandQueue(pano, m_utilsBinDir, inputFile.GetFullPath(), outputPrefix.GetName(), statusText, outputFiles, tempfiles);
00152             }
00153             else
00154             {
00155                 commands = HuginQueue::GetStitchingCommandQueueUserOutput(pano, m_utilsBinDir, inputFile.GetFullPath(), outputPrefix.GetName(), m_userOutput, statusText, outputFiles, tempfiles);
00156             };
00157             if (!m_dryRun)
00158             {
00159                 std::cout << statusText.mb_str(wxConvLocal) << std::endl;
00160             }
00161         };
00162 
00163         if (commands->empty())
00164         {
00165             std::cout << "ERROR: Queue is empty." << std::endl;
00166             return 1;
00167         };
00168 
00169         if (m_threads == -1)
00170         {
00171             m_threads = wxConfigBase::Get()->Read(wxT("/output/NumberOfThreads"), 0l);
00172         };
00173 
00174         const bool success = HuginQueue::RunCommandsQueue(commands, m_threads, m_dryRun);
00175         if (!tempfiles.IsEmpty())
00176         {
00177             if (m_dryRun)
00178             {
00179 #ifdef __WXMSW__
00180                 std::cout << "del ";
00181 #else
00182                 std::cout << "rm ";
00183 #endif
00184                 std::cout << HuginQueue::GetQuotedFilenamesString(tempfiles).mb_str(wxConvLocal) << std::endl;
00185             }
00186             else
00187             {
00188                 // short waiting time to write all files to disc
00189                 wxMilliSleep(100);
00190                 std::cout << _("Removing temporary files...") << std::endl;
00191                 for (size_t i = 0; i < tempfiles.size(); ++i)
00192                 {
00193                     wxRemoveFile(tempfiles[i]);
00194                 };
00195             };
00196         };
00197         // restore current working dir
00198         if (!oldCwd.IsEmpty())
00199         {
00200             wxFileName::SetCwd(oldCwd);
00201         }
00202         return success ? 0 : 1;
00203     };
00204 
00206     virtual void OnInitCmdLine(wxCmdLineParser &parser)
00207     {
00208         parser.AddSwitch(wxT("h"), wxT("help"), _("shows this help message"), wxCMD_LINE_OPTION_HELP);
00209         parser.AddSwitch(wxT("a"), wxT("assistant"), _("execute assistant"));
00210         parser.AddSwitch(wxT("s"), wxT("stitching"), _("execute stitching with given project"));
00211         parser.AddOption(wxT("t"), wxT("threads"), _("number of used threads"), wxCMD_LINE_VAL_NUMBER);
00212         parser.AddOption(wxT("p"), wxT("prefix"), _("prefix used for stitching"), wxCMD_LINE_VAL_STRING);
00213         parser.AddOption(wxT("u"), wxT("user-defined-output"), _("use user defined commands in given file"), wxCMD_LINE_VAL_STRING);
00214         parser.AddLongOption(wxT("user-defined-assistant"), _("use user defined assistant commands in given file"), wxCMD_LINE_VAL_STRING);
00215         parser.AddSwitch(wxT("d"), wxT("dry-run"), _("only print commands"));
00216         parser.AddParam(wxT("input.pto"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY);
00217         m_runAssistant = false;
00218         m_runStitching = false;
00219         m_dryRun = false;
00220         m_threads = -1;
00221     }
00222 
00224     virtual bool OnCmdLineParsed(wxCmdLineParser &parser)
00225     {
00226         // we don't call the parents method of OnCmdLineParse, this will pull in other options we don't want
00227         m_runAssistant = parser.Found(wxT("a"));
00228         m_runStitching = parser.Found(wxT("s"));
00229         m_dryRun = parser.Found(wxT("d"));
00230         long threads;
00231         if (parser.Found(wxT("t"), &threads))
00232         {
00233             m_threads = threads;
00234         };
00235         parser.Found(wxT("p"), &m_prefix);
00236         parser.Found(wxT("u"), &m_userOutput);
00237         if (!m_userOutput.IsEmpty() && m_runStitching)
00238         {
00239             wxFileName userOutputFile(m_userOutput);
00240             if (!userOutputFile.FileExists())
00241             {
00242                 if (userOutputFile.GetDirCount() == 0)
00243                 {
00244                     // file not found, search now in data dir
00245                     userOutputFile.SetPath(wxString(hugin_utils::GetDataDir().c_str(), HUGIN_CONV_FILENAME));
00246                     if (!userOutputFile.FileExists())
00247                     {
00248                         const wxString testedFile1 = userOutputFile.GetFullPath();
00249                         userOutputFile.SetPath(wxString(hugin_utils::GetUserAppDataDir().c_str(), HUGIN_CONV_FILENAME));
00250                         if (!userOutputFile.FileExists())
00251                         {
00252                             std::cerr << "ERROR: File \"" << m_userOutput.mb_str(wxConvLocal) << "\" does not exists." << std::endl
00253                                 << "       Also tried files \"" << testedFile1.mb_str(wxConvLocal) << "\" and \"" << userOutputFile.GetFullPath().mb_str(wxConvLocal) << "\", which don't exist." << std::endl;
00254                             return false;
00255                         };
00256                     }
00257                     m_userOutput = userOutputFile.GetFullPath();
00258                 }
00259                 else
00260                 {
00261                     std::cerr << "ERROR: File \"" << m_userOutput.mb_str(wxConvLocal) << "\" does not exists." << std::endl;
00262                     return false;
00263                 };
00264             };
00265         }
00266         parser.Found(wxT("user-defined-assistant"), &m_userAssistant);
00267         if (!m_userAssistant.IsEmpty() && m_runAssistant)
00268         {
00269             wxFileName userAssistantFile(m_userAssistant);
00270             if (!userAssistantFile.FileExists())
00271             {
00272                 if (userAssistantFile.GetDirCount() == 0)
00273                 {
00274                     // file not found, search now in data dir
00275                     userAssistantFile.SetPath(wxString(hugin_utils::GetDataDir().c_str(), HUGIN_CONV_FILENAME));
00276                     if (!userAssistantFile.FileExists())
00277                     {
00278                         const wxString testedFile1 = userAssistantFile.GetFullPath();
00279                         userAssistantFile.SetPath(wxString(hugin_utils::GetUserAppDataDir().c_str(), HUGIN_CONV_FILENAME));
00280                         if (!userAssistantFile.FileExists())
00281                         {
00282                             std::cerr << "ERROR: File \"" << m_userAssistant.mb_str(wxConvLocal) << "\" does not exists." << std::endl
00283                                 << "       Also tried files \"" << testedFile1.mb_str(wxConvLocal) << "\" and \"" << userAssistantFile.GetFullPath().mb_str(wxConvLocal) << "\", which don't exist." << std::endl;
00284                             return false;
00285                         };
00286                     }
00287                     m_userAssistant = userAssistantFile.GetFullPath();
00288                 }
00289                 else
00290                 {
00291                     std::cerr << "ERROR: File \"" << m_userAssistant.mb_str(wxConvLocal) << "\" does not exists." << std::endl;
00292                     return false;
00293                 };
00294             };
00295         }
00296         m_input = parser.GetParam();
00297         if (!m_runAssistant && !m_runStitching)
00298         {
00299             std::cerr << "ERROR: Switch --assistant or --stitching is required." << std::endl;
00300             return false;
00301         };
00302         if (m_runAssistant == m_runStitching)
00303         {
00304             std::cerr << "ERROR: Switches --assistant and --stitching are mutually excluse." << std::endl;
00305             return false;
00306         }
00307         return true;
00308     };
00309 
00310 private:
00312     bool m_runAssistant;
00314     bool m_runStitching;
00316     wxString m_userOutput;
00318     wxString m_userAssistant;
00320     bool m_dryRun;
00322     wxString m_input;
00324     wxString m_prefix;
00326     long m_threads;
00328     wxString m_utilsBinDir;
00330     wxLocale m_locale;
00331 };
00332 
00333 DECLARE_APP(HuginExecutor)
00334 
00335 IMPLEMENT_APP_CONSOLE(HuginExecutor)

Generated on 25 Apr 2018 for Hugintrunk by  doxygen 1.4.7